New API considering comments from Craig: NetDevice->Node uses two callbacks; Node->ProtocolHandlers uses a single API with a promiscuous flag.
This commit is contained in:
@@ -38,4 +38,19 @@ TypeId NetDevice::GetTypeId (void)
|
||||
NetDevice::~NetDevice ()
|
||||
{}
|
||||
|
||||
bool
|
||||
NetDevice::SupportsPromiscuous () const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
NetDevice::SetPromiscReceiveCallback (PromiscReceiveCallback cb)
|
||||
{
|
||||
// assert that the virtual method was overridden in a subclass if it
|
||||
// claims to support promiscuous mode.
|
||||
NS_ASSERT (!SupportsPromiscuous ());
|
||||
}
|
||||
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -271,11 +271,10 @@ public:
|
||||
* This protocol number is expected to be the same protocol number
|
||||
* given to the Send method by the user on the sender side.
|
||||
* \param sender the address of the sender
|
||||
* \param receiver the address of the receiver
|
||||
* \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 &, PacketType> ReceiveCallback;
|
||||
typedef Callback<bool,Ptr<NetDevice>,Ptr<Packet>,uint16_t,const Address &> ReceiveCallback;
|
||||
|
||||
/**
|
||||
* \param cb callback to invoke whenever a packet has been received and must
|
||||
@@ -284,6 +283,39 @@ 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 sender the address of the sender
|
||||
* \param receiver the address of the receiver
|
||||
* \param packetType type of packet received (broadcast/multicast/unicast/otherhost)
|
||||
* \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 &, PacketType > PromiscReceiveCallback;
|
||||
|
||||
/**
|
||||
* \param cb callback to invoke whenever a packet has been received in promiscuous mode and must
|
||||
* be forwarded to the higher layers.
|
||||
*
|
||||
* Enables netdevice promiscuous mode and sets the callback that
|
||||
* will handle promiscuous mode packets. Note, promiscuous mode
|
||||
* packets means _all_ packets, including those packets that can be
|
||||
* sensed by the netdevice but which are intended to be received by
|
||||
* other hosts.
|
||||
*/
|
||||
virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb);
|
||||
|
||||
/**
|
||||
* \return true if this interface supports a promiscuous mode, false otherwise.
|
||||
*/
|
||||
virtual bool SupportsPromiscuous (void) const;
|
||||
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -26,6 +26,9 @@
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/object-vector.h"
|
||||
#include "ns3/uinteger.h"
|
||||
#include "ns3/log.h"
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("Node");
|
||||
|
||||
namespace ns3{
|
||||
|
||||
@@ -95,7 +98,7 @@ Node::AddDevice (Ptr<NetDevice> device)
|
||||
m_devices.push_back (device);
|
||||
device->SetNode (this);
|
||||
device->SetIfIndex(index);
|
||||
device->SetReceiveCallback (MakeCallback (&Node::ReceiveFromDevice, this));
|
||||
device->SetReceiveCallback (MakeCallback (&Node::NonPromiscReceiveFromDevice, this));
|
||||
NotifyDeviceAdded (device);
|
||||
return index;
|
||||
}
|
||||
@@ -170,12 +173,44 @@ Node::NotifyDeviceAdded (Ptr<NetDevice> device)
|
||||
void
|
||||
Node::RegisterProtocolHandler (ProtocolHandler handler,
|
||||
uint16_t protocolType,
|
||||
Ptr<NetDevice> device)
|
||||
Ptr<NetDevice> device,
|
||||
bool promiscuous)
|
||||
{
|
||||
struct Node::ProtocolHandlerEntry entry;
|
||||
entry.handler = handler;
|
||||
entry.protocol = protocolType;
|
||||
entry.device = device;
|
||||
entry.promiscuous = promiscuous;
|
||||
|
||||
// On demand enable promiscuous mode in netdevices
|
||||
if (promiscuous)
|
||||
{
|
||||
if (device == 0)
|
||||
{
|
||||
for (std::vector<Ptr<NetDevice> >::iterator i = m_devices.begin ();
|
||||
i != m_devices.end (); i++)
|
||||
{
|
||||
Ptr<NetDevice> dev = *i;
|
||||
if (dev->SupportsPromiscuous ())
|
||||
{
|
||||
dev->SetPromiscReceiveCallback (MakeCallback (&Node::PromiscReceiveFromDevice, this));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (device->SupportsPromiscuous ())
|
||||
{
|
||||
device->SetPromiscReceiveCallback (MakeCallback (&Node::PromiscReceiveFromDevice, this));
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_WARN ("Protocol handler request promiscuous mode for a specific netdevice,"
|
||||
" but netdevice does not support promiscuous mode.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_handlers.push_back (entry);
|
||||
}
|
||||
|
||||
@@ -194,9 +229,26 @@ Node::UnregisterProtocolHandler (ProtocolHandler handler)
|
||||
}
|
||||
|
||||
bool
|
||||
Node::ReceiveFromDevice (Ptr<NetDevice> device, Ptr<Packet> packet, uint16_t protocol,
|
||||
const Address &from, const Address &to, NetDevice::PacketType packetType)
|
||||
Node::PromiscReceiveFromDevice (Ptr<NetDevice> device, Ptr<Packet> packet, uint16_t protocol,
|
||||
const Address &from, const Address &to, NetDevice::PacketType packetType)
|
||||
{
|
||||
NS_LOG_FUNCTION(device->GetName ());
|
||||
return ReceiveFromDevice (device, packet, protocol, from, to, packetType, true);
|
||||
}
|
||||
|
||||
bool
|
||||
Node::NonPromiscReceiveFromDevice (Ptr<NetDevice> device, Ptr<Packet> packet, uint16_t protocol,
|
||||
const Address &from)
|
||||
{
|
||||
NS_LOG_FUNCTION(device->GetName ());
|
||||
return ReceiveFromDevice (device, packet, protocol, from, from, NetDevice::PacketType (0), false);
|
||||
}
|
||||
|
||||
bool
|
||||
Node::ReceiveFromDevice (Ptr<NetDevice> device, Ptr<Packet> packet, uint16_t protocol,
|
||||
const Address &from, const Address &to, NetDevice::PacketType packetType, bool promiscuous)
|
||||
{
|
||||
NS_LOG_FUNCTION(device->GetName ());
|
||||
bool found = false;
|
||||
// if there are (potentially) multiple handlers, we need to copy the
|
||||
// packet before passing it to each handler, because handlers may
|
||||
@@ -212,8 +264,11 @@ Node::ReceiveFromDevice (Ptr<NetDevice> device, Ptr<Packet> packet, uint16_t pro
|
||||
if (i->protocol == 0 ||
|
||||
i->protocol == protocol)
|
||||
{
|
||||
i->handler (device, (copyNeeded ? packet->Copy () : packet), protocol, from, to, packetType);
|
||||
found = true;
|
||||
if (promiscuous == i->promiscuous)
|
||||
{
|
||||
i->handler (device, (copyNeeded ? packet->Copy () : packet), protocol, from, to, packetType);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,6 +136,20 @@ public:
|
||||
|
||||
/**
|
||||
* A protocol handler
|
||||
*
|
||||
* \param device a pointer to the net device which received the packet
|
||||
* \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 sender the address of the sender
|
||||
* \param receiver the address of the receiver; Note: this value is
|
||||
* only valid for promiscuous mode protocol
|
||||
* handlers.
|
||||
* \param packetType type of packet received
|
||||
* (broadcast/multicast/unicast/otherhost); Note:
|
||||
* this value is only valid for promiscuous mode
|
||||
* protocol handlers.
|
||||
*/
|
||||
typedef Callback<void,Ptr<NetDevice>, Ptr<Packet>,uint16_t,const Address &,
|
||||
const Address &, NetDevice::PacketType> ProtocolHandler;
|
||||
@@ -150,10 +164,12 @@ public:
|
||||
* \param device the device attached to this handler. If the
|
||||
* value is zero, the handler is attached to all
|
||||
* devices on this node.
|
||||
* \param promiscuous whether to register a promiscuous mode handler
|
||||
*/
|
||||
void RegisterProtocolHandler (ProtocolHandler handler,
|
||||
uint16_t protocolType,
|
||||
Ptr<NetDevice> device);
|
||||
Ptr<NetDevice> device,
|
||||
bool promiscuous=false);
|
||||
/**
|
||||
* \param handler the handler to unregister
|
||||
*
|
||||
@@ -162,34 +178,6 @@ public:
|
||||
*/
|
||||
void UnregisterProtocolHandler (ProtocolHandler handler);
|
||||
|
||||
/**
|
||||
* A promiscuous protocol handler
|
||||
*/
|
||||
typedef Callback<void,Ptr<NetDevice>, Ptr<Packet>,uint16_t,
|
||||
const Address &, const Address &, bool> 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:
|
||||
/**
|
||||
@@ -207,14 +195,19 @@ private:
|
||||
*/
|
||||
virtual void NotifyDeviceAdded (Ptr<NetDevice> device);
|
||||
|
||||
bool NonPromiscReceiveFromDevice (Ptr<NetDevice> device, Ptr<Packet>, uint16_t protocol, const Address &from);
|
||||
bool PromiscReceiveFromDevice (Ptr<NetDevice> device, Ptr<Packet>, uint16_t protocol,
|
||||
const Address &from, const Address &to, NetDevice::PacketType packetType);
|
||||
bool ReceiveFromDevice (Ptr<NetDevice> device, Ptr<Packet>, uint16_t protocol,
|
||||
const Address &from, const Address &to, NetDevice::PacketType packetType);
|
||||
const Address &from, const Address &to, NetDevice::PacketType packetType, bool promisc);
|
||||
|
||||
void Construct (void);
|
||||
|
||||
struct ProtocolHandlerEntry {
|
||||
ProtocolHandler handler;
|
||||
uint16_t protocol;
|
||||
Ptr<NetDevice> device;
|
||||
uint16_t protocol;
|
||||
bool promiscuous;
|
||||
};
|
||||
typedef std::vector<struct Node::ProtocolHandlerEntry> ProtocolHandlerList;
|
||||
uint32_t m_id; // Node id for this node
|
||||
|
||||
@@ -59,7 +59,7 @@ SimpleNetDevice::Receive (Ptr<Packet> packet, uint16_t protocol,
|
||||
{
|
||||
NS_FATAL_ERROR ("Weird packet destination " << to);
|
||||
}
|
||||
m_rxCallback (this, packet, protocol, from, to, packetType);
|
||||
m_rxCallback (this, packet, protocol, from);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
Reference in New Issue
Block a user