From d0f8197a1a1d27adaedd481287424a37908c35cd Mon Sep 17 00:00:00 2001 From: Robert Ricci Date: Thu, 17 Aug 2006 23:00:28 +0000 Subject: [PATCH] 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 . --- pelab/magent/KernelTcp.cc | 14 +++++------ pelab/magent/PacketSensor.cc | 47 +++++++++++++++++++++++++++++++++--- pelab/magent/lib.h | 21 +--------------- 3 files changed, 51 insertions(+), 31 deletions(-) diff --git a/pelab/magent/KernelTcp.cc b/pelab/magent/KernelTcp.cc index 90b2357d9..426810476 100755 --- a/pelab/magent/KernelTcp.cc +++ b/pelab/magent/KernelTcp.cc @@ -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 + ipPacket = reinterpret_cast (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"); diff --git a/pelab/magent/PacketSensor.cc b/pelab/magent/PacketSensor.cc index 80bfa951f..b6613a19c 100644 --- a/pelab/magent/PacketSensor.cc +++ b/pelab/magent/PacketSensor.cc @@ -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::iterator pos = unacked.begin(); list::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) diff --git a/pelab/magent/lib.h b/pelab/magent/lib.h index 22bf0af12..0d33eb05c 100755 --- a/pelab/magent/lib.h +++ b/pelab/magent/lib.h @@ -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; -- GitLab