branch merge
authorCraig Dowell <craigdo@ee.washington.edu>
Mon, 23 Mar 2009 19:23:11 -0700
changeset 4291 141f01bbfa8b
parent 4290 af8a40d5c2cb (current diff)
parent 4284 2050b1c0efdd (diff)
child 4292 ef09115f80ca
branch merge
examples/tap-wifi-dumbbell.cc
src/devices/csma/csma-net-device.h
src/devices/tap-bridge/tap-bridge.cc
--- a/CHANGES.html	Mon Mar 23 18:28:08 2009 -0700
+++ b/CHANGES.html	Mon Mar 23 19:23:11 2009 -0700
@@ -51,9 +51,32 @@
 <li>ConstantAccelerationMobilityModel in src/mobility/constant-acceleration-mobility-model.h</li>
 </ul>
 
+<ul>
+<li>A new emulation mode is supported with the TapBridge net device (see</li>
+<li>src/devices/tap-bridge)</li>
+</ul>
+
+<ul>
+<li>A new facility for naming ns-3 Objects is included (see</li>
+<li>src/core/names.{cc,h})</li>
+</ul>
+
 <h2>changes to existing API:</h2>
 
 <ul>
+<li>The trace sources in the various NetDevice classes has been completely</li>
+<li>reworked to allow for a consistent set of trace sources across the</li>
+<li>devices.  The names of the trace sources have been changed to provide</li>
+<li>some context with respect to the level at which the trace occurred.</li>
+<li>A new set of trace sources has been added which emulates the behavior</li>
+<li>of packet sniffers.  These sources have been used to implement tcpdump-</li>
+<li>like functionality and are plumbed up into the helper classes.  The </li>
+<li>user-visible changes are the trace source name changes and the ability </li>
+<li>to do promiscuous-mode pcap tracing via helpers.  For further information</li>
+<li>regarding these changes, please see the ns-3 manual</li>
+</ul>
+
+<ul>
 <li>StaticMobilityModel has been renamed ConstantPositionMobilityModel</li>
 <li>StaticSpeedMobilityModel has been renamed ConstantVelocityMobilityModel</li>
 </ul>
--- a/bindings/python/ns3_module_contrib.py	Mon Mar 23 18:28:08 2009 -0700
+++ b/bindings/python/ns3_module_contrib.py	Mon Mar 23 19:23:11 2009 -0700
@@ -7,6 +7,8 @@
     module.add_class('DelayJitterEstimation')
     ## event-garbage-collector.h: ns3::EventGarbageCollector [class]
     module.add_class('EventGarbageCollector')
+    ## file-config.h: ns3::FileConfig [class]
+    module.add_class('FileConfig', allow_subclassing=True)
     ## gnuplot.h: ns3::Gnuplot [class]
     module.add_class('Gnuplot')
     ## gnuplot.h: ns3::GnuplotCollection [class]
@@ -15,8 +17,14 @@
     module.add_class('GnuplotDataset')
     ## gtk-config-store.h: ns3::GtkConfigStore [class]
     module.add_class('GtkConfigStore')
+    ## file-config.h: ns3::NoneFileConfig [class]
+    module.add_class('NoneFileConfig', parent=root_module['ns3::FileConfig'])
     ## config-store.h: ns3::ConfigStore [class]
     module.add_class('ConfigStore', parent=root_module['ns3::ObjectBase'])
+    ## config-store.h: ns3::ConfigStore::Mode [enumeration]
+    module.add_enum('Mode', ['LOAD', 'SAVE', 'NONE'], outer_class=root_module['ns3::ConfigStore'])
+    ## config-store.h: ns3::ConfigStore::FileFormat [enumeration]
+    module.add_enum('FileFormat', ['XML', 'RAW_TEXT'], outer_class=root_module['ns3::ConfigStore'])
     ## flow-id-tag.h: ns3::FlowIdTag [class]
     module.add_class('FlowIdTag', parent=root_module['ns3::Tag'])
     ## gnuplot.h: ns3::Gnuplot2dDataset [class]
@@ -75,10 +83,12 @@
 def register_methods(root_module):
     register_Ns3DelayJitterEstimation_methods(root_module, root_module['ns3::DelayJitterEstimation'])
     register_Ns3EventGarbageCollector_methods(root_module, root_module['ns3::EventGarbageCollector'])
+    register_Ns3FileConfig_methods(root_module, root_module['ns3::FileConfig'])
     register_Ns3Gnuplot_methods(root_module, root_module['ns3::Gnuplot'])
     register_Ns3GnuplotCollection_methods(root_module, root_module['ns3::GnuplotCollection'])
     register_Ns3GnuplotDataset_methods(root_module, root_module['ns3::GnuplotDataset'])
     register_Ns3GtkConfigStore_methods(root_module, root_module['ns3::GtkConfigStore'])
+    register_Ns3NoneFileConfig_methods(root_module, root_module['ns3::NoneFileConfig'])
     register_Ns3ConfigStore_methods(root_module, root_module['ns3::ConfigStore'])
     register_Ns3FlowIdTag_methods(root_module, root_module['ns3::FlowIdTag'])
     register_Ns3Gnuplot2dDataset_methods(root_module, root_module['ns3::Gnuplot2dDataset'])
@@ -124,6 +134,33 @@
                    [param('ns3::EventId', 'event')])
     return
 
+def register_Ns3FileConfig_methods(root_module, cls):
+    ## file-config.h: ns3::FileConfig::FileConfig(ns3::FileConfig const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::FileConfig const &', 'arg0')])
+    ## file-config.h: ns3::FileConfig::FileConfig() [constructor]
+    cls.add_constructor([])
+    ## file-config.h: void ns3::FileConfig::SetFilename(std::string filename) [member function]
+    cls.add_method('SetFilename', 
+                   'void', 
+                   [param('std::string', 'filename')], 
+                   is_pure_virtual=True, is_virtual=True)
+    ## file-config.h: void ns3::FileConfig::Default() [member function]
+    cls.add_method('Default', 
+                   'void', 
+                   [], 
+                   is_pure_virtual=True, is_virtual=True)
+    ## file-config.h: void ns3::FileConfig::Global() [member function]
+    cls.add_method('Global', 
+                   'void', 
+                   [], 
+                   is_pure_virtual=True, is_virtual=True)
+    ## file-config.h: void ns3::FileConfig::Attributes() [member function]
+    cls.add_method('Attributes', 
+                   'void', 
+                   [], 
+                   is_pure_virtual=True, is_virtual=True)
+    return
+
 def register_Ns3Gnuplot_methods(root_module, cls):
     ## gnuplot.h: ns3::Gnuplot::Gnuplot(ns3::Gnuplot const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::Gnuplot const &', 'arg0')])
@@ -215,12 +252,43 @@
     cls.add_constructor([param('ns3::GtkConfigStore const &', 'arg0')])
     ## gtk-config-store.h: ns3::GtkConfigStore::GtkConfigStore() [constructor]
     cls.add_constructor([])
-    ## gtk-config-store.h: void ns3::GtkConfigStore::Configure() [member function]
-    cls.add_method('Configure', 
+    ## gtk-config-store.h: void ns3::GtkConfigStore::ConfigureDefaults() [member function]
+    cls.add_method('ConfigureDefaults', 
+                   'void', 
+                   [])
+    ## gtk-config-store.h: void ns3::GtkConfigStore::ConfigureAttributes() [member function]
+    cls.add_method('ConfigureAttributes', 
                    'void', 
                    [])
     return
 
+def register_Ns3NoneFileConfig_methods(root_module, cls):
+    ## file-config.h: ns3::NoneFileConfig::NoneFileConfig(ns3::NoneFileConfig const & arg0) [copy constructor]
+    cls.add_constructor([param('ns3::NoneFileConfig const &', 'arg0')])
+    ## file-config.h: ns3::NoneFileConfig::NoneFileConfig() [constructor]
+    cls.add_constructor([])
+    ## file-config.h: void ns3::NoneFileConfig::SetFilename(std::string filename) [member function]
+    cls.add_method('SetFilename', 
+                   'void', 
+                   [param('std::string', 'filename')], 
+                   is_virtual=True)
+    ## file-config.h: void ns3::NoneFileConfig::Default() [member function]
+    cls.add_method('Default', 
+                   'void', 
+                   [], 
+                   is_virtual=True)
+    ## file-config.h: void ns3::NoneFileConfig::Global() [member function]
+    cls.add_method('Global', 
+                   'void', 
+                   [], 
+                   is_virtual=True)
+    ## file-config.h: void ns3::NoneFileConfig::Attributes() [member function]
+    cls.add_method('Attributes', 
+                   'void', 
+                   [], 
+                   is_virtual=True)
+    return
+
 def register_Ns3ConfigStore_methods(root_module, cls):
     ## config-store.h: ns3::ConfigStore::ConfigStore(ns3::ConfigStore const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::ConfigStore const &', 'arg0')])
@@ -236,8 +304,24 @@
                    is_const=True, is_virtual=True)
     ## config-store.h: ns3::ConfigStore::ConfigStore() [constructor]
     cls.add_constructor([])
-    ## config-store.h: void ns3::ConfigStore::Configure() [member function]
-    cls.add_method('Configure', 
+    ## config-store.h: void ns3::ConfigStore::SetMode(ns3::ConfigStore::Mode mode) [member function]
+    cls.add_method('SetMode', 
+                   'void', 
+                   [param('ns3::ConfigStore::Mode', 'mode')])
+    ## config-store.h: void ns3::ConfigStore::SetFileFormat(ns3::ConfigStore::FileFormat format) [member function]
+    cls.add_method('SetFileFormat', 
+                   'void', 
+                   [param('ns3::ConfigStore::FileFormat', 'format')])
+    ## config-store.h: void ns3::ConfigStore::SetFilename(std::string filename) [member function]
+    cls.add_method('SetFilename', 
+                   'void', 
+                   [param('std::string', 'filename')])
+    ## config-store.h: void ns3::ConfigStore::ConfigureDefaults() [member function]
+    cls.add_method('ConfigureDefaults', 
+                   'void', 
+                   [])
+    ## config-store.h: void ns3::ConfigStore::ConfigureAttributes() [member function]
+    cls.add_method('ConfigureAttributes', 
                    'void', 
                    [])
     return
--- a/bindings/python/ns3_module_core.py	Mon Mar 23 18:28:08 2009 -0700
+++ b/bindings/python/ns3_module_core.py	Mon Mar 23 19:23:11 2009 -0700
@@ -1984,7 +1984,7 @@
     cls.add_method('ConnectWithoutContext', 
                    'void', 
                    [param('ns3::CallbackBase const &', 'cb')])
-    ## traced-value.h: void ns3::TracedValue<unsigned int>::Connect(ns3::CallbackBase const & cb, std::string path) [member function]
+    ## traced-value.h: void ns3::TracedValue<unsigned int>::Connect(ns3::CallbackBase const & cb, std::basic_string<char,std::char_traits<char>,std::allocator<char> > path) [member function]
     cls.add_method('Connect', 
                    'void', 
                    [param('ns3::CallbackBase const &', 'cb'), param('std::string', 'path')])
@@ -1992,7 +1992,7 @@
     cls.add_method('DisconnectWithoutContext', 
                    'void', 
                    [param('ns3::CallbackBase const &', 'cb')])
-    ## traced-value.h: void ns3::TracedValue<unsigned int>::Disconnect(ns3::CallbackBase const & cb, std::string path) [member function]
+    ## traced-value.h: void ns3::TracedValue<unsigned int>::Disconnect(ns3::CallbackBase const & cb, std::basic_string<char,std::char_traits<char>,std::allocator<char> > path) [member function]
     cls.add_method('Disconnect', 
                    'void', 
                    [param('ns3::CallbackBase const &', 'cb'), param('std::string', 'path')])
--- a/bindings/python/ns3_module_helper.py	Mon Mar 23 18:28:08 2009 -0700
+++ b/bindings/python/ns3_module_helper.py	Mon Mar 23 19:23:11 2009 -0700
@@ -219,25 +219,35 @@
                    'void', 
                    [param('std::string', 'n1'), param('ns3::AttributeValue const &', 'v1')], 
                    deprecated=True)
