New API considering comments from Craig: NetDevice->Node uses two callbacks; Node->ProtocolHandlers uses a single API with a promiscuous flag.
authorGustavo J. A. M. Carneiro <gjc@inescporto.pt>
Wed, 16 Jul 2008 16:06:50 +0100
changeset 3460 99698bc858e8
parent 3459 a67df503c7bc
child 3461 b38ddf78470a
New API considering comments from Craig: NetDevice->Node uses two callbacks; Node->ProtocolHandlers uses a single API with a promiscuous flag.
bindings/python/callbacks_list.py
bindings/python/ns3_module_bridge.py
bindings/python/ns3_module_core.py
bindings/python/ns3_module_csma.py
bindings/python/ns3_module_node.py
bindings/python/ns3_module_point_to_point.py
bindings/python/ns3_module_wifi.py
src/devices/bridge/bridge-net-device.cc
src/devices/bridge/bridge-net-device.h
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/wifi/wifi-net-device.cc
src/node/net-device.cc
src/node/net-device.h
src/node/node.cc
src/node/node.h
src/node/simple-net-device.cc
--- a/bindings/python/callbacks_list.py	Wed Jul 16 14:33:44 2008 +0100
+++ b/bindings/python/callbacks_list.py	Wed Jul 16 16:06:50 2008 +0100
@@ -6,6 +6,7 @@
     ['bool', 'ns3::Ptr<ns3::Socket>', 'ns3::Address const&', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
     ['void', 'ns3::Ptr<ns3::Packet>', 'ns3::Mac48Address const&', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
     ['bool', 'ns3::Ptr<ns3::NetDevice>', 'ns3::Ptr<ns3::Packet>', 'unsigned short', 'ns3::Address const&', 'ns3::Address const&', 'ns3::NetDevice::PacketType'],
+    ['bool', 'ns3::Ptr<ns3::NetDevice>', 'ns3::Ptr<ns3::Packet>', 'unsigned short', 'ns3::Address const&', 'ns3::empty', 'ns3::empty'],
     ['void', 'ns3::Ptr<ns3::NetDevice>', 'ns3::Ptr<ns3::Packet>', 'unsigned short', 'ns3::Address const&', 'ns3::Address const&', 'ns3::NetDevice::PacketType'],
     ['void', 'ns3::Ptr<ns3::Packet>', 'double', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
     ['void', 'ns3::Ptr<ns3::Packet>', 'double', 'ns3::WifiMode', 'ns3::WifiPreamble', 'ns3::empty', 'ns3::empty'],
--- a/bindings/python/ns3_module_bridge.py	Wed Jul 16 14:33:44 2008 +0100
+++ b/bindings/python/ns3_module_bridge.py	Wed Jul 16 16:06:50 2008 +0100
@@ -102,8 +102,12 @@
     cls.add_method('SetNode', 'void', [param('ns3::Ptr< ns3::Node >', 'node')], is_virtual=True)
     ## bridge-net-device.h: bool ns3::BridgeNetDevice::NeedsArp() const [member function]
     cls.add_method('NeedsArp', 'bool', [], is_const=True, is_virtual=True)
-    ## bridge-net-device.h: void ns3::BridgeNetDevice::SetReceiveCallback(ns3::Callback<bool, ns3::Ptr<ns3::NetDevice>, ns3::Ptr<ns3::Packet>, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> cb) [member function]
-    cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'cb')], is_virtual=True)
+    ## bridge-net-device.h: void ns3::BridgeNetDevice::SetReceiveCallback(ns3::Callback<bool, ns3::Ptr<ns3::NetDevice>, ns3::Ptr<ns3::Packet>, unsigned short, ns3::Address const&, ns3::empty, ns3::empty> cb) [member function]
+    cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')], is_virtual=True)
+    ## bridge-net-device.h: void ns3::BridgeNetDevice::SetPromiscReceiveCallback(ns3::Callback<bool, ns3::Ptr<ns3::NetDevice>, ns3::Ptr<ns3::Packet>, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> cb) [member function]
+    cls.add_method('SetPromiscReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'cb')], is_virtual=True)
+    ## bridge-net-device.h: bool ns3::BridgeNetDevice::SupportsPromiscuous() const [member function]
+    cls.add_method('SupportsPromiscuous', 'bool', [], is_const=True, is_virtual=True)
     ## bridge-net-device.h: void ns3::BridgeNetDevice::DoDispose() [member function]
     cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True)
     ## bridge-net-device.h: void ns3::BridgeNetDevice::ReceiveFromDevice(ns3::Ptr<ns3::NetDevice> device, ns3::Ptr<ns3::Packet> packet, uint16_t protocol, ns3::Address const & source, ns3::Address const & destination, ns3::NetDevice::PacketType packetType) [member function]
