Bug 1845 - FlowMonitor should discard any broadcast/multicast packet
authorTommaso Pecorella <tommaso.pecorella@unifi.it>
Mon, 17 Mar 2014 19:44:36 +0100
changeset 10670 d04c750525d7
parent 10669 46c9391bc38b
child 10671 ceea137a2468
Bug 1845 - FlowMonitor should discard any broadcast/multicast packet
RELEASE_NOTES
src/flow-monitor/model/ipv4-flow-classifier.cc
src/flow-monitor/model/ipv4-flow-probe.cc
src/flow-monitor/model/ipv4-flow-probe.h
src/internet/model/ipv4-l3-protocol.cc
src/internet/model/ipv4-l3-protocol.h
--- a/RELEASE_NOTES	Mon Mar 17 19:43:11 2014 +0100
+++ b/RELEASE_NOTES	Mon Mar 17 19:44:36 2014 +0100
@@ -33,6 +33,8 @@
   from the Helper.
 - Ipv6Extension::m_dropTrace has been removed. Ipv6L3Protocol::m_dropTrace 
   is now fired when appropriate.
+- FlowMonitor does not track anymore multicast/broadcast packets, reflecting
+  its original design.
 
 Bugs fixed
 ----------
@@ -49,6 +51,7 @@
 - Bug 1841 - FlowMonitor fails to install if IPv4 is not installed in the node
 - Bug 1842 - FlowMonitor SerializeToXml<Something> should be called by the helper
 - Bug 1843 - IPv6 extensions dropped packets do not fire L3 drop trace
+- Bug 1845 - FlowMonitor should discard any broadcast/multicast packet
 - Bug 1846 - IPv6 should send Destination Unreachable if no route is available
 - Bug 1852 - cairo-wideint-private.h error cannot find definitions for fixed-width integral types
 - Bug 1853 - NS_LOG_FUNCTION broken on OSX 10.9
