Commit d0f8197a authored by Robert Ricci's avatar Robert Ricci

Comment much of PacketSensor.cc while looking for bugs.

Add a lot of additional debugging output.

Fix incorrect TCP payload size calculation - assumed Ethernet,
ignored IP and TCP option headers.

Replace weird nonstandart IpHeader structure with 'struct ip' from
netinet/ip.h .
parent afa661e8
......@@ -17,7 +17,7 @@ namespace
int getLinkLayer(struct pcap_pkthdr const * pcapInfo,
unsigned char const * packet);
void handleTcp(struct pcap_pkthdr const * pcapInfo,
IpHeader const * ipPacket,
struct ip const * ipPacket,
struct tcphdr const * tcpPacket);
void handleKernel(Connection * conn, struct tcp_info * kernel);
}
......@@ -407,13 +407,13 @@ namespace
logWrite(ERROR, "Unknown link layer type: %d", packetType);
return;
}
IpHeader const * ipPacket;
struct ip const * ipPacket;
struct tcphdr const * tcpPacket;
size_t bytesRemaining = pcapInfo->caplen - sizeof(struct ether_header);
ipPacket = reinterpret_cast<IpHeader const *>
ipPacket = reinterpret_cast<struct ip const *>
(packet + sizeof(struct ether_header));
if (bytesRemaining < sizeof(IpHeader))
if (bytesRemaining < sizeof(struct ip))
{
logWrite(ERROR, "A captured packet was too short to contain an "
"IP header");
......@@ -421,8 +421,8 @@ namespace
}
// ipHeaderLength and version are in a one byte field so
// endian-ness doesn't matter.
int ipHeaderLength = IP_HL(ipPacket);
int version = IP_V(ipPacket);
int ipHeaderLength = ipPacket->ip_hl;
int version = ipPacket->ip_v;
if (version != 4)
{
logWrite(ERROR, "A non IPv4 packet was captured");
......@@ -472,7 +472,7 @@ namespace
}
void handleTcp(struct pcap_pkthdr const * pcapInfo,
IpHeader const * ipPacket,
struct ip const * ipPacket,
struct tcphdr const * tcpPacket)
{
logWrite(PCAP, "Captured a TCP packet");
......
......@@ -32,9 +32,18 @@ Time const & PacketSensor::getAckedSendTime(void) const
void PacketSensor::localSend(PacketInfo * packet)
{
logWrite(SENSOR,
"PacketSensor::localSend() for sequence number %i",
ntohl(packet->tcp->seq));
unsigned int startSequence = ntohl(packet->tcp->seq);
if (globalSequence.inSequenceBlock(startSequence))
{
logWrite(SENSOR,
"PacketSensor::localSend() within globalSequence");
/*
* This packet should be in our list of sent packets - ie. it's a
* retransmit.
*/
list<SentPacket>::iterator pos = unacked.begin();
list<SentPacket>::iterator limit = unacked.end();
bool done = false;
......@@ -46,23 +55,46 @@ void PacketSensor::localSend(PacketInfo * packet)
done = true;
}
}
if (!done) {
logWrite(ERROR, "localSend() unable to find packet record to update.");
}
}
else
{
/*
* Not in the current window of unacked packets - create a new
* SentPacket record for it
*/
SentPacket record;
record.seqStart = startSequence;
unsigned int sequenceLength = packet->packetLength -
sizeof(struct ether_header) - IP_HL(packet->ip)*4 -
sizeof(struct tcphdr);
/*
* Caclulate the packet payload size - we have to make sure to take into
* account IP and TCP option headers
*/
unsigned int sequenceLength =
// Total length of the IP part of the packet
(ntohs(packet->ip->ip_len))
// Total length of all IP headers (including options)
- (packet->ip->ip_hl*4)
// Total length of all TCP headers (including options)
- (packet->tcp->doff*4);
record.seqEnd = record.seqStart + sequenceLength;
record.totalLength = packet->packetLength;
record.timestamp = packet->packetTime;
logWrite(SENSOR,
"PacketSensor::localSend() new record: ss=%i,sl=%i,se=%i,tl=%i",
record.seqStart);
globalSequence.seqEnd = record.seqEnd;
if (unacked.empty())
{
globalSequence.seqStart = record.seqStart;
globalSequence.seqEnd = record.seqEnd;
}
logWrite(SENSOR,
"PacketSensor::localSend(): global start = %i, global end = %i",
globalSequence.seqStart, globalSequence.seqEnd);
unacked.push_back(record);
}
......@@ -80,6 +112,10 @@ void PacketSensor::localAck(PacketInfo * packet)
while (pos != limit && !found)
{
found = pos->inSequenceBlock(ntohl(packet->tcp->ack_seq));
/*
* XXX: Assumes that SACK is not in use - assumes that this ACK is for all
* sequence numbers up to the one it's ACKing
*/
ackedSize += pos->totalLength;
if (found)
{
......@@ -113,7 +149,7 @@ void PacketSensor::localAck(PacketInfo * packet)
bool PacketSensor::SentPacket::inSequenceBlock(unsigned int sequence)
{
logWrite(SENSOR,
"PacketSensor inSequencBlock(): Is %u between %u and %u?",
"PacketSensor::inSequenceBlock(): Is %u between %u and %u?",
sequence, seqStart, seqEnd);
bool result = false;
if (seqStart < seqEnd)
......@@ -122,6 +158,9 @@ bool PacketSensor::SentPacket::inSequenceBlock(unsigned int sequence)
}
else if (seqStart > seqEnd)
{
/*
* This handles the sequence number wrapping around
*/
result = sequence >= seqStart || sequence < seqEnd;
}
if (result)
......
......@@ -165,25 +165,6 @@ struct WriteResult
Time nextWrite;
};
struct IpHeader
{
unsigned char ip_vhl; /* header length, version */
#define IP_V(ip) (((ip)->ip_vhl & 0xf0) >> 4)
#define IP_HL(ip) ((ip)->ip_vhl & 0x0f)
unsigned char ip_tos; /* type of service */
unsigned short ip_len; /* total length */
unsigned short ip_id; /* identification */
unsigned short ip_off; /* fragment offset field */
#define IP_DF 0x4000 /* dont fragment flag */
#define IP_MF 0x2000 /* more fragments flag */
#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
unsigned char ip_ttl; /* time to live */
unsigned char ip_p; /* protocol */
unsigned short ip_sum; /* checksum */
struct in_addr ip_src;
struct in_addr ip_dst; /* source and dest address */
};
struct PacketInfo
{
// packetTime+packetLength+kernel+elab
......@@ -195,7 +176,7 @@ struct PacketInfo
Time packetTime;
int packetLength;
struct tcp_info const * kernel;
IpHeader const * ip;
struct ip const * ip;
struct tcphdr const * tcp;
Order elab;
bool bufferFull;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment