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:
Gustavo J. A. M. Carneiro
2008-07-16 16:06:50 +01:00
parent ccb5ec4d4d
commit c33568c079
18 changed files with 299 additions and 88 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}
}
}
}

View File

@@ -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

View File

@@ -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