--- a/bindings/python/ns3_module_core.py	Wed Jul 16 14:33:44 2008 +0100
+++ b/bindings/python/ns3_module_core.py	Wed Jul 16 16:06:50 2008 +0100
@@ -21,12 +21,16 @@
     module.add_class('SystemWallClockMs')
     ## callback.h: ns3::CallbackImplBase [class]
     module.add_class('CallbackImplBase', incref_method='Ref', allow_subclassing=True, decref_method='Unref', peekref_method='GetReferenceCount')
+    ## system-mutex.h: ns3::CriticalSection [class]
+    module.add_class('CriticalSection')
     ## trace-source-accessor.h: ns3::TraceSourceAccessor [class]
     module.add_class('TraceSourceAccessor', allow_subclassing=True)
     ## attribute.h: ns3::AttributeChecker [class]
     module.add_class('AttributeChecker', incref_method='Ref', allow_subclassing=False, automatic_type_narrowing=True, decref_method='Unref', parent=root_module['ns3::RefCountBase'])
     ## random-variable.h: ns3::RandomVariableChecker [class]
     module.add_class('RandomVariableChecker', parent=root_module['ns3::AttributeChecker'])
+    ## system-mutex.h: ns3::SystemMutex [class]
+    module.add_class('SystemMutex')
     ## random-variable.h: ns3::NormalVariable [class]
     module.add_class('NormalVariable', parent=root_module['ns3::RandomVariable'])
     ## object-factory.h: ns3::ObjectFactory [class]
@@ -37,6 +41,8 @@
     module.add_class('ParetoVariable', parent=root_module['ns3::RandomVariable'])
     ## random-variable.h: ns3::ConstantVariable [class]
     module.add_class('ConstantVariable', parent=root_module['ns3::RandomVariable'])
+    ## system-thread.h: ns3::SystemThread [class]
+    module.add_class('SystemThread')
     ## random-variable.h: ns3::EmpiricalVariable [class]
     module.add_class('EmpiricalVariable', parent=root_module['ns3::RandomVariable'])
     ## enum.h: ns3::EnumChecker [class]
@@ -121,6 +127,8 @@
     module.add_class('Object', incref_method='Ref', automatic_type_narrowing=True, decref_method='Unref', parent=root_module['ns3::ObjectBase'], peekref_method='GetReferenceCount')
     ## object.h: ns3::Object::AggregateIterator [class]
     module.add_class('AggregateIterator', outer_class=root_module['ns3::Object'])
+    ## system-condition.h: ns3::SystemCondition [class]
+    module.add_class('SystemCondition')
     ## random-variable.h: ns3::SequentialVariable [class]
     module.add_class('SequentialVariable', parent=root_module['ns3::RandomVariable'])
     ## object-vector.h: ns3::ObjectVectorChecker [class]
@@ -219,14 +227,17 @@
     register_Ns3TypeIdAttributeInfo_methods(root_module, root_module['ns3::TypeId::AttributeInfo'])
     register_Ns3SystemWallClockMs_methods(root_module, root_module['ns3::SystemWallClockMs'])
     register_Ns3CallbackImplBase_methods(root_module, root_module['ns3::CallbackImplBase'])
+    register_Ns3CriticalSection_methods(root_module, root_module['ns3::CriticalSection'])
     register_Ns3TraceSourceAccessor_methods(root_module, root_module['ns3::TraceSourceAccessor'])
     register_Ns3AttributeChecker_methods(root_module, root_module['ns3::AttributeChecker'])
     register_Ns3RandomVariableChecker_methods(root_module, root_module['ns3::RandomVariableChecker'])
+    register_Ns3SystemMutex_methods(root_module, root_module['ns3::SystemMutex'])
     register_Ns3NormalVariable_methods(root_module, root_module['ns3::NormalVariable'])
     register_Ns3ObjectFactory_methods(root_module, root_module['ns3::ObjectFactory'])
     register_Ns3AttributeAccessor_methods(root_module, root_module['ns3::AttributeAccessor'])
     register_Ns3ParetoVariable_methods(root_module, root_module['ns3::ParetoVariable'])
     register_Ns3ConstantVariable_methods(root_module, root_module['ns3::ConstantVariable'])
+    register_Ns3SystemThread_methods(root_module, root_module['ns3::SystemThread'])
     register_Ns3EmpiricalVariable_methods(root_module, root_module['ns3::EmpiricalVariable'])
     register_Ns3EnumChecker_methods(root_module, root_module['ns3::EnumChecker'])
     register_Ns3Empty_methods(root_module, root_module['ns3::empty'])
@@ -262,6 +273,7 @@
     register_Ns3UniformVariable_methods(root_module, root_module['ns3::UniformVariable'])
     register_Ns3Object_methods(root_module, root_module['ns3::Object'])
     register_Ns3ObjectAggregateIterator_methods(root_module, root_module['ns3::Object::AggregateIterator'])
+    register_Ns3SystemCondition_methods(root_module, root_module['ns3::SystemCondition'])
     register_Ns3SequentialVariable_methods(root_module, root_module['ns3::SequentialVariable'])
     register_Ns3ObjectVectorChecker_methods(root_module, root_module['ns3::ObjectVectorChecker'])
     register_Ns3StringChecker_methods(root_module, root_module['ns3::StringChecker'])
@@ -449,6 +461,11 @@
     cls.add_method('IsEqual', 'bool', [param('ns3::Ptr< ns3::CallbackImplBase const >', 'other')], is_pure_virtual=True, is_const=True, is_virtual=True)
     return
 
+def register_Ns3CriticalSection_methods(root_module, cls):
+    ## system-mutex.h: ns3::CriticalSection::CriticalSection(ns3::SystemMutex & mutex) [constructor]
+    cls.add_constructor([param('ns3::SystemMutex&', 'mutex')], visibility='public')
+    return
+
 def register_Ns3TraceSourceAccessor_methods(root_module, cls):
     ## trace-source-accessor.h: ns3::TraceSourceAccessor::TraceSourceAccessor() [constructor]
     cls.add_constructor([], visibility='public')
@@ -487,6 +504,15 @@
     cls.add_constructor([])
     return
 
+def register_Ns3SystemMutex_methods(root_module, cls):
+    ## system-mutex.h: ns3::SystemMutex::SystemMutex() [constructor]
+    cls.add_constructor([], visibility='public')
+    ## system-mutex.h: void ns3::SystemMutex::Lock() [member function]
+    cls.add_method('Lock', 'void', [])
+    ## system-mutex.h: void ns3::SystemMutex::Unlock() [member function]
+    cls.add_method('Unlock', 'void', [])
+    return
+
 def register_Ns3NormalVariable_methods(root_module, cls):
     ## random-variable.h: ns3::NormalVariable::NormalVariable() [constructor]
     cls.add_constructor([], visibility='public')
@@ -555,6 +581,19 @@
     cls.add_method('SetConstant', 'void', [param('double', 'c')])
     return
 
+def register_Ns3SystemThread_methods(root_module, cls):
+    ## system-thread.h: ns3::SystemThread::SystemThread(ns3::Callback<void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> callback) [constructor]
+    cls.add_constructor([param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')], visibility='public')
+    ## system-thread.h: void ns3::SystemThread::Ref() const [member function]
+    cls.add_method('Ref', 'void', [], is_const=True)
+    ## system-thread.h: void ns3::SystemThread::Unref() const [member function]
+    cls.add_method('Unref', 'void', [], is_const=True)
+    ## system-thread.h: void ns3::SystemThread::Start() [member function]
+    cls.add_method('Start', 'void', [])
+    ## system-thread.h: void ns3::SystemThread::Join() [member function]
+    cls.add_method('Join', 'void', [])
+    return
+
 def register_Ns3EmpiricalVariable_methods(root_module, cls):
     ## random-variable.h: ns3::EmpiricalVariable::EmpiricalVariable() [constructor]
     cls.add_constructor([], visibility='public')
@@ -944,6 +983,23 @@
     cls.add_method('Next', 'ns3::Ptr< ns3::Object const >', [])
     return
 
+def register_Ns3SystemCondition_methods(root_module, cls):
+    ## system-condition.h: ns3::SystemCondition::SystemCondition() [constructor]
+    cls.add_constructor([], visibility='public')
+    ## system-condition.h: void ns3::SystemCondition::SetCondition(bool condition) [member function]
+    cls.add_method('SetCondition', 'void', [param('bool', 'condition')])
+    ## system-condition.h: bool ns3::SystemCondition::GetCondition() [member function]
+    cls.add_method('GetCondition', 'bool', [])
+    ## system-condition.h: void ns3::SystemCondition::Signal() [member function]
+    cls.add_method('Signal', 'void', [])
+    ## system-condition.h: void ns3::SystemCondition::Broadcast() [member function]
+    cls.add_method('Broadcast', 'void', [])
+    ## system-condition.h: void ns3::SystemCondition::Wait() [member function]
+    cls.add_method('Wait', 'void', [])
+    ## system-condition.h: bool ns3::SystemCondition::TimedWait(uint64_t ns) [member function]
+    cls.add_method('TimedWait', 'bool', [param('uint64_t', 'ns')])
+    return
+
 def register_Ns3SequentialVariable_methods(root_module, cls):
     ## random-variable.h: ns3::SequentialVariable::SequentialVariable(double f, double l, double i=1, uint32_t c=1) [constructor]
     cls.add_constructor([param('double', 'f'), param('double', 'l'), param('double', 'i', default_value='1'), param('uint32_t', 'c', default_value='1')], visibility='public')
--- a/bindings/python/ns3_module_csma.py	Wed Jul 16 14:33:44 2008 +0100
+++ b/bindings/python/ns3_module_csma.py	Wed Jul 16 16:06:50 2008 +0100
@@ -213,8 +213,12 @@
     cls.add_method('SetNode', 'void', [param('ns3::Ptr< ns3::Node >', 'node')], is_virtual=True)
     ## csma-net-device.h: bool ns3::CsmaNetDevice::NeedsArp() const [member function]
     cls.add_method('NeedsArp', 'bool', [], is_const=True, is_virtual=True)
-    ## csma-net-device.h: void ns3::CsmaNetDevice::SetReceiveCallback(ns3::Callback<bool, ns3::Ptr<ns3::NetDevice>, ns3::Ptr<ns3::Packet>, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> cb) [member function]
-    cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'cb')], is_virtual=True)
+    ## csma-net-device.h: void ns3::CsmaNetDevice::SetReceiveCallback(ns3::Callback<bool, ns3::Ptr<ns3::NetDevice>, ns3::Ptr<ns3::Packet>, unsigned short, ns3::Address const&, ns3::empty, ns3::empty> cb) [member function]
+    cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')], is_virtual=True)
+    ## csma-net-device.h: void ns3::CsmaNetDevice::SetPromiscReceiveCallback(ns3::Callback<bool, ns3::Ptr<ns3::NetDevice>, ns3::Ptr<ns3::Packet>, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> cb) [member function]
+    cls.add_method('SetPromiscReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'cb')], is_virtual=True)
+    ## csma-net-device.h: bool ns3::CsmaNetDevice::SupportsPromiscuous() const [member function]
+    cls.add_method('SupportsPromiscuous', 'bool', [], is_const=True, is_virtual=True)
     ## csma-net-device.h: void ns3::CsmaNetDevice::DoDispose() [member function]
     cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True)
     ## csma-net-device.h: ns3::Ptr<ns3::Queue> ns3::CsmaNetDevice::GetQueue() const [member function]