-    ## csma-helper.h: static void ns3::CsmaHelper::EnablePcap(std::string filename, uint32_t nodeid, uint32_t deviceid) [member function]
+    ## csma-helper.h: static void ns3::CsmaHelper::EnablePcap(std::string filename, uint32_t nodeid, uint32_t deviceid, bool promiscuous) [member function]
     cls.add_method('EnablePcap', 
                    'void', 
-                   [param('std::string', 'filename'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], 
+                   [param('std::string', 'filename'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid'), param('bool', 'promiscuous')], 
                    is_static=True)
-    ## csma-helper.h: static void ns3::CsmaHelper::EnablePcap(std::string filename, ns3::NetDeviceContainer d) [member function]
+    ## csma-helper.h: static void ns3::CsmaHelper::EnablePcap(std::string filename, ns3::Ptr<ns3::NetDevice> nd, bool promiscuous) [member function]
+    cls.add_method('EnablePcap', 
+                   'void', 
+                   [param('std::string', 'filename'), param('ns3::Ptr< ns3::NetDevice >', 'nd'), param('bool', 'promiscuous')], 
+                   is_static=True)
+    ## csma-helper.h: static void ns3::CsmaHelper::EnablePcap(std::string filename, std::string ndName, bool promiscuous) [member function]
     cls.add_method('EnablePcap', 
                    'void', 
-                   [param('std::string', 'filename'), param('ns3::NetDeviceContainer', 'd')], 
+                   [param('std::string', 'filename'), param('std::string', 'ndName'), param('bool', 'promiscuous')], 
                    is_static=True)
-    ## csma-helper.h: static void ns3::CsmaHelper::EnablePcap(std::string filename, ns3::NodeContainer n) [member function]
+    ## csma-helper.h: static void ns3::CsmaHelper::EnablePcap(std::string filename, ns3::NetDeviceContainer d, bool promiscuous) [member function]
     cls.add_method('EnablePcap', 
                    'void', 
-                   [param('std::string', 'filename'), param('ns3::NodeContainer', 'n')], 
+                   [param('std::string', 'filename'), param('ns3::NetDeviceContainer', 'd'), param('bool', 'promiscuous')], 
                    is_static=True)
-    ## csma-helper.h: static void ns3::CsmaHelper::EnablePcapAll(std::string filename) [member function]
+    ## csma-helper.h: static void ns3::CsmaHelper::EnablePcap(std::string filename, ns3::NodeContainer n, bool promiscuous) [member function]
+    cls.add_method('EnablePcap', 
+                   'void', 
+                   [param('std::string', 'filename'), param('ns3::NodeContainer', 'n'), param('bool', 'promiscuous')], 
+                   is_static=True)
+    ## csma-helper.h: static void ns3::CsmaHelper::EnablePcapAll(std::string filename, bool promiscuous) [member function]
     cls.add_method('EnablePcapAll', 
                    'void', 
-                   [param('std::string', 'filename')], 
+                   [param('std::string', 'filename'), param('bool', 'promiscuous')], 
                    is_static=True)
     ## csma-helper.h: static void ns3::CsmaHelper::EnableAscii(std::ostream & os, uint32_t nodeid, uint32_t deviceid) [member function]
     cls.add_method('EnableAscii', 
@@ -327,25 +337,35 @@
     cls.add_method('SetAttribute', 
                    'void', 
                    [param('std::string', 'n1'), param('ns3::AttributeValue const &', 'v1')])
-    ## emu-helper.h: static void ns3::EmuHelper::EnablePcap(std::string filename, uint32_t nodeid, uint32_t deviceid) [member function]
+    ## emu-helper.h: static void ns3::EmuHelper::EnablePcap(std::string filename, uint32_t nodeid, uint32_t deviceid, bool promiscuous) [member function]
     cls.add_method('EnablePcap', 
                    'void', 
-                   [param('std::string', 'filename'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], 
+                   [param('std::string', 'filename'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid'), param('bool', 'promiscuous')], 
                    is_static=True)
-    ## emu-helper.h: static void ns3::EmuHelper::EnablePcap(std::string filename, ns3::NetDeviceContainer d) [member function]
+    ## emu-helper.h: static void ns3::EmuHelper::EnablePcap(std::string filename, ns3::Ptr<ns3::NetDevice> nd, bool promiscuous) [member function]
+    cls.add_method('EnablePcap', 
+                   'void', 
+                   [param('std::string', 'filename'), param('ns3::Ptr< ns3::NetDevice >', 'nd'), param('bool', 'promiscuous')], 
+                   is_static=True)
+    ## emu-helper.h: static void ns3::EmuHelper::EnablePcap(std::string filename, std::string ndName, bool promiscuous) [member function]
     cls.add_method('EnablePcap', 
                    'void', 
-                   [param('std::string', 'filename'), param('ns3::NetDeviceContainer', 'd')], 
+                   [param('std::string', 'filename'), param('std::string', 'ndName'), param('bool', 'promiscuous')], 
                    is_static=True)
-    ## emu-helper.h: static void ns3::EmuHelper::EnablePcap(std::string filename, ns3::NodeContainer n) [member function]
+    ## emu-helper.h: static void ns3::EmuHelper::EnablePcap(std::string filename, ns3::NetDeviceContainer d, bool promiscuous) [member function]
     cls.add_method('EnablePcap', 
                    'void', 
-                   [param('std::string', 'filename'), param('ns3::NodeContainer', 'n')], 
+                   [param('std::string', 'filename'), param('ns3::NetDeviceContainer', 'd'), param('bool', 'promiscuous')], 
                    is_static=True)
-    ## emu-helper.h: static void ns3::EmuHelper::EnablePcapAll(std::string filename) [member function]
+    ## emu-helper.h: static void ns3::EmuHelper::EnablePcap(std::string filename, ns3::NodeContainer n, bool promiscuous) [member function]
+    cls.add_method('EnablePcap', 
+                   'void', 
+                   [param('std::string', 'filename'), param('ns3::NodeContainer', 'n'), param('bool', 'promiscuous')], 
+                   is_static=True)
+    ## emu-helper.h: static void ns3::EmuHelper::EnablePcapAll(std::string filename, bool promiscuous) [member function]
     cls.add_method('EnablePcapAll', 
                    'void', 
-                   [param('std::string', 'filename')], 
+                   [param('std::string', 'filename'), param('bool', 'promiscuous')], 
                    is_static=True)
     ## emu-helper.h: static void ns3::EmuHelper::EnableAscii(std::ostream & os, uint32_t nodeid, uint32_t deviceid) [member function]
     cls.add_method('EnableAscii', 
@@ -801,6 +821,16 @@
                    'void', 
                    [param('std::string', 'filename'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], 
                    is_static=True)
+    ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnablePcap(std::string filename, ns3::Ptr<ns3::NetDevice> nd) [member function]
+    cls.add_method('EnablePcap', 
+                   'void', 
+                   [param('std::string', 'filename'), param('ns3::Ptr< ns3::NetDevice >', 'nd')], 
+                   is_static=True)
+    ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnablePcap(std::string filename, std::string ndName) [member function]
+    cls.add_method('EnablePcap', 
+                   'void', 
+                   [param('std::string', 'filename'), param('std::string', 'ndName')], 
+                   is_static=True)
     ## point-to-point-helper.h: static void ns3::PointToPointHelper::EnablePcap(std::string filename, ns3::NetDeviceContainer d) [member function]
     cls.add_method('EnablePcap', 
                    'void', 
@@ -1121,6 +1151,16 @@
                    'void', 
                    [param('std::string', 'filename'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')], 
                    is_static=True)
+    ## yans-wifi-helper.h: static void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, ns3::Ptr<ns3::NetDevice> nd) [member function]
+    cls.add_method('EnablePcap', 
+                   'void', 
+                   [param('std::string', 'filename'), param('ns3::Ptr< ns3::NetDevice >', 'nd')], 
+                   is_static=True)
+    ## yans-wifi-helper.h: static void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, std::string ndName) [member function]
+    cls.add_method('EnablePcap', 
+                   'void', 
+                   [param('std::string', 'filename'), param('std::string', 'ndName')], 
+                   is_static=True)
     ## yans-wifi-helper.h: static void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, ns3::NetDeviceContainer d) [member function]
     cls.add_method('EnablePcap', 
                    'void', 
--- a/bindings/python/ns3_module_wifi.py	Mon Mar 23 18:28:08 2009 -0700
+++ b/bindings/python/ns3_module_wifi.py	Mon Mar 23 19:23:11 2009 -0700
@@ -1336,6 +1336,26 @@
                    'void', 
                    [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'linkDown')], 
                    is_pure_virtual=True, is_virtual=True)
+    ## wifi-mac.h: void ns3::WifiMac::NotifyTx(ns3::Ptr<const ns3::Packet> packet) [member function]
+    cls.add_method('NotifyTx', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::Packet const >', 'packet')])
+    ## wifi-mac.h: void ns3::WifiMac::NotifyTxDrop(ns3::Ptr<const ns3::Packet> packet) [member function]
+    cls.add_method('NotifyTxDrop', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::Packet const >', 'packet')])
+    ## wifi-mac.h: void ns3::WifiMac::NotifyRx(ns3::Ptr<const ns3::Packet> packet) [member function]
+    cls.add_method('NotifyRx', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::Packet const >', 'packet')])
+    ## wifi-mac.h: void ns3::WifiMac::NotifyPromiscRx(ns3::Ptr<const ns3::Packet> packet) [member function]
+    cls.add_method('NotifyPromiscRx', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::Packet const >', 'packet')])
+    ## wifi-mac.h: void ns3::WifiMac::NotifyRxDrop(ns3::Ptr<const ns3::Packet> packet) [member function]
+    cls.add_method('NotifyRxDrop', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::Packet const >', 'packet')])
     return
 
 def register_Ns3WifiModeChecker_methods(root_module, cls):
@@ -1528,6 +1548,34 @@
                    'ns3::WifiMode', 
                    [], 
                    is_static=True)
+    ## wifi-phy.h: void ns3::WifiPhy::NotifyTxBegin(ns3::Ptr<const ns3::Packet> packet) [member function]
+    cls.add_method('NotifyTxBegin', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::Packet const >', 'packet')])
+    ## wifi-phy.h: void ns3::WifiPhy::NotifyTxEnd(ns3::Ptr<const ns3::Packet> packet) [member function]
+    cls.add_method('NotifyTxEnd', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::Packet const >', 'packet')])
+    ## wifi-phy.h: void ns3::WifiPhy::NotifyTxDrop(ns3::Ptr<const ns3::Packet> packet) [member function]
+    cls.add_method('NotifyTxDrop', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::Packet const >', 'packet')])
+    ## wifi-phy.h: void ns3::WifiPhy::NotifyRxBegin(ns3::Ptr<const ns3::Packet> packet) [member function]
+    cls.add_method('NotifyRxBegin', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::Packet const >', 'packet')])
+    ## wifi-phy.h: void ns3::WifiPhy::NotifyRxEnd(ns3::Ptr<const ns3::Packet> packet) [member function]
+    cls.add_method('NotifyRxEnd', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::Packet const >', 'packet')])
+    ## wifi-phy.h: void ns3::WifiPhy::NotifyRxDrop(ns3::Ptr<const ns3::Packet> packet) [member function]
+    cls.add_method('NotifyRxDrop', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::Packet const >', 'packet')])
+    ## wifi-phy.h: void ns3::WifiPhy::NotifyPromiscSniff(ns3::Ptr<const ns3::Packet> packet) [member function]
+    cls.add_method('NotifyPromiscSniff', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::Packet const >', 'packet')])
     return
 
 def register_Ns3WifiRemoteStationManager_methods(root_module, cls):
--- a/examples/csma-bridge-one-hop.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/examples/csma-bridge-one-hop.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -225,11 +225,11 @@
   //
   // Also configure some tcpdump traces; each interface will be traced.
   // The output files will be named:
-  //     csma-bridge.pcap-<nodeId>-<interfaceId>
+  //     csma-bridge-<nodeId>-<interfaceId>.pcap
   // and can be read by the "tcpdump -r" command (use "-tt" option to
   // display timestamps correctly)
   //
-  CsmaHelper::EnablePcapAll ("csma-bridge-one-hop");
+  CsmaHelper::EnablePcapAll ("csma-bridge-one-hop", false);
 
   //
   // Now, do the actual simulation.
--- a/examples/csma-bridge.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/examples/csma-bridge.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -150,11 +150,11 @@
   //
   // Also configure some tcpdump traces; each interface will be traced.
   // The output files will be named:
-  //     csma-bridge.pcap-<nodeId>-<interfaceId>
+  //     csma-bridge-<nodeId>-<interfaceId>.pcap
   // and can be read by the "tcpdump -r" command (use "-tt" option to
   // display timestamps correctly)
   //
-  CsmaHelper::EnablePcapAll ("csma-bridge");
+  CsmaHelper::EnablePcapAll ("csma-bridge", false);
 
   //
   // Now, do the actual simulation.
--- a/examples/csma-bridge.py	Mon Mar 23 18:28:08 2009 -0700
+++ b/examples/csma-bridge.py	Mon Mar 23 19:23:11 2009 -0700
@@ -134,7 +134,7 @@
     # and can be read by the "tcpdump -r" command(use "-tt" option to
     # display timestamps correctly)
     #
-    ns3.CsmaHelper.EnablePcapAll("csma-bridge")
+    ns3.CsmaHelper.EnablePcapAll("csma-bridge", False)
 
     #
     # Now, do the actual simulation.
--- a/examples/csma-broadcast.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/examples/csma-broadcast.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -107,9 +107,9 @@
 
   // Also configure some tcpdump traces; each interface will be traced
   // The output files will be named 
-  // csma-broadcast.pcap-<nodeId>-<interfaceId>
+  // csma-broadcast-<nodeId>-<interfaceId>.pcap
   // and can be read by the "tcpdump -tt -r" command 
-  CsmaHelper::EnablePcapAll ("csma-broadcast");
+  CsmaHelper::EnablePcapAll ("csma-broadcast", false);
   std::ofstream ascii;
   ascii.open ("csma-broadcast.tr");
   CsmaHelper::EnableAsciiAll (ascii);
--- a/examples/csma-multicast.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/examples/csma-multicast.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -171,10 +171,10 @@
 
   // Also configure some tcpdump traces; each interface will be traced.
   // The output files will be named:
-  //     csma-multicast.pcap-<nodeId>-<interfaceId>
+  //     csma-multicast-<nodeId>-<interfaceId>.pcap
   // and can be read by the "tcpdump -r" command (use "-tt" option to
   // display timestamps correctly)
-  CsmaHelper::EnablePcapAll ("csma-multicast");
+  CsmaHelper::EnablePcapAll ("csma-multicast", false);
   //
   // Now, do the actual simulation.
   //
--- a/examples/csma-one-subnet.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/examples/csma-one-subnet.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -125,11 +125,11 @@
 //
 // Also configure some tcpdump traces; each interface will be traced.
 // The output files will be named:
-//     csma-one-subnet.pcap-<nodeId>-<interfaceId>
+//     csma-one-subnet-<nodeId>-<interfaceId>.pcap
 // and can be read by the "tcpdump -r" command (use "-tt" option to
 // display timestamps correctly)
 //
-  CsmaHelper::EnablePcapAll ("csma-one-subnet");
+  CsmaHelper::EnablePcapAll ("csma-one-subnet", false);
 //
 // Now, do the actual simulation.
 //
--- a/examples/csma-ping.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/examples/csma-ping.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -117,8 +117,9 @@
   apps.Stop (Seconds (5.0));
 
   NS_LOG_INFO ("Configure Tracing.");
-  // first, pcap tracing.
-  csma.EnablePcapAll ("csma-ping");
+  // first, pcap tracing in non-promiscuous mode
+  csma.EnablePcapAll ("csma-ping", false);
+
   // then, print what the packet sink receives.
   Config::ConnectWithoutContext ("/NodeList/3/ApplicationList/0/$ns3::PacketSink/Rx", 
                                  MakeCallback (&SinkRx));
--- a/examples/csma-raw-ip-socket.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/examples/csma-raw-ip-socket.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -101,8 +101,8 @@
   apps.Stop (Seconds (11.0));
 
   NS_LOG_INFO ("Configure Tracing.");
-  // first, pcap tracing.
-  csma.EnablePcapAll ("csma-raw-ip-socket");
+  // first, pcap tracing in non-promiscuous mode
+  csma.EnablePcapAll ("csma-raw-ip-socket", false);
   // then, print what the packet sink receives.
   Config::ConnectWithoutContext ("/NodeList/3/ApplicationList/0/$ns3::PacketSink/Rx", 
                                  MakeCallback (&SinkRx));
--- a/examples/csma-star.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/examples/csma-star.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -202,7 +202,7 @@
   //
   // Do pcap tracing on all devices on all nodes.
   //
-  CsmaHelper::EnablePcapAll ("csma-star");
+  CsmaHelper::EnablePcapAll ("csma-star", false);
 
   NS_LOG_INFO ("Run Simulation.");
   Simulator::Run ();
--- a/examples/dynamic-global-routing.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/examples/dynamic-global-routing.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -193,7 +193,7 @@
   ascii.open ("dynamic-global-routing.tr");
   PointToPointHelper::EnablePcapAll ("dynamic-global-routing");
   PointToPointHelper::EnableAsciiAll (ascii);
-  CsmaHelper::EnablePcapAll ("dynamic-global-routing");
+  CsmaHelper::EnablePcapAll ("dynamic-global-routing", false);
   CsmaHelper::EnableAsciiAll (ascii);
   InternetStackHelper::EnableAsciiAll (ascii);
  
--- a/examples/emu-udp-echo.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/examples/emu-udp-echo.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -145,7 +145,7 @@
 
   std::ofstream ascii;
   ascii.open ("emu-udp-echo.tr");
-  EmuHelper::EnablePcapAll ("emu-udp-echo");
+  EmuHelper::EnablePcapAll ("emu-udp-echo", true);
 
   //
   // Now, do the actual simulation.
--- a/examples/mixed-global-routing.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/examples/mixed-global-routing.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -125,7 +125,7 @@
   ascii.open ("mixed-global-routing.tr");
   PointToPointHelper::EnablePcapAll ("mixed-global-routing");
   PointToPointHelper::EnableAsciiAll (ascii);
-  CsmaHelper::EnablePcapAll ("mixed-global-routing");
+  CsmaHelper::EnablePcapAll ("mixed-global-routing", false);
   CsmaHelper::EnableAsciiAll (ascii);
 
 
--- a/examples/mixed-wireless.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/examples/mixed-wireless.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -388,7 +388,8 @@
       InternetStackHelper::EnableAsciiAll (ascii);
 
       // Let's do a pcap trace on the application source and sink, ifIndex 0
-      CsmaHelper::EnablePcap ("mixed-wireless", appSource->GetId (), 0);
+      // Csma captures in non-promiscuous mode
+      CsmaHelper::EnablePcap ("mixed-wireless", appSource->GetId (), 0, false);
       YansWifiPhyHelper::EnablePcap ("mixed-wireless", appSink->GetId (), 0);
       YansWifiPhyHelper::EnablePcap ("mixed-wireless", 9, 2);
       YansWifiPhyHelper::EnablePcap ("mixed-wireless", 9, 0);
--- a/examples/realtime-udp-echo.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/examples/realtime-udp-echo.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -107,7 +107,7 @@
 
   std::ofstream ascii;
   ascii.open ("realtime-udp-echo.tr");
-  CsmaHelper::EnablePcapAll ("realtime-udp-echo");
+  CsmaHelper::EnablePcapAll ("realtime-udp-echo", false);
   CsmaHelper::EnableAsciiAll (ascii);
 
   //
--- a/examples/second.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/examples/second.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -102,8 +102,8 @@
 
   GlobalRouteManager::PopulateRoutingTables ();
 
-  PointToPointHelper::EnablePcapAll ("second");
-  CsmaHelper::EnablePcapAll ("second");
+  PointToPointHelper::EnablePcap ("second", p2pDevices.Get (1));
+  CsmaHelper::EnablePcap ("second", csmaDevices.Get (0), true);
 
   Simulator::Run ();
   Simulator::Destroy ();
--- a/examples/star.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/examples/star.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -136,7 +136,7 @@
 
   NS_LOG_INFO ("Enable pcap tracing.");
   //
-  // Do pcap tracing on all devices on all nodes.
+  // Do pcap tracing on all point-to-point devices on all nodes.
   //
   PointToPointHelper::EnablePcapAll ("star");
 
--- a/examples/stats/wifi-example-sim.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/examples/stats/wifi-example-sim.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -127,7 +127,7 @@
   nodes.Create(2);
 
   NS_LOG_INFO("Installing WiFi and Internet stack.");
-  WifiHelper wifi;
+  WifiHelper wifi = WifiHelper::Default ();
   wifi.SetMac("ns3::AdhocWifiMac");
   YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
   YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
--- a/examples/tap-wifi-dumbbell.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/examples/tap-wifi-dumbbell.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -230,7 +230,7 @@
   apps = sink.Install (nodesRight.Get (0));
   apps.Start (Seconds (1.0));
 
-  CsmaHelper::EnablePcapAll ("tap-dumbbell");
+  CsmaHelper::EnablePcapAll ("tap-dumbbell", false);
   GlobalRouteManager::PopulateRoutingTables ();
 
   Simulator::Stop (Seconds (60.));
--- a/examples/tcp-large-transfer.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/examples/tcp-large-transfer.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -57,9 +57,14 @@
 void StartFlow(Ptr<Socket>, Ipv4Address, uint16_t);
 void WriteUntilBufferFull (Ptr<Socket>, uint32_t);
 
+static void 
+CwndTracer (uint32_t oldval, uint32_t newval)
+{
+  NS_LOG_INFO ("Moving cwnd from " << oldval << " to " << newval);
+}
+
 int main (int argc, char *argv[])
 {
-
   // Users may find it convenient to turn on explicit debugging
   // for selected modules; the below lines suggest how to do this
   //  LogComponentEnable("TcpL4Protocol", LOG_LEVEL_ALL);
@@ -67,9 +72,6 @@
   //  LogComponentEnable("PacketSink", LOG_LEVEL_ALL);
   //  LogComponentEnable("TcpLargeTransfer", LOG_LEVEL_ALL);
 
-
-  // Allow the user to override any of the defaults and the above
-  // Bind()s at run-time, via command-line arguments
   CommandLine cmd;
   cmd.Parse (argc, argv);
 
@@ -140,6 +142,9 @@
       Socket::CreateSocket (n0n1.Get (0), TcpSocketFactory::GetTypeId ());
   localSocket->Bind ();
 
+  // Trace changes to the congestion window
+  Config::ConnectWithoutContext ("/NodeList/0/$ns3::TcpL4Protocol/SocketList/0/CongestionWindow", MakeCallback (&CwndTracer));
+
   // ...and schedule the sending "Application"; This is similar to what an 
   // ns3::Application subclass would do internally.
   Simulator::ScheduleNow (&StartFlow, localSocket,
@@ -155,7 +160,6 @@
   std::ofstream ascii;
   ascii.open ("tcp-large-transfer.tr");
   PointToPointHelper::EnableAsciiAll (ascii);
-
   PointToPointHelper::EnablePcapAll ("tcp-large-transfer");
 
   // Finally, set up the simulator to run.  The 1000 second hard limit is a
--- a/examples/tcp-nsc-lfn.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/examples/tcp-nsc-lfn.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -43,6 +43,11 @@
 
 NS_LOG_COMPONENT_DEFINE ("TcpNscLfn");
 
+static void 
+CwndTracer (uint32_t oldval, uint32_t newval)
+{
+  NS_LOG_INFO ("Moving cwnd from " << oldval << " to " << newval);
+}
 
 int main (int argc, char *argv[])
 {
@@ -133,6 +138,10 @@
       clientApp.Stop (Seconds (runtime + 1.0 + i));
     }
 
+  // Trace changes to the congestion window
+  Config::ConnectWithoutContext ("/NodeList/1/$ns3::NscTcpL4Protocol/SocketList/0/CongestionWindow", 
+                                 MakeCallback (&CwndTracer));
+
   // This tells ns-3 to generate pcap traces.
   PointToPointHelper::EnablePcapAll ("tcp-nsc-lfn");
 
--- a/examples/tcp-nsc-zoo.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/examples/tcp-nsc-zoo.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -136,7 +136,7 @@
 	}
     }
 
-  CsmaHelper::EnablePcapAll ("tcp-nsc-zoo");
+  CsmaHelper::EnablePcapAll ("tcp-nsc-zoo", false);
 
   Simulator::Stop (Seconds(100));
   Simulator::Run ();
--- a/examples/third.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/examples/third.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -162,10 +162,9 @@
 
   Simulator::Stop (Seconds (10.0));
 
-  YansWifiPhyHelper::EnablePcap ("third", 
-    wifiStaNodes.Get (nWifi - 1)->GetId (), 0);
-  CsmaHelper::EnablePcap ("third", 
-    csmaNodes.Get (nCsma)->GetId (), 0);
+  PointToPointHelper::EnablePcap ("third", p2pDevices.Get (0));
+  YansWifiPhyHelper::EnablePcap ("third", apDevices.Get (0));
+  CsmaHelper::EnablePcap ("third", csmaDevices.Get (0), true);
 
   Simulator::Run ();
   Simulator::Destroy ();
--- a/examples/udp-echo.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/examples/udp-echo.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -127,7 +127,7 @@
 
   std::ofstream ascii;
   ascii.open ("udp-echo.tr");
-  CsmaHelper::EnablePcapAll ("udp-echo");
+  CsmaHelper::EnablePcapAll ("udp-echo", false);
   CsmaHelper::EnableAsciiAll (ascii);
 
 //
--- a/examples/wifi-wired-bridging.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/examples/wifi-wired-bridging.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -183,8 +183,9 @@
   apps.Start (Seconds (0.5));
   apps.Stop (Seconds (3.0));
   
-  YansWifiPhyHelper::EnablePcap ("wifi-wired-bridging", staNodes[1].Get (1));
-  YansWifiPhyHelper::EnablePcap ("wifi-wired-bridging", staNodes[0].Get (0));
+  YansWifiPhyHelper::EnablePcap ("wifi-wired-bridging", apDevices[0]);
+  YansWifiPhyHelper::EnablePcap ("wifi-wired-bridging", apDevices[1]);
+
   std::ofstream os;
   os.open ("wifi-wired-bridging.mob");
   MobilityHelper::EnableAsciiAll (os);
--- a/src/applications/onoff/onoff-application.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/applications/onoff/onoff-application.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -176,7 +176,7 @@
 void OnOffApplication::StartSending()
 {
   NS_LOG_FUNCTION_NOARGS ();
-
+  m_lastStartTime = Simulator::Now();
   ScheduleNextTx();  // Schedule the send packet event
   ScheduleStopEvent();
 }
--- a/src/applications/onoff/onoff-application.h	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/applications/onoff/onoff-application.h	Mon Mar 23 19:23:11 2009 -0700
@@ -64,6 +64,22 @@
  * variables. During the "Off" state, no traffic is generated.
  * During the "On" state, cbr traffic is generated. This cbr traffic is
  * characterized by the specified "data rate" and "packet size".
+ *
+ * Note:  When an application is started, the first packet transmission
+ * occurs _after_ a delay equal to (packet size/bit rate).  Note also,
+ * when an application transitions into an off state in between packet
+ * transmissions, the remaining time until when the next transmission
+ * would have occurred is cached and is used when the application starts
+ * up again.  Example:  packet size = 1000 bits, bit rate = 500 bits/sec.
+ * If the application is started at time 3 seconds, the first packet
+ * transmission will be scheduled for time 5 seconds (3 + 1000/500)
+ * and subsequent transmissions at 2 second intervals.  If the above
+ * application were instead stopped at time 4 seconds, and restarted at
+ * time 5.5 seconds, then the first packet would be sent at time 6.5 seconds,
+ * because when it was stopped at 4 seconds, there was only 1 second remaining
+ * until the originally scheduled transmission, and this time remaining
+ * information is cached and used to schedule the next transmission
+ * upon restarting.
  */
 class OnOffApplication : public Application 
 {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/attribute-default-iterator.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -0,0 +1,88 @@
+#include "attribute-default-iterator.h"
+#include "ns3/type-id.h"
+#include "ns3/attribute.h"
+#include "ns3/object-vector.h"
+#include "ns3/pointer.h"
+#include "ns3/global-value.h"
+#include "ns3/string.h"
+
+namespace ns3 {
+
+AttributeDefaultIterator::~AttributeDefaultIterator ()
+{}
+void 
+AttributeDefaultIterator::Iterate (void)
+{
+  for (uint32_t i = 0; i < TypeId::GetRegisteredN (); i++)
+    {
+      TypeId tid = TypeId::GetRegistered (i);
+      if (tid.MustHideFromDocumentation ())
+	{
+	  continue;
+	}
+      bool calledStart = false;
+      for (uint32_t j = 0; j < tid.GetAttributeN (); j++)
+	{
+	  uint32_t flags = tid.GetAttributeFlags (j);
+	  if (!(flags & TypeId::ATTR_CONSTRUCT))
+	    {
+	      // we can't construct the attribute, so, there is no
+	      // initial value for the attribute
+	      continue;
+	    }
+	  Ptr<const AttributeAccessor> accessor = tid.GetAttributeAccessor (j);
+	  if (accessor == 0)
+	    {
+	      continue;
+	    }
+	  if (!accessor->HasSetter ())
+	    {
+	      continue;
+	    }
+	  Ptr<const AttributeChecker> checker = tid.GetAttributeChecker (j);
+	  if (checker == 0)
+	    {
+	      continue;
+	    }
+	  Ptr<const AttributeValue> value = tid.GetAttributeInitialValue (j);
+	  if (value == 0)
+	    {
+	      continue;
+	    }
+	  Ptr<const ObjectVectorValue> vector = DynamicCast<const ObjectVectorValue> (value);
+	  if (vector != 0)
+	    {
+	      continue;
+	    }
+	  Ptr<const PointerValue> pointer = DynamicCast<const PointerValue> (value);
+	  if (pointer != 0)
+	    {
+	      continue;
+	    }
+	  if (!calledStart)
+	    {
+	      StartVisitTypeId (tid.GetName ());
+	    }
+	  VisitAttribute (tid.GetAttributeName (j),
+			  value->SerializeToString (checker));
+	  calledStart = true;
+	}
+      if (calledStart)
+	{
+	  EndVisitTypeId ();
+	}
+    }
+}
+
+void 
+AttributeDefaultIterator::StartVisitTypeId (std::string name)
+{}
+void 
+AttributeDefaultIterator::EndVisitTypeId (void)
+{}
+void 
+AttributeDefaultIterator::VisitAttribute (std::string name, std::string defaultValue)
+{}
+
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/attribute-default-iterator.h	Mon Mar 23 19:23:11 2009 -0700
@@ -0,0 +1,21 @@
+#ifndef ATTRIBUTE_DEFAULT_ITERATOR_H
+#define ATTRIBUTE_DEFAULT_ITERATOR_H
+
+#include <string>
+
+namespace ns3 {
+
+class AttributeDefaultIterator
+{
+public:
+  virtual ~AttributeDefaultIterator () = 0;
+  void Iterate (void);
+private:
+  virtual void StartVisitTypeId (std::string name);
+  virtual void EndVisitTypeId (void);
+  virtual void VisitAttribute (std::string name, std::string defaultValue);
+};
+
+} // namespace ns3
+
+#endif /* ATTRIBUTE_DEFAULT_ITERATOR_H */
--- a/src/contrib/attribute-iterator.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/contrib/attribute-iterator.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -252,23 +252,5 @@
     }
 }
 
-TextFileAttributeIterator::TextFileAttributeIterator (std::ostream &os)
-  : m_os (os)
-{}
-void 
-TextFileAttributeIterator::DoVisitAttribute (Ptr<Object> object, std::string name)
-{
-  StringValue str;
-  object->GetAttribute (name, str);
-  m_os << GetCurrentPath () << " " << str.Get () << std::endl;
-}
-
-void 
-TextFileAttributeIterator::Save (void)
-{
-  Iterate ();
-}
-
-
 
 } // namespace ns3
--- a/src/contrib/attribute-iterator.h	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/contrib/attribute-iterator.h	Mon Mar 23 19:23:11 2009 -0700
@@ -49,17 +49,6 @@
   std::vector<std::string> m_currentPath;
 };
 
-class TextFileAttributeIterator : public AttributeIterator
-{
-public:
-  TextFileAttributeIterator (std::ostream &os);
-  void Save (void);
-private:
-  virtual void DoVisitAttribute (Ptr<Object> object, std::string name);
-  std::ostream &m_os;
-};
-
-
 } // namespace ns3
 
 #endif /* ATTRIBUTE_ITERATOR_H */
--- a/src/contrib/config-store.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/contrib/config-store.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -1,19 +1,27 @@
 #include "config-store.h"
-#include "attribute-iterator.h"
+#include "raw-text-config.h"
 #include "ns3/string.h"
 #include "ns3/log.h"
+#include "ns3/simulator.h"
+#include "ns3/enum.h"
 #include "ns3/attribute-list.h"
-#include "ns3/config.h"
+#include "ns3/contrib-config.h"
+#ifdef HAVE_LIBXML2
+#include "xml-config.h"
+#endif
+
 #include <string>
 #include <fstream>
 #include <iostream>
 #include <unistd.h>
 #include <stdlib.h>
 
+
 NS_LOG_COMPONENT_DEFINE ("ConfigStore");
 
 namespace ns3 {
 
+
 NS_OBJECT_ENSURE_REGISTERED (ConfigStore);
 
 TypeId 
@@ -21,16 +29,24 @@
 {
   static TypeId tid = TypeId ("ns3::ConfigStore")
     .SetParent<ObjectBase> ()
-    .AddAttribute ("LoadFilename", 
-		   "The file where the configuration should be loaded from.",
+    .AddAttribute ("Mode", 
+		   "Configuration mode",
+		   EnumValue (ConfigStore::NONE),
+		   MakeEnumAccessor (&ConfigStore::SetMode),
+		   MakeEnumChecker (ConfigStore::NONE, "None",
+				    ConfigStore::LOAD, "Load",
+				    ConfigStore::SAVE, "Save"))
+    .AddAttribute ("Filename", 
+		   "The file where the configuration should be saved to or loaded from.",
 		   StringValue (""),
-		   MakeStringAccessor (&ConfigStore::m_loadFilename),
+		   MakeStringAccessor (&ConfigStore::SetFilename),
 		   MakeStringChecker ())
-    .AddAttribute ("StoreFilename", 
-		   "The file where the configuration should be stored to.",
-		   StringValue (""),
-		   MakeStringAccessor (&ConfigStore::m_storeFilename),
-		   MakeStringChecker ())
+    .AddAttribute ("FileFormat",
+		   "Type of file format",
+		   EnumValue (ConfigStore::RAW_TEXT),
+		   MakeEnumAccessor (&ConfigStore::SetFileFormat),
+		   MakeEnumChecker (ConfigStore::RAW_TEXT, "RawText",
+				    ConfigStore::XML, "Xml"))
     ;
   return tid;
 }
@@ -44,44 +60,76 @@
 ConfigStore::ConfigStore ()
 {
   ObjectBase::ConstructSelf (AttributeList ());
+
+#ifdef HAVE_LIBXML2
+  if (m_fileFormat == ConfigStore::XML)
+    {
+      if (m_mode == ConfigStore::SAVE)
+	{
+	  m_file = new XmlConfigSave ();
+	}
+      else if (m_mode == ConfigStore::LOAD)
+	{
+	  m_file = new XmlConfigLoad ();
+	}
+      else 
+	{
+	  m_file = new NoneFileConfig ();
+	}
+    }
+  else 
+#endif /* HAVE_LIBXML2 */
+  if (m_fileFormat == ConfigStore::RAW_TEXT)
+    {
+      if (m_mode == ConfigStore::SAVE)
+	{
+	  m_file = new RawTextConfigSave ();
+	}
+      else if (m_mode == ConfigStore::LOAD)
+	{
+	  m_file = new RawTextConfigLoad ();
+	}
+      else
+	{
+	  m_file = new NoneFileConfig ();
+	}
+    }
+  m_file->SetFilename (m_filename);
+}
+
+ConfigStore::~ConfigStore ()
+{
+  delete m_file;
+  m_file = 0;
 }
 
 void 
-ConfigStore::LoadFrom (std::string filename)
+ConfigStore::SetMode (enum Mode mode)
 {
-  std::ifstream is;
-  is.open (filename.c_str (), std::ios::in);
-  std::string path, value;
-  while (is.good())
-    {
-      is >> path >> value;
-      NS_LOG_DEBUG (path << " " << value);
-      Config::Set (path, StringValue (value));
-    }
+  m_mode = mode;
 }
 void 
-ConfigStore::StoreTo (std::string filename)
+ConfigStore::SetFileFormat (enum FileFormat format)
 {
-
-  std::ofstream os;
-  os.open (filename.c_str (), std::ios::out);
-  TextFileAttributeIterator iter = TextFileAttributeIterator (os);
-  iter.Save ();
-  os.close ();
-  exit (0);
+  m_fileFormat = format;
+}
+void 
+ConfigStore::SetFilename (std::string filename)
+{
+  m_filename = filename;
 }
 
 void 
-ConfigStore::Configure (void)
+ConfigStore::ConfigureAttributes (void)
 {
-  if (m_loadFilename != "")
-    {
-      LoadFrom (m_loadFilename);
-    }
-  if (m_storeFilename != "")
-    {
-      StoreTo (m_storeFilename);
-    }
+  m_file->Attributes ();
+}
+
+void 
+ConfigStore::ConfigureDefaults (void)
+{
+  m_file->Default ();
+  m_file->Global ();
 }
 
 } // namespace ns3
--- a/src/contrib/config-store.h	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/contrib/config-store.h	Mon Mar 23 19:23:11 2009 -0700
@@ -2,6 +2,7 @@
 #define CONFIG_STORE_H
 
 #include "ns3/object-base.h"
+#include "file-config.h"
 
 namespace ns3 {
 
@@ -26,24 +27,33 @@
 class ConfigStore : public ObjectBase
 {
 public:
+  enum Mode {
+    LOAD,
+    SAVE,
+    NONE
+  };
+  enum FileFormat {
+    XML,
+    RAW_TEXT
+  };
   static TypeId GetTypeId (void);
   virtual TypeId GetInstanceTypeId (void) const;
 
   ConfigStore ();
+  ~ConfigStore ();
 
-  /**
-   * Depending on which attribute was set:
-   *  - Store simulation configuration in file and exit
-   *  - Load simulation configuration from file and proceed.
-   */
-  void Configure (void);
+  void SetMode (enum Mode mode);
+  void SetFileFormat (enum FileFormat format);
+  void SetFilename (std::string filename);
+
+  void ConfigureDefaults (void);
+  void ConfigureAttributes (void);
 
 private:
-  void LoadFrom (std::string filename);
-  void StoreTo (std::string filename);
-
-  std::string m_loadFilename;
-  std::string m_storeFilename;
+  enum Mode m_mode;
+  enum FileFormat m_fileFormat;
+  std::string m_filename;
+  FileConfig *m_file;
 };
 
 }  // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/file-config.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -0,0 +1,25 @@
+#include "file-config.h"
+
+namespace ns3 {
+
+FileConfig::~FileConfig ()
+{}
+
+NoneFileConfig::NoneFileConfig ()
+{}
+NoneFileConfig::~NoneFileConfig ()
+{}
+void 
+NoneFileConfig::SetFilename (std::string filename)
+{}
+void 
+NoneFileConfig::Default (void)
+{}
+void 
+NoneFileConfig::Global (void)
+{}
+void 
+NoneFileConfig::Attributes (void)
+{}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/file-config.h	Mon Mar 23 19:23:11 2009 -0700
@@ -0,0 +1,31 @@
+#ifndef FILE_CONFIG_H
+#define FILE_CONFIG_H
+
+#include <string>
+
+namespace ns3 {
+
+class FileConfig
+{
+public:
+  virtual ~FileConfig ();
+  virtual void SetFilename (std::string filename) = 0;
+  virtual void Default (void) = 0;
+  virtual void Global (void) = 0;
+  virtual void Attributes (void) = 0;
+};
+
+class NoneFileConfig : public FileConfig
+{
+public:
+  NoneFileConfig ();
+  virtual ~NoneFileConfig ();
+  virtual void SetFilename (std::string filename);
+  virtual void Default (void);
+  virtual void Global (void);
+  virtual void Attributes (void);
+};
+
+} // namespace ns3
+
+#endif /* FILE_CONFIG_H */
--- a/src/contrib/gtk-config-store.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/contrib/gtk-config-store.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -1,5 +1,6 @@
 #include "gtk-config-store.h"
 #include "attribute-iterator.h"
+#include "raw-text-config.h"
 #include "ns3/config.h"
 #include "ns3/string.h"
 #include "ns3/pointer.h"
@@ -403,11 +404,9 @@
       char *filename;
 
       filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
-      std::ofstream os;
-      os.open (filename);
-      TextFileAttributeIterator file = TextFileAttributeIterator (os);
-      file.Save ();
-      os.close ();
+      RawTextConfigSave config;
+      config.SetFilename (filename);
+      config.Attributes ();
       g_free (filename);
     }
 
@@ -433,15 +432,9 @@
       char *filename;
 
       filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
-      std::ifstream is;
-      is.open (filename, std::ios::in);
-      std::string path, value;
-      while (is.good())
-	{
-	  is >> path >> value;
-	  Config::Set (path, StringValue (value));
-	}
-      g_free (filename);
+      RawTextConfigLoad config;
+      config.SetFilename (filename);
+      config.Attributes ();
     }
 
   gtk_widget_destroy (dialog);
@@ -486,7 +479,11 @@
 {}
 
 void 
-GtkConfigStore::Configure (void)
+GtkConfigStore::ConfigureDefaults (void)
+{}
+
+void 
+GtkConfigStore::ConfigureAttributes (void)
 {
   GtkWidget *window;
   GtkWidget *view;
--- a/src/contrib/gtk-config-store.h	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/contrib/gtk-config-store.h	Mon Mar 23 19:23:11 2009 -0700
@@ -11,7 +11,8 @@
 public:
   GtkConfigStore ();
 
-  void Configure (void);
+  void ConfigureDefaults (void);
+  void ConfigureAttributes (void);
 };
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/raw-text-config.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -0,0 +1,166 @@
+#include "raw-text-config.h"
+#include "attribute-iterator.h"
+#include "attribute-default-iterator.h"
+#include "ns3/global-value.h"
+#include "ns3/string.h"
+#include "ns3/log.h"
+#include "ns3/config.h"
+
+NS_LOG_COMPONENT_DEFINE ("RawTextConfig");
+
+namespace ns3 {
+
+RawTextConfigSave::RawTextConfigSave ()
+  : m_os (0)
+{}
+RawTextConfigSave::~RawTextConfigSave ()
+{
+  if (m_os != 0)
+    {
+      m_os->close ();
+    }
+  delete m_os;
+  m_os = 0;
+}
+void 
+RawTextConfigSave::SetFilename (std::string filename)
+{
+  m_os = new std::ofstream ();
+  m_os->open (filename.c_str (), std::ios::out);
+}
+void 
+RawTextConfigSave::Default (void)
+{
+  class RawTextDefaultIterator : public AttributeDefaultIterator
+  {
+  public:
+    RawTextDefaultIterator (std::ostream *os) {
+      m_os = os;
+    }
+  private:
+    virtual void StartVisitTypeId (std::string name) {
+      m_typeId = name;
+    }
+    virtual void VisitAttribute (std::string name, std::string defaultValue) {
+      *m_os << "default " << m_typeId << "::" << name << " \"" << defaultValue << "\"" << std::endl;
+    }
+    std::string m_typeId;
+    std::ostream *m_os;
+  };
+
+  RawTextDefaultIterator iterator = RawTextDefaultIterator (m_os);
+  iterator.Iterate ();
+}
+void 
+RawTextConfigSave::Global (void)
+{
+  for (GlobalValue::Iterator i = GlobalValue::Begin (); i != GlobalValue::End (); ++i)
+    {
+      StringValue value;
+      (*i)->GetValue (value);
+      *m_os << "global " << (*i)->GetName () << " \"" << value.Get () << "\"" << std::endl;
+    }
+}
+void 
+RawTextConfigSave::Attributes (void)
+{
+  class RawTextAttributeIterator : public AttributeIterator
+  {
+  public:
+    RawTextAttributeIterator (std::ostream *os)
+      : m_os (os) {}
+  private:
+    virtual void DoVisitAttribute (Ptr<Object> object, std::string name) {
+      StringValue str;
+      object->GetAttribute (name, str);
+      *m_os << "value " << GetCurrentPath () << " \"" << str.Get () << "\"" << std::endl;
+    }
+    std::ostream *m_os;
+  };
+
+  RawTextAttributeIterator iter = RawTextAttributeIterator (m_os);
+  iter.Iterate ();
+}
+
+RawTextConfigLoad::RawTextConfigLoad ()
+  : m_is (0)
+{}
+RawTextConfigLoad::~RawTextConfigLoad ()
+{
+  if (m_is != 0)
+    {
+      m_is->close ();
+      delete m_is;
+      m_is = 0;
+    }
+}
+void 
+RawTextConfigLoad::SetFilename (std::string filename)
+{
+  m_is = new std::ifstream ();
+  m_is->open (filename.c_str (), std::ios::in);
+}
+std::string
+RawTextConfigLoad::Strip (std::string value)
+{
+  std::string::size_type start = value.find ("\"");
+  std::string::size_type end = value.find ("\"", 1);
+  NS_ASSERT (start == 0);
+  NS_ASSERT (end == value.size () - 1);
+  return value.substr (start+1, end-start-1);
+}
+
+void 
+RawTextConfigLoad::Default (void)
+{
+  m_is->seekg (0);
+  std::string type, name, value;
+  *m_is >> type >> name >> value;
+  while (m_is->good())
+    {
+      NS_LOG_DEBUG ("type=" << type << ", name=" << name << ", value=" << value);
+      value = Strip (value);
+      if (type == "global")
+	{
+	  Config::SetDefault (name, StringValue (value));
+	}
+      *m_is >> type >> name >> value;
+    }
+}
+void 
+RawTextConfigLoad::Global (void)
+{
+  m_is->seekg (0);
+  std::string type, name, value;
+  *m_is >> type >> name >> value;
+  while (m_is->good())
+    {
+      NS_LOG_DEBUG ("type=" << type << ", name=" << name << ", value=" << value);
+      value = Strip (value);
+      if (type == "global")
+	{
+	  Config::SetGlobal (name, StringValue (value));
+	}
+      *m_is >> type >> name >> value;
+    }
+}
+void 
+RawTextConfigLoad::Attributes (void)
+{
+  m_is->seekg (0);
+  std::string type, path, value;
+  *m_is >> type >> path >> value;
+  while (m_is->good())
+    {
+      NS_LOG_DEBUG ("type=" << type << ", path=" << path << ", value=" << value);
+      value = Strip (value);
+      if (type == "value")
+	{
+	  Config::Set (path, StringValue (value));
+	}
+      *m_is >> type >> path >> value;
+    }
+}
+
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/raw-text-config.h	Mon Mar 23 19:23:11 2009 -0700
@@ -0,0 +1,39 @@
+#ifndef RAW_TEXT_CONFIG_H
+#define RAW_TEXT_CONFIG_H
+
+#include <string>
+#include <fstream>
+#include "file-config.h"
+
+namespace ns3 {
+
+class RawTextConfigSave : public FileConfig
+{
+public:
+  RawTextConfigSave ();
+  virtual ~RawTextConfigSave ();
+  virtual void SetFilename (std::string filename);
+  virtual void Default (void);
+  virtual void Global (void);
+  virtual void Attributes (void);
+private:
+  std::ofstream *m_os;
+};
+
+class RawTextConfigLoad : public FileConfig
+{
+public:
+  RawTextConfigLoad ();
+  virtual ~RawTextConfigLoad ();
+  virtual void SetFilename (std::string filename);
+  virtual void Default (void);
+  virtual void Global (void);
+  virtual void Attributes (void);
+private:
+  std::string Strip (std::string value);
+  std::ifstream *m_is;
+};
+
+} // namespace ns3
+
+#endif /* RAW_TEXT_CONFIG_H */
--- a/src/contrib/wscript	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/contrib/wscript	Mon Mar 23 19:23:11 2009 -0700
@@ -1,14 +1,23 @@
 ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
 
 def configure(conf):
-    have_it = conf.pkg_check_modules('GTK_CONFIG_STORE', 'gtk+-2.0 >= 2.12', mandatory=False)
-    conf.env['ENABLE_GTK_CONFIG_STORE'] = have_it
+    have_gtk = conf.pkg_check_modules('GTK_CONFIG_STORE', 'gtk+-2.0 >= 2.12', mandatory=False)
+    conf.env['ENABLE_GTK_CONFIG_STORE'] = have_gtk
     conf.report_optional_feature("GtkConfigStore", "GtkConfigStore",
                                  conf.env['ENABLE_GTK_CONFIG_STORE'],
                                  "library 'gtk+-2.0 >= 2.12' not found")
+    have_libxml2 = conf.pkg_check_modules('LIBXML2', 'libxml-2.0 >= 2.6', mandatory=False)
+    if have_libxml2:
+        conf.define('HAVE_LIBXML2', 1)
 
+    conf.env['ENABLE_LIBXML2'] = have_libxml2
+    conf.report_optional_feature("XmlIo", "XmlIo",
+                                 conf.env['ENABLE_LIBXML2'],
+                                 "library 'libxml-2.0 >= 2.7' not found")
     conf.sub_config('stats')
 
+    conf.write_config_header('ns3/contrib-config.h')
+
 def build(bld):
     module = bld.create_ns3_module('contrib', ['simulator', 'common'])
     module.source = [
@@ -18,6 +27,9 @@
         'attribute-iterator.cc',
         'config-store.cc',
         'flow-id-tag.cc',
+        'attribute-default-iterator.cc',
+        'file-config.cc',
+        'raw-text-config.cc',
         ]
 
     headers = bld.new_task_gen('ns3header')
@@ -26,6 +38,7 @@
         'event-garbage-collector.h',
         'gnuplot.h',
         'delay-jitter-estimation.h',
+        'file-config.h',
         'config-store.h',
         'flow-id-tag.h',
         ]
@@ -34,3 +47,10 @@
         headers.source.append ('gtk-config-store.h')
         module.source.append ('gtk-config-store.cc')
         module.uselib = 'GTK_CONFIG_STORE'
+
+    if bld.env['ENABLE_LIBXML2']:
+        module.source.append ('xml-config.cc')
+        if bld.env['ENABLE_GTK_CONFIG_STORE']:
+            module.uselib = module.uselib + ' LIBXML2'
+        else:
+            module.uselib = 'LIBXML2'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/xml-config.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -0,0 +1,335 @@
+#include "xml-config.h"
+#include "attribute-default-iterator.h"
+#include "attribute-iterator.h"
+#include "ns3/fatal-error.h"
+#include "ns3/log.h"
+#include "ns3/global-value.h"
+#include "ns3/string.h"
+#include "ns3/config.h"
+#include <libxml/encoding.h>
+#include <libxml/xmlwriter.h>
+
+NS_LOG_COMPONENT_DEFINE ("XmlConfig");
+
+namespace ns3 {
+
+XmlConfigSave::XmlConfigSave ()
+  : m_writer (0)
+{
+  NS_LOG_FUNCTION (this);
+}
+void
+XmlConfigSave::SetFilename (std::string filename)
+{
+  NS_LOG_FUNCTION (filename);
+  if (filename == "")
+    {
+      return;
+    }
+  int rc;
+
+  /* Create a new XmlWriter for uri, with no compression. */
+  m_writer = xmlNewTextWriterFilename(filename.c_str (), 0);
+  if (m_writer == NULL) 
+    {
+      NS_FATAL_ERROR ("Error creating the xml writer");
+    }
+  rc = xmlTextWriterSetIndent (m_writer, 1);
+  if (rc < 0)
+    {
+      NS_FATAL_ERROR ("Error at xmlTextWriterSetIndent");
+    }
+  /* Start the document with the xml default for the version,
+   * encoding utf-8 and the default for the standalone
+   * declaration. */
+  rc = xmlTextWriterStartDocument(m_writer, NULL, "utf-8", NULL);
+  if (rc < 0) 
+    {
+      NS_FATAL_ERROR ("Error at xmlTextWriterStartDocument");
+    }
+
+  /* Start an element named "ns3". Since thist is the first
+   * element, this will be the root element of the document. */
+  rc = xmlTextWriterStartElement(m_writer, BAD_CAST "ns3");
+  if (rc < 0) 
+    {
+      NS_FATAL_ERROR ("Error at xmlTextWriterStartElement\n");
+    }
+}
+XmlConfigSave::~XmlConfigSave ()
+{
+  NS_LOG_FUNCTION (this);
+  if (m_writer == 0)
+    {
+      return;
+    }
+  int rc;
+  /* Here we could close the remaining elements using the
+   * function xmlTextWriterEndElement, but since we do not want to
+   * write any other elements, we simply call xmlTextWriterEndDocument,
+   * which will do all the work. */
+  rc = xmlTextWriterEndDocument(m_writer);
+  if (rc < 0) 
+    {
+      NS_FATAL_ERROR ("Error at xmlTextWriterEndDocument\n");
+    }
+
+  xmlFreeTextWriter(m_writer);
+  m_writer = 0;
+}
+void 
+XmlConfigSave::Default (void)
+{
+  class XmlDefaultIterator : public AttributeDefaultIterator
+  {
+  public:
+    XmlDefaultIterator (xmlTextWriterPtr writer) {
+      m_writer = writer;
+    }
+  private:
+    virtual void StartVisitTypeId (std::string name) {
+      m_typeid = name;
+    }
+    virtual void VisitAttribute (std::string name, std::string defaultValue) {
+      int rc;
+      rc = xmlTextWriterStartElement(m_writer, BAD_CAST "default");
+       if (rc < 0) 
+	 {
+	   NS_FATAL_ERROR ("Error at xmlTextWriterStartElement");
+	 }
+       std::string fullname = m_typeid + "::" + name;
+       rc = xmlTextWriterWriteAttribute(m_writer, BAD_CAST "name",
+					BAD_CAST fullname.c_str ());
+       if (rc < 0) 
+	 {
+	   NS_FATAL_ERROR ("Error at xmlTextWriterWriteAttribute");
+	 }
+       rc = xmlTextWriterWriteAttribute(m_writer, BAD_CAST "value",
+					BAD_CAST defaultValue.c_str ());
+       if (rc < 0) 
+	 {
+	   NS_FATAL_ERROR ("Error at xmlTextWriterWriteAttribute");
+	 }
+      rc = xmlTextWriterEndElement(m_writer);
+      if (rc < 0) 
+	{
+	  NS_FATAL_ERROR ("Error at xmlTextWriterEndElement");
+	}
+    }
+    xmlTextWriterPtr m_writer;
+    std::string m_typeid;
+  };
+  XmlDefaultIterator iterator = XmlDefaultIterator (m_writer);
+  iterator.Iterate ();
+}
+
+void
+XmlConfigSave::Attributes (void)
+{
+  class XmlTextAttributeIterator : public AttributeIterator
+  {
+  public:
+    XmlTextAttributeIterator (xmlTextWriterPtr writer)
+      : m_writer (writer) {}
+  private:
+    virtual void DoVisitAttribute (Ptr<Object> object, std::string name) {
+      StringValue str;
+      object->GetAttribute (name, str);
+      int rc;
+      rc = xmlTextWriterStartElement(m_writer, BAD_CAST "value");
+      if (rc < 0) 
+	{
+	  NS_FATAL_ERROR ("Error at xmlTextWriterStartElement");
+	}
+      rc = xmlTextWriterWriteAttribute(m_writer, BAD_CAST "path",
+				       BAD_CAST GetCurrentPath ().c_str ());
+      if (rc < 0) 
+	{
+	  NS_FATAL_ERROR ("Error at xmlTextWriterWriteAttribute");
+	}
+      rc = xmlTextWriterWriteAttribute(m_writer, BAD_CAST "value",
+				       BAD_CAST str.Get ().c_str ());
+      if (rc < 0) 
+	{
+	  NS_FATAL_ERROR ("Error at xmlTextWriterWriteAttribute");
+	}
+      rc = xmlTextWriterEndElement(m_writer);
+      if (rc < 0) 
+	{
+	  NS_FATAL_ERROR ("Error at xmlTextWriterEndElement");
+	}
+    }
+    xmlTextWriterPtr m_writer;
+  };
+
+  XmlTextAttributeIterator iter = XmlTextAttributeIterator (m_writer);
+  iter.Iterate ();
+}
+
+void
+XmlConfigSave::Global (void)
+{
+  int rc;
+  for (GlobalValue::Iterator i = GlobalValue::Begin (); i != GlobalValue::End (); ++i)
+    {
+      StringValue value;
+      (*i)->GetValue (value);
+
+      rc = xmlTextWriterStartElement(m_writer, BAD_CAST "global");
+       if (rc < 0) 
+	 {
+	   NS_FATAL_ERROR ("Error at xmlTextWriterStartElement");
+	 }
+       rc = xmlTextWriterWriteAttribute(m_writer, BAD_CAST "name",
+					BAD_CAST (*i)->GetName ().c_str ());
+       if (rc < 0) 
+	 {
+	   NS_FATAL_ERROR ("Error at xmlTextWriterWriteAttribute");
+	 }
+       rc = xmlTextWriterWriteAttribute(m_writer, BAD_CAST "value",
+					BAD_CAST value.Get ().c_str ());
+       if (rc < 0) 
+	 {
+	   NS_FATAL_ERROR ("Error at xmlTextWriterWriteAttribute");
+	 }
+      rc = xmlTextWriterEndElement(m_writer);
+       if (rc < 0) 
+	 {
+	   NS_FATAL_ERROR ("Error at xmlTextWriterEndElement");
+	 }
+    }
+}
+
+XmlConfigLoad::XmlConfigLoad ()
+{
+  NS_LOG_FUNCTION (this);
+}
+XmlConfigLoad::~XmlConfigLoad ()
+{
+  NS_LOG_FUNCTION (this);
+}
+
+void
+XmlConfigLoad::SetFilename (std::string filename)
+{
+  NS_LOG_FUNCTION (filename);
+  m_filename = filename;
+}
+void 
+XmlConfigLoad::Default (void)
+{
+  xmlTextReaderPtr reader = xmlNewTextReaderFilename(m_filename.c_str ());
+  if (reader == NULL)
+    {
+      NS_FATAL_ERROR ("Error at xmlReaderForFile");
+    }
+  int rc;
+  rc = xmlTextReaderRead (reader);
+  while (rc > 0)
+    {
+      const xmlChar *type = xmlTextReaderConstName(reader);
+      if (type == 0)
+	{
+	  NS_FATAL_ERROR ("Invalid value");
+	}
+      if (std::string ((char*)type) == "default")
+	{
+	  xmlChar *name = xmlTextReaderGetAttribute (reader, BAD_CAST "name");
+	  if (name == 0)
+	    {
+	      NS_FATAL_ERROR ("Error getting attribute 'name'");
+	    }
+	  xmlChar *value = xmlTextReaderGetAttribute (reader, BAD_CAST "value");
+	  if (value == 0)
+	    {
+	      NS_FATAL_ERROR ("Error getting attribute 'value'");
+	    }
+	  NS_LOG_DEBUG ("default="<<(char*)name<<", value=" <<value);
+	  Config::SetDefault ((char*)name, StringValue ((char*)value));
+	  xmlFree (name);
+	  xmlFree (value);
+	}
+      rc = xmlTextReaderRead (reader);
+    }
+  xmlFreeTextReader (reader);
+}
+void 
+XmlConfigLoad::Global (void)
+{
+  xmlTextReaderPtr reader = xmlNewTextReaderFilename(m_filename.c_str ());
+  if (reader == NULL)
+    {
+      NS_FATAL_ERROR ("Error at xmlReaderForFile");
+    }
+  int rc;
+  rc = xmlTextReaderRead (reader);
+  while (rc > 0)
+    {
+      const xmlChar *type = xmlTextReaderConstName(reader);
+      if (type == 0)
+	{
+	  NS_FATAL_ERROR ("Invalid value");
+	}
+      if (std::string ((char*)type) == "global")
+	{
+	  xmlChar *name = xmlTextReaderGetAttribute (reader, BAD_CAST "name");
+	  if (name == 0)
+	    {
+	      NS_FATAL_ERROR ("Error getting attribute 'name'");
+	    }
+	  xmlChar *value = xmlTextReaderGetAttribute (reader, BAD_CAST "value");
+	  if (value == 0)
+	    {
+	      NS_FATAL_ERROR ("Error getting attribute 'value'");
+	    }
+	  NS_LOG_DEBUG ("global="<<(char*)name<<", value=" <<value);
+	  Config::SetGlobal ((char*)name, StringValue ((char*)value));
+	  xmlFree (name);
+	  xmlFree (value);
+	}
+      rc = xmlTextReaderRead (reader);
+    }
+  xmlFreeTextReader (reader);
+}
+void 
+XmlConfigLoad::Attributes (void)
+{
+  xmlTextReaderPtr reader = xmlNewTextReaderFilename(m_filename.c_str ());
+  if (reader == NULL)
+    {
+      NS_FATAL_ERROR ("Error at xmlReaderForFile");
+    }
+  int rc;
+  rc = xmlTextReaderRead (reader);
+  while (rc > 0)
+    {
+      const xmlChar *type = xmlTextReaderConstName(reader);
+      if (type == 0)
+	{
+	  NS_FATAL_ERROR ("Invalid value");
+	}
+      if (std::string ((char*)type) == "value")
+	{
+	  xmlChar *path = xmlTextReaderGetAttribute (reader, BAD_CAST "path");
+	  if (path == 0)
+	    {
+	      NS_FATAL_ERROR ("Error getting attribute 'path'");
+	    }
+	  xmlChar *value = xmlTextReaderGetAttribute (reader, BAD_CAST "value");
+	  if (value == 0)
+	    {
+	      NS_FATAL_ERROR ("Error getting attribute 'value'");
+	    }
+	  NS_LOG_DEBUG ("path="<<(char*)path << ", value=" << (char*)value);
+	  Config::Set ((char*)path, StringValue ((char*)value));
+	  xmlFree (path);
+	  xmlFree (value);
+	}
+      rc = xmlTextReaderRead (reader);
+    }
+  xmlFreeTextReader (reader);
+}
+
+
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/xml-config.h	Mon Mar 23 19:23:11 2009 -0700
@@ -0,0 +1,41 @@
+#ifndef XML_CONFIG_STORE_H
+#define XML_CONFIG_STORE_H
+
+#include <string>
+#include <libxml/xmlwriter.h>
+#include <libxml/xmlreader.h>
+#include "file-config.h"
+
+namespace ns3 {
+
+class XmlConfigSave : public FileConfig
+{
+public:
+  XmlConfigSave ();
+  virtual ~XmlConfigSave ();
+
+  virtual void SetFilename (std::string filename);
+  virtual void Default (void);
+  virtual void Global (void);
+  virtual void Attributes (void);
+private:
+  xmlTextWriterPtr m_writer;
+};
+
+class XmlConfigLoad : public FileConfig
+{
+public:
+  XmlConfigLoad ();
+  virtual ~XmlConfigLoad ();
+
+  virtual void SetFilename (std::string filename);
+  virtual void Default (void);
+  virtual void Global (void);
+  virtual void Attributes (void);
+private:
+  std::string m_filename;
+};
+
+} // namespace ns3
+
+#endif /* XML_CONFIG_STORE_H */
--- a/src/devices/csma/csma-net-device.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/devices/csma/csma-net-device.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -77,17 +77,78 @@
                    PointerValue (),
                    MakePointerAccessor (&CsmaNetDevice::m_receiveErrorModel),
                    MakePointerChecker<ErrorModel> ())
+
+    //
+    // Transmit queueing discipline for the device which includes its own set
+    // of trace hooks.
+    //
     .AddAttribute ("TxQueue", 
                    "A queue to use as the transmit queue in the device.",
                    PointerValue (),
                    MakePointerAccessor (&CsmaNetDevice::m_queue),
                    MakePointerChecker<Queue> ())
-    .AddTraceSource ("Rx", 
-                     "Trace source indicating reception of packet destined for broadcast, multicast or local address.",
-                     MakeTraceSourceAccessor (&CsmaNetDevice::m_rxTrace))
-    .AddTraceSource ("Drop", 
-                     "Trace source indicating packet discarded due to receiver disabled or error model decision.",
-                     MakeTraceSourceAccessor (&CsmaNetDevice::m_dropTrace))
+
+    //
+    // Trace sources at the "top" of the net device, where packets transition
+    // to/from higher layers.
+    //
+    .AddTraceSource ("MacTx", 
+                     "Trace source indicating a packet has arrived for transmission by this device",
+                     MakeTraceSourceAccessor (&CsmaNetDevice::m_macTxTrace))
+    .AddTraceSource ("MacTxDrop", 
+                     "Trace source indicating a packet has been dropped by the device before transmission",
+                     MakeTraceSourceAccessor (&CsmaNetDevice::m_macTxDropTrace))
+    .AddTraceSource ("MacPromiscRx", 
+                     "A packet has been received by this device, has been passed up from the physical layer "
+                     "and is being forwarded up the local protocol stack.  This is a promiscuous trace,",
+                     MakeTraceSourceAccessor (&CsmaNetDevice::m_macPromiscRxTrace))
+    .AddTraceSource ("MacRx", 
+                     "A packet has been received by this device, has been passed up from the physical layer "
+                     "and is being forwarded up the local protocol stack.  This is a non-promiscuous trace,",
+                     MakeTraceSourceAccessor (&CsmaNetDevice::m_macRxTrace))
+#if 0
+    // Not currently implemented in this device
+    .AddTraceSource ("MacRxDrop", 
+                     "Trace source indicating a packet was received, but dropped before being forwarded up the stack",
+                     MakeTraceSourceAccessor (&CsmaNetDevice::m_macRxDropTrace))
+#endif
+    .AddTraceSource ("MacTxBackoff", 
+                     "Trace source indicating a packet has been delayed by the CSMA backoff process",
+                     MakeTraceSourceAccessor (&CsmaNetDevice::m_macTxBackoffTrace))
+    //
+    // Trace souces at the "bottom" of the net device, where packets transition
+    // to/from the channel.
+    //
+    .AddTraceSource ("PhyTxBegin", 
+                     "Trace source indicating a packet has begun transmitting over the channel",
+                     MakeTraceSourceAccessor (&CsmaNetDevice::m_phyTxBeginTrace))
+    .AddTraceSource ("PhyTxEnd", 
+                     "Trace source indicating a packet has been completely transmitted over the channel",
+                     MakeTraceSourceAccessor (&CsmaNetDevice::m_phyTxEndTrace))
+    .AddTraceSource ("PhyTxDrop", 
+                     "Trace source indicating a packet has been dropped by the device during transmission",
+                     MakeTraceSourceAccessor (&CsmaNetDevice::m_phyTxDropTrace))
+#if 0
+    // Not currently implemented in this device
+    .AddTraceSource ("PhyRxBegin", 
+                     "Trace source indicating a packet has begun being received by the device",
+                     MakeTraceSourceAccessor (&CsmaNetDevice::m_phyRxBeginTrace))
+#endif
+    .AddTraceSource ("PhyRxEnd", 
+                     "Trace source indicating a packet has been completely received by the device",
+                     MakeTraceSourceAccessor (&CsmaNetDevice::m_phyRxEndTrace))
+    .AddTraceSource ("PhyRxDrop", 
+                     "Trace source indicating a packet has been dropped by the device during reception",
+                     MakeTraceSourceAccessor (&CsmaNetDevice::m_phyRxDropTrace))
+    //
+    // Trace sources designed to simulate a packet sniffer facility (tcpdump). 
+    //
+    .AddTraceSource ("Sniffer", 
+                     "Trace source simulating a non-promiscuous packet sniffer attached to the device",
+                     MakeTraceSourceAccessor (&CsmaNetDevice::m_snifferTrace))
+    .AddTraceSource ("PromiscSniffer", 
+                     "Trace source simulating a promiscuous packet sniffer attached to the device",
+                     MakeTraceSourceAccessor (&CsmaNetDevice::m_promiscSnifferTrace))
     ;
   return tid;
 }
@@ -102,11 +163,15 @@
   m_channel = 0; 
 
   // 
-  // We would like to let the attribute system take care of initializing the packet encapsulation stuff, but we also don't want to
-  // get caught up in initialization order changes.  So we'll get the three problem variables into a consistent state here before the
-  // attribute calls, and then depend on the semantics of the setters to preserve a consistent state.  This really doesn't have to be
-  // the same set of values as the initial values set by the attributes, but it does have to be a consistent set.  That is, you can
-  // just change the ddfault encapsulation mode above without having to change it here.  We keep it the same for GP.
+  // We would like to let the attribute system take care of initializing the 
+  // packet encapsulation stuff, but we also don't want to get caught up in
+  // initialization order changes.  So we'll get the three problem variables
+  // into a consistent state here before the attribute calls, and then depend
+  // on the semantics of the setters to preserve a consistent state.  This 
+  // really doesn't have to be the same set of values as the initial values 
+  // set by the attributes, but it does have to be a consistent set.  That is,
+  // you can just change the default encapsulation mode above without having 
+  // to change it here.
   //
   m_encapMode = DIX;
   m_frameSize = DEFAULT_FRAME_SIZE;
@@ -332,7 +397,8 @@
     case DIX:
       NS_LOG_LOGIC ("Encapsulating packet as DIX (type interpretation)");
       //
-      // This corresponds to the type interpretation of the lengthType field as in the old Ethernet Blue Book.
+      // This corresponds to the type interpretation of the lengthType field as
+      // in the old Ethernet Blue Book.
       //
       lengthType = protocolNumber;
       break;
@@ -407,38 +473,47 @@
 }
 
   void
-CsmaNetDevice::TransmitStart ()
+CsmaNetDevice::TransmitStart (void)
 {
   NS_LOG_FUNCTION_NOARGS ();
 
   //
   // This function is called to start the process of transmitting a packet.  We 
-  // expect that a Ptr to the packet to be transmitted has been placed in 
-  // m_currentPkt.
+  // expect that the packet to transmit will be found in m_currentPkt.
+  //
+  NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitStart(): m_currentPkt not set");
 
-  NS_LOG_LOGIC ("m_currentPkt=" << m_currentPkt);
-  NS_LOG_LOGIC ("UID is " << m_currentPkt->GetUid ());
+  NS_LOG_LOGIC ("m_currentPkt = " << m_currentPkt);
+  NS_LOG_LOGIC ("UID = " << m_currentPkt->GetUid ());
 
   //
-  // We need to tell the channel that we've started wiggling the wire and
-  // schedule an event that will be executed when it's time to tell the 
-  // channel that we're done wiggling the wire.
+  // Only transmit if the send side of net device is enabled
+  //
+  if (IsSendEnabled () == false)
+    {
+      m_phyTxDropTrace (m_currentPkt);
+      m_currentPkt = 0;
+      return;
+    }
+
+  //
+  // Somebody has called here telling us to start transmitting a packet.  They 
+  // can only do this if the state machine is in the READY or BACKOFF state.
+  // Specifically, if we are ready to start transmitting, we cannot already
+  // be transmitting (i.e., BUSY)
   //
   NS_ASSERT_MSG ((m_txMachineState == READY) || (m_txMachineState == BACKOFF), 
                  "Must be READY to transmit. Tx state is: " << m_txMachineState);
 
   //
-  // Only transmit if send side of net device is enabled
+  // Now we have to sense the state of the medium and either start transmitting
+  // if it is idle, or backoff our transmission if someone else is on the wire.
   //
-  if (IsSendEnabled () == false)
-    {
-      return;
-    }
-
   if (m_channel->GetState () != IDLE)
     {
       //
-      // The channel is busy -- backoff and rechedule TransmitStart ()
+      // The channel is busy -- backoff and rechedule TransmitStart() unless
+      // we have exhausted all of our retries.
       //
       m_txMachineState = BACKOFF;
 
@@ -451,6 +526,8 @@
         } 
       else 
         {
+          m_macTxBackoffTrace (m_currentPkt);
+
           m_backoff.IncrNumRetries ();
           Time backoffTime = m_backoff.GetBackoffTime ();
 
@@ -464,48 +541,47 @@
       //
       // The channel is free, transmit the packet
       //
-      m_txMachineState = BUSY;
-      Time tEvent = Seconds (m_bps.CalculateTxTime (m_currentPkt->GetSize ()));
-      
-      NS_LOG_LOGIC ("Schedule TransmitCompleteEvent in " << tEvent.GetSeconds () << "sec");
-      
-      Simulator::Schedule (tEvent, &CsmaNetDevice::TransmitCompleteEvent, this);
-
       if (m_channel->TransmitStart (m_currentPkt, m_deviceId) == false)
         {
-          NS_LOG_WARN ("Channel transmit start did not work at " << tEvent.GetSeconds () << "sec");
+          NS_LOG_WARN ("Channel TransmitStart returns an error");
+          m_phyTxDropTrace (m_currentPkt);
+          m_currentPkt = 0;
           m_txMachineState = READY;
         } 
       else 
         {
           //
-          // Transmission succeeded, reset the backoff time parameters.
+          // Transmission succeeded, reset the backoff time parameters and
+          // schedule a transmit complete event.
           //
           m_backoff.ResetBackoffTime ();
+          m_txMachineState = BUSY;
+          m_phyTxBeginTrace (m_currentPkt);
+
+          Time tEvent = Seconds (m_bps.CalculateTxTime (m_currentPkt->GetSize ()));
+          NS_LOG_LOGIC ("Schedule TransmitCompleteEvent in " << tEvent.GetSeconds () << "sec");
+          Simulator::Schedule (tEvent, &CsmaNetDevice::TransmitCompleteEvent, this);
         }
     }
 }
 
-
   void
 CsmaNetDevice::TransmitAbort (void)
 {
   NS_LOG_FUNCTION_NOARGS ();
 
   //
-  // When we started transmitting the current packet, it was placed in 
-  // m_currentPkt.  So we had better find one there.
+  // When we started the process of transmitting the current packet, it was 
+  // placed in m_currentPkt.  So we had better find one there.
   //
   NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitAbort(): m_currentPkt zero");
   NS_LOG_LOGIC ("m_currentPkt=" << m_currentPkt);
   NS_LOG_LOGIC ("Pkt UID is " << m_currentPkt->GetUid () << ")");
 
-  //
-  // Hit the drop trace source.
-  //
-  // XXX Should there be a separate transmit drop trace?
-  //
-  m_dropTrace (m_currentPkt);
+  m_phyTxDropTrace (m_currentPkt);
+  m_currentPkt = 0;
+
+  NS_ASSERT_MSG (m_txMachineState == BACKOFF, "Must be in BACKOFF state to abort.  Tx state is: " << m_txMachineState);
 
   // 
   // We're done with that one, so reset the backoff algorithm and ready the
@@ -527,6 +603,8 @@
     {
       m_currentPkt = m_queue->Dequeue ();
       NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitAbort(): IsEmpty false but no Packet on queue?");
+      m_snifferTrace (m_currentPkt);
+      m_promiscSnifferTrace (m_currentPkt);
       TransmitStart ();
     }
 }
@@ -555,6 +633,8 @@
   NS_LOG_LOGIC ("Pkt UID is " << m_currentPkt->GetUid () << ")");
 
   m_channel->TransmitEnd (); 
+  m_phyTxEndTrace (m_currentPkt);
+  m_currentPkt = 0;
 
   NS_LOG_LOGIC ("Schedule TransmitReadyEvent in " << m_tInterframeGap.GetSeconds () << "sec");
 
@@ -575,12 +655,10 @@
   m_txMachineState = READY;
 
   //
-  // When we started transmitting the current packet, it was placed in 
-  // m_currentPkt.  So we had better find one there.
+  // We expect that the packet we had been transmitting was cleared when the 
+  // TransmitCompleteEvent() was executed.
   //
-  NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitCompleteEvent(): m_currentPkt zero");
-  NS_LOG_LOGIC ("m_currentPkt=" << m_currentPkt);
-  NS_LOG_LOGIC ("Pkt UID is " << m_currentPkt->GetUid () << ")");
+  NS_ASSERT_MSG (m_currentPkt == 0, "CsmaNetDevice::TransmitReadyEvent(): m_currentPkt nonzero");
 
   //
   // Get the next packet from the queue for transmitting
@@ -593,6 +671,8 @@
     {
       m_currentPkt = m_queue->Dequeue ();
       NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitReadyEvent(): IsEmpty false but no Packet on queue?");
+      m_snifferTrace (m_currentPkt);
+      m_promiscSnifferTrace (m_currentPkt);
       TransmitStart ();
     }
 }
@@ -658,21 +738,26 @@
   multicast6Node.CopyFrom(mac);
 
   //
-  // We never forward up packets that we sent. Real devices don't do this since
-  // their receivers are disabled during send, so we don't. Drop the packet
-  // silently (no tracing) since it would really never get here in a real device.
+  // We never forward up packets that we sent.  Real devices don't do this since
+  // their receivers are disabled during send, so we don't.
   // 
   if (senderDevice == this)
     {
       return;
     }
 
+  //
+  // Hit the trace hook.  This trace will fire on all packets received from the
+  // channel except those originated by this device.
+  //
+  m_phyRxEndTrace (packet);
+
   // 
   // Only receive if the send side of net device is enabled
   //
   if (IsReceiveEnabled () == false)
     {
-      m_dropTrace (packet);
+      m_phyRxDropTrace (packet);
       return;
     }
 
@@ -695,7 +780,7 @@
   if (m_receiveErrorModel && m_receiveErrorModel->IsCorrupt (packet) )
     {
       NS_LOG_LOGIC ("Dropping pkt due to error model ");
-      m_dropTrace (packet);
+      m_phyRxDropTrace (packet);
     }
   else
     {
@@ -717,12 +802,14 @@
           protocol = header.GetLengthType ();
         }
 
+      //
+      // Classify the packet based on its destination.
+      //
       PacketType packetType;
       
       if (header.GetDestination ().IsBroadcast ())
         {
           packetType = PACKET_BROADCAST;
-          m_rxTrace (originalPacket);
         }
       else if (header.GetDestination ().IsMulticast () ||
           header.GetDestination() == multicast6Node ||
@@ -731,25 +818,37 @@
           header.GetDestination() == multicast6AllHosts)
         {
           packetType = PACKET_MULTICAST;          
-          m_rxTrace (originalPacket);
         }
       else if (header.GetDestination () == m_address)
         {
           packetType = PACKET_HOST;
-          m_rxTrace (originalPacket);
         }
       else
         {
           packetType = PACKET_OTHERHOST;
         }
-      
+
+      // 
+      // For all kinds of packetType we receive, we hit the promiscuous sniffer
+      // hook and pass a copy up to the promiscuous callback.  Pass a copy to 
+      // make sure that nobody messes with our packet.
+      //
+      m_promiscSnifferTrace (originalPacket);
       if (!m_promiscRxCallback.IsNull ())
         {
+          m_macPromiscRxTrace (originalPacket);
           m_promiscRxCallback (this, packet, protocol, header.GetSource (), header.GetDestination (), packetType);
         }
 
+      //
+      // If this packet is not destined for some other host, it must be for us
+      // as either a broadcast, multicast or unicast.  We need to hit the mac
+      // packet received trace hook and forward the packet up the stack.
+      //
       if (packetType != PACKET_OTHERHOST)
         {
+          m_snifferTrace (originalPacket);
+          m_macRxTrace (originalPacket);
           m_rxCallback (this, packet, protocol, header.GetSource ());
         }
     }
@@ -893,7 +992,7 @@
 CsmaNetDevice::SendFrom (Ptr<Packet> packet, const Address& src, const Address& dest, uint16_t protocolNumber)
 {
   NS_LOG_FUNCTION (packet << src << dest << protocolNumber);
-  NS_LOG_LOGIC ("p=" << packet);
+  NS_LOG_LOGIC ("packet =" << packet);
   NS_LOG_LOGIC ("UID is " << packet->GetUid () << ")");
 
   NS_ASSERT (IsLinkUp ());
@@ -903,6 +1002,7 @@
   //
   if (IsSendEnabled () == false)
     {
+      m_macTxDropTrace (packet);
       return false;
     }
 
@@ -910,11 +1010,15 @@
   Mac48Address source = Mac48Address::ConvertFrom (src);
   AddHeader (packet, source, destination, protocolNumber);
 
+  m_macTxTrace (packet);
+
   //
-  // Place the packet to be sent on the send queue
+  // Place the packet to be sent on the send queue.  Note that the 
+  // queue may fire a drop trace, but we will too.
   //
   if (m_queue->Enqueue(packet) == false)
     {
+      m_macTxDropTrace (packet);
       return false;
     }
 
@@ -925,12 +1029,12 @@
   //
   if (m_txMachineState == READY) 
     {
-      //
-      // The next packet to be transmitted goes in m_currentPkt
-      //
-      m_currentPkt = m_queue->Dequeue ();
-      if (m_currentPkt != 0)
+      if (m_queue->IsEmpty () == false)
         {
+          m_currentPkt = m_queue->Dequeue ();
+          NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::SendFrom(): IsEmpty false but no Packet on queue?");
+          m_promiscSnifferTrace (packet);
+          m_snifferTrace (packet);
           TransmitStart ();
         }
     }
--- a/src/devices/csma/csma-net-device.h	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/devices/csma/csma-net-device.h	Mon Mar 23 19:23:11 2009 -0700
@@ -636,25 +636,150 @@
   Ptr<Queue> m_queue;
 
   /**
-   * Error model for receive packet events
+   * Error model for receive packet events.  When active this model will be
+   * used to model transmission errors by marking some of the packets 
+   * received as corrupt.
    */
   Ptr<ErrorModel> m_receiveErrorModel;
 
   /**
-   * The trace source for the packet reception events that the device can
-   * fire.
+   * The trace source fired when packets come into the "top" of the device
+   * at the L3/L2 transition, before being queued for transmission.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_macTxTrace;
+
+  /**
+   * The trace source fired when packets coming into the "top" of the device
+   * at the L3/L2 transition are dropped before being queued for transmission.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_macTxDropTrace;
+
+  /**
+   * The trace source fired for packets successfully received by the device
+   * immediately before being forwarded up to higher layers (at the L2/L3 
+   * transition).  This is a promiscuous trace.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_macPromiscRxTrace;
+
+  /**
+   * The trace source fired for packets successfully received by the device
+   * immediately before being forwarded up to higher layers (at the L2/L3 
+   * transition).  This is a non-promiscuous trace.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_macRxTrace;
+
+  /**
+   * The trace source fired for packets successfully received by the device
+   * but dropped before being forwarded up to higher layers (at the L2/L3 
+   * transition).
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_macRxDropTrace;
+
+  /**
+   * The trace source fired when the mac layer is forced to begin the backoff
+   * process for a packet.  This can happen a number of times as the backoff
+   * sequence is repeated with increasing delays.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_macTxBackoffTrace;
+
+  /**
+   * The trace source fired when a packet begins the transmission process on
+   * the medium.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_phyTxBeginTrace;
+
+  /**
+   * The trace source fired when a packet ends the transmission process on
+   * the medium.
    *
    * \see class CallBackTraceSource
    */
-  TracedCallback<Ptr<const Packet> > m_rxTrace;
+  TracedCallback<Ptr<const Packet> > m_phyTxEndTrace;
+
+  /**
+   * The trace source fired when the phy layer drops a packet as it tries
+   * to transmit it.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_phyTxDropTrace;
 
   /**
-   * The trace source for the packet drop events that the device can
-   * fire.
+   * The trace source fired when a packet begins the reception process from
+   * the medium.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_phyRxBeginTrace;
+
+  /**
+   * The trace source fired when a packet ends the reception process from
+   * the medium.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_phyRxEndTrace;
+
+  /**
+   * The trace source fired when the phy layer drops a packet it has received.
    *
    * \see class CallBackTraceSource
    */
-  TracedCallback<Ptr<const Packet> > m_dropTrace;
+  TracedCallback<Ptr<const Packet> > m_phyRxDropTrace;
+
+  /**
+   * A trace source that emulates a non-promiscuous protocol sniffer connected 
+   * to the device.  Unlike your average everyday sniffer, this trace source 
+   * will not fire on PACKET_OTHERHOST events.
+   *
+   * On the transmit size, this trace hook will fire after a packet is dequeued
+   * from the device queue for transmission.  In Linux, for example, this would
+   * correspond to the point just before a device hard_start_xmit where 
+   * dev_queue_xmit_nit is called to dispatch the packet to the PF_PACKET 
+   * ETH_P_ALL handlers.
+   *
+   * On the receive side, this trace hook will fire when a packet is received,
+   * just before the receive callback is executed.  In Linux, for example, 
+   * this would correspond to the point at which the packet is dispatched to 
+   * packet sniffers in netif_receive_skb.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_snifferTrace;
+
+  /**
+   * A trace source that emulates a promiscuous mode protocol sniffer connected
+   * to the device.  This trace source fire on packets destined for any host
+   * just like your average everyday packet sniffer.
+   *
+   * On the transmit size, this trace hook will fire after a packet is dequeued
+   * from the device queue for transmission.  In Linux, for example, this would
+   * correspond to the point just before a device hard_start_xmit where 
+   * dev_queue_xmit_nit is called to dispatch the packet to the PF_PACKET 
+   * ETH_P_ALL handlers.
+   *
+   * On the receive side, this trace hook will fire when a packet is received,
+   * just before the receive callback is executed.  In Linux, for example, 
+   * this would correspond to the point at which the packet is dispatched to 
+   * packet sniffers in netif_receive_skb.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_promiscSnifferTrace;
 
   /**
    * The Node to which this device is attached.
@@ -670,6 +795,7 @@
    * 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.
    */
--- a/src/devices/emu/emu-net-device.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/devices/emu/emu-net-device.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -22,17 +22,18 @@
 #include "ns3/log.h"
 #include "ns3/queue.h"
 #include "ns3/simulator.h"
-#include "ns3/realtime-simulator-impl.h"
-#include "ns3/mac48-address.h"
 #include "ns3/ethernet-header.h"
 #include "ns3/ethernet-trailer.h"
 #include "ns3/llc-snap-header.h"
+#include "ns3/boolean.h"
+#include "ns3/uinteger.h"
+#include "ns3/pointer.h"
+#include "ns3/string.h"
 #include "ns3/trace-source-accessor.h"
-#include "ns3/pointer.h"
 #include "ns3/channel.h"
 #include "ns3/system-thread.h"
-#include "ns3/string.h"
-#include "ns3/boolean.h"
+#include "ns3/realtime-simulator-impl.h"
+#include "ns3/mac48-address.h"
 
 #include <sys/wait.h>
 #include <sys/stat.h>
@@ -82,14 +83,84 @@
                    TimeValue (Seconds (0.)),
                    MakeTimeAccessor (&EmuNetDevice::m_tStop),
                    MakeTimeChecker ())
+
+    //
+    // Transmit queueing discipline for the device which includes its own set
+    // of trace hooks.  Note that this is really going to run "on top of" the 
+    // queueing discipline that will most likely be present in the devices of
+    // the underlying operating system.
+    //
     .AddAttribute ("TxQueue", 
                    "A queue to use as the transmit queue in the device.",
                    PointerValue (),
                    MakePointerAccessor (&EmuNetDevice::m_queue),
                    MakePointerChecker<Queue> ())
-    .AddTraceSource ("Rx", 
-                     "Trace source indicating recvfrom of packet destined for broadcast, multicast or local address.",
-                     MakeTraceSourceAccessor (&EmuNetDevice::m_rxTrace))
+
+    //
+    // Trace sources at the "top" of the net device, where packets transition
+    // to/from higher layers.  These points do not really correspond to the 
+    // MAC layer of the underlying operating system, but exist to provide 
+    // a consitent tracing environment.  These trace hooks should really be
+    // interpreted as the points at which a packet leaves the ns-3 environment
+    // destined for the underlying operating system or vice-versa.
+    //
+    .AddTraceSource ("MacTx", 
+                     "Trace source indicating a packet has arrived for transmission by this device",
+                     MakeTraceSourceAccessor (&EmuNetDevice::m_macTxTrace))
+    .AddTraceSource ("MacTxDrop", 
+                     "Trace source indicating a packet has been dropped by the device before transmission",
+                     MakeTraceSourceAccessor (&EmuNetDevice::m_macTxDropTrace))
+    .AddTraceSource ("MacPromiscRx", 
+                     "A packet has been received by this device, has been passed up from the physical layer "
+                     "and is being forwarded up the local protocol stack.  This is a promiscuous trace,",
+                     MakeTraceSourceAccessor (&EmuNetDevice::m_macPromiscRxTrace))
+    .AddTraceSource ("MacRx", 
+                     "A packet has been received by this device, has been passed up from the physical layer "
+                     "and is being forwarded up the local protocol stack.  This is a non-promiscuous trace,",
+                     MakeTraceSourceAccessor (&EmuNetDevice::m_macRxTrace))
+#if 0
+    // Not currently implemented for this device
+    .AddTraceSource ("MacRxDrop", 
+                     "Trace source indicating a packet was dropped before being forwarded up the stack",
+                     MakeTraceSourceAccessor (&EmuNetDevice::m_macRxDropTrace))
+#endif
+    //
+    // In normal ns-3 net devices, these trace souces correspond to the "bottom"
+    // of the net device, where packets transition to/from the channel.  In 
+    // the case of the emu device, there is no physical layer access -- all we
+    // do is to send packets to another device that is really at a "real" MAC
+    // level.  Since it could be misleading to call anything here PHY, we do not
+    // implement these trace sources.
+    //
+#if 0
+    .AddTraceSource ("PhyTxBegin", 
+                     "Trace source indicating a packet has begun transmitting over the channel",
+                     MakeTraceSourceAccessor (&EmuNetDevice::m_phyTxBeginTrace))
+    .AddTraceSource ("PhyTxEnd", 
+                     "Trace source indicating a packet has been completely transmitted over the channel",
+                     MakeTraceSourceAccessor (&EmuNetDevice::m_phyTxEndTrace))
+    .AddTraceSource ("PhyTxDrop", 
+                     "Trace source indicating a packet has been dropped by the device during transmission",
+                     MakeTraceSourceAccessor (&EmuNetDevice::m_phyTxDropTrace))
+    .AddTraceSource ("PhyRxBegin", 
+                     "Trace source indicating a packet has begun being received by the device",
+                     MakeTraceSourceAccessor (&EmuNetDevice::m_phyRxBeginTrace))
+    .AddTraceSource ("PhyRxEnd", 
+                     "Trace source indicating a packet has been completely received by the device",
+                     MakeTraceSourceAccessor (&EmuNetDevice::m_phyRxEndTrace))
+    .AddTraceSource ("PhyRxDrop", 
+                     "Trace source indicating a packet has been dropped by the device during reception",
+                     MakeTraceSourceAccessor (&EmuNetDevice::m_phyRxDropTrace))
+#endif
+    //
+    // Trace sources designed to simulate a packet sniffer facility (tcpdump). 
+    //
+    .AddTraceSource ("Sniffer", 
+                     "Trace source simulating a non-promiscuous packet sniffer attached to the device",
+                     MakeTraceSourceAccessor (&EmuNetDevice::m_snifferTrace))
+    .AddTraceSource ("PromiscSniffer", 
+                     "Trace source simulating a promiscuous packet sniffer attached to the device",
+                     MakeTraceSourceAccessor (&EmuNetDevice::m_promiscSnifferTrace))
     ;
   return tid;
 }
@@ -490,6 +561,19 @@
 {
   NS_LOG_FUNCTION (buf << len);
 
+  /* IPv6 support*/
+  uint8_t mac[6];
+  Mac48Address multicast6AllNodes("33:33:00:00:00:01");
+  Mac48Address multicast6AllRouters("33:33:00:00:00:02");
+  Mac48Address multicast6AllHosts("33:33:00:00:00:03");
+  Mac48Address multicast6Node; /* multicast address addressed to our MAC address */
+
+  /* generate IPv6 multicast ethernet destination that nodes will accept */
+  GetAddress().CopyTo(mac);
+  mac[0]=0x33;
+  mac[1]=0x33;
+  multicast6Node.CopyFrom(mac);
+
   //
   // Create a packet out of the buffer we received and free that buffer.
   //
@@ -516,43 +600,70 @@
   NS_LOG_LOGIC ("Pkt source is " << header.GetSource ());
   NS_LOG_LOGIC ("Pkt destination is " << header.GetDestination ());
 
-  LlcSnapHeader llc;
-  packet->RemoveHeader (llc);
-  uint16_t protocol = llc.GetType ();
+  uint16_t protocol;
+  
+  //
+  // If the length/type is less than 1500, it corresponds to a length 
+  // interpretation packet.  In this case, it is an 802.3 packet and 
+  // will also have an 802.2 LLC header.  If greater than 1500, we
+  // find the protocol number (Ethernet type) directly.
+  //
+  if (header.GetLengthType () <= 1500)
+    {
+      LlcSnapHeader llc;
+      packet->RemoveHeader (llc);
+      protocol = llc.GetType ();
+    }
+  else
+    {
+      protocol = header.GetLengthType ();
+    }
 
   PacketType packetType;
       
   if (header.GetDestination ().IsBroadcast ())
     {
-      NS_LOG_LOGIC ("Pkt destination is PACKET_BROADCAST");
       packetType = NS3_PACKET_BROADCAST;
     }
-  else if (header.GetDestination ().IsMulticast ())
+  else if (header.GetDestination ().IsMulticast () ||
+           header.GetDestination() == multicast6Node ||
+           header.GetDestination() == multicast6AllNodes ||
+           header.GetDestination() == multicast6AllRouters ||
+           header.GetDestination() == multicast6AllHosts)
     {
-      NS_LOG_LOGIC ("Pkt destination is PACKET_MULTICAST");
-      packetType = NS3_PACKET_MULTICAST;
+      packetType = NS3_PACKET_MULTICAST;          
     }
   else if (header.GetDestination () == m_address)
     {
-      NS_LOG_LOGIC ("Pkt destination is PACKET_HOST");
       packetType = NS3_PACKET_HOST;
     }
   else
     {
-      NS_LOG_LOGIC ("Pkt destination is PACKET_OTHERHOST");
       packetType = NS3_PACKET_OTHERHOST;
     }
 
+  // 
+  // For all kinds of packetType we receive, we hit the promiscuous sniffer
+  // hook and pass a copy up to the promiscuous callback.  Pass a copy to 
+  // make sure that nobody messes with our packet.
+  //
+  m_promiscSnifferTrace (originalPacket);
+
   if (!m_promiscRxCallback.IsNull ())
     {
-      NS_LOG_LOGIC ("calling m_promiscRxCallback");
-      m_promiscRxCallback (this, packet->Copy (), protocol, header.GetSource (), header.GetDestination (), packetType);
+      m_macPromiscRxTrace (originalPacket);
+      m_promiscRxCallback (this, packet, protocol, header.GetSource (), header.GetDestination (), packetType);
     }
 
+  //
+  // If this packet is not destined for some other host, it must be for us
+  // as either a broadcast, multicast or unicast.  We need to hit the mac
+  // packet received trace hook and forward the packet up the stack.
+  //
   if (packetType != NS3_PACKET_OTHERHOST)
     {
-      m_rxTrace (originalPacket);
-      NS_LOG_LOGIC ("calling m_rxCallback");
+      m_snifferTrace (originalPacket);
+      m_macRxTrace (originalPacket);
       m_rxCallback (this, packet, protocol, header.GetSource ());
     }
 }
@@ -632,10 +743,12 @@
 EmuNetDevice::SendFrom (Ptr<Packet> packet, const Address &src, const Address &dest, uint16_t protocolNumber)
 {
   NS_LOG_FUNCTION (packet << src << dest << protocolNumber);
+  NS_LOG_LOGIC ("packet =" << packet);
+  NS_LOG_LOGIC ("UID is " << packet->GetUid () << ")");
 
   if (IsLinkUp () == false)
     {
-      NS_LOG_LOGIC ("Link is down, returning");
+      m_macTxDropTrace (packet);
       return false;
     }
 
@@ -646,34 +759,11 @@
   NS_LOG_LOGIC ("Transmit packet from " << source);
   NS_LOG_LOGIC ("Transmit packet to " << destination);
 
-#if 0
-  {
-    struct ifreq ifr;
-    bzero (&ifr, sizeof(ifr));
-    strncpy ((char *)ifr.ifr_name, m_deviceName.c_str (), IFNAMSIZ);
-
-    NS_LOG_LOGIC ("Getting MAC address");
-    int32_t rc = ioctl (m_sock, SIOCGIFHWADDR, &ifr);
-    if (rc == -1)
-      {
-        NS_FATAL_ERROR ("EmuNetDevice::SendFrom(): Can't get MAC address");
-      }
-
-    std::ostringstream oss;
-    oss << std::hex <<
-      (ifr.ifr_hwaddr.sa_data[0] & 0xff) << ":" <<
-      (ifr.ifr_hwaddr.sa_data[1] & 0xff) << ":" <<
-      (ifr.ifr_hwaddr.sa_data[2] & 0xff) << ":" <<
-      (ifr.ifr_hwaddr.sa_data[3] & 0xff) << ":" <<
-      (ifr.ifr_hwaddr.sa_data[4] & 0xff) << ":" <<
-      (ifr.ifr_hwaddr.sa_data[5] & 0xff) << std::dec;
-
-    NS_LOG_LOGIC ("Fixup source to HW MAC " << oss.str ());
-    source = Mac48Address (oss.str ().c_str ());
-    NS_LOG_LOGIC ("source now " << source);
-  }
-#endif
-
+  //
+  // We've got to pick either DIX (Ethernet) or LLC/SNAP (IEEE 802.3) as a 
+  // packet format.  IEEE 802.3 is slightly more formally correct, so we 
+  // go that route.
+  //
   LlcSnapHeader llc;
   llc.SetType (protocolNumber);
   packet->AddHeader (llc);
@@ -688,11 +778,23 @@
   trailer.CalcFcs (packet);
   packet->AddTrailer (trailer);
 
+  //
+  // there's not much meaning associated with the different layers in this
+  // device, so don't be surprised when they're all stacked together in 
+  // essentially one place.  We do this for trace consistency across devices.
+  //
+  m_macTxTrace (packet);
+
   // 
-  // Enqueue and dequeue the packet to hit the tracing hooks.
+  // Enqueue and dequeue the packet to hit the queue tracing hooks.
   //
   m_queue->Enqueue (packet);
   packet = m_queue->Dequeue ();
+  NS_ASSERT_MSG (packet, "EmuNetDevice::SendFrom(): packet zero from queue");
+
+  m_promiscSnifferTrace (packet);
+  m_snifferTrace (packet);
+
 
   struct sockaddr_ll ll;
   bzero (&ll, sizeof (ll));
@@ -705,7 +807,6 @@
 
   int32_t rc;
   rc = sendto (m_sock, packet->PeekData (), packet->GetSize (), 0, reinterpret_cast<struct sockaddr *> (&ll), sizeof (ll));
-
   NS_LOG_LOGIC ("sendto returns " << rc);
 
   return rc == -1 ? false : true;
--- a/src/devices/emu/emu-net-device.h	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/devices/emu/emu-net-device.h	Mon Mar 23 19:23:11 2009 -0700
@@ -264,20 +264,142 @@
   Ptr<Queue> m_queue;
 
   /**
-   * The trace source for the packet reception events that the device can
-   * fire.
+   * The trace source fired when packets come into the "top" of the device
+   * at the L3/L2 transition, before being queued for transmission.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_macTxTrace;
+
+  /**
+   * The trace source fired when packets coming into the "top" of the device
+   * at the L3/L2 transition are dropped before being queued for transmission.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_macTxDropTrace;
+
+  /**
+   * The trace source fired for packets successfully received by the device
+   * immediately before being forwarded up to higher layers (at the L2/L3 
+   * transition).  This is a promiscuous trace.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_macPromiscRxTrace;
+
+  /**
+   * The trace source fired for packets successfully received by the device
+   * immediately before being forwarded up to higher layers (at the L2/L3 
+   * transition).  This is a non-promiscuous trace.
    *
-   * @see class CallBackTraceSource
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_macRxTrace;
+
+  /**
+   * The trace source fired for packets successfully received by the device
+   * but which are dropped before being forwarded up to higher layers (at the 
+   * L2/L3 transition).
+   *
+   * \see class CallBackTraceSource
    */
-  TracedCallback<Ptr<const Packet> > m_rxTrace;
+  TracedCallback<Ptr<const Packet> > m_macRxDropTrace;
+
+  /**
+   * The trace source fired when a packet begins the transmission process on
+   * the medium.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_phyTxBeginTrace;
+
+  /**
+   * The trace source fired when a packet ends the transmission process on
+   * the medium.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_phyTxEndTrace;
+
+  /**
+   * The trace source fired when the phy layer drops a packet as it tries
+   * to transmit it.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_phyTxDropTrace;
 
   /**
-   * The trace source for the packet drop events that the device can
-   * fire.
+   * The trace source fired when a packet ends the reception process from
+   * the medium.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_phyRxTrace;
+
+  /**
+   * The trace source fired when a packet begins the reception process from
+   * the medium.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_phyRxBeginTrace;
+
+  /**
+   * The trace source fired when a packet begins the reception process from
+   * the medium.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_phyRxEndTrace;
+
+  /**
+   * The trace source fired when the phy layer drops a packet it has received.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_phyRxDropTrace;
+
+  /**
+   * A trace source that emulates a non-promiscuous protocol sniffer connected 
+   * to the device.  Unlike your average everyday sniffer, this trace source 
+   * will not fire on PACKET_OTHERHOST events.
    *
-   * @see class CallBackTraceSource
+   * On the transmit size, this trace hook will fire after a packet is dequeued
+   * from the device queue for transmission.  In Linux, for example, this would
+   * correspond to the point just before a device hard_start_xmit where 
+   * dev_queue_xmit_nit is called to dispatch the packet to the PF_PACKET 
+   * ETH_P_ALL handlers.
+   *
+   * On the receive side, this trace hook will fire when a packet is received,
+   * just before the receive callback is executed.  In Linux, for example, 
+   * this would correspond to the point at which the packet is dispatched to 
+   * packet sniffers in netif_receive_skb.
+   *
+   * \see class CallBackTraceSource
    */
-  TracedCallback<Ptr<const Packet> > m_dropTrace;
+  TracedCallback<Ptr<const Packet> > m_snifferTrace;
+
+  /**
+   * A trace source that emulates a promiscuous mode protocol sniffer connected
+   * to the device.  This trace source fire on packets destined for any host
+   * just like your average everyday packet sniffer.
+   *
+   * On the transmit size, this trace hook will fire after a packet is dequeued
+   * from the device queue for transmission.  In Linux, for example, this would
+   * correspond to the point just before a device hard_start_xmit where 
+   * dev_queue_xmit_nit is called to dispatch the packet to the PF_PACKET 
+   * ETH_P_ALL handlers.
+   *
+   * On the receive side, this trace hook will fire when a packet is received,
+   * just before the receive callback is executed.  In Linux, for example, 
+   * this would correspond to the point at which the packet is dispatched to 
+   * packet sniffers in netif_receive_skb.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_promiscSnifferTrace;
 
   /**
    * Time to start spinning up the device
--- a/src/devices/point-to-point/point-to-point-channel.h	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/devices/point-to-point/point-to-point-channel.h	Mon Mar 23 19:23:11 2009 -0700
@@ -62,13 +62,13 @@
   void Attach (Ptr<PointToPointNetDevice> device);
 
   /**
-   * \brief Attach a given netdevice to this channel
+   * \brief Transmit a packet over this channel
    * \param p Packet to transmit
    * \param src Source PointToPointNetDevice
    * \param txTime Transmit time to apply
+   * \returns true if successful (currently always true)
    */
-  bool TransmitStart (Ptr<Packet> p, Ptr<PointToPointNetDevice> src,
-    Time txTime);
+  bool TransmitStart (Ptr<Packet> p, Ptr<PointToPointNetDevice> src, Time txTime);
 
   /**
    * \brief Get number of devices on this channel
--- a/src/devices/point-to-point/point-to-point-net-device.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/devices/point-to-point/point-to-point-net-device.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -62,23 +62,83 @@
                    PointerValue (),
                    MakePointerAccessor (&PointToPointNetDevice::m_receiveErrorModel),
                    MakePointerChecker<ErrorModel> ())
-    .AddAttribute ("TxQueue",
-                   "A queue to use as the transmit queue in the device.",
-                   PointerValue (),
-                   MakePointerAccessor (&PointToPointNetDevice::m_queue),
-                   MakePointerChecker<Queue> ())
     .AddAttribute ("InterframeGap", 
                    "The time to wait between packet (frame) transmissions",
                    TimeValue (Seconds (0.0)),
                    MakeTimeAccessor (&PointToPointNetDevice::m_tInterframeGap),
                    MakeTimeChecker ())
-    .AddTraceSource ("Rx", 
-                     "Trace source indicating reception of packet from the PointToPointChannel.",
-                     MakeTraceSourceAccessor (&PointToPointNetDevice::m_rxTrace))
-    .AddTraceSource ("Drop",
-                     "Trace source indicating a packet was discarded due to a ReceiveErrorModel decision.",
-                     MakeTraceSourceAccessor (&PointToPointNetDevice::m_dropTrace))
+
+    //
+    // Transmit queueing discipline for the device which includes its own set
+    // of trace hooks.
+    //
+    .AddAttribute ("TxQueue", 
+                   "A queue to use as the transmit queue in the device.",
+                   PointerValue (),
+                   MakePointerAccessor (&PointToPointNetDevice::m_queue),
+                   MakePointerChecker<Queue> ())
 
+    //
+    // Trace sources at the "top" of the net device, where packets transition
+    // to/from higher layers.
+    //
+    .AddTraceSource ("MacTx", 
+                     "Trace source indicating a packet has arrived for transmission by this device",
+                     MakeTraceSourceAccessor (&PointToPointNetDevice::m_macTxTrace))
+    .AddTraceSource ("MacTxDrop", 
+                     "Trace source indicating a packet has been dropped by the device before transmission",
+                     MakeTraceSourceAccessor (&PointToPointNetDevice::m_macTxDropTrace))
+    .AddTraceSource ("MacPromiscRx", 
+                     "A packet has been received by this device, has been passed up from the physical layer "
+                     "and is being forwarded up the local protocol stack.  This is a promiscuous trace,",
+                     MakeTraceSourceAccessor (&PointToPointNetDevice::m_macPromiscRxTrace))
+    .AddTraceSource ("MacRx", 
+                     "A packet has been received by this device, has been passed up from the physical layer "
+                     "and is being forwarded up the local protocol stack.  This is a non-promiscuous trace,",
+                     MakeTraceSourceAccessor (&PointToPointNetDevice::m_macRxTrace))
+#if 0
+    // Not currently implemented for this device
+    .AddTraceSource ("MacRxDrop", 
+                     "Trace source indicating a packet was dropped before being forwarded up the stack",
+                     MakeTraceSourceAccessor (&PointToPointNetDevice::m_macRxDropTrace))
+#endif
+    //
+    // Trace souces at the "bottom" of the net device, where packets transition
+    // to/from the channel.
+    //
+    .AddTraceSource ("PhyTxBegin", 
+                     "Trace source indicating a packet has begun transmitting over the channel",
+                     MakeTraceSourceAccessor (&PointToPointNetDevice::m_phyTxBeginTrace))
+    .AddTraceSource ("PhyTxEnd", 
+                     "Trace source indicating a packet has been completely transmitted over the channel",
+                     MakeTraceSourceAccessor (&PointToPointNetDevice::m_phyTxEndTrace))
+    .AddTraceSource ("PhyTxDrop", 
+                     "Trace source indicating a packet has been dropped by the device during transmission",
+                     MakeTraceSourceAccessor (&PointToPointNetDevice::m_phyTxDropTrace))
+#if 0
+    // Not currently implemented for this device
+    .AddTraceSource ("PhyRxBegin", 
+                     "Trace source indicating a packet has begun being received by the device",
+                     MakeTraceSourceAccessor (&PointToPointNetDevice::m_phyRxBeginTrace))
+#endif
+    .AddTraceSource ("PhyRxEnd", 
+                     "Trace source indicating a packet has been completely received by the device",
+                     MakeTraceSourceAccessor (&PointToPointNetDevice::m_phyRxEndTrace))
+    .AddTraceSource ("PhyRxDrop", 
+                     "Trace source indicating a packet has been dropped by the device during reception",
+                     MakeTraceSourceAccessor (&PointToPointNetDevice::m_phyRxDropTrace))
+
+    //
+    // Trace sources designed to simulate a packet sniffer facility (tcpdump).
+    // Note that there is really no difference between promiscuous and 
+    // non-promiscuous traces in a point-to-point link.
+    //
+    .AddTraceSource ("Sniffer", 
+                     "Trace source simulating a non-promiscuous packet sniffer attached to the device",
+                     MakeTraceSourceAccessor (&PointToPointNetDevice::m_snifferTrace))
+    .AddTraceSource ("PromiscSniffer", 
+                     "Trace source simulating a promiscuous packet sniffer attached to the device",
+                     MakeTraceSourceAccessor (&PointToPointNetDevice::m_promiscSnifferTrace))
     ;
   return tid;
 }
@@ -89,7 +149,8 @@
   m_txMachineState (READY),
   m_channel (0), 
   m_name (""),
-  m_linkUp (false)
+  m_linkUp (false),
+  m_currentPkt (0)
 {
   NS_LOG_FUNCTION (this);
 
@@ -106,14 +167,14 @@
 
 PointToPointNetDevice::~PointToPointNetDevice ()
 {
+  NS_LOG_FUNCTION_NOARGS ();
 }
 
   void 
 PointToPointNetDevice::AddHeader(Ptr<Packet> p, uint16_t protocolNumber)
 {
   NS_LOG_FUNCTION_NOARGS ();
-  NS_ASSERT_MSG (protocolNumber == 0x800,
-    "PointToPointNetDevice::AddHeader(): protocolNumber must be 0x800");
+  NS_ASSERT_MSG (protocolNumber == 0x800, "PointToPointNetDevice::AddHeader(): protocolNumber must be 0x800");
   PppHeader ppp;
   p->AddHeader (ppp);
 }
@@ -135,6 +196,7 @@
   m_node = 0;
   m_channel = 0;
   m_receiveErrorModel = 0;
+  m_currentPkt = 0;
   NetDevice::DoDispose ();
 }
 
@@ -157,48 +219,64 @@
 {
   NS_LOG_FUNCTION (this << p);
   NS_LOG_LOGIC ("UID is " << p->GetUid () << ")");
-//
-// This function is called to start the process of transmitting a packet.
-// We need to tell the channel that we've started wiggling the wire and
-// schedule an event that will be executed when the transmission is complete.
-//
+
+  //
+  // This function is called to start the process of transmitting a packet.
+  // We need to tell the channel that we've started wiggling the wire and
+  // schedule an event that will be executed when the transmission is complete.
+  //
   NS_ASSERT_MSG(m_txMachineState == READY, "Must be READY to transmit");
   m_txMachineState = BUSY;
+  m_currentPkt = p;
+  m_phyTxBeginTrace (m_currentPkt);
+
   Time txTime = Seconds (m_bps.CalculateTxTime(p->GetSize()));
   Time txCompleteTime = txTime + m_tInterframeGap;
 
-  NS_LOG_LOGIC ("Schedule TransmitCompleteEvent in " << 
-    txCompleteTime.GetSeconds () << "sec");
+  NS_LOG_LOGIC ("Schedule TransmitCompleteEvent in " << txCompleteTime.GetSeconds () << "sec");
+  Simulator::Schedule (txCompleteTime, &PointToPointNetDevice::TransmitComplete, this);
 
-  Simulator::Schedule (txCompleteTime, 
-    &PointToPointNetDevice::TransmitComplete, this);
-
-  return m_channel->TransmitStart(p, this, txTime); 
+  bool result = m_channel->TransmitStart(p, this, txTime); 
+  if (result == false)
+    {
+      m_phyTxDropTrace (p);
+    }
+  return result;
 }
 
   void 
 PointToPointNetDevice::TransmitComplete (void)
 {
   NS_LOG_FUNCTION_NOARGS ();
-//
-// This function is called to when we're all done transmitting a packet.
-// We try and pull another packet off of the transmit queue.  If the queue
-// is empty, we are done, otherwise we need to start transmitting the
-// next packet.
-//
+
+  //
+  // This function is called to when we're all done transmitting a packet.
+  // We try and pull another packet off of the transmit queue.  If the queue
+  // is empty, we are done, otherwise we need to start transmitting the
+  // next packet.
+  //
   NS_ASSERT_MSG(m_txMachineState == BUSY, "Must be BUSY if transmitting");
   m_txMachineState = READY;
+
+  NS_ASSERT_MSG (m_currentPkt != 0, "PointToPointNetDevice::TransmitComplete(): m_currentPkt zero");
+
+  m_phyTxEndTrace (m_currentPkt);
+  m_currentPkt = 0;
+
   Ptr<Packet> p = m_queue->Dequeue ();
   if (p == 0)
     {
-//
-// No packet was on the queue, so we just exit.
-//
+      //
+      // No packet was on the queue, so we just exit.
+      //
       return;
     }
-//
-// Got another packet off of the queue, so start the transmit process agin.
-//
+
+  //
+  // Got another packet off of the queue, so start the transmit process agin.
+  //
+  m_snifferTrace (p);
+  m_promiscSnifferTrace (p);
   TransmitStart(p);
 }
 
@@ -211,11 +289,11 @@
 
   m_channel->Attach(this);
 
-//
-// This device is up whenever it is attached to a channel.  A better plan
-// would be to have the link come up when both devices are attached, but this
-// is not done for now.
-//
+  //
+  // This device is up whenever it is attached to a channel.  A better plan
+  // would be to have the link come up when both devices are attached, but this
+  // is not done for now.
+  //
   NotifyLinkUp ();
   return true;
 }
@@ -242,25 +320,39 @@
 
   if (m_receiveErrorModel && m_receiveErrorModel->IsCorrupt (packet) ) 
     {
-// 
-// If we have an error model and it indicates that it is time to lose a
-// corrupted packet, don't forward this packet up, let it go.
-//
-      m_dropTrace (packet);
+      // 
+      // If we have an error model and it indicates that it is time to lose a
+      // corrupted packet, don't forward this packet up, let it go.
+      //
+      m_phyRxDropTrace (packet);
     }
   else 
     {
-// 
-// Hit the receive trace hook, strip off the point-to-point protocol header
-// and forward this packet up the protocol stack.
-//
-      m_rxTrace (packet);
+      // 
+      // Hit the trace hooks.  All of these hooks are in the same place in this 
+      // device becuase it is so simple, but this is not usually the case in 
+      // more complicated devices.
+      //
+      m_snifferTrace (packet);
+      m_promiscSnifferTrace (packet);
+      m_phyRxEndTrace (packet);
+
+      //
+      // Strip off the point-to-point protocol header and forward this packet
+      // up the protocol stack.  Since this is a simple point-to-point link,
+      // there is no difference in what the promisc callback sees and what the
+      // normal receive callback sees.
+      //
       ProcessHeader(packet, protocol);
-      m_rxCallback (this, packet, protocol, GetRemote ());
+
       if (!m_promiscCallback.IsNull ())
         {
+          m_macPromiscRxTrace (packet);
           m_promiscCallback (this, packet, protocol, GetRemote (), GetAddress (), NetDevice::PACKET_HOST);
         }
+
+      m_macRxTrace (packet);
+      m_rxCallback (this, packet, protocol, GetRemote ());
     }
 }
 
@@ -406,33 +498,38 @@
   NS_LOG_LOGIC ("p=" << packet << ", dest=" << &dest);
   NS_LOG_LOGIC ("UID is " << packet->GetUid ());
 
-//
-// If IsLinkUp() is false it means there is no channel to send any packet 
-// over so we just return an error.
-//
+  //
+  // If IsLinkUp() is false it means there is no channel to send any packet 
+  // over so we just hit the drop trace on the packet and return an error.
+  //
   if (IsLinkUp () == false)
     {
+      m_macTxDropTrace (packet);
       return false;
     }
 
-//
-// Stick a point to point protocol header on the packet in preparation for
-// shoving it out the door.
-//
+  //
+  // Stick a point to point protocol header on the packet in preparation for
+  // shoving it out the door.
+  //
   AddHeader(packet, protocolNumber);
 
-//
-// If there's a transmission in progress, we enque the packet for later
-// transmission; otherwise we send it now.
-//
+  m_macTxTrace (packet);
+
+  //
+  // If there's a transmission in progress, we enque the packet for later
+  // transmission; otherwise we send it now.
+  //
   if (m_txMachineState == READY) 
     {
-// 
-// Even if the transmitter is immediately available, we still enqueue and 
-// dequeue the packet to hit the tracing hooks.
-//
+      // 
+      // Even if the transmitter is immediately available, we still enqueue and
+      // dequeue the packet to hit the tracing hooks.
+      //
       m_queue->Enqueue (packet);
       packet = m_queue->Dequeue ();
+      m_snifferTrace (packet);
+      m_promiscSnifferTrace (packet);
       return TransmitStart (packet);
     }
   else
@@ -477,7 +574,7 @@
 void
 PointToPointNetDevice::SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb)
 {
-  NS_FATAL_ERROR ("not implemented");
+  NS_FATAL_ERROR ("PointToPointNetDevice::SetPromiscReceiveCallback(): Not implemented");
   m_promiscCallback = cb;
 }
 
--- a/src/devices/point-to-point/point-to-point-net-device.h	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/devices/point-to-point/point-to-point-net-device.h	Mon Mar 23 19:23:11 2009 -0700
@@ -388,26 +388,144 @@
   Ptr<Queue> m_queue;
 
   /**
-   * The trace source for the packet reception events that the device can
-   * fire.
-   *
-   * @see class CallBackTraceSource
-   */
-  TracedCallback<Ptr<const Packet> > m_rxTrace;
-
-  /**
-   * The trace source for the packet drop events that the device can
-   * fire.
-   *
-   * @see class CallBackTraceSource
-   */
-  TracedCallback<Ptr<const Packet> > m_dropTrace;
-
-  /**
    * Error model for receive packet events
    */
   Ptr<ErrorModel> m_receiveErrorModel;
 
+  /**
+   * The trace source fired when packets come into the "top" of the device
+   * at the L3/L2 transition, before being queued for transmission.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_macTxTrace;
+
+  /**
+   * The trace source fired when packets coming into the "top" of the device
+   * at the L3/L2 transition are dropped before being queued for transmission.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_macTxDropTrace;
+
+  /**
+   * The trace source fired for packets successfully received by the device
+   * immediately before being forwarded up to higher layers (at the L2/L3 
+   * transition).  This is a promiscuous trace (which doesn't mean a lot here
+   * in the point-to-point device).
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_macPromiscRxTrace;
+
+  /**
+   * The trace source fired for packets successfully received by the device
+   * immediately before being forwarded up to higher layers (at the L2/L3 
+   * transition).  This is a non-promiscuous trace (which doesn't mean a lot 
+   * here in the point-to-point device).
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_macRxTrace;
+
+  /**
+   * The trace source fired for packets successfully received by the device
+   * but are dropped before being forwarded up to higher layers (at the L2/L3 
+   * transition).
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_macRxDropTrace;
+
+  /**
+   * The trace source fired when a packet begins the transmission process on
+   * the medium.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_phyTxBeginTrace;
+
+  /**
+   * The trace source fired when a packet ends the transmission process on
+   * the medium.  
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_phyTxEndTrace;
+
+  /**
+   * The trace source fired when the phy layer drops a packet before it tries
+   * to transmit it.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_phyTxDropTrace;
+
+  /**
+   * The trace source fired when a packet begins the reception process from
+   * the medium -- when the simulated first bit(s) arrive.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_phyRxBeginTrace;
+
+  /**
+   * The trace source fired when a packet ends the reception process from
+   * the medium.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_phyRxEndTrace;
+
+  /**
+   * The trace source fired when the phy layer drops a packet it has received.
+   * This happens if the receiver is not enabled or the error model is active
+   * and indicates that the packet is corrupt.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_phyRxDropTrace;
+
+  /**
+   * A trace source that emulates a non-promiscuous protocol sniffer connected 
+   * to the device.  Unlike your average everyday sniffer, this trace source 
+   * will not fire on PACKET_OTHERHOST events.
+   *
+   * On the transmit size, this trace hook will fire after a packet is dequeued
+   * from the device queue for transmission.  In Linux, for example, this would
+   * correspond to the point just before a device hard_start_xmit where 
+   * dev_queue_xmit_nit is called to dispatch the packet to the PF_PACKET 
+   * ETH_P_ALL handlers.
+   *
+   * On the receive side, this trace hook will fire when a packet is received,
+   * just before the receive callback is executed.  In Linux, for example, 
+   * this would correspond to the point at which the packet is dispatched to 
+   * packet sniffers in netif_receive_skb.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_snifferTrace;
+
+  /**
+   * A trace source that emulates a promiscuous mode protocol sniffer connected
+   * to the device.  This trace source fire on packets destined for any host
+   * just like your average everyday packet sniffer.
+   *
+   * On the transmit size, this trace hook will fire after a packet is dequeued
+   * from the device queue for transmission.  In Linux, for example, this would
+   * correspond to the point just before a device hard_start_xmit where 
+   * dev_queue_xmit_nit is called to dispatch the packet to the PF_PACKET 
+   * ETH_P_ALL handlers.
+   *
+   * On the receive side, this trace hook will fire when a packet is received,
+   * just before the receive callback is executed.  In Linux, for example, 
+   * this would correspond to the point at which the packet is dispatched to 
+   * packet sniffers in netif_receive_skb.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_promiscSnifferTrace;
+
   Ptr<Node> m_node;
   Mac48Address m_address;
   NetDevice::ReceiveCallback m_rxCallback;
@@ -435,6 +553,8 @@
    * Ethernet.
    */
   uint32_t m_mtu;
+
+  Ptr<Packet> m_currentPkt;
 };
 
 } // namespace ns3
--- a/src/devices/tap-bridge/tap-bridge.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/devices/tap-bridge/tap-bridge.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -940,7 +940,6 @@
     }
 
   Ptr<Packet> p = packet->Copy ();
-
   EthernetHeader header = EthernetHeader (false);
   header.SetSource (from);
   header.SetDestination (to);
--- a/src/devices/wifi/adhoc-wifi-mac.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/devices/wifi/adhoc-wifi-mac.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -24,6 +24,7 @@
 #include "mac-rx-middle.h"
 #include "wifi-phy.h"
 #include "dcf-manager.h"
+#include "wifi-mac-trailer.h"
 #include "ns3/pointer.h"
 #include "ns3/packet.h"
 #include "ns3/log.h"
--- a/src/devices/wifi/nqap-wifi-mac.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/devices/wifi/nqap-wifi-mac.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -30,6 +30,7 @@
 #include "dcf-manager.h"
 #include "mac-rx-middle.h"
 #include "mac-low.h"
+#include "wifi-mac-trailer.h"
 #include "ns3/pointer.h"
 
 NS_LOG_COMPONENT_DEFINE ("NqapWifiMac");
@@ -287,6 +288,7 @@
   NS_LOG_FUNCTION (this << packet << from);
   m_upCallback (packet, from, to);
 }
+
 void 
 NqapWifiMac::ForwardDown (Ptr<const Packet> packet, Mac48Address from, Mac48Address to)
 {
@@ -298,6 +300,7 @@
   hdr.SetAddr3 (from);
   hdr.SetDsFrom ();
   hdr.SetDsNotTo ();
+
   m_dca->Queue (packet, hdr);  
 }
 void 
@@ -472,11 +475,13 @@
         {
           // this is an AP-to-AP frame
           // we ignore for now.
+          NotifyRxDrop (packet);
         } 
       else 
         {
           // we can ignore these frames since 
           // they are not targeted at the AP
+          NotifyRxDrop (packet);
         }
     } 
   else if (hdr->IsMgt ()) 
--- a/src/devices/wifi/nqsta-wifi-mac.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/devices/wifi/nqsta-wifi-mac.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -34,6 +34,7 @@
 #include "mac-low.h"
 #include "dcf-manager.h"
 #include "mac-rx-middle.h"
+#include "wifi-mac-trailer.h"
 #include "ns3/trace-source-accessor.h"
 #include "ns3/pointer.h"
 
@@ -457,14 +458,16 @@
 void 
 NqstaWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to, Mac48Address from)
 {
-  NS_FATAL_ERROR ("Qsta does not support enqueue");
+  NS_FATAL_ERROR ("Qsta does not support SendTo");
 }
+
 void 
 NqstaWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to)
 {
   NS_LOG_FUNCTION (this << packet << to);
   if (!IsAssociated ()) 
     {
+      NotifyTxDrop (packet);
       TryToEnsureAssociated ();
       return;
     }
@@ -476,12 +479,18 @@
   hdr.SetAddr3 (to);
   hdr.SetDsNotFrom ();
   hdr.SetDsTo ();
+
   m_dca->Queue (packet, hdr);
 }
+
 bool 
 NqstaWifiMac::SupportsSendFrom (void) const
 {
-  return true;
+  //
+  // The 802.11 MAC protocol has no way to support bridging outside of
+  // infrastructure mode
+  //
+  return false;
 }  
 
 
@@ -498,24 +507,29 @@
            !hdr->GetAddr1 ().IsGroup ()) 
     {
       NS_LOG_LOGIC ("packet is not for us");
+      NotifyRxDrop (packet);
     } 
   else if (hdr->IsData ()) 
     {
       if (!IsAssociated ())
         {
           NS_LOG_LOGIC ("Received data frame while not associated: ignore");
+          NotifyRxDrop (packet);
           return;
         }
       if (!(hdr->IsFromDs () && !hdr->IsToDs ()))
         {
           NS_LOG_LOGIC ("Received data frame not from the DS: ignore");
+          NotifyRxDrop (packet);
           return;
         }
       if (hdr->GetAddr2 () != GetBssid ())
         {
           NS_LOG_LOGIC ("Received data frame not from the the BSS we are associated with: ignore");
+          NotifyRxDrop (packet);
           return;
         }
+
       ForwardUp (packet, hdr->GetAddr3 (), hdr->GetAddr1 ());
     } 
   else if (hdr->IsProbeReq () ||
@@ -524,6 +538,7 @@
       /* this is a frame aimed at an AP.
        * so we can safely ignore it.
        */
+      NotifyRxDrop (packet);
     } 
   else if (hdr->IsBeacon ()) 
     {
--- a/src/devices/wifi/wifi-mac.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/devices/wifi/wifi-mac.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -19,6 +19,7 @@
  */
 #include "wifi-mac.h"
 #include "ns3/uinteger.h"
+#include "ns3/trace-source-accessor.h"
 
 namespace ns3 {
 
@@ -67,7 +68,6 @@
   return ctsTimeout;
 }
 
-
 TypeId 
 WifiMac::GetTypeId (void)
 {
@@ -117,7 +117,33 @@
 		   MakeSsidAccessor (&WifiMac::GetSsid,
 				     &WifiMac::SetSsid),
 		   MakeSsidChecker ())
+    .AddTraceSource ("MacTx", 
+                     "A packet has been received from higher layers and is being processed in preparation for "
+                     "queueing for transmission.",
+                     MakeTraceSourceAccessor (&WifiMac::m_macTxTrace))
+    .AddTraceSource ("MacTxDrop", 
+                     "A packet has been dropped in the MAC layer before being queued for transmission.",
+                     MakeTraceSourceAccessor (&WifiMac::m_macTxDropTrace))
+    .AddTraceSource ("MacPromiscRx", 
+                     "A packet has been received by this device, has been passed up from the physical layer "
+                     "and is being forwarded up the local protocol stack.  This is a promiscuous trace,",
+                     MakeTraceSourceAccessor (&WifiMac::m_macPromiscRxTrace))
+    .AddTraceSource ("MacRx", 
+                     "A packet has been received by this device, has been passed up from the physical layer "
+                     "and is being forwarded up the local protocol stack.  This is a non-promiscuous trace,",
+                     MakeTraceSourceAccessor (&WifiMac::m_macRxTrace))
+    .AddTraceSource ("MacRxDrop", 
+                     "A packet has been dropped in the MAC layer after it has been passed up from the physical "
+                     "layer.",
+                     MakeTraceSourceAccessor (&WifiMac::m_macRxDropTrace))
+#if 0
+    // Not currently implemented in this device
+    .AddTraceSource ("Sniffer", 
+                     "Trace source simulating a non-promiscuous packet sniffer attached to the device",
+                     MakeTraceSourceAccessor (&WifiMac::m_snifferTrace))
+#endif
     ;
+
   return tid;
 }
 
@@ -144,5 +170,34 @@
   return m_maxMsduSize;
 }
 
+void 
+WifiMac::NotifyTx (Ptr<const Packet> packet)
+{
+  m_macTxTrace (packet);
+}
+
+void 
+WifiMac::NotifyTxDrop (Ptr<const Packet> packet) 
+{
+  m_macTxDropTrace (packet);
+}
+
+void 
+WifiMac::NotifyRx (Ptr<const Packet> packet) 
+{
+  m_macRxTrace (packet);
+}
+
+void 
+WifiMac::NotifyPromiscRx (Ptr<const Packet> packet) 
+{
+  m_macPromiscRxTrace (packet);
+}
+
+void 
+WifiMac::NotifyRxDrop (Ptr<const Packet> packet) 
+{
+  m_macRxDropTrace (packet);
+}
 
 } // namespace ns3
--- a/src/devices/wifi/wifi-mac.h	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/devices/wifi/wifi-mac.h	Mon Mar 23 19:23:11 2009 -0700
@@ -176,10 +176,38 @@
    * \param linkDown the callback to invoke when the link becomes down.
    */
   virtual void SetLinkDownCallback (Callback<void> linkDown) = 0;
-private:
+
+  /**
+   * Public method used to fire a MacTx trace.  Implemented for encapsulation 
+   * purposes.
+   */
+  void NotifyTx (Ptr<const Packet> packet);
+
+  /**
+   * Public method used to fire a MacTxDrop trace.  Implemented for encapsulation 
+   * purposes.
+   */
+  void NotifyTxDrop (Ptr<const Packet> packet);
 
+  /**
+   * Public method used to fire a MacRx trace.  Implemented for encapsulation 
+   * purposes.
+   */
+  void NotifyRx (Ptr<const Packet> packet);
 
+  /**
+   * Public method used to fire a MacPromiscRx trace.  Implemented for encapsulation 
+   * purposes.
+   */
+  void NotifyPromiscRx (Ptr<const Packet> packet);
 
+  /**
+   * Public method used to fire a MacRxDrop trace.  Implemented for encapsulation 
+   * purposes.
+   */
+  void NotifyRxDrop (Ptr<const Packet> packet);
+
+private:
   static Time GetDefaultMaxPropagationDelay (void);
   static Time GetDefaultSlot (void);
   static Time GetDefaultSifs (void);
@@ -189,6 +217,49 @@
 
   Time m_maxPropagationDelay;
   uint32_t m_maxMsduSize;
+
+  /**
+   * The trace source fired when packets come into the "top" of the device
+   * at the L3/L2 transition, before being queued for transmission.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_macTxTrace;
+
+  /**
+   * The trace source fired when packets coming into the "top" of the device
+   * are dropped at the MAC layer during transmission.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_macTxDropTrace;
+
+  /**
+   * The trace source fired for packets successfully received by the device
+   * immediately before being forwarded up to higher layers (at the L2/L3 
+   * transition).  This is a promiscuous trace.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_macPromiscRxTrace;
+
+  /**
+   * The trace source fired for packets successfully received by the device
+   * immediately before being forwarded up to higher layers (at the L2/L3 
+   * transition).  This is a non- promiscuous trace.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_macRxTrace;
+
+  /**
+   * The trace source fired when packets coming into the "top" of the device
+   * are dropped at the MAC layer during reception.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_macRxDropTrace;
+
 };
 
 } // namespace ns3
--- a/src/devices/wifi/wifi-net-device.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/devices/wifi/wifi-net-device.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -57,10 +57,6 @@
                    MakePointerAccessor (&WifiNetDevice::SetRemoteStationManager,
                                         &WifiNetDevice::GetRemoteStationManager),
                    MakePointerChecker<WifiRemoteStationManager> ())
-    .AddTraceSource ("Rx", "Received payload from the MAC layer.",
-                     MakeTraceSourceAccessor (&WifiNetDevice::m_rxLogger))
-    .AddTraceSource ("Tx", "Send payload to the MAC layer.",
-                     MakeTraceSourceAccessor (&WifiNetDevice::m_txLogger))
     ;
   return tid;
 }
@@ -243,18 +239,18 @@
   return false;
 }
 bool 
-WifiNetDevice::Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
+WifiNetDevice::Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
 {
   NS_ASSERT (Mac48Address::IsMatchingType (dest));
 
   Mac48Address realTo = Mac48Address::ConvertFrom (dest);
+  Mac48Address realFrom = Mac48Address::ConvertFrom (GetAddress ());
 
   LlcSnapHeader llc;
   llc.SetType (protocolNumber);
   packet->AddHeader (llc);
 
-  m_txLogger (packet, realTo);
-
+  m_mac->NotifyTx (packet);
   m_mac->Enqueue (packet, realTo);
   return true;
 }
@@ -283,7 +279,6 @@
 void
 WifiNetDevice::ForwardUp (Ptr<Packet> packet, Mac48Address from, Mac48Address to)
 {
-  m_rxLogger (packet, from);
   LlcSnapHeader llc;
   packet->RemoveHeader (llc);
   enum NetDevice::PacketType type;
@@ -303,12 +298,16 @@
     {
       type = NetDevice::PACKET_OTHERHOST;
     }
+
   if (type != NetDevice::PACKET_OTHERHOST)
     {
+      m_mac->NotifyRx (packet);
       m_forwardUp (this, packet, llc.GetType (), from);
     }
+
   if (!m_promiscRx.IsNull ())
     {
+      m_mac->NotifyPromiscRx (packet);
       m_promiscRx (this, packet, llc.GetType (), from, to, type);
     }
 }
@@ -345,8 +344,7 @@
   llc.SetType (protocolNumber);
   packet->AddHeader (llc);
 
-  m_txLogger (packet, realTo);
-
+  m_mac->NotifyTx (packet);
   m_mac->Enqueue (packet, realTo, realFrom);
 
   return true;
--- a/src/devices/wifi/wifi-net-device.h	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/devices/wifi/wifi-net-device.h	Mon Mar 23 19:23:11 2009 -0700
@@ -118,8 +118,10 @@
   Ptr<WifiRemoteStationManager> m_stationManager;
   NetDevice::ReceiveCallback m_forwardUp;
   NetDevice::PromiscReceiveCallback m_promiscRx;
+
   TracedCallback<Ptr<const Packet>, Mac48Address> m_rxLogger;
   TracedCallback<Ptr<const Packet>, Mac48Address> m_txLogger;
+
   uint32_t m_ifIndex;
   std::string m_name;
   bool m_linkUp;
--- a/src/devices/wifi/wifi-phy.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/devices/wifi/wifi-phy.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -55,6 +55,27 @@
 {
   static TypeId tid = TypeId ("ns3::WifiPhy")
     .SetParent<Object> ()
+    .AddTraceSource ("PhyTxBegin", 
+                     "Trace source indicating a packet has begun transmitting over the channel medium",
+                     MakeTraceSourceAccessor (&WifiPhy::m_phyTxBeginTrace))
+    .AddTraceSource ("PhyTxEnd", 
+                     "Trace source indicating a packet has been completely transmitted over the channel",
+                     MakeTraceSourceAccessor (&WifiPhy::m_phyTxEndTrace))
+    .AddTraceSource ("PhyTxDrop", 
+                     "Trace source indicating a packet has been dropped by the device during transmission",
+                     MakeTraceSourceAccessor (&WifiPhy::m_phyTxDropTrace))
+    .AddTraceSource ("PhyRxBegin", 
+                     "Trace source indicating a packet has begun being received from the channel medium by the device",
+                     MakeTraceSourceAccessor (&WifiPhy::m_phyRxBeginTrace))
+    .AddTraceSource ("PhyRxEnd", 
+                     "Trace source indicating a packet has been completely received from the channel medium by the device",
+                     MakeTraceSourceAccessor (&WifiPhy::m_phyRxEndTrace))
+    .AddTraceSource ("PhyRxDrop", 
+                     "Trace source indicating a packet has been dropped by the device during reception",
+                     MakeTraceSourceAccessor (&WifiPhy::m_phyRxDropTrace))
+    .AddTraceSource ("PromiscSniffer", 
+                     "Trace source simulating a promiscuous packet sniffer attached to the device",
+                     MakeTraceSourceAccessor (&WifiPhy::m_phyPromiscSnifferTrace))
     ;
   return tid;
 }
@@ -136,6 +157,48 @@
   return mode;
 }
 
+void 
+WifiPhy::NotifyTxBegin (Ptr<const Packet> packet)
+{
+  m_phyTxBeginTrace (packet);
+}
+
+void 
+WifiPhy::NotifyTxEnd (Ptr<const Packet> packet)
+{
+  m_phyTxEndTrace (packet);
+}
+
+void 
+WifiPhy::NotifyTxDrop (Ptr<const Packet> packet) 
+{
+  m_phyTxDropTrace (packet);
+}
+
+void 
+WifiPhy::NotifyRxBegin (Ptr<const Packet> packet) 
+{
+  m_phyRxBeginTrace (packet);
+}
+
+void 
+WifiPhy::NotifyRxEnd (Ptr<const Packet> packet) 
+{
+  m_phyRxEndTrace (packet);
+}
+
+void 
+WifiPhy::NotifyRxDrop (Ptr<const Packet> packet) 
+{
+  m_phyRxDropTrace (packet);
+}
+
+void 
+WifiPhy::NotifyPromiscSniff (Ptr<const Packet> packet) 
+{
+  m_phyPromiscSnifferTrace (packet);
+}
+
 } // namespace ns3
 
 namespace {
--- a/src/devices/wifi/wifi-phy.h	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/devices/wifi/wifi-phy.h	Mon Mar 23 19:23:11 2009 -0700
@@ -30,6 +30,7 @@
 #include "wifi-mode.h"
 #include "wifi-preamble.h"
 #include "wifi-phy-standard.h"
+#include "ns3/traced-callback.h"
 
 
 namespace ns3 {
@@ -79,6 +80,7 @@
    * unless they have received a cca busy report.
    */
   virtual void NotifyTxStart (Time duration) = 0;
+
   /**
    * \param duration the expected busy duration.
    *
@@ -250,6 +252,116 @@
   static WifiMode Get36mba (void);
   static WifiMode Get48mba (void);
   static WifiMode Get54mba (void);
+
+  /**
+   * Public method used to fire a PhyTxBegin trace.  Implemented for encapsulation 
+   * purposes.
+   */
+  void NotifyTxBegin (Ptr<const Packet> packet);
+
+  /**
+   * Public method used to fire a PhyTxEnd trace.  Implemented for encapsulation 
+   * purposes.
+   */
+  void NotifyTxEnd (Ptr<const Packet> packet);
+
+  /**
+   * Public method used to fire a PhyTxDrop trace.  Implemented for encapsulation 
+   * purposes.
+   */
+  void NotifyTxDrop (Ptr<const Packet> packet);
+
+  /**
+   * Public method used to fire a PhyRxBegin trace.  Implemented for encapsulation 
+   * purposes.
+   */
+  void NotifyRxBegin (Ptr<const Packet> packet);
+
+  /**
+   * Public method used to fire a PhyRxEnd trace.  Implemented for encapsulation 
+   * purposes.
+   */
+  void NotifyRxEnd (Ptr<const Packet> packet);
+
+  /**
+   * Public method used to fire a PhyRxDrop trace.  Implemented for encapsulation 
+   * purposes.
+   */
+  void NotifyRxDrop (Ptr<const Packet> packet);
+
+  /**
+   * Public method used to fire a PromiscSniffer trace.  Implemented for encapsulation 
+   * purposes.
+   */
+  void NotifyPromiscSniff (Ptr<const Packet> packet);
+
+private:
+  /**
+   * The trace source fired when a packet begins the transmission process on
+   * the medium.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_phyTxBeginTrace;
+
+  /**
+   * The trace source fired when a packet ends the transmission process on
+   * the medium.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_phyTxEndTrace;
+
+  /**
+   * The trace source fired when the phy layer drops a packet as it tries
+   * to transmit it.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_phyTxDropTrace;
+
+  /**
+   * The trace source fired when a packet begins the reception process from
+   * the medium.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_phyRxBeginTrace;
+
+  /**
+   * The trace source fired when a packet ends the reception process from
+   * the medium.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_phyRxEndTrace;
+
+  /**
+   * The trace source fired when the phy layer drops a packet it has received.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_phyRxDropTrace;
+
+  /**
+   * A trace source that emulates a promiscuous mode protocol sniffer connected
+   * to the device.  This trace source fire on packets destined for any host
+   * just like your average everyday packet sniffer.
+   *
+   * On the transmit size, this trace hook will fire after a packet is dequeued
+   * from the device queue for transmission.  In Linux, for example, this would
+   * correspond to the point just before a device hard_start_xmit where 
+   * dev_queue_xmit_nit is called to dispatch the packet to the PF_PACKET 
+   * ETH_P_ALL handlers.
+   *
+   * On the receive side, this trace hook will fire when a packet is received,
+   * just before the receive callback is executed.  In Linux, for example, 
+   * this would correspond to the point at which the packet is dispatched to 
+   * packet sniffers in netif_receive_skb.
+   *
+   * \see class CallBackTraceSource
+   */
+  TracedCallback<Ptr<const Packet> > m_phyPromiscSnifferTrace;
 };
 
 } // namespace ns3
--- a/src/devices/wifi/yans-wifi-phy.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/devices/wifi/yans-wifi-phy.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -34,6 +34,7 @@
 #include "ns3/enum.h"
 #include "ns3/pointer.h"
 #include "ns3/net-device.h"
+#include "ns3/trace-source-accessor.h"
 #include <math.h>
 
 NS_LOG_COMPONENT_DEFINE ("YansWifiPhy");
@@ -322,6 +323,7 @@
   case YansWifiPhy::SYNC:
     NS_LOG_DEBUG ("drop packet because already in Sync (power="<<
                   rxPowerW<<"W)");
+    NotifyRxDrop (packet);
     if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ()) 
       {
         // that packet will be noise _after_ the reception of the
@@ -332,6 +334,7 @@
   case YansWifiPhy::TX:
     NS_LOG_DEBUG ("drop packet because already in Tx (power="<<
                   rxPowerW<<"W)");
+    NotifyRxDrop (packet);
     if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ()) 
       {
         // that packet will be noise _after_ the transmission of the
@@ -347,6 +350,7 @@
         // sync to signal
         m_state->SwitchToSync (rxDuration);
         NS_ASSERT (m_endSyncEvent.IsExpired ());
+        NotifyRxBegin (packet);
         m_endSyncEvent = Simulator::Schedule (rxDuration, &YansWifiPhy::EndSync, this, 
                                               packet,
                                               event);
@@ -355,6 +359,7 @@
       {
         NS_LOG_DEBUG ("drop packet because signal power too Small ("<<
                       rxPowerW<<"<"<<m_edThresholdW<<")");
+        NotifyRxDrop (packet);
         goto maybeCcaBusy;
       }
     break;
@@ -374,6 +379,7 @@
       m_state->SwitchMaybeToCcaBusy (delayUntilCcaEnd);
     }
 }
+
 void 
 YansWifiPhy::SendPacket (Ptr<const Packet> packet, WifiMode txMode, WifiPreamble preamble, uint8_t txPower)
 {
@@ -391,6 +397,8 @@
     {
       m_endSyncEvent.Cancel ();
     }
+  NotifyTxBegin (packet);
+  NotifyPromiscSniff (packet);
   m_state->SwitchToTx (txDuration, packet, txMode, preamble, txPower);
   m_channel->Send (this, packet, GetPowerDbm (txPower) + m_txGainDb, txMode, preamble);
 }
@@ -550,16 +558,16 @@
   
   if (m_random.GetValue () > snrPer.per) 
     {
+      NotifyRxEnd (packet);
+      NotifyPromiscSniff (packet);
       m_state->SwitchFromSyncEndOk (packet, snrPer.snr, event->GetPayloadMode (), event->GetPreambleType ());
     } 
   else 
     {
       /* failure. */
+      NotifyRxDrop (packet);
       m_state->SwitchFromSyncEndError (packet, snrPer.snr);
     }
 }
 
-
-
-
 } // namespace ns3
--- a/src/devices/wifi/yans-wifi-phy.h	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/devices/wifi/yans-wifi-phy.h	Mon Mar 23 19:23:11 2009 -0700
@@ -151,6 +151,7 @@
   WifiPhyStandard m_standard;
   Ptr<WifiPhyStateHelper> m_state;
   InterferenceHelper m_interference;
+
 };
 
 } // namespace ns3
--- a/src/helper/csma-helper.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/helper/csma-helper.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -69,6 +69,7 @@
 {
   SetDeviceAttribute (n1, v1);
 }
+
 void 
 CsmaHelper::SetChannelParameter (std::string n1, const AttributeValue &v1)
 {
@@ -76,7 +77,7 @@
 }
 
 void 
-CsmaHelper::EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid)
+CsmaHelper::EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid, bool promiscuous)
 {
   std::ostringstream oss;
   oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::CsmaNetDevice/";
@@ -91,23 +92,43 @@
   pcap->Open (oss.str ());
   pcap->WriteEthernetHeader ();
   oss.str ("");
-  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::CsmaNetDevice/Rx";
-  Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&CsmaHelper::RxEvent, pcap));
-  oss.str ("");
-  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::CsmaNetDevice/TxQueue/Enqueue";
-  Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&CsmaHelper::EnqueueEvent, pcap));
+  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid;
+  if (promiscuous)
+    {
+      oss << "/$ns3::CsmaNetDevice/PromiscSniffer";
+    }
+  else
+    {
+      oss << "/$ns3::CsmaNetDevice/Sniffer";
+    }
+  Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&CsmaHelper::SniffEvent, pcap));
 }
+
 void 
-CsmaHelper::EnablePcap (std::string filename, NetDeviceContainer d)
+CsmaHelper::EnablePcap (std::string filename, NetDeviceContainer d, bool promiscuous)
 {
   for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i)
     {
       Ptr<NetDevice> dev = *i;
-      EnablePcap (filename, dev->GetNode ()->GetId (), dev->GetIfIndex ());
+      EnablePcap (filename, dev->GetNode ()->GetId (), dev->GetIfIndex (), promiscuous);
     }
 }
+
+void 
+CsmaHelper::EnablePcap (std::string filename, Ptr<NetDevice> nd, bool promiscuous)
+{
+  EnablePcap (filename, nd->GetNode ()->GetId (), nd->GetIfIndex (), promiscuous);
+}
+
+void 
+CsmaHelper::EnablePcap (std::string filename, std::string ndName, bool promiscuous)
+{
+  Ptr<NetDevice> nd = Names::Find<NetDevice> (ndName);
+  EnablePcap (filename, nd->GetNode ()->GetId (), nd->GetIfIndex (), promiscuous);
+}
+
 void
-CsmaHelper::EnablePcap (std::string filename, NodeContainer n)
+CsmaHelper::EnablePcap (std::string filename, NodeContainer n, bool promiscuous)
 {
   NetDeviceContainer devs;
   for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
@@ -118,13 +139,13 @@
           devs.Add (node->GetDevice (j));
         }
     }
-  EnablePcap (filename, devs);
+  EnablePcap (filename, devs, promiscuous);
 }
 
 void
-CsmaHelper::EnablePcapAll (std::string filename)
+CsmaHelper::EnablePcapAll (std::string filename, bool promiscuous)
 {
-  EnablePcap (filename, NodeContainer::GetGlobal ());
+  EnablePcap (filename, NodeContainer::GetGlobal (), promiscuous);
 }
 
 void 
@@ -132,7 +153,7 @@
 {
   Packet::EnablePrinting ();
   std::ostringstream oss;
-  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::CsmaNetDevice/Rx";
+  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::CsmaNetDevice/MacRx";
   Config::Connect (oss.str (), MakeBoundCallback (&CsmaHelper::AsciiRxEvent, &os));
   oss.str ("");
   oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::CsmaNetDevice/TxQueue/Enqueue";
@@ -279,15 +300,11 @@
 }
 
 void 
-CsmaHelper::EnqueueEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet)
+CsmaHelper::SniffEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet)
 {
   writer->WritePacket (packet);
 }
-void 
-CsmaHelper::RxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet)
-{
-  writer->WritePacket (packet);
-}
+
 void 
 CsmaHelper::AsciiEnqueueEvent (std::ostream *os, std::string path, Ptr<const Packet> packet)
 {
--- a/src/helper/csma-helper.h	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/helper/csma-helper.h	Mon Mar 23 19:23:11 2009 -0700
@@ -87,6 +87,7 @@
    * \param filename filename prefix to use for pcap files.
    * \param nodeid the id of the node to generate pcap output for.
    * \param deviceid the id of the device to generate pcap output for.
+   * \param promiscuous If true capture all possible packets available at the device.
    *
    * Generate a pcap file which contains the link-level data observed
    * by the specified deviceid within the specified nodeid. The pcap
@@ -95,31 +96,53 @@
    * This method should be invoked after the network topology has 
    * been fully constructed.
    */
-  static void EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid);
+  static void EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid, bool promiscuous);
+
+  /**
+   * \param filename filename prefix to use for pcap files.
+   * \param nd Net device in which you want to enable tracing.
+   * \param promiscuous If true capture all possible packets available at the device.
+   *
+   * Enable pcap output the indicated net device.
+   */
+  static void EnablePcap (std::string filename, Ptr<NetDevice> nd, bool promiscuous);
+
+  /**
+   * \param filename filename prefix to use for pcap files.
+   * \param ndName The name of the net device in which you want to enable tracing.
+   * \param promiscuous If true capture all possible packets available at the device.
+   *
+   * Enable pcap output the indicated net device.
+   */
+  static void EnablePcap (std::string filename, std::string ndName, bool promiscuous);
+
   /**
    * \param filename filename prefix to use for pcap files.
    * \param d container of devices of type ns3::CsmaNetDevice
+   * \param promiscuous If true capture all possible packets available at the device.
    *
-   * Enable pcap output on each input device which is of the
-   * ns3::CsmaNetDevice type.
+   * Enable pcap output on each input device which is of the ns3::CsmaNetDevice type.
    */
