--- a/RELEASE_NOTES Tue Dec 03 17:06:35 2013 -0800
+++ b/RELEASE_NOTES Mon Dec 02 23:05:14 2013 +0100
@@ -38,6 +38,7 @@
- Bug 1777 - Implement the more direct way of "using" configuration of existing tap interface
- Bug 1776 - Improve CRC performance for CsmaNetDevice in emulation modes
- Bug 1798 - Changing the rate of onOffApplication might stop transmission
+- Bug 1802 - FlowMon header deserialization problem with IPv4 fragments
- Bug 1807 - Multiple bugs in Ipv4L3Protocol::LocalDeliver
Release 3.18.1
--- a/src/flow-monitor/model/ipv4-flow-classifier.cc Tue Dec 03 17:06:35 2013 -0800
+++ b/src/flow-monitor/model/ipv4-flow-classifier.cc Mon Dec 02 23:05:14 2013 +0100
@@ -109,35 +109,49 @@
return false;
}
+ if (ipHeader.GetFragmentOffset () > 0 )
+ {
+ // Ignore fragments: they don't carry a valid L4 header
+ return false;
+ }
+
FiveTuple tuple;
tuple.sourceAddress = ipHeader.GetSource ();
tuple.destinationAddress = ipHeader.GetDestination ();
tuple.protocol = ipHeader.GetProtocol ();
- switch (tuple.protocol)
+ if ((tuple.protocol != UDP_PROT_NUMBER) && (tuple.protocol != TCP_PROT_NUMBER))
{
- case UDP_PROT_NUMBER:
- {
- UdpHeader udpHeader;
- ipPayload->PeekHeader (udpHeader);
- tuple.sourcePort = udpHeader.GetSourcePort ();
- tuple.destinationPort = udpHeader.GetDestinationPort ();
- }
- break;
+ return false;
+ }
- case TCP_PROT_NUMBER:
- {
- TcpHeader tcpHeader;
- ipPayload->PeekHeader (tcpHeader);
- tuple.sourcePort = tcpHeader.GetSourcePort ();
- tuple.destinationPort = tcpHeader.GetDestinationPort ();
- }
- break;
-
- default:
+ if (ipPayload->GetSize () < 4)
+ {
+ // the packet doesn't carry enough bytes
return false;
}
+ // we rely on the fact that for both TCP and UDP the ports are
+ // carried in the first 4 octects.
+ // This allows to read the ports even on fragmented packets
+ // not carrying a full TCP or UDP header.
+
+ uint8_t data[4];
+ ipPayload->CopyData (data, 4);
+
+ uint16_t srcPort = 0;
+ srcPort |= data[0];
+ srcPort <<= 8;
+ srcPort |= data[1];
+
+ uint16_t dstPort = 0;
+ dstPort |= data[2];
+ dstPort <<= 8;
+ dstPort |= data[3];
+
+ tuple.sourcePort = srcPort;
+ tuple.destinationPort = dstPort;
+
// try to insert the tuple, but check if it already exists
std::pair<std::map<FiveTuple, FlowId>::iterator, bool> insert
= m_flowMap.insert (std::pair<FiveTuple, FlowId> (tuple, 0));