--- a/bindings/python/ns3_module_node.py	Wed Jul 16 14:33:44 2008 +0100
+++ b/bindings/python/ns3_module_node.py	Wed Jul 16 16:06:50 2008 +0100
@@ -77,10 +77,10 @@
     module.add_class('AddressValue', parent=root_module['ns3::AttributeValue'])
     ## node.h: ns3::Node [class]
     module.add_class('Node', parent=root_module['ns3::Object'])
+    ## channel.h: ns3::Channel [class]
+    module.add_class('Channel', parent=root_module['ns3::Object'])
     ## tcp-socket.h: ns3::TcpSocket [class]
     module.add_class('TcpSocket', parent=root_module['ns3::Socket'])
-    ## channel.h: ns3::Channel [class]
-    module.add_class('Channel', parent=root_module['ns3::Object'])
     ## ethernet-header.h: ns3::EthernetHeader [class]
     module.add_class('EthernetHeader', parent=root_module['ns3::Header'])
     ## socket.h: ns3::SocketIpTtlTag [class]
@@ -175,8 +175,8 @@
     register_Ns3NetDevice_methods(root_module, root_module['ns3::NetDevice'])
     register_Ns3AddressValue_methods(root_module, root_module['ns3::AddressValue'])
     register_Ns3Node_methods(root_module, root_module['ns3::Node'])
+    register_Ns3Channel_methods(root_module, root_module['ns3::Channel'])
     register_Ns3TcpSocket_methods(root_module, root_module['ns3::TcpSocket'])
-    register_Ns3Channel_methods(root_module, root_module['ns3::Channel'])
     register_Ns3EthernetHeader_methods(root_module, root_module['ns3::EthernetHeader'])
     register_Ns3SocketIpTtlTag_methods(root_module, root_module['ns3::SocketIpTtlTag'])
     register_Ns3Ipv4_methods(root_module, root_module['ns3::Ipv4'])
@@ -861,8 +861,12 @@
     cls.add_method('SetNode', 'void', [param('ns3::Ptr< ns3::Node >', 'node')], is_pure_virtual=True, is_virtual=True)
     ## net-device.h: bool ns3::NetDevice::NeedsArp() const [member function]
     cls.add_method('NeedsArp', 'bool', [], is_pure_virtual=True, is_const=True, is_virtual=True)