-  static void EnablePcap (std::string filename, NetDeviceContainer d);
+  static void EnablePcap (std::string filename, NetDeviceContainer d, bool promiscuous);
+
   /**
    * \param filename filename prefix to use for pcap files.
    * \param n container of nodes.
+   * \param promiscuous If true capture all possible packets available at the device.
    *
    * Enable pcap output on each device which is of the
    * ns3::CsmaNetDevice type and which is located in one of the 
    * input nodes.
    */
-  static void EnablePcap (std::string filename, NodeContainer n);
+  static void EnablePcap (std::string filename, NodeContainer n, bool promiscuous);
   /**
    * \param filename filename prefix to use for pcap files.
+   * \param promiscuous If true capture all possible packets available at the device.
    *
    * Enable pcap output on each device which is of the
    * ns3::CsmaNetDevice type
    */
-  static void EnablePcapAll (std::string filename);
+  static void EnablePcapAll (std::string filename, bool promiscuous);
 
   /**
    * \param os output stream
@@ -331,12 +354,13 @@
 private:
   Ptr<NetDevice> InstallPriv (Ptr<Node> node, Ptr<CsmaChannel> channel) const;
 
-  static void RxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet);
-  static void EnqueueEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet);
+  static void SniffEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet);
+
+  static void AsciiRxEvent (std::ostream *os, std::string path, Ptr<const Packet> packet);
   static void AsciiEnqueueEvent (std::ostream *os, std::string path, Ptr<const Packet> packet);
   static void AsciiDequeueEvent (std::ostream *os, std::string path, Ptr<const Packet> packet);
   static void AsciiDropEvent (std::ostream *os, std::string path, Ptr<const Packet> packet);
-  static void AsciiRxEvent (std::ostream *os, std::string path, Ptr<const Packet> packet);
+
   ObjectFactory m_queueFactory;
   ObjectFactory m_deviceFactory;
   ObjectFactory m_channelFactory;
--- a/src/helper/emu-helper.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/helper/emu-helper.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -41,7 +41,7 @@
   m_deviceFactory.SetTypeId ("ns3::EmuNetDevice");
 }
 
-  void 
+void 
 EmuHelper::SetQueue (
   std::string type,
   std::string n1, const AttributeValue &v1,
@@ -57,20 +57,17 @@
   m_queueFactory.Set (n4, v4);
 }
 
-  void 
+void 
 EmuHelper::SetAttribute (std::string n1, const AttributeValue &v1)
 {
   NS_LOG_FUNCTION_NOARGS ();
   m_deviceFactory.Set (n1, v1);
 }
 
-  void 
-EmuHelper::EnablePcap (
-  std::string filename, 
-  uint32_t nodeid, 
-  uint32_t deviceid)
+void 
+EmuHelper::EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid, bool promiscuous)
 {
-  NS_LOG_FUNCTION (filename << nodeid << deviceid);
+  NS_LOG_FUNCTION (filename << nodeid << deviceid << promiscuous);
   std::ostringstream oss;
   oss << filename << "-" << nodeid << "-" << deviceid << ".pcap";
   Ptr<PcapWriter> pcap = Create<PcapWriter> ();
@@ -78,33 +75,48 @@
   pcap->WriteEthernetHeader ();
 
   oss.str ("");
-  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << 
-    "/$ns3::EmuNetDevice/Rx";
-  Config::ConnectWithoutContext (oss.str (), 
-    MakeBoundCallback (&EmuHelper::RxEvent, pcap));
-
-  oss.str ("");
-  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << 
-    "/$ns3::EmuNetDevice/TxQueue/Enqueue";
-  Config::ConnectWithoutContext (oss.str (), 
-    MakeBoundCallback (&EmuHelper::EnqueueEvent, pcap));
+  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid;
+  if (promiscuous)
+    {
+      oss << "/$ns3::EmuNetDevice/PromiscSniffer";
+    }
+  else
+    {
+      oss << "/$ns3::EmuNetDevice/Sniffer";
+    }
+  Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&EmuHelper::SniffEvent, pcap));
 }
 
-  void 
-EmuHelper::EnablePcap (std::string filename, NetDeviceContainer d)
+void 
+EmuHelper::EnablePcap (std::string filename, Ptr<NetDevice> nd, bool promiscuous)
+{
+  NS_LOG_FUNCTION (filename << &nd << promiscuous);
+  EnablePcap (filename, nd->GetNode ()->GetId (), nd->GetIfIndex (), promiscuous);
+}
+
+void 
+EmuHelper::EnablePcap (std::string filename, std::string ndName, bool promiscuous)
 {
-  NS_LOG_FUNCTION (filename << &d);
+  NS_LOG_FUNCTION (filename << ndName << promiscuous);
+  Ptr<NetDevice> nd = Names::Find<NetDevice> (ndName);
+  EnablePcap (filename, nd->GetNode ()->GetId (), nd->GetIfIndex (), promiscuous);
+}
+
+void 
+EmuHelper::EnablePcap (std::string filename, NetDeviceContainer d, bool promiscuous)
+{
+  NS_LOG_FUNCTION (filename << &d << promiscuous);
   for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i)
     {
       Ptr<NetDevice> dev = *i;
-      EnablePcap (filename, dev->GetNode ()->GetId (), dev->GetIfIndex ());
+      EnablePcap (filename, dev->GetNode ()->GetId (), dev->GetIfIndex (), promiscuous);
     }
 }
 
-  void
-EmuHelper::EnablePcap (std::string filename, NodeContainer n)
+void
+EmuHelper::EnablePcap (std::string filename, NodeContainer n, bool promiscuous)
 {
-  NS_LOG_FUNCTION (filename << &n);
+  NS_LOG_FUNCTION (filename << &n << promiscuous);
   NetDeviceContainer devs;
   for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
     {
@@ -114,48 +126,40 @@
 	  devs.Add (node->GetDevice (j));
 	}
     }
-  EnablePcap (filename, devs);
+  EnablePcap (filename, devs, promiscuous);
 }
 
-  void
-EmuHelper::EnablePcapAll (std::string filename)
+void
+EmuHelper::EnablePcapAll (std::string filename, bool promiscuous)
 {
-  NS_LOG_FUNCTION (filename);
-  EnablePcap (filename, NodeContainer::GetGlobal ());
+  NS_LOG_FUNCTION (filename << promiscuous);
+  EnablePcap (filename, NodeContainer::GetGlobal (), promiscuous);
 }
 
-  void 
+void 
 EmuHelper::EnableAscii (std::ostream &os, uint32_t nodeid, uint32_t deviceid)
 {
   NS_LOG_FUNCTION (&os << nodeid << deviceid);
   Packet::EnablePrinting ();
   std::ostringstream oss;
 
-  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << 
-    "/$ns3::EmuNetDevice/Rx";
-  Config::Connect (oss.str (), 
-    MakeBoundCallback (&EmuHelper::AsciiRxEvent, &os));
+  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::EmuNetDevice/MacRx";
+  Config::Connect (oss.str (), MakeBoundCallback (&EmuHelper::AsciiRxEvent, &os));
 
   oss.str ("");
-  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << 
-    "/$ns3::EmuNetDevice/TxQueue/Enqueue";
-  Config::Connect (oss.str (), 
-    MakeBoundCallback (&EmuHelper::AsciiEnqueueEvent, &os));
+  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::EmuNetDevice/TxQueue/Enqueue";
+  Config::Connect (oss.str (), MakeBoundCallback (&EmuHelper::AsciiEnqueueEvent, &os));
 
   oss.str ("");
-  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << 
-    "/$ns3::EmuNetDevice/TxQueue/Dequeue";
-  Config::Connect (oss.str (), 
-    MakeBoundCallback (&EmuHelper::AsciiDequeueEvent, &os));
+  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::EmuNetDevice/TxQueue/Dequeue";
+  Config::Connect (oss.str (), MakeBoundCallback (&EmuHelper::AsciiDequeueEvent, &os));
 
   oss.str ("");
-  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << 
-    "/$ns3::EmuNetDevice/TxQueue/Drop";
-  Config::Connect (oss.str (), 
-    MakeBoundCallback (&EmuHelper::AsciiDropEvent, &os));
+  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::EmuNetDevice/TxQueue/Drop";
+  Config::Connect (oss.str (), MakeBoundCallback (&EmuHelper::AsciiDropEvent, &os));
 }
 
-  void 
+void 
 EmuHelper::EnableAscii (std::ostream &os, NetDeviceContainer d)
 {
   NS_LOG_FUNCTION (&os << &d);
@@ -182,7 +186,7 @@
   EnableAscii (os, devs);
 }
 
-  void
+void
 EmuHelper::EnableAsciiAll (std::ostream &os)
 {
   NS_LOG_FUNCTION (&os);
@@ -215,7 +219,7 @@
   return devs;
 }
 
-  Ptr<NetDevice>
+Ptr<NetDevice>
 EmuHelper::InstallPriv (Ptr<Node> node) const
 {
   Ptr<EmuNetDevice> device = m_deviceFactory.Create<EmuNetDevice> ();
@@ -227,21 +231,14 @@
   return device;
 }
 
-  void 
-EmuHelper::EnqueueEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet)
+void 
+EmuHelper::SniffEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet)
 {
   NS_LOG_FUNCTION (writer << packet);
   writer->WritePacket (packet);
 }
 
-  void 
-EmuHelper::RxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet)
-{
-  NS_LOG_FUNCTION (writer << packet);
-  writer->WritePacket (packet);
-}
-
-  void 
+void 
 EmuHelper::AsciiEnqueueEvent (
   std::ostream *os, 
   std::string path, 
@@ -252,7 +249,7 @@
   *os << path << " " << *packet << std::endl;
 }
 
-  void 
+void 
 EmuHelper::AsciiDequeueEvent (
   std::ostream *os, 
   std::string path, 
@@ -263,7 +260,7 @@
   *os << path << " " << *packet << std::endl;
 }
 
-  void 
+void 
 EmuHelper::AsciiDropEvent (
   std::ostream *os, 
   std::string path, 
@@ -274,7 +271,7 @@
   *os << path << " " << *packet << std::endl;
 }
 
-  void 
+void 
 EmuHelper::AsciiRxEvent (
   std::ostream *os, 
   std::string path, 
--- a/src/helper/emu-helper.h	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/helper/emu-helper.h	Mon Mar 23 19:23:11 2009 -0700
@@ -73,6 +73,7 @@
    * \param filename filename prefix to use for pcap files.
    * \param nodeid the id of the node to generate pcap output for.
    * \param deviceid the id of the device to generate pcap output for.
+   * \param promiscuous If true capture all possible packets available at the device.
    *
    * Generate a pcap file which contains the link-level data observed
    * by the specified deviceid within the specified nodeid. The pcap
@@ -81,35 +82,57 @@
    * This method should be invoked after the network topology has 
    * been fully constructed.
    */
-  static void EnablePcap (std::string filename, uint32_t nodeid, 
-    uint32_t deviceid);
+  static void EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid, bool promiscuous);
+
+  /**
+   * \param filename filename prefix to use for pcap files.
+   * \param nd Indicates net device on which you want to enable tracing.
+   * \param promiscuous If true capture all possible packets available at the device.
+   *
+   * Enable pcap output on each input device which is of the
+   * ns3::EmuNetDevice type.
+   */
+  static void EnablePcap (std::string filename, Ptr<NetDevice> nd, bool promiscuous);
+
+  /**
+   * \param filename filename prefix to use for pcap files.
+   * \param ndName Name of net device on which you want to enable tracing.
+   * \param promiscuous If true capture all possible packets available at the device.
+   *
+   * Enable pcap output on each input device which is of the
+   * ns3::EmuNetDevice type.
+   */
+  static void EnablePcap (std::string filename, std::string ndName, bool promiscuous);
 
   /**
    * \param filename filename prefix to use for pcap files.
    * \param d container of devices of type ns3::EmuNetDevice
+   * \param promiscuous If true capture all possible packets available at the device.
    *
    * Enable pcap output on each input device which is of the
    * ns3::EmuNetDevice type.
    */
-  static void EnablePcap (std::string filename, NetDeviceContainer d);
+  static void EnablePcap (std::string filename, NetDeviceContainer d, bool promiscuous);
 
   /**
    * \param filename filename prefix to use for pcap files.
    * \param n container of nodes.
+   * \param promiscuous If true capture all possible packets available at the device.
    *
    * Enable pcap output on each device which is of the
    * ns3::EmuNetDevice type and which is located in one of the 
    * input nodes.
    */
