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