-    ## net-device.h: void ns3::NetDevice::SetReceiveCallback(ns3::Callback<bool, ns3::Ptr<ns3::NetDevice>, ns3::Ptr<ns3::Packet>, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> cb) [member function]
-    cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'cb')], is_pure_virtual=True, is_virtual=True)
+    ## net-device.h: void ns3::NetDevice::SetReceiveCallback(ns3::Callback<bool, ns3::Ptr<ns3::NetDevice>, ns3::Ptr<ns3::Packet>, unsigned short, ns3::Address const&, ns3::empty, ns3::empty> cb) [member function]
+    cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')], is_pure_virtual=True, is_virtual=True)
+    ## net-device.h: void ns3::NetDevice::SetPromiscReceiveCallback(ns3::Callback<bool, ns3::Ptr<ns3::NetDevice>, ns3::Ptr<ns3::Packet>, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> cb) [member function]
+    cls.add_method('SetPromiscReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'cb')], is_virtual=True)
+    ## net-device.h: bool ns3::NetDevice::SupportsPromiscuous() const [member function]
+    cls.add_method('SupportsPromiscuous', 'bool', [], is_const=True, is_virtual=True)
     cls.add_constructor([])
     return
 
@@ -908,20 +912,33 @@
     cls.add_method('GetFirstApplication', 'ns3::Ptr< ns3::Application >', [param('ns3::TypeId', 'tid')])
     ## node.h: uint32_t ns3::Node::GetNApplications() const [member function]
     cls.add_method('GetNApplications', 'uint32_t', [], is_const=True)
-    ## node.h: void ns3::Node::RegisterProtocolHandler(ns3::Callback<void, ns3::Ptr<ns3::NetDevice>, ns3::Ptr<ns3::Packet>, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> handler, uint16_t protocolType, ns3::Ptr<ns3::NetDevice> device) [member function]
-    cls.add_method('RegisterProtocolHandler', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'handler'), param('uint16_t', 'protocolType'), param('ns3::Ptr< ns3::NetDevice >', 'device')])
+    ## node.h: void ns3::Node::RegisterProtocolHandler(ns3::Callback<void, ns3::Ptr<ns3::NetDevice>, ns3::Ptr<ns3::Packet>, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> handler, uint16_t protocolType, ns3::Ptr<ns3::NetDevice> device, bool promiscuous=false) [member function]
+    cls.add_method('RegisterProtocolHandler', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'handler'), param('uint16_t', 'protocolType'), param('ns3::Ptr< ns3::NetDevice >', 'device'), param('bool', 'promiscuous', default_value='false')])
     ## node.h: void ns3::Node::UnregisterProtocolHandler(ns3::Callback<void, ns3::Ptr<ns3::NetDevice>, ns3::Ptr<ns3::Packet>, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> handler) [member function]
     cls.add_method('UnregisterProtocolHandler', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'handler')])
-    ## node.h: void ns3::Node::RegisterPromiscuousProtocolHandler(ns3::Callback<void,ns3::Ptr<ns3::NetDevice>,ns3::Ptr<ns3::Packet>,short unsigned int,const ns3::Address&,const ns3::Address&,bool> handler, uint16_t protocolType, ns3::Ptr<ns3::NetDevice> device) [member function]
-    cls.add_method('RegisterPromiscuousProtocolHandler', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, short unsigned int, const ns3::Address&, const ns3::Address&, bool >', 'handler'), param('uint16_t', 'protocolType'), param('ns3::Ptr< ns3::NetDevice >', 'device')])
-    ## node.h: void ns3::Node::UnregisterPromiscuousProtocolHandler(ns3::Callback<void,ns3::Ptr<ns3::NetDevice>,ns3::Ptr<ns3::Packet>,short unsigned int,const ns3::Address&,const ns3::Address&,bool> handler) [member function]
-    cls.add_method('UnregisterPromiscuousProtocolHandler', 'void', [param('ns3::Callback< void, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, short unsigned int, const ns3::Address&, const ns3::Address&, bool >', 'handler')])
     ## node.h: void ns3::Node::DoDispose() [member function]
     cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True)
     ## node.h: void ns3::Node::NotifyDeviceAdded(ns3::Ptr<ns3::NetDevice> device) [member function]
     cls.add_method('NotifyDeviceAdded', 'void', [param('ns3::Ptr< ns3::NetDevice >', 'device')], visibility='private', is_virtual=True)
     return
 
+def register_Ns3Channel_methods(root_module, cls):
+    ## channel.h: static ns3::TypeId ns3::Channel::GetTypeId() [member function]
+    cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True)
+    ## channel.h: ns3::Channel::Channel() [constructor]
+    cls.add_constructor([], visibility='public')
+    ## channel.h: ns3::Channel::Channel(std::string name) [constructor]
+    cls.add_constructor([param('std::string', 'name')], visibility='public')
+    ## channel.h: void ns3::Channel::SetName(std::string arg0) [member function]
+    cls.add_method('SetName', 'void', [param('std::string', 'arg0')])
+    ## channel.h: std::string ns3::Channel::GetName() [member function]
+    cls.add_method('GetName', 'std::string', [])
+    ## channel.h: uint32_t ns3::Channel::GetNDevices() const [member function]
+    cls.add_method('GetNDevices', 'uint32_t', [], is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## channel.h: ns3::Ptr<ns3::NetDevice> ns3::Channel::GetDevice(uint32_t i) const [member function]
+    cls.add_method('GetDevice', 'ns3::Ptr< ns3::NetDevice >', [param('uint32_t', 'i')], is_pure_virtual=True, is_const=True, is_virtual=True)
+    return
+
 def register_Ns3TcpSocket_methods(root_module, cls):
     ## tcp-socket.h: static ns3::TypeId ns3::TcpSocket::GetTypeId() [member function]
     cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True)
@@ -969,23 +986,6 @@
     cls.add_method('GetDelAckMaxCount', 'uint32_t', [], is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True)
     return
 