-  static void EnablePcap (std::string filename, NodeContainer n);
+  static void EnablePcap (std::string filename, NodeContainer n, bool promiscuous);
 
   /**
    * \param filename filename prefix to use for pcap files.
+   * \param promiscuous If true capture all possible packets available at the device.
    *
    * Enable pcap output on each device which is of the
    * ns3::EmuNetDevice type
    */
-  static void EnablePcapAll (std::string filename);
+  static void EnablePcapAll (std::string filename, bool promiscuous);
 
   /**
    * \param os output stream
@@ -120,8 +143,7 @@
    * specified nodeid if it is of type ns3::EmuNetDevice and dump 
    * that to the specified stdc++ output stream.
    */
-  static void EnableAscii (std::ostream &os, uint32_t nodeid, 
-    uint32_t deviceid);
+  static void EnableAscii (std::ostream &os, uint32_t nodeid, uint32_t deviceid);
 
   /**
    * \param os output stream
@@ -184,16 +206,12 @@
 
 private:
   Ptr<NetDevice> InstallPriv (Ptr<Node> node) const;
-  static void RxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet);
-  static void EnqueueEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet);
-  static void AsciiEnqueueEvent (std::ostream *os, std::string path, 
-    Ptr<const Packet> packet);
-  static void AsciiDequeueEvent (std::ostream *os, std::string path, 
-    Ptr<const Packet> packet);
-  static void AsciiDropEvent (std::ostream *os, std::string path, 
-    Ptr<const Packet> packet);
-  static void AsciiRxEvent (std::ostream *os, std::string path, 
-    Ptr<const Packet> packet);
+  static void SniffEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet);
+
+  static void AsciiRxEvent (std::ostream *os, std::string path, Ptr<const Packet> packet);
+  static void AsciiEnqueueEvent (std::ostream *os, std::string path, Ptr<const Packet> packet);
+  static void AsciiDequeueEvent (std::ostream *os, std::string path, Ptr<const Packet> packet);
+  static void AsciiDropEvent (std::ostream *os, std::string path, Ptr<const Packet> packet);
 
   ObjectFactory m_queueFactory;
   ObjectFactory m_deviceFactory;
--- a/src/helper/point-to-point-helper.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/helper/point-to-point-helper.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -90,12 +90,24 @@
   pcap->Open (oss.str ());
   pcap->WritePppHeader ();
   oss.str ("");
-  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointToPointNetDevice/Rx";
-  Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&PointToPointHelper::RxEvent, pcap));
-  oss.str ("");
-  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointToPointNetDevice/TxQueue/Enqueue";
-  Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&PointToPointHelper::EnqueueEvent, pcap));
+  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid;
+  oss << "/$ns3::PointToPointNetDevice/PromiscSniffer";
+  Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&PointToPointHelper::SniffEvent, pcap));
 }
+
+void 
+PointToPointHelper::EnablePcap (std::string filename, Ptr<NetDevice> nd)
+{
+  EnablePcap (filename, nd->GetNode ()->GetId (), nd->GetIfIndex ());
+}
+
+void 
+PointToPointHelper::EnablePcap (std::string filename, std::string ndName)
+{
+  Ptr<NetDevice> nd = Names::Find<NetDevice> (ndName);
+  EnablePcap (filename, nd->GetNode ()->GetId (), nd->GetIfIndex ());
+}
+
 void 
 PointToPointHelper::EnablePcap (std::string filename, NetDeviceContainer d)
 {
@@ -105,6 +117,7 @@
       EnablePcap (filename, dev->GetNode ()->GetId (), dev->GetIfIndex ());
     }
 }
+
 void
 PointToPointHelper::EnablePcap (std::string filename, NodeContainer n)
 {
@@ -131,7 +144,7 @@
 {
   Packet::EnablePrinting ();
   std::ostringstream oss;
-  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointToPointNetDevice/Rx";
+  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointToPointNetDevice/MacRx";
   Config::Connect (oss.str (), MakeBoundCallback (&PointToPointHelper::AsciiRxEvent, &os));
   oss.str ("");
   oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointToPointNetDevice/TxQueue/Enqueue";
@@ -143,6 +156,7 @@
   oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointToPointNetDevice/TxQueue/Drop";
   Config::Connect (oss.str (), MakeBoundCallback (&PointToPointHelper::AsciiDropEvent, &os));
 }
+
 void 
 PointToPointHelper::EnableAscii (std::ostream &os, NetDeviceContainer d)
 {
@@ -152,6 +166,7 @@
       EnableAscii (os, dev->GetNode ()->GetId (), dev->GetIfIndex ());
     }
 }
+
 void
 PointToPointHelper::EnableAscii (std::ostream &os, NodeContainer n)
 {
@@ -247,33 +262,32 @@
 }
 
 void 
-PointToPointHelper::EnqueueEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet)
+PointToPointHelper::SniffEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet)
 {
   writer->WritePacket (packet);
 }
-void 
-PointToPointHelper::RxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet)
-{
-  writer->WritePacket (packet);
-}
+
 void 
 PointToPointHelper::AsciiEnqueueEvent (std::ostream *os, std::string path, Ptr<const Packet> packet)
 {
   *os << "+ " << Simulator::Now ().GetSeconds () << " ";
   *os << path << " " << *packet << std::endl;
 }
+
 void 
 PointToPointHelper::AsciiDequeueEvent (std::ostream *os, std::string path, Ptr<const Packet> packet)
 {
   *os << "- " << Simulator::Now ().GetSeconds () << " ";
   *os << path << " " << *packet << std::endl;
 }
+
 void 
 PointToPointHelper::AsciiDropEvent (std::ostream *os, std::string path, Ptr<const Packet> packet)
 {
   *os << "d " << Simulator::Now ().GetSeconds () << " ";
   *os << path << " " << *packet << std::endl;
 }
+
 void 
 PointToPointHelper::AsciiRxEvent (std::ostream *os, std::string path, Ptr<const Packet> packet)
 {
@@ -281,5 +295,4 @@
   *os << path << " " << *packet << std::endl;
 }
 
-
 } // namespace ns3
--- a/src/helper/point-to-point-helper.h	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/helper/point-to-point-helper.h	Mon Mar 23 19:23:11 2009 -0700
@@ -95,6 +95,25 @@
    * been fully constructed.
    */
   static void EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid);
+
+  /**
+   * \param filename filename prefix to use for pcap files.
+   * \param nd Net device on which you want to enable tracing.
+   *
+   * Enable pcap output on each input device which is of the
+   * ns3::PointToPointNetDevice type.
+   */
+  static void EnablePcap (std::string filename, Ptr<NetDevice> nd);
+
+  /**
+   * \param filename filename prefix to use for pcap files.
+   * \param ndName Name of net device on which you want to enable tracing.
+   *
+   * Enable pcap output on each input device which is of the
+   * ns3::PointToPointNetDevice type.
+   */
+  static void EnablePcap (std::string filename, std::string ndName);
+
   /**
    * \param filename filename prefix to use for pcap files.
    * \param d container of devices of type ns3::PointToPointNetDevice
@@ -103,6 +122,8 @@
    * ns3::PointToPointNetDevice type.
    */
   static void EnablePcap (std::string filename, NetDeviceContainer d);
+
+
   /**
    * \param filename filename prefix to use for pcap files.
    * \param n container of nodes.
@@ -112,6 +133,7 @@
    * input nodes.
    */
   static void EnablePcap (std::string filename, NodeContainer n);
+
   /**
    * \param filename filename prefix to use for pcap files.
    *
@@ -130,6 +152,7 @@
    * that to the specified stdc++ output stream.
    */
   static void EnableAscii (std::ostream &os, uint32_t nodeid, uint32_t deviceid);
+
   /**
    * \param os output stream
    * \param d device container
@@ -140,6 +163,7 @@
    * stdc++ output stream.
    */
   static void EnableAscii (std::ostream &os, NetDeviceContainer d);
+
   /**
    * \param os output stream
    * \param n node container
@@ -150,6 +174,7 @@
    * stdc++ output stream.
    */
   static void EnableAscii (std::ostream &os, NodeContainer n);
+
   /**
    * \param os output stream
    *
@@ -261,13 +286,14 @@
 
 private:
   void EnablePcap (Ptr<Node> node, Ptr<NetDevice> device, Ptr<Queue> queue);
+  static void SniffEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet);
+
   void EnableAscii (Ptr<Node> node, Ptr<NetDevice> device);
-  static void RxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet);
-  static void EnqueueEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet);
+  static void AsciiRxEvent (std::ostream *os, std::string path, Ptr<const Packet> packet);
   static void AsciiEnqueueEvent (std::ostream *os, std::string path, Ptr<const Packet> packet);
   static void AsciiDequeueEvent (std::ostream *os, std::string path, Ptr<const Packet> packet);
   static void AsciiDropEvent (std::ostream *os, std::string path, Ptr<const Packet> packet);
-  static void AsciiRxEvent (std::ostream *os, std::string path, Ptr<const Packet> packet);
+
   ObjectFactory m_queueFactory;
   ObjectFactory m_channelFactory;
   ObjectFactory m_deviceFactory;
--- a/src/helper/yans-wifi-helper.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/helper/yans-wifi-helper.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -31,16 +31,7 @@
 
 namespace ns3 {
 
-static void PcapPhyTxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet,
-                            WifiMode mode, WifiPreamble preamble, 
-                            uint8_t txLevel)
-{
-  writer->WritePacket (packet);
-}
-
-static void PcapPhyRxEvent (Ptr<PcapWriter> writer, 
-                            Ptr<const Packet> packet, double snr, WifiMode mode, 
-                            enum WifiPreamble preamble)
+static void PcapSnifferEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet)
 {
   writer->WritePacket (packet);
 }
@@ -229,12 +220,11 @@
   pcap->Open (oss.str ());
   pcap->WriteWifiHeader ();
   oss.str ("");
-  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/State/Tx";
-  Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&PcapPhyTxEvent, pcap));
-  oss.str ("");
-  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/State/RxOk";
-  Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&PcapPhyRxEvent, pcap));
+  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid;
+  oss << "/$ns3::WifiNetDevice/Phy/PromiscSniffer";
+  Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&PcapSnifferEvent, pcap));
 }
+
 void 
 YansWifiPhyHelper::EnablePcap (std::string filename, NetDeviceContainer d)
 {
@@ -244,6 +234,20 @@
       EnablePcap (filename, dev->GetNode ()->GetId (), dev->GetIfIndex ());
     }
 }
+
+void 
+YansWifiPhyHelper::EnablePcap (std::string filename, Ptr<NetDevice> nd)
+{
+  EnablePcap (filename, nd->GetNode ()->GetId (), nd->GetIfIndex ());
+}
+
+void 
+YansWifiPhyHelper::EnablePcap (std::string filename, std::string ndName)
+{
+  Ptr<NetDevice> nd = Names::Find<NetDevice> (ndName);
+  EnablePcap (filename, nd->GetNode ()->GetId (), nd->GetIfIndex ());
+}
+
 void
 YansWifiPhyHelper::EnablePcap (std::string filename, NodeContainer n)
 {
@@ -306,6 +310,4 @@
   EnableAscii (os, NodeContainer::GetGlobal ());
 }
 
-
-
 } // namespace ns3
--- a/src/helper/yans-wifi-helper.h	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/helper/yans-wifi-helper.h	Mon Mar 23 19:23:11 2009 -0700
@@ -131,8 +131,7 @@
  * http://cutebugs.net/files/wns2-yans.pdf
  *
  * The Pcap and ascii traces generated by the EnableAscii and EnablePcap methods defined
- * in this class correspond to PHY-level traces. That is, they capture traffic
- * at the top of the PHY layer, just below the MAC layer.
+ * in this class correspond to PHY-level traces. 
  */
 class YansWifiPhyHelper : public WifiPhyHelper
 {
@@ -211,6 +210,25 @@
    * been fully constructed.
    */
   static void EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid);
+
+  /**
+   * \param filename filename prefix to use for pcap files.
+   * \param nd Net device on which you want to enable tracing.
+   *
+   * Enable pcap output on each input device which is of the
+   * ns3::WifiNetDevice type.
+   */
+  static void EnablePcap (std::string filename, Ptr<NetDevice> nd);
+
+  /**
+   * \param filename filename prefix to use for pcap files.
+   * \param ndName Name of net device on which you want to enable tracing.
+   *
+   * Enable pcap output on each input device which is of the
+   * ns3::WifiNetDevice type.
+   */
+  static void EnablePcap (std::string filename, std::string ndName);
+
   /**
    * \param filename filename prefix to use for pcap files.
    * \param d container of devices of type ns3::WifiNetDevice
@@ -219,6 +237,7 @@
    * ns3::WifiNetDevice type.
    */
   static void EnablePcap (std::string filename, NetDeviceContainer d);
+
   /**
    * \param filename filename prefix to use for pcap files.
    * \param n container of nodes.
@@ -228,6 +247,7 @@
    * input nodes.
    */
   static void EnablePcap (std::string filename, NodeContainer n);
+
   /**
    * \param filename filename prefix to use for pcap files.
    *
@@ -246,6 +266,7 @@
    * that to the specified stdc++ output stream.
    */
   static void EnableAscii (std::ostream &os, uint32_t nodeid, uint32_t deviceid);
+
   /**
    * \param os output stream
    * \param d device container
@@ -256,6 +277,7 @@
    * stdc++ output stream.
    */
   static void EnableAscii (std::ostream &os, NetDeviceContainer d);
+
   /**
    * \param os output stream
    * \param n node container
@@ -266,6 +288,7 @@
    * stdc++ output stream.
    */
   static void EnableAscii (std::ostream &os, NodeContainer n);
+
   /**
    * \param os output stream
    *
--- a/src/internet-stack/internet-stack.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/internet-stack/internet-stack.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -54,6 +54,8 @@
   Ptr<UdpL4Protocol> udp = CreateObject<UdpL4Protocol> ();
   udp->SetNode (node);
   ipv4->Insert (udp);
+  node->AggregateObject (udp);
+
   Ptr<UdpSocketFactoryImpl> udpFactory = CreateObject<UdpSocketFactoryImpl> ();
   udpFactory->SetUdp (udp);
   node->AggregateObject (udpFactory);
@@ -66,6 +68,8 @@
   Ptr<Icmpv4L4Protocol> icmp = CreateObject<Icmpv4L4Protocol> ();
   icmp->SetNode (node);
   ipv4->Insert (icmp);
+  node->AggregateObject (icmp);
+
   Ptr<Ipv4RawSocketFactoryImpl> rawFactory = CreateObject<Ipv4RawSocketFactoryImpl> ();
   node->AggregateObject (rawFactory);
 }
@@ -76,8 +80,8 @@
   Ptr<Ipv4L3Protocol> ipv4 = node->GetObject<Ipv4L3Protocol> ();
   Ptr<TcpL4Protocol> tcp = CreateObject<TcpL4Protocol> ();
   tcp->SetNode (node);
-
   ipv4->Insert (tcp);
+  node->AggregateObject (tcp);
 
   Ptr<TcpSocketFactoryImpl> tcpFactory = CreateObject<TcpSocketFactoryImpl> ();
   tcpFactory->SetTcp (tcp);
@@ -114,6 +118,8 @@
   tcp->SetNscLibrary(soname);
   tcp->SetNode (node);
   ipv4->Insert (tcp);
+  node->AggregateObject (tcp);
+
   Ptr<NscTcpSocketFactoryImpl> tcpFactory = CreateObject<NscTcpSocketFactoryImpl> ();
   tcpFactory->SetTcp (tcp);
   node->AggregateObject (tcpFactory);
--- a/src/internet-stack/ipv4-l3-protocol.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/internet-stack/ipv4-l3-protocol.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -152,17 +152,16 @@
   NS_LOG_FUNCTION (this);
   for (L4List_t::iterator i = m_protocols.begin(); i != m_protocols.end(); ++i)
     {
-      (*i)->Dispose ();
       *i = 0;
     }
   m_protocols.clear ();
 
-  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); ++i)
+  for (Ipv4InterfaceList::iterator i = m_interfaces.begin (); i != m_interfaces.end (); ++i)
     {
-      Ptr<Ipv4Interface> interface = *i;
-      interface->Dispose ();
+      *i = 0;
     }
   m_interfaces.clear ();
+  m_routingProtocols.clear ();
   m_node = 0;
   m_staticRouting->Dispose ();
   m_staticRouting = 0;
--- a/src/internet-stack/nsc-tcp-l4-protocol.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/internet-stack/nsc-tcp-l4-protocol.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -24,12 +24,13 @@
 #include "ns3/packet.h"
 #include "ns3/node.h"
 
+#include "ns3/object-vector.h"
+
 #include "tcp-header.h"
 #include "ipv4-end-point-demux.h"
 #include "ipv4-end-point.h"
 #include "ipv4-l3-protocol.h"
 #include "nsc-tcp-l4-protocol.h"
-#include "nsc-tcp-socket-impl.h"
 #include "nsc-sysctl.h"
 
 #include "tcp-typedefs.h"
@@ -70,6 +71,10 @@
                    ObjectFactoryValue (GetDefaultRttEstimatorFactory ()),
                    MakeObjectFactoryAccessor (&NscTcpL4Protocol::m_rttFactory),
                    MakeObjectFactoryChecker ())
+    .AddAttribute ("SocketList", "The list of sockets associated to this protocol.",
+                   ObjectVectorValue (),
+                   MakeObjectVectorAccessor (&NscTcpL4Protocol::m_sockets),
+                   MakeObjectVectorChecker<NscTcpSocketImpl> ())
     ;
   return tid;
 }
@@ -154,6 +159,14 @@
 NscTcpL4Protocol::DoDispose (void)
 {
   NS_LOG_FUNCTION (this);
+
+  for (std::vector<Ptr<NscTcpSocketImpl> >::iterator i = m_sockets.begin (); i != m_sockets.end (); i++)
+    {
+      *i = 0;
+    }
+  m_sockets.clear ();
+
+
   if (m_endPoints != 0)
     {
       delete m_endPoints;
@@ -173,6 +186,7 @@
   socket->SetNode (m_node);
   socket->SetTcp (this);
   socket->SetRtt (rtt);
+  m_sockets.push_back (socket);
   return socket;
 }
 
--- a/src/internet-stack/nsc-tcp-l4-protocol.h	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/internet-stack/nsc-tcp-l4-protocol.h	Mon Mar 23 19:23:11 2009 -0700
@@ -31,6 +31,7 @@
 
 #include "ns3/timer.h"
 #include "sim_interface.h"
+#include "nsc-tcp-socket-impl.h"
 
 namespace ns3 {
 
@@ -116,6 +117,7 @@
   INetStack* m_nscStack;
   void *m_dlopenHandle;
   Timer m_softTimer;
+  std::vector<Ptr<NscTcpSocketImpl> > m_sockets;
 };
 
 }; // namespace ns3
--- a/src/internet-stack/nsc-tcp-socket-factory-impl.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/internet-stack/nsc-tcp-socket-factory-impl.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -13,8 +13,8 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
+#include "nsc-tcp-l4-protocol.h"
 #include "nsc-tcp-socket-factory-impl.h"
-#include "nsc-tcp-l4-protocol.h"
 #include "ns3/socket.h"
 #include "ns3/assert.h"
 
--- a/src/internet-stack/tcp-l4-protocol.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/internet-stack/tcp-l4-protocol.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -22,6 +22,7 @@
 #include "ns3/log.h"
 #include "ns3/nstime.h"
 #include "ns3/boolean.h"
+#include "ns3/object-vector.h"
 
 #include "ns3/packet.h"
 #include "ns3/node.h"
@@ -31,7 +32,6 @@
 #include "ipv4-end-point-demux.h"
 #include "ipv4-end-point.h"
 #include "ipv4-l3-protocol.h"
-#include "tcp-socket-impl.h"
 
 #include "tcp-typedefs.h"
 
@@ -334,6 +334,10 @@
                    BooleanValue (false),
                    MakeBooleanAccessor (&TcpL4Protocol::m_calcChecksum),
                    MakeBooleanChecker ())
+    .AddAttribute ("SocketList", "The list of sockets associated to this protocol.",
+                   ObjectVectorValue (),
+                   MakeObjectVectorAccessor (&TcpL4Protocol::m_sockets),
+                   MakeObjectVectorChecker<TcpSocketImpl> ())
     ;
   return tid;
 }
@@ -366,11 +370,18 @@
 TcpL4Protocol::DoDispose (void)
 {
   NS_LOG_FUNCTION_NOARGS ();
+  for (std::vector<Ptr<TcpSocketImpl> >::iterator i = m_sockets.begin (); i != m_sockets.end (); i++)
+    {
+      *i = 0;
+    }
+  m_sockets.clear ();
+
   if (m_endPoints != 0)
     {
       delete m_endPoints;
       m_endPoints = 0;
     }
+
   m_node = 0;
   Ipv4L4Protocol::DoDispose ();
 }
@@ -384,6 +395,7 @@
   socket->SetNode (m_node);
   socket->SetTcp (this);
   socket->SetRtt (rtt);
+  m_sockets.push_back (socket);
   return socket;
 }
 
--- a/src/internet-stack/tcp-l4-protocol.h	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/internet-stack/tcp-l4-protocol.h	Mon Mar 23 19:23:11 2009 -0700
@@ -31,6 +31,7 @@
 #include "ipv4-l4-protocol.h"
 #include "ipv4-interface.h"
 
+#include "tcp-socket-impl.h"
 #include "tcp-header.h"
 #include "tcp-typedefs.h"
 
@@ -120,6 +121,7 @@
 
   bool m_goodChecksum;
   bool m_calcChecksum;
+  std::vector<Ptr<TcpSocketImpl> > m_sockets;
 };
 
 }; // namespace ns3
--- a/src/internet-stack/tcp-socket-impl.cc	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/internet-stack/tcp-socket-impl.cc	Mon Mar 23 19:23:11 2009 -0700
@@ -680,6 +680,11 @@
   Ptr<Packet> p = Create<Packet> ();
   TcpHeader header;
 
+  if (flags & TcpHeader::FIN)
+    {
+      flags |= TcpHeader::ACK;
+    }
+
   header.SetFlags (flags);
   header.SetSequenceNumber (m_nextTxSequence);
   header.SetAckNumber (m_nextRxSequence);
@@ -759,7 +764,7 @@
       break;
     case TX_DATA:
       NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action TX_DATA");
-      SendPendingData ();
+      SendPendingData (m_connected);
       break;
     case PEER_CLOSE:
       NS_ASSERT (false); // This should be processed in ProcessPacketAction
@@ -855,10 +860,21 @@
             NotifySend (GetTxAvailable ());
           }
       }
-      SendPendingData ();
+      SendPendingData (m_connected); //send acks if we are connected
       break;
     case NEW_ACK:
       NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action NEW_ACK_TX");
+      //check to see of the ACK had data with it; if so, pass it along
+      //to NEW_SEQ_RX
+      if(p->GetSize () > 0)
+        {
+          Simulator::ScheduleNow(&TcpSocketImpl::ProcessPacketAction,
+                                 this,
+                                 NEW_SEQ_RX,
+                                 p,
+                                 tcpHeader,
+                                 fromAddress);
+        }
       if (tcpHeader.GetAckNumber () < m_highestRxAck) //old ack, do nothing
       {
         break;
@@ -1001,10 +1017,6 @@
                    << " s " << s 
                    << " datasize " << p->GetSize() );
       uint8_t flags = 0;
-      if (withAck)
-        {
-          flags |= TcpHeader::ACK;
-        }
       uint32_t sz = p->GetSize (); // Size of packet
       uint32_t remainingData = m_pendingData->SizeFromSeq(
           m_firstPendingSequence,
@@ -1014,7 +1026,10 @@
           flags = TcpHeader::FIN;
           m_state = FIN_WAIT_1;
         }
-
+      if (withAck)
+        {
+          flags |= TcpHeader::ACK;
+        }
       TcpHeader header;
       header.SetFlags (flags);
       header.SetSequenceNumber (m_nextTxSequence);
@@ -1386,7 +1401,7 @@
         }
     }
   // Try to send more data
-  SendPendingData();
+  SendPendingData (m_connected);
 }
 
 Ptr<TcpSocketImpl> TcpSocketImpl::Copy ()
@@ -1440,7 +1455,7 @@
     m_cWnd = m_segmentSize; // Collapse cwnd (re-enter slowstart)
     // For Tahoe, we also reset nextTxSeq
     m_nextTxSequence = m_highestRxAck;
-    SendPendingData ();
+    SendPendingData (m_connected);
   }
 }
 
--- a/src/internet-stack/udp-socket-impl.h	Mon Mar 23 18:28:08 2009 -0700
+++ b/src/internet-stack/udp-socket-impl.h	Mon Mar 23 19:23:11 2009 -0700
@@ -105,8 +105,6 @@
   Ptr<UdpL4Protocol> m_udp;
   Ipv4Address m_defaultAddress;
   uint16_t m_defaultPort;
-  Callback<void,Ptr<Socket>,uint32_t,const Address &> m_dummyRxCallback;
-  Callback<void,Ptr<Socket>,uint8_t const*,uint32_t,const Address &> m_rxCallback;
   TracedCallback<Ptr<const Packet> > m_dropTrace;
 
   enum SocketErrno m_errno;