Sketching a new promiscuous mode protocol handlers API; Netdevices implementation missing, though.
authorGustavo J. A. M. Carneiro <gjc@inescporto.pt>
Mon, 30 Jun 2008 19:25:58 +0100
changeset 3435 1d704c128f1f
parent 3364 8e6ac6061680
child 3436 c741d41f9bfb
Sketching a new promiscuous mode protocol handlers API; Netdevices implementation missing, though.
src/devices/csma/csma-net-device.cc
src/devices/csma/csma-net-device.h
src/devices/point-to-point/point-to-point-net-device.cc
src/devices/point-to-point/point-to-point-net-device.h
src/devices/wifi/wifi-net-device.cc
src/devices/wifi/wifi-net-device.h
src/node/net-device.h
src/node/node.cc
src/node/node.h
src/node/simple-net-device.cc
src/node/simple-net-device.h
--- a/src/devices/csma/csma-net-device.cc	Tue Jul 01 11:00:29 2008 -0700
+++ b/src/devices/csma/csma-net-device.cc	Mon Jun 30 19:25:58 2008 +0100
@@ -806,4 +806,10 @@
   m_rxCallback = cb;
 }
 
+void 
+CsmaNetDevice::SetPromiscuousReceiveCallback (NetDevice::PromiscuousReceiveCallback cb)
+{
+  // TODO
+}
+
 } // namespace ns3
--- a/src/devices/csma/csma-net-device.h	Tue Jul 01 11:00:29 2008 -0700
+++ b/src/devices/csma/csma-net-device.h	Mon Jun 30 19:25:58 2008 +0100
@@ -279,6 +279,7 @@
    * \param cb The callback.
    */
   virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
+  virtual void SetPromiscuousReceiveCallback (PromiscuousReceiveCallback cb);
 
 protected:
   /**
--- a/src/devices/point-to-point/point-to-point-net-device.cc	Tue Jul 01 11:00:29 2008 -0700
+++ b/src/devices/point-to-point/point-to-point-net-device.cc	Mon Jun 30 19:25:58 2008 +0100
@@ -458,4 +458,10 @@
   m_rxCallback = cb;
 }
 
+void 
+PointToPointNetDevice::SetPromiscuousReceiveCallback (NetDevice::PromiscuousReceiveCallback cb)
+{
+  // TODO
+}
+
 } // namespace ns3
--- a/src/devices/point-to-point/point-to-point-net-device.h	Tue Jul 01 11:00:29 2008 -0700
+++ b/src/devices/point-to-point/point-to-point-net-device.h	Mon Jun 30 19:25:58 2008 +0100
@@ -176,6 +176,7 @@
   virtual bool NeedsArp (void) const;
 
   virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
+  virtual void SetPromiscuousReceiveCallback (PromiscuousReceiveCallback cb);
 
 private:
 
--- a/src/devices/wifi/wifi-net-device.cc	Tue Jul 01 11:00:29 2008 -0700
+++ b/src/devices/wifi/wifi-net-device.cc	Mon Jun 30 19:25:58 2008 +0100
@@ -304,6 +304,12 @@
   m_forwardUp = cb;
 }
 
+void 
+WifiNetDevice::SetPromiscuousReceiveCallback (NetDevice::PromiscuousReceiveCallback cb)
+{
+  // TODO
+}
+
 void
 WifiNetDevice::ForwardUp (Ptr<Packet> packet, const Mac48Address &from)
 {
--- a/src/devices/wifi/wifi-net-device.h	Tue Jul 01 11:00:29 2008 -0700
+++ b/src/devices/wifi/wifi-net-device.h	Mon Jun 30 19:25:58 2008 +0100
@@ -100,6 +100,7 @@
   virtual void SetNode (Ptr<Node> node);
   virtual bool NeedsArp (void) const;
   virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
+  virtual void SetPromiscuousReceiveCallback (PromiscuousReceiveCallback cb);
 
 private:
   virtual void DoDispose (void);
--- a/src/node/net-device.h	Tue Jul 01 11:00:29 2008 -0700
+++ b/src/node/net-device.h	Mon Jun 30 19:25:58 2008 +0100
@@ -259,6 +259,30 @@
    */
   virtual void SetReceiveCallback (ReceiveCallback cb) = 0;
 