-def register_Ns3Channel_methods(root_module, cls):
-    ## channel.h: static ns3::TypeId ns3::Channel::GetTypeId() [member function]
-    cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True)
-    ## channel.h: ns3::Channel::Channel() [constructor]
-    cls.add_constructor([], visibility='public')
-    ## channel.h: ns3::Channel::Channel(std::string name) [constructor]
-    cls.add_constructor([param('std::string', 'name')], visibility='public')
-    ## channel.h: void ns3::Channel::SetName(std::string arg0) [member function]
-    cls.add_method('SetName', 'void', [param('std::string', 'arg0')])
-    ## channel.h: std::string ns3::Channel::GetName() [member function]
-    cls.add_method('GetName', 'std::string', [])
-    ## channel.h: uint32_t ns3::Channel::GetNDevices() const [member function]
-    cls.add_method('GetNDevices', 'uint32_t', [], is_pure_virtual=True, is_const=True, is_virtual=True)
-    ## channel.h: ns3::Ptr<ns3::NetDevice> ns3::Channel::GetDevice(uint32_t i) const [member function]
-    cls.add_method('GetDevice', 'ns3::Ptr< ns3::NetDevice >', [param('uint32_t', 'i')], is_pure_virtual=True, is_const=True, is_virtual=True)
-    return
-
 def register_Ns3EthernetHeader_methods(root_module, cls):
     ## ethernet-header.h: ns3::EthernetHeader::EthernetHeader(bool hasPreamble) [constructor]
     cls.add_constructor([param('bool', 'hasPreamble')], visibility='public')
@@ -1256,8 +1256,8 @@
     cls.add_method('SetNode', 'void', [param('ns3::Ptr< ns3::Node >', 'node')], is_virtual=True)
     ## simple-net-device.h: bool ns3::SimpleNetDevice::NeedsArp() const [member function]
     cls.add_method('NeedsArp', 'bool', [], is_const=True, is_virtual=True)
-    ## simple-net-device.h: void ns3::SimpleNetDevice::SetReceiveCallback(ns3::Callback<bool, ns3::Ptr<ns3::NetDevice>, ns3::Ptr<ns3::Packet>, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> cb) [member function]
-    cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'cb')], is_virtual=True)
+    ## simple-net-device.h: void ns3::SimpleNetDevice::SetReceiveCallback(ns3::Callback<bool, ns3::Ptr<ns3::NetDevice>, ns3::Ptr<ns3::Packet>, unsigned short, ns3::Address const&, ns3::empty, ns3::empty> cb) [member function]
+    cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')], is_virtual=True)
     ## simple-net-device.h: void ns3::SimpleNetDevice::DoDispose() [member function]
     cls.add_method('DoDispose', 'void', [], visibility='protected', is_virtual=True)
     return
--- a/bindings/python/ns3_module_point_to_point.py	Wed Jul 16 14:33:44 2008 +0100
+++ b/bindings/python/ns3_module_point_to_point.py	Wed Jul 16 16:06:50 2008 +0100
@@ -131,8 +131,8 @@
     cls.add_method('SetNode', 'void', [param('ns3::Ptr< ns3::Node >', 'node')], is_virtual=True)
     ## point-to-point-net-device.h: bool ns3::PointToPointNetDevice::NeedsArp() const [member function]
     cls.add_method('NeedsArp', 'bool', [], is_const=True, is_virtual=True)
-    ## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetReceiveCallback(ns3::Callback<bool, ns3::Ptr<ns3::NetDevice>, ns3::Ptr<ns3::Packet>, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> cb) [member function]
-    cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'cb')], is_virtual=True)
+    ## point-to-point-net-device.h: void ns3::PointToPointNetDevice::SetReceiveCallback(ns3::Callback<bool, ns3::Ptr<ns3::NetDevice>, ns3::Ptr<ns3::Packet>, unsigned short, ns3::Address const&, ns3::empty, ns3::empty> cb) [member function]
+    cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')], is_virtual=True)
     ## point-to-point-net-device.h: void ns3::PointToPointNetDevice::DoDispose() [member function]
     cls.add_method('DoDispose', 'void', [], visibility='private', is_virtual=True)
     return
--- a/bindings/python/ns3_module_wifi.py	Wed Jul 16 14:33:44 2008 +0100
+++ b/bindings/python/ns3_module_wifi.py	Wed Jul 16 16:06:50 2008 +0100
@@ -1075,8 +1075,8 @@
     cls.add_method('SetNode', 'void', [param('ns3::Ptr< ns3::Node >', 'node')], is_virtual=True)
     ## wifi-net-device.h: bool ns3::WifiNetDevice::NeedsArp() const [member function]
     cls.add_method('NeedsArp', 'bool', [], is_const=True, is_virtual=True)
