From bf513e45d2422dbcecd45f293c41fc75d50d831f Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Mon, 30 Jun 2008 19:25:58 +0100 Subject: [PATCH] Sketching a new promiscuous mode protocol handlers API; Netdevices implementation missing, though. --- src/devices/csma/csma-net-device.cc | 6 ++ src/devices/csma/csma-net-device.h | 1 + .../point-to-point-net-device.cc | 6 ++ .../point-to-point-net-device.h | 1 + src/devices/wifi/wifi-net-device.cc | 6 ++ src/devices/wifi/wifi-net-device.h | 1 + src/node/net-device.h | 24 ++++++++ src/node/node.cc | 55 +++++++++++++++++++ src/node/node.h | 40 ++++++++++++++ src/node/simple-net-device.cc | 4 ++ src/node/simple-net-device.h | 1 + 11 files changed, 145 insertions(+) diff --git a/src/devices/csma/csma-net-device.cc b/src/devices/csma/csma-net-device.cc index 09734519b..05dde61b3 100644 --- a/src/devices/csma/csma-net-device.cc +++ b/src/devices/csma/csma-net-device.cc @@ -806,4 +806,10 @@ CsmaNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb) m_rxCallback = cb; } +void +CsmaNetDevice::SetPromiscuousReceiveCallback (NetDevice::PromiscuousReceiveCallback cb) +{ + // TODO +} + } // namespace ns3 diff --git a/src/devices/csma/csma-net-device.h b/src/devices/csma/csma-net-device.h index 440206d23..f283c9c47 100644 --- a/src/devices/csma/csma-net-device.h +++ b/src/devices/csma/csma-net-device.h @@ -279,6 +279,7 @@ public: * \param cb The callback. */ virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb); + virtual void SetPromiscuousReceiveCallback (PromiscuousReceiveCallback cb); protected: /** diff --git a/src/devices/point-to-point/point-to-point-net-device.cc b/src/devices/point-to-point/point-to-point-net-device.cc index 6e3ea3f5a..d7100177d 100644 --- a/src/devices/point-to-point/point-to-point-net-device.cc +++ b/src/devices/point-to-point/point-to-point-net-device.cc @@ -458,4 +458,10 @@ PointToPointNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb) m_rxCallback = cb; } +void +PointToPointNetDevice::SetPromiscuousReceiveCallback (NetDevice::PromiscuousReceiveCallback cb) +{ + // TODO +} + } // namespace ns3 diff --git a/src/devices/point-to-point/point-to-point-net-device.h b/src/devices/point-to-point/point-to-point-net-device.h index 6b63ecb37..2cdadd122 100644 --- a/src/devices/point-to-point/point-to-point-net-device.h +++ b/src/devices/point-to-point/point-to-point-net-device.h @@ -176,6 +176,7 @@ public: virtual bool NeedsArp (void) const; virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb); + virtual void SetPromiscuousReceiveCallback (PromiscuousReceiveCallback cb); private: diff --git a/src/devices/wifi/wifi-net-device.cc b/src/devices/wifi/wifi-net-device.cc index f3bcad80d..44eb5acac 100644 --- a/src/devices/wifi/wifi-net-device.cc +++ b/src/devices/wifi/wifi-net-device.cc @@ -304,6 +304,12 @@ WifiNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb) m_forwardUp = cb; } +void +WifiNetDevice::SetPromiscuousReceiveCallback (NetDevice::PromiscuousReceiveCallback cb) +{ + // TODO +} + void WifiNetDevice::ForwardUp (Ptr packet, const Mac48Address &from) { diff --git a/src/devices/wifi/wifi-net-device.h b/src/devices/wifi/wifi-net-device.h index 6740b9e20..b66cedc11 100644 --- a/src/devices/wifi/wifi-net-device.h +++ b/src/devices/wifi/wifi-net-device.h @@ -100,6 +100,7 @@ public: virtual void SetNode (Ptr node); virtual bool NeedsArp (void) const; virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb); + virtual void SetPromiscuousReceiveCallback (PromiscuousReceiveCallback cb); private: virtual void DoDispose (void); diff --git a/src/node/net-device.h b/src/node/net-device.h index 3e5af9e36..f0fe4de36 100644 --- a/src/node/net-device.h +++ b/src/node/net-device.h @@ -259,6 +259,30 @@ public: */ 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,Ptr,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 diff --git a/src/node/node.cc b/src/node/node.cc index ef56ec6db..d7e032174 100644 --- a/src/node/node.cc +++ b/src/node/node.cc @@ -96,6 +96,7 @@ Node::AddDevice (Ptr device) 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 @@ Node::UnregisterProtocolHandler (ProtocolHandler handler) } } +void +Node::RegisterPromiscuousProtocolHandler (PromiscuousProtocolHandler handler, + uint16_t protocolType, + Ptr 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 device, Ptr packet, uint16_t protocol, const Address &from) @@ -208,4 +235,32 @@ Node::ReceiveFromDevice (Ptr device, Ptr packet, return found; } + +bool +Node::PromiscuousReceiveFromDevice (Ptr device, Ptr 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 diff --git a/src/node/node.h b/src/node/node.h index 8a48d1d62..3588ffc19 100644 --- a/src/node/node.h +++ b/src/node/node.h @@ -154,6 +154,35 @@ public: */ void UnregisterProtocolHandler (ProtocolHandler handler); + /** + * A promiscuous protocol handler + */ + typedef Callback, Ptr,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 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 @@ private: bool ReceiveFromDevice (Ptr device, Ptr, uint16_t protocol, const Address &from); + bool PromiscuousReceiveFromDevice (Ptr device, Ptr, + uint16_t protocol, const Address &from, const Address &to); void Construct (void); struct ProtocolHandlerEntry { @@ -185,6 +216,15 @@ private: std::vector > m_devices; std::vector > m_applications; ProtocolHandlerList m_handlers; + + // promiscuous protocol handlers + struct PromiscuousProtocolHandlerEntry { + PromiscuousProtocolHandler handler; + uint16_t protocol; + Ptr device; + }; + typedef std::vector PromiscuousProtocolHandlerList; + PromiscuousProtocolHandlerList m_promiscuousHandlers; }; } //namespace ns3 diff --git a/src/node/simple-net-device.cc b/src/node/simple-net-device.cc index 50e4c3611..5b30922d3 100644 --- a/src/node/simple-net-device.cc +++ b/src/node/simple-net-device.cc @@ -171,6 +171,10 @@ SimpleNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb) { m_rxCallback = cb; } +void +SimpleNetDevice::SetPromiscuousReceiveCallback (NetDevice::PromiscuousReceiveCallback cb) +{ +} void SimpleNetDevice::DoDispose (void) diff --git a/src/node/simple-net-device.h b/src/node/simple-net-device.h index 19ce5ef3a..fb98e53d7 100644 --- a/src/node/simple-net-device.h +++ b/src/node/simple-net-device.h @@ -67,6 +67,7 @@ public: virtual void SetNode (Ptr node); virtual bool NeedsArp (void) const; virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb); + virtual void SetPromiscuousReceiveCallback (PromiscuousReceiveCallback cb); protected: virtual void DoDispose (void);