+  /**
+   * \param device a pointer to the net device which is calling this callback
+   * \param packet the packet received
+   * \param protocol the 16 bit protocol number associated with this packet.
+   *        This protocol number is expected to be the same protocol number
+   *        given to the Send method by the user on the sender side.
+   * \param sourceAddress source address
+   * \param destinationAddress destination address
+   * \returns true if the callback could handle the packet successfully, false
+   *          otherwise.
+   */
+  typedef Callback<bool,Ptr<NetDevice>,Ptr<Packet>,uint16_t,const Address &, const Address &> PromiscuousReceiveCallback;
+
+  /**
+   * \param cb callback to invoke whenever a packet has been received
+   *        in promiscuous mode and must be forwarded to the higher
+   *        layers, i.e. for all packets whose destination address
+   *        does NOT match the NetDevice address.  Note that
+   *        ReceiveCallback and PromiscuousReceiveCallback handle
+   *        mutually exclusive sets of packets, and you need to use
+   *        both callbacks in order to receive ALL packets.
+   */
+  virtual void SetPromiscuousReceiveCallback (PromiscuousReceiveCallback cb) = 0;
+
 };
 
 } // namespace ns3
--- a/src/node/node.cc	Tue Jul 01 11:00:29 2008 -0700
+++ b/src/node/node.cc	Mon Jun 30 19:25:58 2008 +0100
@@ -96,6 +96,7 @@
   device->SetNode (this);
   device->SetIfIndex(index);
   device->SetReceiveCallback (MakeCallback (&Node::ReceiveFromDevice, this));
+  device->SetPromiscuousReceiveCallback (MakeCallback (&Node::PromiscuousReceiveFromDevice, this));
   NotifyDeviceAdded (device);
   return index;
 }
@@ -181,6 +182,32 @@
     }
 }
 
+void
+Node::RegisterPromiscuousProtocolHandler (PromiscuousProtocolHandler handler, 
+                                          uint16_t protocolType,
+                                          Ptr<NetDevice> device)
+{
+  struct Node::PromiscuousProtocolHandlerEntry entry;
+  entry.handler = handler;
+  entry.protocol = protocolType;
+  entry.device = device;
+  m_promiscuousHandlers.push_back (entry);
+}
+
+void
+Node::UnregisterPromiscuousProtocolHandler (PromiscuousProtocolHandler handler)
+{
+  for (PromiscuousProtocolHandlerList::iterator i = m_promiscuousHandlers.begin ();
+       i != m_promiscuousHandlers.end (); i++)
+    {
+      if (i->handler.IsEqual (handler))
+        {
+          m_promiscuousHandlers.erase (i);
+          break;
+        }
+    }
+}
+
 bool
 Node::ReceiveFromDevice (Ptr<NetDevice> device, Ptr<Packet> packet, 
                          uint16_t protocol, const Address &from)
@@ -208,4 +235,32 @@
   return found;
 }
 
+
+bool
+Node::PromiscuousReceiveFromDevice (Ptr<NetDevice> device, Ptr<Packet> packet, 
+                                    uint16_t protocol, const Address &from, const Address &to)
+{
+  bool found = false;
+  // if there are (potentially) multiple handlers, we need to copy the
+  // packet before passing it to each handler, because handlers may
+  // modify it.
+  bool copyNeeded = (m_handlers.size () > 1);
+
+  for (PromiscuousProtocolHandlerList::iterator i = m_promiscuousHandlers.begin ();
+       i != m_promiscuousHandlers.end (); i++)
+    {
+      if (i->device == 0 ||
+          (i->device != 0 && i->device == device))
+        {
+          if (i->protocol == 0 || 
+              i->protocol == protocol)
+            {
+              i->handler (device, (copyNeeded ? packet->Copy () : packet), protocol, from, to);
+              found = true;
+            }
+        }
+    }
+  return found;
+}
+
 }//namespace ns3