--- a/src/flow-monitor/model/ipv4-flow-classifier.cc	Mon Mar 17 19:43:11 2014 +0100
+++ b/src/flow-monitor/model/ipv4-flow-classifier.cc	Mon Mar 17 19:44:36 2014 +0100
@@ -103,12 +103,6 @@
 Ipv4FlowClassifier::Classify (const Ipv4Header &ipHeader, Ptr<const Packet> ipPayload,
                               uint32_t *out_flowId, uint32_t *out_packetId)
 {
-  if (ipHeader.GetDestination () == Ipv4Address::GetBroadcast ())
-    {
-      // we are not prepared to handle broadcast yet
-      return false;
-    }
-
   if (ipHeader.GetFragmentOffset () > 0 )
     {
       // Ignore fragments: they don't carry a valid L4 header
--- a/src/flow-monitor/model/ipv4-flow-probe.cc	Mon Mar 17 19:43:11 2014 +0100
+++ b/src/flow-monitor/model/ipv4-flow-probe.cc	Mon Mar 17 19:44:36 2014 +0100
@@ -196,26 +196,26 @@
 {
   NS_LOG_FUNCTION (this << node->GetId ());
 
-  Ptr<Ipv4L3Protocol> ipv4 = node->GetObject<Ipv4L3Protocol> ();
+  m_ipv4 = node->GetObject<Ipv4L3Protocol> ();
 
-  if (!ipv4->TraceConnectWithoutContext ("SendOutgoing",
-                                         MakeCallback (&Ipv4FlowProbe::SendOutgoingLogger, Ptr<Ipv4FlowProbe> (this))))
+  if (!m_ipv4->TraceConnectWithoutContext ("SendOutgoing",
+                                           MakeCallback (&Ipv4FlowProbe::SendOutgoingLogger, Ptr<Ipv4FlowProbe> (this))))
     {
       NS_FATAL_ERROR ("trace fail");
     }
-  if (!ipv4->TraceConnectWithoutContext ("UnicastForward",
-                                         MakeCallback (&Ipv4FlowProbe::ForwardLogger, Ptr<Ipv4FlowProbe> (this))))
+  if (!m_ipv4->TraceConnectWithoutContext ("UnicastForward",
+                                           MakeCallback (&Ipv4FlowProbe::ForwardLogger, Ptr<Ipv4FlowProbe> (this))))
     {
       NS_FATAL_ERROR ("trace fail");
     }
-  if (!ipv4->TraceConnectWithoutContext ("LocalDeliver",
-                                         MakeCallback (&Ipv4FlowProbe::ForwardUpLogger, Ptr<Ipv4FlowProbe> (this))))
+  if (!m_ipv4->TraceConnectWithoutContext ("LocalDeliver",
+                                           MakeCallback (&Ipv4FlowProbe::ForwardUpLogger, Ptr<Ipv4FlowProbe> (this))))
     {
       NS_FATAL_ERROR ("trace fail");
     }
 
-  if (!ipv4->TraceConnectWithoutContext ("Drop",
-                                         MakeCallback (&Ipv4FlowProbe::DropLogger, Ptr<Ipv4FlowProbe> (this))))
+  if (!m_ipv4->TraceConnectWithoutContext ("Drop",
+                                           MakeCallback (&Ipv4FlowProbe::DropLogger, Ptr<Ipv4FlowProbe> (this))))
     {
       NS_FATAL_ERROR ("trace fail");
     }
@@ -233,6 +233,8 @@
 void
 Ipv4FlowProbe::DoDispose ()
 {
+  m_ipv4 = 0;
+  m_classifier = 0;
   FlowProbe::DoDispose ();
 }
 
@@ -242,6 +244,12 @@
   FlowId flowId;
   FlowPacketId packetId;
 
+  if (!m_ipv4->IsUnicast(ipHeader.GetDestination ()))
+    {
+      // we are not prepared to handle broadcast yet
+      return;
+    }
+
   if (m_classifier->Classify (ipHeader, ipPayload, &flowId, &packetId))
     {
       uint32_t size = (ipPayload->GetSize () + ipHeader.GetSerializedSize ());
--- a/src/flow-monitor/model/ipv4-flow-probe.h	Mon Mar 17 19:43:11 2014 +0100
+++ b/src/flow-monitor/model/ipv4-flow-probe.h	Mon Mar 17 19:44:36 2014 +0100
@@ -106,6 +106,7 @@
   void QueueDropLogger (Ptr<const Packet> ipPayload);
 
   Ptr<Ipv4FlowClassifier> m_classifier; //!< the Ipv4FlowClassifier this probe is associated with
+  Ptr<Ipv4L3Protocol> m_ipv4; //!< the Ipv4L3Protocol this probe is bound to
 };
 
 
--- a/src/internet/model/ipv4-l3-protocol.cc	Mon Mar 17 19:43:11 2014 +0100
+++ b/src/internet/model/ipv4-l3-protocol.cc	Mon Mar 17 19:44:36 2014 +0100
@@ -540,6 +540,35 @@
 }
 
 bool
+Ipv4L3Protocol::IsUnicast (Ipv4Address ad) const
+{
+  NS_LOG_FUNCTION (this << ad);
+
+  if (ad.IsBroadcast () || ad.IsMulticast ())
+    {
+      return false;
+    }
+  else
+    {
+      // check for subnet-broadcast
+      for (uint32_t ifaceIndex = 0; ifaceIndex < GetNInterfaces (); ifaceIndex++)
+        {
+          for (uint32_t j = 0; j < GetNAddresses (ifaceIndex); j++)
+            {
+              Ipv4InterfaceAddress ifAddr = GetAddress (ifaceIndex, j);
+              NS_LOG_LOGIC ("Testing address " << ad << " with subnet-directed broadcast " << ifAddr.GetBroadcast () );
+              if (ad == ifAddr.GetBroadcast () )
+                {
+                  return false;
+                }
+            }
+        }
+    }
+
+  return true;
+}
+
+bool
 Ipv4L3Protocol::IsUnicast (Ipv4Address ad, Ipv4Mask interfaceMask) const
 {
   NS_LOG_FUNCTION (this << ad << interfaceMask);
--- a/src/internet/model/ipv4-l3-protocol.h	Mon Mar 17 19:43:11 2014 +0100
+++ b/src/internet/model/ipv4-l3-protocol.h	Mon Mar 17 19:44:36 2014 +0100
@@ -225,6 +225,18 @@
 
   Ptr<NetDevice> GetNetDevice (uint32_t i);
 
+  /**
+   * \brief Check if an IPv4 address is unicast according to the node.
+   *
+   * This function checks all the node's interfaces and the respective subnet masks.
+   * An address is considered unicast if it's not broadcast, subnet-broadcast or multicast.
+   *
+   * \param ad address
+   *
+   * \return true if the address is unicast
+   */
+  bool IsUnicast (Ipv4Address ad) const;
+
 protected:
 
   virtual void DoDispose (void);