-    ## wifi-net-device.h: void ns3::WifiNetDevice::SetReceiveCallback(ns3::Callback<bool, ns3::Ptr<ns3::NetDevice>, ns3::Ptr<ns3::Packet>, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType> cb) [member function]
-    cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::Address const&, ns3::NetDevice::PacketType >', 'cb')], is_virtual=True)
+    ## wifi-net-device.h: void ns3::WifiNetDevice::SetReceiveCallback(ns3::Callback<bool, ns3::Ptr<ns3::NetDevice>, ns3::Ptr<ns3::Packet>, unsigned short, ns3::Address const&, ns3::empty, ns3::empty> cb) [member function]
+    cls.add_method('SetReceiveCallback', 'void', [param('ns3::Callback< bool, ns3::Ptr< ns3::NetDevice >, ns3::Ptr< ns3::Packet >, unsigned short, ns3::Address const&, ns3::empty, ns3::empty >', 'cb')], is_virtual=True)
     ## wifi-net-device.h: void ns3::WifiNetDevice::DoDispose() [member function]
     cls.add_method('DoDispose', 'void', [], visibility='private', is_virtual=True)
     return
--- a/src/devices/bridge/bridge-net-device.cc	Wed Jul 16 14:33:44 2008 +0100
+++ b/src/devices/bridge/bridge-net-device.cc	Wed Jul 16 16:06:50 2008 +0100
@@ -68,19 +68,23 @@
   Mac48Address src48 = Mac48Address::ConvertFrom (src);
   Mac48Address dst48 = Mac48Address::ConvertFrom (dst);
 
+  if (!m_promiscRxCallback.IsNull ())
+    {
+      m_promiscRxCallback (this, packet, protocol, src, dst, packetType);
+    }
 
   switch (packetType)
     {
     case PACKET_HOST:
       if (dst48 == m_address)
         {
-          m_rxCallback (this, packet, protocol, src, dst, packetType);
+          m_rxCallback (this, packet, protocol, src);
         }
       break;
 
     case PACKET_BROADCAST:
     case PACKET_MULTICAST:
-      m_rxCallback (this, packet, protocol, src, dst, packetType);
+      m_rxCallback (this, packet, protocol, src);
       ForwardBroadcast (incomingPort, packet, protocol, src48, dst48);
       break;
 
@@ -160,12 +164,13 @@
 {
   if (m_enableLearning)
     {
+      Time now = Simulator::Now ();
       std::map<Mac48Address, LearnedState>::iterator iter =
         m_learnState.find (source);
       if (iter != m_learnState.end ())
         {
           LearnedState &state = iter->second;
-          if (state.expirationTime > Simulator::Now ())
+          if (state.expirationTime > now)
             {
               return state.associatedPort;
             }
@@ -187,8 +192,9 @@
       m_address = Mac48Address::ConvertFrom (bridgePort->GetAddress ());
     }
 
+  NS_LOG_DEBUG ("RegisterProtocolHandler for " << bridgePort->GetName ());
   m_node->RegisterProtocolHandler (MakeCallback (&BridgeNetDevice::ReceiveFromDevice, this),
-                                   0, bridgePort);
+                                   0, bridgePort, true);
   m_ports.push_back (bridgePort);
   m_channel->AddChannel (bridgePort->GetChannel ());
 }
@@ -396,6 +402,18 @@
   m_rxCallback = cb;
 }
 
+void 
+BridgeNetDevice::SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb)
+{
+  m_promiscRxCallback = cb;
+}
+
+bool
+BridgeNetDevice::SupportsPromiscuous () const
+{
+  return true;
+}
+
 
 void
 BridgeNetDevice::DoDispose (void)
--- a/src/devices/bridge/bridge-net-device.h	Wed Jul 16 14:33:44 2008 +0100
+++ b/src/devices/bridge/bridge-net-device.h	Wed Jul 16 16:06:50 2008 +0100
@@ -66,6 +66,8 @@
   virtual void SetNode (Ptr<Node> node);
   virtual bool NeedsArp (void) const;
   virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
+  virtual void SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb);
+  virtual bool SupportsPromiscuous () const;
 
 protected:
   virtual void DoDispose (void);
@@ -81,6 +83,7 @@
 
 private:
   NetDevice::ReceiveCallback m_rxCallback;
+  NetDevice::PromiscReceiveCallback m_promiscRxCallback;
 
   Mac48Address m_address;
   Time m_expirationTime; // time it takes for learned MAC state to expire
--- a/src/devices/csma/csma-net-device.cc	Wed Jul 16 14:33:44 2008 +0100
+++ b/src/devices/csma/csma-net-device.cc	Wed Jul 16 16:06:50 2008 +0100
@@ -481,7 +481,11 @@
   if (m_encapMode == RAW)
     {
       m_rxTrace (packet);
-      m_rxCallback (this, packet, 0, GetBroadcast (), GetAddress (), PACKET_HOST);
+      if (!m_promiscRxCallback.IsNull ())
+        {
+          m_promiscRxCallback (this, packet, 0, GetBroadcast (), GetAddress (), PACKET_HOST);
+        }
+      m_rxCallback (this, packet, 0, GetBroadcast ());
       return;
     }
 