--- a/src/node/node.h	Tue Jul 01 11:00:29 2008 -0700
+++ b/src/node/node.h	Mon Jun 30 19:25:58 2008 +0100
@@ -154,6 +154,35 @@
    */
   void UnregisterProtocolHandler (ProtocolHandler handler);
 
+  /**
+   * A promiscuous protocol handler
+   */
+  typedef Callback<void,Ptr<NetDevice>, Ptr<Packet>,uint16_t,
+                   const Address &, const Address &> PromiscuousProtocolHandler;
+  /**
+   * \param handler the handler to register
+   * \param protocolType the type of protocol this handler is 
+   *        interested in. This protocol type is a so-called
+   *        EtherType, as registered here:
+   *        http://standards.ieee.org/regauth/ethertype/eth.txt
+   *        the value zero is interpreted as matching all
+   *        protocols.
+   * \param device the device attached to this handler. If the
+   *        value is zero, the handler is attached to all
+   *        devices on this node.
+   */
+  void RegisterPromiscuousProtocolHandler (PromiscuousProtocolHandler handler, 
+                                           uint16_t protocolType,
+                                           Ptr<NetDevice> device);
+  /**
+   * \param handler the handler to unregister
+   *
+   * After this call returns, the input handler will never
+   * be invoked anymore.
+   */
+  void UnregisterPromiscuousProtocolHandler (PromiscuousProtocolHandler handler);
+
+
 protected:
   /**
    * The dispose method. Subclasses must override this method
@@ -172,6 +201,8 @@
 
   bool ReceiveFromDevice (Ptr<NetDevice> device, Ptr<Packet>, 
                           uint16_t protocol, const Address &from);
+  bool PromiscuousReceiveFromDevice (Ptr<NetDevice> device, Ptr<Packet>, 
+                                     uint16_t protocol, const Address &from, const Address &to);
   void Construct (void);
 
   struct ProtocolHandlerEntry {
@@ -185,6 +216,15 @@
   std::vector<Ptr<NetDevice> > m_devices;
   std::vector<Ptr<Application> > m_applications;
   ProtocolHandlerList m_handlers;
+
+  // promiscuous protocol handlers
+  struct PromiscuousProtocolHandlerEntry {
+    PromiscuousProtocolHandler handler;
+    uint16_t protocol;
+    Ptr<NetDevice> device;
+  };
+  typedef std::vector<struct Node::PromiscuousProtocolHandlerEntry> PromiscuousProtocolHandlerList;
+  PromiscuousProtocolHandlerList m_promiscuousHandlers;
 };
 
 } //namespace ns3
--- a/src/node/simple-net-device.cc	Tue Jul 01 11:00:29 2008 -0700
+++ b/src/node/simple-net-device.cc	Mon Jun 30 19:25:58 2008 +0100
@@ -171,6 +171,10 @@
 {
   m_rxCallback = cb;
 }
+void 
+SimpleNetDevice::SetPromiscuousReceiveCallback (NetDevice::PromiscuousReceiveCallback cb)
+{
+}
 
 void
 SimpleNetDevice::DoDispose (void)
--- a/src/node/simple-net-device.h	Tue Jul 01 11:00:29 2008 -0700
+++ b/src/node/simple-net-device.h	Mon Jun 30 19:25:58 2008 +0100
@@ -67,6 +67,7 @@
   virtual void SetNode (Ptr<Node> node);
   virtual bool NeedsArp (void) const;
   virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
+  virtual void SetPromiscuousReceiveCallback (PromiscuousReceiveCallback cb);
 
 protected:
   virtual void DoDispose (void);