@@ -575,7 +579,15 @@
           packetType = PACKET_OTHERHOST;
         }
       
-      m_rxCallback (this, packet, protocol, header.GetSource (), header.GetDestination (), packetType);
+      if (!m_promiscRxCallback.IsNull ())
+        {
+          m_promiscRxCallback (this, packet, protocol, header.GetSource (), header.GetDestination (), packetType);
+        }
+
+      if (packetType != PACKET_OTHERHOST)
+        {
+          m_rxCallback (this, packet, protocol, header.GetSource ());
+        }
     }
 }
 
@@ -847,4 +859,16 @@
   m_rxCallback = cb;
 }
 
+void 
+CsmaNetDevice::SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb)
+{
+  m_promiscRxCallback = cb;
+}
+
+bool 
+CsmaNetDevice::SupportsPromiscuous () const
+{
+  return true;
+}
+
 } // namespace ns3
--- a/src/devices/csma/csma-net-device.h	Wed Jul 16 14:33:44 2008 +0100
+++ b/src/devices/csma/csma-net-device.h	Wed Jul 16 16:06:50 2008 +0100
@@ -287,6 +287,10 @@
    */
   virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
 
+
+  virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb);
+  virtual bool SupportsPromiscuous (void) const;
+
 protected:
   /**
    * Perform any object release functionality required to break reference 
@@ -533,6 +537,10 @@
    * The callback used to notify higher layers that a packet has been received.
    */
   NetDevice::ReceiveCallback m_rxCallback;
+  /**
+   * The callback used to notify higher layers that a packet has been received in promiscuous mode.
+   */
+  NetDevice::PromiscReceiveCallback m_promiscRxCallback;
 
   /**
    * The interface index (really net evice index) that has been assigned to 
--- a/src/devices/point-to-point/point-to-point-net-device.cc	Wed Jul 16 14:33:44 2008 +0100
+++ b/src/devices/point-to-point/point-to-point-net-device.cc	Wed Jul 16 16:06:50 2008 +0100
@@ -241,7 +241,7 @@
 //
       m_rxTrace (packet);
       ProcessHeader(packet, protocol);
-      m_rxCallback (this, packet, protocol, GetBroadcast (), m_address, PACKET_HOST);
+      m_rxCallback (this, packet, protocol, GetBroadcast ());
     }
 }
 
--- a/src/devices/wifi/wifi-net-device.cc	Wed Jul 16 14:33:44 2008 +0100
+++ b/src/devices/wifi/wifi-net-device.cc	Wed Jul 16 16:06:50 2008 +0100
@@ -316,9 +316,7 @@
   m_rxLogger (packet, from);
   LlcSnapHeader llc;
   packet->RemoveHeader (llc);
-  Mac48Address to = from; // FIXME
-  PacketType packetType = PACKET_HOST; // FIXME
-  m_forwardUp (this, packet, llc.GetType (), from, to, packetType);
+  m_forwardUp (this, packet, llc.GetType (), from);
 }
 
 void
--- a/src/node/net-device.cc	Wed Jul 16 14:33:44 2008 +0100
+++ b/src/node/net-device.cc	Wed Jul 16 16:06:50 2008 +0100
@@ -38,4 +38,19 @@
 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
--- a/src/node/net-device.h	Wed Jul 16 14:33:44 2008 +0100
+++ b/src/node/net-device.h	Wed Jul 16 16:06:50 2008 +0100
@@ -271,11 +271,10 @@
    *        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 @@
    */
   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
--- a/src/node/node.cc	Wed Jul 16 14:33:44 2008 +0100
+++ b/src/node/node.cc	Wed Jul 16 16:06:50 2008 +0100
@@ -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 @@
   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 @@
 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 @@
 }
 
 bool
+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)
+                         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 @@
           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;
+                }
             }
         }
     }
--- a/src/node/node.h	Wed Jul 16 14:33:44 2008 +0100
+++ b/src/node/node.h	Wed Jul 16 16:06:50 2008 +0100
@@ -136,6 +136,20 @@
 
   /**
    * 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 @@
    * \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 @@
    */
   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 @@
    */
   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;
+    Ptr<NetDevice> device;
     uint16_t protocol;
-    Ptr<NetDevice> device;
+    bool promiscuous;
   };
   typedef std::vector<struct Node::ProtocolHandlerEntry> ProtocolHandlerList;
   uint32_t    m_id;         // Node id for this node
--- a/src/node/simple-net-device.cc	Wed Jul 16 14:33:44 2008 +0100
+++ b/src/node/simple-net-device.cc	Wed Jul 16 16:06:50 2008 +0100
@@ -59,7 +59,7 @@
     {
       NS_FATAL_ERROR ("Weird packet destination " << to);
     }
-  m_rxCallback (this, packet, protocol, from, to, packetType);
+  m_rxCallback (this, packet, protocol, from);
 }
 
 void