--- a/AUTHORS Fri Jun 05 16:06:25 2009 +0400
+++ b/AUTHORS Mon Jun 08 15:12:15 2009 +0400
@@ -1,3 +1,5 @@
+Nicola Baldo (nbaldo@cttc.es)
+Mirko Banchi (mk.banchi@gmail.com)
Raj Bhattacharjea (raj.b@gatech.edu)
Gustavo Carneiro (gjc@inescporto.pt, gjcarneiro@gmail.com)
Craig Dowell (craigdo@ee.washington.edu)
--- a/CHANGES.html Fri Jun 05 16:06:25 2009 +0400
+++ b/CHANGES.html Mon Jun 08 15:12:15 2009 +0400
@@ -51,16 +51,82 @@
</ul>
<h2>New API:</h2>
+
<ul>
+<li><b>YansWifiPhyHelper supporting radiotap and prism PCAP output</b>
+<p>The newly supported pcap formats can be adopted by calling the following new method of YansWifiPhyHelper:</p>
+<pre>
+ + void SetPcapFormat (enum PcapFormat format);
+</pre>
+where format is one of PCAP_FORMAT_80211_RADIOTAP, PCAP_FORMAT_80211_PRISM or PCAP_FORMAT_80211. By default, PCAP_FORMAT_80211 is used, so the default PCAP format is the same as before.</p>
+</li>
+
<li> <b>attributes for class Ipv4</b>
<p> class Ipv4 now contains attributes in ipv4.cc; the first one
is called "IpForward" that will enable/disable Ipv4 forwarding.
</li>
+
+<li> <b>packet tags</b>
+<p>class Packet now contains AddPacketTag, RemovePacketTag and PeekPacketTag
+which can be used to attach a tag to a packet, as opposed to the old
+AddTag method which attached a tag to a set of bytes. The main
+semantic difference is in how these tags behave in the presence of
+fragmentation and reassembly.
+</li>
+
</ul>
<h2>Changes to existing API:</h2>
<ul>
+<li> <b>packet byte tags renaming</b>
+ <ul>
+ <li>Packet::AddTag to Packet::AddByteTag</li>
+ <li>Packet::FindFirstMatchingTag to Packet::FindFirstMatchingByteTag</li>
+ <li>Packet::RemoveAllTags to Packet::RemoveAllByteTags</li>
+ <li>Packet::PrintTags to Packet::PrintByteTags</li>
+ <li>Packet::GetTagIterator to Packet::GetByteTagIterator</li>
+ </ul>
+</li>
+
+<li><b>YansWifiPhyHelper::EnablePcap* methods not static any more</b>
+<p>To accommodate the possibility of configuring the PCAP format used for wifi promiscuous mode traces, several methods of YansWifiPhyHelper had to be made non-static:
+<pre>
+- static void EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid);
++ void EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid);
+- static void EnablePcap (std::string filename, Ptr<NetDevice> nd);
++ void EnablePcap (std::string filename, Ptr<NetDevice> nd);
+- static void EnablePcap (std::string filename, std::string ndName);
++ void EnablePcap (std::string filename, std::string ndName);
+- static void EnablePcap (std::string filename, NetDeviceContainer d);
++ void EnablePcap (std::string filename, NetDeviceContainer d);
+- static void EnablePcap (std::string filename, NodeContainer n);
++ void EnablePcap (std::string filename, NodeContainer n);
+- static void EnablePcapAll (std::string filename);
++ void EnablePcapAll (std::string filename);
+</pre>
+</p>
+</li>
+
+<li><b>Wifi Promisc Sniff interface modified </b>
+<p>
+To accommodate support for the radiotap and prism headers in PCAP traces, the interface for promiscuos mode sniff in the wifi device was changed. The new implementation was heavily inspired by the way the madwifi driver handles monitor mode. A distinction between TX and RX events is introduced, to account for the fact that different information is to be put in the radiotap/prism header (e.g., RSSI and noise make sense only for RX packets). The following are the relevant modifications to the WifiPhy class:
+<pre>
+- void NotifyPromiscSniff (Ptr<const Packet> packet);
++ void NotifyPromiscSniffRx (Ptr<const Packet> packet, uint16_t channelFreqMhz, uint32_t rate, bool isShortPreamble, double signalDbm, double noiseDbm);
++ void NotifyPromiscSniffTx (Ptr<const Packet> packet, uint16_t channelFreqMhz, uint32_t rate, bool isShortPreamble);
+- TracedCallback<Ptr<const Packet> > m_phyPromiscSnifferTrace;
++ TracedCallback<Ptr<const Packet>, uint16_t, uint32_t, bool, double, double> m_phyPromiscSniffRxTrace;
++ TracedCallback<Ptr<const Packet>, uint16_t, uint32_t, bool> m_phyPromiscSniffTxTrace;
+</pre>
+The above mentioned callbacks are expected to be used to call the following method to write Wifi PCAP traces in promiscuous mode:
+<pre>
++ void WriteWifiMonitorPacket(Ptr<const Packet> packet, uint16_t channelFreqMhz, uint32_t rate, bool isShortPreamble, bool isTx, double signalDbm, double noiseDbm);
+</pre>
+In the above method, the isTx parameter is to be used to differentiate between TX and RX packets. For an example of how to implement these callbacks, see the implementation of PcapSniffTxEvent and PcapSniffRxEvent in src/helper/yans-wifi-helper.cc
+</p>
+</li>
+
<li><b> Routing decoupled from class Ipv4</b>
<p> All calls of the form "Ipv4::AddHostRouteTo ()" etc. (i.e. to
add static routes, both unicast and multicast) have been moved to a new
--- a/RELEASE_NOTES Fri Jun 05 16:06:25 2009 +0400
+++ b/RELEASE_NOTES Mon Jun 08 15:12:15 2009 +0400
@@ -25,6 +25,7 @@
b) 802.11 PHY:
- 802.11b PHY support (Gary Pei)
- Nakagami propagation loss model (Timo Bingmann)
+ - radiotap and prism headers for PCAP output (Nicola Baldo)
c) GammaVariable and ErlangVariable (Timo Bingmann)
API changes from ns-3.4
--- a/bindings/python/ns3_module_common.py Fri Jun 05 16:06:25 2009 +0400
+++ b/bindings/python/ns3_module_common.py Mon Jun 08 15:12:15 2009 +0400
@@ -1055,6 +1055,14 @@
cls.add_method('WriteWifiHeader',
'void',
[])
+ ## pcap-writer.h: void ns3::PcapWriter::WriteWifiRadiotapHeader() [member function]
+ cls.add_method('WriteWifiRadiotapHeader',
+ 'void',
+ [])
+ ## pcap-writer.h: void ns3::PcapWriter::WriteWifiPrismHeader() [member function]
+ cls.add_method('WriteWifiPrismHeader',
+ 'void',
+ [])
## pcap-writer.h: void ns3::PcapWriter::WritePppHeader() [member function]
cls.add_method('WritePppHeader',
'void',
@@ -1063,6 +1071,10 @@
cls.add_method('WritePacket',
'void',
[param('ns3::Ptr< ns3::Packet const >', 'packet')])
+ ## pcap-writer.h: void ns3::PcapWriter::WriteWifiMonitorPacket(ns3::Ptr<ns3::Packet const> packet, uint16_t channelFreqMhz, uint32_t rate, bool isShortPreamble, bool isTx, double signalDbm, double noiseDbm) [member function]
+ cls.add_method('WriteWifiMonitorPacket',
+ 'void',
+ [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('uint16_t', 'channelFreqMhz'), param('uint32_t', 'rate'), param('bool', 'isShortPreamble'), param('bool', 'isTx'), param('double', 'signalDbm'), param('double', 'noiseDbm')])
return
def register_Ns3Trailer_methods(root_module, cls):
--- a/bindings/python/ns3_module_core.py Fri Jun 05 16:06:25 2009 +0400
+++ b/bindings/python/ns3_module_core.py Mon Jun 08 15:12:15 2009 +0400
@@ -495,10 +495,10 @@
cls.add_constructor([param('ns3::Names const &', 'arg0')])
## names.h: ns3::Names::Names() [constructor]
cls.add_constructor([])
- ## names.h: static void ns3::Names::Add(std::string name, ns3::Ptr<ns3::Object> obj) [member function]
+ ## names.h: static void ns3::Names::Add(std::string name, ns3::Ptr<ns3::Object> object) [member function]
cls.add_method('Add',
'void',
- [param('std::string', 'name'), param('ns3::Ptr< ns3::Object >', 'obj')],
+ [param('std::string', 'name'), param('ns3::Ptr< ns3::Object >', 'object')],
is_static=True)
## names.h: static void ns3::Names::Add(std::string path, std::string name, ns3::Ptr<ns3::Object> object) [member function]
cls.add_method('Add',
@@ -2043,7 +2043,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::basic_string<char,std::char_traits<char>,std::allocator<char> > path) [member function]
+ ## traced-value.h: void ns3::TracedValue<unsigned int>::Connect(ns3::CallbackBase const & cb, std::string path) [member function]
cls.add_method('Connect',
'void',
[param('ns3::CallbackBase const &', 'cb'), param('std::string', 'path')])
@@ -2051,7 +2051,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::basic_string<char,std::char_traits<char>,std::allocator<char> > path) [member function]
+ ## traced-value.h: void ns3::TracedValue<unsigned int>::Disconnect(ns3::CallbackBase const & cb, std::string path) [member function]
cls.add_method('Disconnect',
'void',
[param('ns3::CallbackBase const &', 'cb'), param('std::string', 'path')])
@@ -2199,7 +2199,7 @@
module.add_function('TypeNameGet',
'std::string',
[],
- template_parameters=['long'])
+ template_parameters=['long long'])
## type-name.h: extern std::string ns3::TypeNameGet() [free function]
module.add_function('TypeNameGet',
'std::string',
@@ -2219,7 +2219,7 @@
module.add_function('TypeNameGet',
'std::string',
[],
- template_parameters=['unsigned long'])
+ template_parameters=['unsigned long long'])
## type-name.h: extern std::string ns3::TypeNameGet() [free function]
module.add_function('TypeNameGet',
'std::string',
--- a/bindings/python/ns3_module_helper.py Fri Jun 05 16:06:25 2009 +0400
+++ b/bindings/python/ns3_module_helper.py Mon Jun 08 15:12:15 2009 +0400
@@ -55,6 +55,8 @@
module.add_class('YansWifiChannelHelper', allow_subclassing=False)
## yans-wifi-helper.h: ns3::YansWifiPhyHelper [class]
module.add_class('YansWifiPhyHelper', allow_subclassing=False, parent=root_module['ns3::WifiPhyHelper'])
+ ## yans-wifi-helper.h: ns3::YansWifiPhyHelper::PcapFormat [enumeration]
+ module.add_enum('PcapFormat', ['PCAP_FORMAT_80211', 'PCAP_FORMAT_80211_PRISM', 'PCAP_FORMAT_80211_RADIOTAP'], outer_class=root_module['ns3::YansWifiPhyHelper'])
## nqos-wifi-mac-helper.h: ns3::NqosWifiMacHelper [class]
module.add_class('NqosWifiMacHelper', allow_subclassing=False, parent=root_module['ns3::WifiMacHelper'])
## qos-wifi-mac-helper.h: ns3::QosWifiMacHelper [class]
@@ -1160,36 +1162,34 @@
cls.add_method('SetErrorRateModel',
'void',
[param('std::string', 'name'), param('std::string', 'n0', default_value='""'), param('ns3::AttributeValue const &', 'v0', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue const &', 'v1', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue const &', 'v2', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue const &', 'v3', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue const &', 'v4', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n5', default_value='""'), param('ns3::AttributeValue const &', 'v5', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n6', default_value='""'), param('ns3::AttributeValue const &', 'v6', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n7', default_value='""'), param('ns3::AttributeValue const &', 'v7', default_value='ns3::EmptyAttributeValue()')])
- ## yans-wifi-helper.h: static void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, uint32_t nodeid, uint32_t deviceid) [member function]
+ ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::SetPcapFormat(ns3::YansWifiPhyHelper::PcapFormat format) [member function]
+ cls.add_method('SetPcapFormat',
+ 'void',
+ [param('ns3::YansWifiPhyHelper::PcapFormat', 'format')])
+ ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, uint32_t nodeid, uint32_t deviceid) [member function]
cls.add_method('EnablePcap',
'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]
+ [param('std::string', 'filename'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')])
+ ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, ns3::Ptr<ns3::NetDevice> nd) [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]
+ [param('std::string', 'filename'), param('ns3::Ptr< ns3::NetDevice >', 'nd')])
+ ## yans-wifi-helper.h: 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')])
+ ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, ns3::NetDeviceContainer d) [member function]
cls.add_method('EnablePcap',
'void',
- [param('std::string', 'filename'), param('ns3::NetDeviceContainer', 'd')],
- is_static=True)
- ## yans-wifi-helper.h: static void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, ns3::NodeContainer n) [member function]
+ [param('std::string', 'filename'), param('ns3::NetDeviceContainer', 'd')])
+ ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, ns3::NodeContainer n) [member function]
cls.add_method('EnablePcap',
'void',
- [param('std::string', 'filename'), param('ns3::NodeContainer', 'n')],
- is_static=True)
- ## yans-wifi-helper.h: static void ns3::YansWifiPhyHelper::EnablePcapAll(std::string filename) [member function]
+ [param('std::string', 'filename'), param('ns3::NodeContainer', 'n')])
+ ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::EnablePcapAll(std::string filename) [member function]
cls.add_method('EnablePcapAll',
'void',
- [param('std::string', 'filename')],
- is_static=True)
+ [param('std::string', 'filename')])
## yans-wifi-helper.h: static void ns3::YansWifiPhyHelper::EnableAscii(std::ostream & os, uint32_t nodeid, uint32_t deviceid) [member function]
cls.add_method('EnableAscii',
'void',
--- a/bindings/python/ns3_module_node.py Fri Jun 05 16:06:25 2009 +0400
+++ b/bindings/python/ns3_module_node.py Mon Jun 08 15:12:15 2009 +0400
@@ -1443,10 +1443,10 @@
'ns3::Ipv4Address',
[],
is_const=True)
- ## ipv4-route.h: void ns3::Ipv4MulticastRoute::SetOrigin(ns3::Ipv4Address const group) [member function]
+ ## ipv4-route.h: void ns3::Ipv4MulticastRoute::SetOrigin(ns3::Ipv4Address const origin) [member function]
cls.add_method('SetOrigin',
'void',
- [param('ns3::Ipv4Address const', 'group')])
+ [param('ns3::Ipv4Address const', 'origin')])
## ipv4-route.h: ns3::Ipv4Address ns3::Ipv4MulticastRoute::GetOrigin() const [member function]
cls.add_method('GetOrigin',
'ns3::Ipv4Address',
--- a/bindings/python/ns3_module_olsr.py Fri Jun 05 16:06:25 2009 +0400
+++ b/bindings/python/ns3_module_olsr.py Mon Jun 08 15:12:15 2009 +0400
@@ -102,13 +102,13 @@
module.add_container('std::vector< ns3::olsr::MessageHeader::Hello::LinkMessage >', 'ns3::olsr::MessageHeader::Hello::LinkMessage', container_type='vector')
module.add_container('std::vector< ns3::olsr::MessageHeader::Hna::Association >', 'ns3::olsr::MessageHeader::Hna::Association', container_type='vector')
typehandlers.add_type_alias('std::vector< ns3::olsr::DuplicateTuple, std::allocator< ns3::olsr::DuplicateTuple > >', 'ns3::olsr::DuplicateSet')
- typehandlers.add_type_alias('std::vector< ns3::olsr::TopologyTuple, std::allocator< ns3::olsr::TopologyTuple > >', 'ns3::olsr::TopologySet')
typehandlers.add_type_alias('std::set< ns3::Ipv4Address, std::less< ns3::Ipv4Address >, std::allocator< ns3::Ipv4Address > >', 'ns3::olsr::MprSet')
typehandlers.add_type_alias('std::vector< ns3::olsr::MprSelectorTuple, std::allocator< ns3::olsr::MprSelectorTuple > >', 'ns3::olsr::MprSelectorSet')
typehandlers.add_type_alias('std::vector< ns3::olsr::MessageHeader, std::allocator< ns3::olsr::MessageHeader > >', 'ns3::olsr::MessageList')
typehandlers.add_type_alias('std::vector< ns3::olsr::IfaceAssocTuple, std::allocator< ns3::olsr::IfaceAssocTuple > >', 'ns3::olsr::IfaceAssocSet')
typehandlers.add_type_alias('std::vector< ns3::olsr::NeighborTuple, std::allocator< ns3::olsr::NeighborTuple > >', 'ns3::olsr::NeighborSet')
typehandlers.add_type_alias('std::vector< ns3::olsr::TwoHopNeighborTuple, std::allocator< ns3::olsr::TwoHopNeighborTuple > >', 'ns3::olsr::TwoHopNeighborSet')
+ typehandlers.add_type_alias('std::vector< ns3::olsr::TopologyTuple, std::allocator< ns3::olsr::TopologyTuple > >', 'ns3::olsr::TopologySet')
typehandlers.add_type_alias('std::vector< ns3::olsr::LinkTuple, std::allocator< ns3::olsr::LinkTuple > >', 'ns3::olsr::LinkSet')
def register_methods(root_module):
--- a/bindings/python/ns3_module_wifi.py Fri Jun 05 16:06:25 2009 +0400
+++ b/bindings/python/ns3_module_wifi.py Mon Jun 08 15:12:15 2009 +0400
@@ -8,7 +8,7 @@
## wifi-preamble.h: ns3::WifiPreamble [enumeration]
module.add_enum('WifiPreamble', ['WIFI_PREAMBLE_LONG', 'WIFI_PREAMBLE_SHORT'])
## wifi-phy-standard.h: ns3::WifiPhyStandard [enumeration]
- module.add_enum('WifiPhyStandard', ['WIFI_PHY_STANDARD_80211a', 'WIFI_PHY_STANDARD_holland'])
+ module.add_enum('WifiPhyStandard', ['WIFI_PHY_STANDARD_80211a', 'WIFI_PHY_STANDARD_80211b', 'WIFI_PHY_STANDARD_holland'])
## qos-utils.h: ns3::AccessClass [enumeration]
module.add_enum('AccessClass', ['AC_VO', 'AC_VI', 'AC_BE', 'AC_BK', 'AC_UNDEF'])
## edca-txop-n.h: ns3::TypeOfStation [enumeration]
@@ -26,7 +26,7 @@
## wifi-mode.h: ns3::WifiMode [class]
module.add_class('WifiMode')
## wifi-mode.h: ns3::WifiMode::ModulationType [enumeration]
- module.add_enum('ModulationType', ['BPSK', 'QAM'], outer_class=root_module['ns3::WifiMode'])
+ module.add_enum('ModulationType', ['BPSK', 'DBPSK', 'DQPSK', 'QAM'], outer_class=root_module['ns3::WifiMode'])
## wifi-mode.h: ns3::WifiModeFactory [class]
module.add_class('WifiModeFactory')
## wifi-phy.h: ns3::WifiPhyListener [class]
@@ -101,6 +101,8 @@
module.add_class('EdcaTxopN', parent=root_module['ns3::Object'])
## error-rate-model.h: ns3::ErrorRateModel [class]
module.add_class('ErrorRateModel', parent=root_module['ns3::Object'])
+ ## propagation-loss-model.h: ns3::FixedRssLossModel [class]
+ module.add_class('FixedRssLossModel', parent=root_module['ns3::PropagationLossModel'])
## propagation-loss-model.h: ns3::FriisPropagationLossModel [class]
module.add_class('FriisPropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
## ideal-wifi-manager.h: ns3::IdealWifiManager [class]
@@ -111,6 +113,8 @@
module.add_class('LogDistancePropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
## msdu-aggregator.h: ns3::MsduAggregator [class]
module.add_class('MsduAggregator', parent=root_module['ns3::Object'])
+ ## propagation-loss-model.h: ns3::NakagamiPropagationLossModel [class]
+ module.add_class('NakagamiPropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
## nqap-wifi-mac.h: ns3::NqapWifiMac [class]
module.add_class('NqapWifiMac', parent=root_module['ns3::WifiMac'])
## nqsta-wifi-mac.h: ns3::NqstaWifiMac [class]
@@ -228,11 +232,13 @@
register_Ns3DcaTxop_methods(root_module, root_module['ns3::DcaTxop'])
register_Ns3EdcaTxopN_methods(root_module, root_module['ns3::EdcaTxopN'])
register_Ns3ErrorRateModel_methods(root_module, root_module['ns3::ErrorRateModel'])
+ register_Ns3FixedRssLossModel_methods(root_module, root_module['ns3::FixedRssLossModel'])
register_Ns3FriisPropagationLossModel_methods(root_module, root_module['ns3::FriisPropagationLossModel'])
register_Ns3IdealWifiManager_methods(root_module, root_module['ns3::IdealWifiManager'])
register_Ns3JakesPropagationLossModel_methods(root_module, root_module['ns3::JakesPropagationLossModel'])
register_Ns3LogDistancePropagationLossModel_methods(root_module, root_module['ns3::LogDistancePropagationLossModel'])
register_Ns3MsduAggregator_methods(root_module, root_module['ns3::MsduAggregator'])
+ register_Ns3NakagamiPropagationLossModel_methods(root_module, root_module['ns3::NakagamiPropagationLossModel'])
register_Ns3NqapWifiMac_methods(root_module, root_module['ns3::NqapWifiMac'])
register_Ns3NqstaWifiMac_methods(root_module, root_module['ns3::NqstaWifiMac'])
register_Ns3OnoeWifiManager_methods(root_module, root_module['ns3::OnoeWifiManager'])
@@ -267,6 +273,10 @@
cls.add_method('Configure80211aParameters',
'void',
[])
+ ## interference-helper.h: void ns3::InterferenceHelper::Configure80211bParameters() [member function]
+ cls.add_method('Configure80211bParameters',
+ 'void',
+ [])
## interference-helper.h: ns3::Time ns3::InterferenceHelper::GetEnergyDuration(double energyW) [member function]
cls.add_method('GetEnergyDuration',
'ns3::Time',
@@ -487,6 +497,16 @@
'ns3::WifiMode',
[param('std::string', 'uniqueName'), param('bool', 'isMandatory'), param('uint32_t', 'bandwidth'), param('uint32_t', 'dataRate'), param('uint32_t', 'phyRate'), param('uint8_t', 'constellationSize')],
is_static=True)
+ ## wifi-mode.h: static ns3::WifiMode ns3::WifiModeFactory::CreateDbpsk(std::string uniqueName, bool isMandatory, uint32_t bandwidth, uint32_t dataRate, uint32_t phyRate) [member function]
+ cls.add_method('CreateDbpsk',
+ 'ns3::WifiMode',
+ [param('std::string', 'uniqueName'), param('bool', 'isMandatory'), param('uint32_t', 'bandwidth'), param('uint32_t', 'dataRate'), param('uint32_t', 'phyRate')],
+ is_static=True)
+ ## wifi-mode.h: static ns3::WifiMode ns3::WifiModeFactory::CreateDqpsk(std::string uniqueName, bool isMandatory, uint32_t bandwidth, uint32_t dataRate, uint32_t phyRate) [member function]
+ cls.add_method('CreateDqpsk',
+ 'ns3::WifiMode',
+ [param('std::string', 'uniqueName'), param('bool', 'isMandatory'), param('uint32_t', 'bandwidth'), param('uint32_t', 'dataRate'), param('uint32_t', 'phyRate')],
+ is_static=True)
return
def register_Ns3WifiPhyListener_methods(root_module, cls):
@@ -2013,6 +2033,26 @@
'ns3::WifiMode',
[],
is_static=True)
+ ## wifi-phy.h: static ns3::WifiMode ns3::WifiPhy::Get1mbb() [member function]
+ cls.add_method('Get1mbb',
+ 'ns3::WifiMode',
+ [],
+ is_static=True)
+ ## wifi-phy.h: static ns3::WifiMode ns3::WifiPhy::Get2mbb() [member function]
+ cls.add_method('Get2mbb',
+ 'ns3::WifiMode',
+ [],
+ is_static=True)
+ ## wifi-phy.h: static ns3::WifiMode ns3::WifiPhy::Get5_5mbb() [member function]
+ cls.add_method('Get5_5mbb',
+ 'ns3::WifiMode',
+ [],
+ is_static=True)
+ ## wifi-phy.h: static ns3::WifiMode ns3::WifiPhy::Get11mbb() [member function]
+ cls.add_method('Get11mbb',
+ 'ns3::WifiMode',
+ [],
+ is_static=True)
## wifi-phy.h: void ns3::WifiPhy::NotifyTxBegin(ns3::Ptr<ns3::Packet const> packet) [member function]
cls.add_method('NotifyTxBegin',
'void',
@@ -2037,10 +2077,14 @@
cls.add_method('NotifyRxDrop',
'void',
[param('ns3::Ptr< ns3::Packet const >', 'packet')])
- ## wifi-phy.h: void ns3::WifiPhy::NotifyPromiscSniff(ns3::Ptr<ns3::Packet const> packet) [member function]
- cls.add_method('NotifyPromiscSniff',
- 'void',
- [param('ns3::Ptr< ns3::Packet const >', 'packet')])
+ ## wifi-phy.h: void ns3::WifiPhy::NotifyPromiscSniffRx(ns3::Ptr<ns3::Packet const> packet, uint16_t channelFreqMhz, uint32_t rate, bool isShortPreamble, double signalDbm, double noiseDbm) [member function]
+ cls.add_method('NotifyPromiscSniffRx',
+ 'void',
+ [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('uint16_t', 'channelFreqMhz'), param('uint32_t', 'rate'), param('bool', 'isShortPreamble'), param('double', 'signalDbm'), param('double', 'noiseDbm')])
+ ## wifi-phy.h: void ns3::WifiPhy::NotifyPromiscSniffTx(ns3::Ptr<ns3::Packet const> packet, uint16_t channelFreqMhz, uint32_t rate, bool isShortPreamble) [member function]
+ cls.add_method('NotifyPromiscSniffTx',
+ 'void',
+ [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('uint16_t', 'channelFreqMhz'), param('uint32_t', 'rate'), param('bool', 'isShortPreamble')])
return
def register_Ns3WifiRemoteStationManager_methods(root_module, cls):
@@ -2972,6 +3016,25 @@
is_pure_virtual=True, is_const=True, is_virtual=True)
return
+def register_Ns3FixedRssLossModel_methods(root_module, cls):
+ ## propagation-loss-model.h: static ns3::TypeId ns3::FixedRssLossModel::GetTypeId() [member function]
+ cls.add_method('GetTypeId',
+ 'ns3::TypeId',
+ [],
+ is_static=True)
+ ## propagation-loss-model.h: ns3::FixedRssLossModel::FixedRssLossModel() [constructor]
+ cls.add_constructor([])
+ ## propagation-loss-model.h: void ns3::FixedRssLossModel::SetRss(double rss) [member function]
+ cls.add_method('SetRss',
+ 'void',
+ [param('double', 'rss')])
+ ## propagation-loss-model.h: double ns3::FixedRssLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+ cls.add_method('DoCalcRxPower',
+ 'double',
+ [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')],
+ is_const=True, visibility='private', is_virtual=True)
+ return
+
def register_Ns3FriisPropagationLossModel_methods(root_module, cls):
## propagation-loss-model.h: static ns3::TypeId ns3::FriisPropagationLossModel::GetTypeId() [member function]
cls.add_method('GetTypeId',
@@ -3122,6 +3185,21 @@
is_static=True)
return
+def register_Ns3NakagamiPropagationLossModel_methods(root_module, cls):
+ ## propagation-loss-model.h: static ns3::TypeId ns3::NakagamiPropagationLossModel::GetTypeId() [member function]
+ cls.add_method('GetTypeId',
+ 'ns3::TypeId',
+ [],
+ is_static=True)
+ ## propagation-loss-model.h: ns3::NakagamiPropagationLossModel::NakagamiPropagationLossModel() [constructor]
+ cls.add_constructor([])
+ ## propagation-loss-model.h: double ns3::NakagamiPropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
+ cls.add_method('DoCalcRxPower',
+ 'double',
+ [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')],
+ is_const=True, visibility='private', is_virtual=True)
+ return
+
def register_Ns3NqapWifiMac_methods(root_module, cls):
## nqap-wifi-mac.h: static ns3::TypeId ns3::NqapWifiMac::GetTypeId() [member function]
cls.add_method('GetTypeId',
--- a/doc/manual/Makefile Fri Jun 05 16:06:25 2009 +0400
+++ b/doc/manual/Makefile Mon Jun 08 15:12:15 2009 +0400
@@ -17,6 +17,8 @@
$(FIGURES)/node.eps \
$(FIGURES)/buffer.eps \
$(FIGURES)/sockets-overview.eps \
+ $(FIGURES)/routing.eps \
+ $(FIGURES)/routing-specialization.eps \
$(FIGURES)/testbed.eps \
$(FIGURES)/emulated-channel.eps \
$(FIGURES)/snir.eps \
--- a/doc/manual/attributes.texi Fri Jun 05 16:06:25 2009 +0400
+++ b/doc/manual/attributes.texi Mon Jun 08 15:12:15 2009 +0400
@@ -207,6 +207,8 @@
In the ns-3 attribute system, these value definitions and accessor
functions are moved into the TypeId class; e.g.:
@verbatim
+NS_OBJECT_ENSURE_REGISTERED (DropTailQueue);
+
TypeId DropTailQueue::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::DropTailQueue")
@@ -239,6 +241,11 @@
section, we will provide an example script that shows how users
may manipulate these values.
+Note that initialization of the attribute relies on the macro
+NS_OBJECT_ENSURE_REGISTERED (DropTailQueue) being called; if you leave
+this out of your new class implementation, your attributes will not be
+initialized corretly.
+
@subsection Basic usage
Let's look at how a user script might access these values.
Binary file doc/manual/figures/packet.dia has changed
Binary file doc/manual/figures/routing-specialization.dia has changed
Binary file doc/manual/figures/routing.dia has changed
--- a/doc/manual/packets.texi Fri Jun 05 16:06:25 2009 +0400
+++ b/doc/manual/packets.texi Mon Jun 08 15:12:15 2009 +0400
@@ -15,11 +15,14 @@
emulated applications
@end itemize
-@emph{ns} Packet objects contain a buffer of bytes: protocol headers and
-trailers are serialized in this buffer of bytes using user-provided
-serialization and deserialization routines. The content of this byte
-buffer is expected to match bit-for-bit the content of a real packet on
-a real network implementing the protocol of interest.
+Each network packet contains a byte buffer, a set of byte tags, a set of
+packet tags, and metadata.
+
+The byte buffer stores the serialized content of the headers and trailers
+added to a packet. The serialized representation of these headers is expected
+to match that of real network packets bit for bit (although nothing
+forces you to do this) which means that the content of a packet buffer
+is expected to be that of a real packet.
Fragmentation and defragmentation are quite natural to implement within
this context: since we have a buffer of real bytes, we can split it in
@@ -29,19 +32,37 @@
the simulator. We also expect that performing a real-time plug of the
simulator to a real-world network will be easy.
-Because we understand that simulation developers often wish to store in
-packet objects data which is not found in the real packets (such as
-timestamps or any kind of similar in-band data), the @emph{ns} Packet class
-can also store extra per-packet "Tags" which are 16 bytes blobs of data.
-Any Packet can store any number of unique Tags, each of which is
-uniquely identified by its C++ type. These tags make it easy to attach
-per-model data to a packet without having to patch the main Packet
-class or Packet facilities.
+One problem that this design choice raises is that it is difficult to
+pretty-print the packet headers without context. The packet metadata
+describes the type of the headers and trailers which
+were serialized in the byte buffer. The maintenance of metadata is
+optional and disabled by default. To enable it, you must call
+Packet::EnableMetadata() and this will allow you to get non-empty
+output from Packet::Print and Packet::Print.
+Also, developers often want to store data in packet objects that is not found
+in the real packets (such as timestamps or flow-ids). The Packet class
+deals with this requirement by storing a set of tags (class Tag).
+We have found two classes of use cases for these tags, which leads to
+two different types of tags. So-called
+'byte' tags are used to tag a subset of the bytes in the packet byte buffer
+while 'packet' tags are used to tag the packet itself. The main difference
+between these two kinds of tags is what happens when packets are copied,
+fragmented, and reassembled: 'byte' tags follow bytes while 'packet' tags
+follow packets. Another important difference between these two kinds of tags
+is that byte tags cannot be removed and are expected to be written once,
+and read many times, while packet tags are expected to be written once,
+read many times, and removed exactly once. An example of a 'byte'
+tag is a FlowIdTag which contains a flow id and is set by the application
+generating traffic. An example of a 'packet' tag is a cross-layer
+QoS class id set by an application and processed by a lower-level MAC
+layer.
+
Memory management of Packet objects is entirely automatic and extremely
efficient: memory for the application-level payload can be modelized by
a virtual buffer of zero-filled bytes for which memory is never allocated
-unless explicitely requested by the user or unless the packet is fragmented.
+unless explicitly requested by the user or unless the packet is fragmented
+or serialized out to a real network device.
Furthermore, copying, adding, and, removing headers or trailers to a packet
has been optimized to be virtually free through a technique known as
Copy On Write.
@@ -54,32 +75,12 @@
tension between ease-of-use, performance, and safe interface
design.
-There are a few requirements on this object design:
-@itemize @bullet
-@item Creation, management, and deletion of this object
-should be as simple as possible, while avoiding the
-chance for memory leaks and/or heap corruption;
-@item Packets should support serialization and deserialization
-so that network emulation is supported;
-@item Packets should support fragmentation and concatenation
-(multiple packets in a data link frame), especially for wireless
-support;
-@item It should be natural for packets to carry actual application
-data, or if there is only an emulated application and there is
-no need to carry dummy bytes, smaller packets could be used with
-just the headers and a record of the payload size, but not actual
-application bytes, conveyed in the simulated packet.
-@item Packets should facilitate BSD-like operations on mbufs, for
-support of ported operating system stacks.
-@item Additional side-information should be supported, such as
-a tag for cross-layer information.
-@end itemize
-
@section Packet design overview
Unlike @emph{ns-2}, in which Packet objects contain a buffer of C++
structures corresponding to protocol headers, each network packet in
-@emph{ns-3} contains a byte Buffer and a list of Tags:
+@emph{ns-3} contains a byte Buffer, a list of byte Tags, a list of
+packet Tags, and a PacketMetadata object:
@itemize @bullet
@item The byte buffer stores the serialized content of the chunks
added to a packet. The serialized representation of these chunks is
@@ -88,16 +89,12 @@
of a packet buffer is expected to be that of a real packet.
Packets can also be created with an arbitrary zero-filled payload
for which no real memory is allocated.
-@item The list of tags stores an arbitrarily large set of arbitrary
+@item Each list of tags stores an arbitrarily large set of arbitrary
user-provided data structures in the packet. Each Tag is uniquely
identified by its type; only one instance of each
type of data structure is allowed in a list of tags. These tags typically
contain per-packet cross-layer information or flow identifiers (i.e.,
-things that you wouldn't find in the bits on the wire). Each tag
-stored in the tag list can be at most 16 bytes.
-Trying to attach bigger data structures will trigger
-crashes at runtime. The 16 byte limit is a modifiable compilation
-constant.
+things that you wouldn't find in the bits on the wire).
@end itemize
@float Figure,fig:packets
@@ -110,17 +107,29 @@
is provided later in Figure @ref{fig:buffer}.
In \nsthree, the Packet byte buffer is analogous to a Linux skbuff
or BSD mbuf; it is a serialized representation of the actual
-data in the packet. The tag list is a container for extra
+data in the packet. The tag lists are containers for extra
items useful for simulation convenience; if a Packet is converted
to an emulated packet and put over an actual network, the tags
are stripped off and the byte buffer is copied directly
into a real packet.
-The Packet class has value semantics: it can be freely copied around,
-allocated on the stack, and passed to functions as arguments. Whenever
-an instance is copied, the full underlying data is not copied; it
-has ``copy-on-write'' (COW) semantics. Packet instances can be passed
-by value to function arguments without any performance hit.
+Packets are reference counted objects. They are handled with smart
+pointer (Ptr) objects like many of the objects in the ns-3 system.
+One small difference you will see is that class Packet does not
+inherit from class Object or class RefCountBase, and implements the
+Ref() and Unref() methods directly. This was designed to avoid the overhead
+of a vtable in class Packet.
+
+The Packet class is designed to be copied cheaply; the overall design
+is based on Copy on Write (COW). When there are multiple references
+to a packet object, and there is an operation on one of them, only
+so-called "dirty" operations will trigger a deep copy of the packet:
+@itemize @bullet
+@item @code{ns3::Packet::AddHeader()}
+@item @code{ns3::Packet::AddTrailer()}
+@item @code{both versions of ns3::Packet::AddAtEnd()}
+@item @code{Packet::RemovePacketTag()}
+@end itemize
The fundamental classes for adding to and removing from the byte
buffer are @code{class Header} and @code{class Trailer}.
@@ -149,78 +158,203 @@
Similarly, user-defined Tags can be appended to the packet.
Unlike Headers, Tags are not serialized into a contiguous buffer
-but are stored in an array. By default, Tags are limited to 16 bytes in
-size. Tags can be flexibly defined to be any type, but there
+but are stored in lists. Tags can be flexibly defined to be any
+type, but there
can only be one instance of any particular object type in
the Tags buffer at any time.
-@section Packet interface
+@section Using the packet interface
+
+This section describes how to create and use the @code{ns3::Packet} object.
+
+@subsection Creating a new packet
-The public member functions of a Packet object are as follows:
+The following command will create a new packet with a new unique
+Id.
-@subsection Constructors
+@verbatim
+ Ptr<Packet> pkt = Create<Packet> ();
+@end verbatim
+
+What is the Uid (unique Id)? It is an internal id that the
+system uses to identify packets. It can be fetched via the following
+method:
@verbatim
- /**
- * Create an empty packet with a new uid (as returned
- * by getUid).
- */
- Packet ();
- /**
- * Create a packet with a zero-filled payload.
- * The memory necessary for the payload is not allocated:
- * it will be allocated at any later point if you attempt
- * to fragment this packet or to access the zero-filled
- * bytes. The packet is allocated with a new uid (as
- * returned by getUid).
- *
- * \param size the size of the zero-filled payload
- */
- Packet (uint32_t size);
+ uint32_t uid = pkt->GetUid ();
+@end verbatim
+
+But please note the following. This uid is an internal uid and cannot
+be counted on to provide an accurate counter of how many
+"simulated packets" of a particular protocol are in the system.
+It is not trivial to make this uid into such a counter, because of
+questions such as what should the uid be when the packet is
+sent over broadcast media, or when fragmentation occurs. If a user
+wants to trace actual packet counts, he or she should look at
+e.g. the IP ID field or transport sequence numbers, or other packet
+or frame counters at other protocol layers.
+
+We mentioned above that it is possible to create packets with zero-filled
+payloads that do not actually require a memory allocation (i.e.,
+the packet may behave, when delays such as serialization or transmission
+delays are computed, to have a certain number of payload bytes, but
+the bytes will only be allocated on-demand when needed). The command to do
+this is, when the packet
+is created:
+@verbatim
+ Ptr<Packet> pkt = Create<Packet> (N);
@end verbatim
+where N is a positive integer.
+
+The packet now has a size of N bytes, which can be verified by the GetSize()
+method:
+@verbatim
+ /**
+ * \returns the size in bytes of the packet (including the zero-filled
+ * initial payload)
+ */
+ uint32_t GetSize (void) const;
+@end verbatim
+
+You can also initialize a packet with a character buffer. The input
+data is copied and the input buffer is untouched. The constructor
+applied is:
+@verbatim
+ Packet (uint8_t const *buffer, uint32_t size);
+@end verbatim
+Here is an example:
+@verbatim
+ Ptr<Packet> pkt1 = Create<Packet> (reinterpret_cast<const uint8_t*> ("hello"), 5);
+@end verbatim
+
+Packets are freed when there are no more references to them, as with
+all ns-3 objects referenced by the Ptr class.
@subsection Adding and removing Buffer data
-The below code is reproduced for Header class only; similar functions
-exist for Trailers.
+
+After the initial packet creation (which may possibly create some
+fake initial bytes of payload), all subsequent buffer data is added by adding
+objects of class Header or class Trailer. Note that, even if you are
+in the application layer, handling packets, and want to write application
+data, you write it as an ns3::Header or ns3::Trailer. If you add a Header,
+it is prepended to the packet, and if you add a Trailer, it is added to
+the end of the packet. If you have no data in the packet, then it
+makes no difference whether you add a Header or Trailer. Since the
+APIs and classes for header and trailer are pretty much identical, we'll
+just look at class Header here.
+
+The first step is to create a new header class. All new Header classes
+must inherit from class Header, and implement the following methods:
+@itemize @bullet
+@item @code{Serialize ()}
+@item @code{Deserialize ()}
+@item @code{GetSerializedSize ()}
+@item @code{Print ()}
+@end itemize
+
+To see a simple example of how these are done, look at the UdpHeader
+class headers src/internet-stack/udp-header.cc. There are many other
+examples within the source code.
+
+Once you have a header (or you have a preexisting header), the following
+Packet API can be used to add or remove such headers.
+
@verbatim
- /**
- * Add header to this packet. This method invokes the
- * ns3::Header::serializeTo method to request the header to serialize
- * itself in the packet buffer.
- *
- * \param header a reference to the header to add to this packet.
- */
- void Add (Header const &header);
- /**
- * Deserialize header from this packet. This method invokes the
- * ns3::Header::deserializeFrom method to request the header to deserialize
- * itself from the packet buffer. This method does not remove
- * the data from the buffer. It merely reads it.
- *
- * \param header a reference to the header to deserialize from the buffer
- */
- void Peek (Header &header);
- /**
- * Remove a deserialized header from the internal buffer.
- * This method removes the bytes read by Packet::peek from
- * the packet buffer.
- *
- * \param header a reference to the header to remove from the internal buffer.
- */
- void Remove (Header const &header);
- /**
- * Add trailer to this packet. This method invokes the
- * ns3::Trailer::serializeTo method to request the trailer to serialize
- * itself in the packet buffer.
- *
- * \param trailer a reference to the trailer to add to this packet.
- */
+ /**
+ * Add header to this packet. This method invokes the
+ * Header::GetSerializedSize and Header::Serialize
+ * methods to reserve space in the buffer and request the
+ * header to serialize itself in the packet buffer.
+ *
+ * \param header a reference to the header to add to this packet.
+ */
+ void AddHeader (const Header & header);
+ /**
+ * Deserialize and remove the header from the internal buffer.
+ * This method invokes Header::Deserialize.
+ *
+ * \param header a reference to the header to remove from the internal buffer.
+ * \returns the number of bytes removed from the packet.
+ */
+ uint32_t RemoveHeader (Header &header);
+ /**
+ * Deserialize but does _not_ remove the header from the internal buffer.
+ * This method invokes Header::Deserialize.
+ *
+ * \param header a reference to the header to read from the internal buffer.
+ * \returns the number of bytes read from the packet.
+ */
+ uint32_t PeekHeader (Header &header) const;
+@end verbatim
+
+For instance, here are the typical operations to add and remove a UDP header.
+
+@verbatim
+ // add header
+ Ptr<Packet> packet = Create<Packet> ();
+ UdpHeader udpHeader;
+ // Fill out udpHeader fields appropriately
+ packet->AddHeader (udpHeader);
+ ...
+ // remove header
+ UdpHeader udpHeader;
+ packet->RemoveHeader (udpHeader);
+ // Read udpHeader fields as needed
@end verbatim
@subsection Adding and removing Tags
-@strong{Note: This part of ns-3 will change for ns-3.5; see this mail message:
-http://mailman.isi.edu/pipermail/ns-developers/2009-March/005557.html}
+There is a single base class of Tag that all packet tags must derive from.
+They are used in two different tag lists in the packet; the lists have
+different semantics and different expected use cases.
+
+As the names imply, ByteTags follow bytes and PacketTags follow packets.
+What this means is that when operations are done on packets, such as
+fragmentation, concatenation, and appending or removing headers, the
+byte tags keep track of which packet bytes they cover. For instance,
+if a user creates a TCP segment, and applies a ByteTag to the segment,
+each byte of the TCP segment will be tagged. However, if the next
+layer down inserts an IPv4 header, this ByteTag will not cover those
+bytes. The converse is true for the PacketTag; it covers a packet
+despite the operations on it.
+
+PacketTags are limited in size to 20 bytes. This is a modifiable
+compile-time constant in @code{src/common/packet-tag-list.h}. ByteTags
+have no such restriction.
+Each tag type must subclass @code{ns3::Tag}, and only one instance of
+each Tag type may be in each tag list. Here are a few differences
+in the behavior of packet tags and byte tags.
+@itemize @bullet
+@item @strong{Fragmentation:} As mentioned above, when a packet is fragmented,
+each packet fragment (which is a new packet) will get a copy of all packet
+tags, and byte tags will follow the new packet boundaries (i.e. if the
+fragmented packets fragment across a buffer region covered by the byte
+tag, both packet fragments will still have the appropriate buffer regions
+byte tagged).
+@item @strong{Concatenation:} When packets are combined, two different
+buffer regions will become one. For byte tags, the byte tags simply
+follow the respective buffer regions. For packet tags, only the
+tags on the first packet survive the merge.
+@item @strong{Finding and Printing:} Both classes allow you to iterate
+over all of the tags and print them.
+@item @strong{Removal:} Users can add and remove the same packet tag
+multiple times on a single packet (AddPacketTag () and RemovePacketTag ()).
+The packet However, once a byte tag is added,
+it can only be removed by stripping all byte tags from the packet.
+Removing one of possibly multiple byte tags is not supported by the
+current API.
+@end itemize
+
+As of ns-3.5, Tags are not serialized and deserialized to a buffer when
+@code{Packet::Serialize ()} and @code{Packet::Deserialize ()} are called;
+this is an open bug.
+
+If a user wants to take an existing packet object and reuse it as a new
+packet, he or she should remove all byte tags and packet tags before doing so.
+An example is the UdpEchoServer class, which takes the received packet
+and "turns it around" to send back to the echo client.
+
+The Packet API for byte tags is given below.
@verbatim
/**
* \param tag the new tag to add to this packet
@@ -228,7 +362,7 @@
* Tag each byte included in this packet with the
* new tag.
*
- * Note that adding a tag is a const operation which is pretty
+ * Note that adding a tag is a const operation which is pretty
* un-intuitive. The rationale is that the content and behavior of
* a packet is _not_ changed when a tag is added to a packet: any
* code which was not aware of the new tag is going to work just
@@ -239,217 +373,160 @@
* totally evil to allow a trace sink to modify the content of a
* packet).
*/
- void AddTag (const Tag &tag) const;
+ void AddByteTag (const Tag &tag) const;
/**
- * \returns an iterator over the set of tags included in this packet.
+ * \returns an iterator over the set of byte tags included in this packet.
*/
- TagIterator GetTagIterator (void) const;
+ ByteTagIterator GetByteTagIterator (void) const;
/**
* \param tag the tag to search in this packet
* \returns true if the requested tag type was found, false otherwise.
*
- * If the requested tag type is found, it is copied in the user's
+ * If the requested tag type is found, it is copied in the user's
* provided tag instance.
*/
- bool FindFirstMatchingTag (Tag &tag) const;
-
+ bool FindFirstMatchingByteTag (Tag &tag) const;
+
/**
* Remove all the tags stored in this packet.
*/
- void RemoveAllTags (void);
+ void RemoveAllByteTags (void);
+
+ /**
+ * \param os output stream in which the data should be printed.
+ *
+ * Iterate over the tags present in this packet, and
+ * invoke the Print method of each tag stored in the packet.
+ */
+ void PrintByteTags (std::ostream &os) const;
@end verbatim
-@subsection Fragmentation
+The Packet API for packet tags is given below.
@verbatim
- /**
- * Create a new packet which contains a fragment of the original
- * packet. The returned packet shares the same uid as this packet.
- *
- * \param start offset from start of packet to start of fragment to create
- * \param length length of fragment to create
- * \returns a fragment of the original packet
- */
- Packet CreateFragment (uint32_t start, uint32_t length) const;
-
- /**
- * Concatenate the input packet at the end of the current
- * packet. This does not alter the uid of either packet.
- *
- * \param packet packet to concatenate
- */
- void addAtEnd (Packet packet);
-
- /oncatenate the input packet at the end of the current
- * packet. This does not alter the uid of either packet.
- *
- * \param packet packet to concatenate
- */
- void AddAtEnd (Packet packet);
- /**
- * Concatenate the fragment of the input packet identified
- * by the offset and size parameters at the end of the current
- * packet. This does not alter the uid of either packet.
- *
- * \param packet to concatenate
- * \param offset offset of fragment to copy from the start of the input packet
- * \param size size of fragment of input packet to copy.
- */
- void AddAtEnd (Packet packet, uint32_t offset, uint32_t size);
- /**
- * Remove size bytes from the end of the current packet
- * It is safe to remove more bytes that what is present in
- * the packet.
- *
- * \param size number of bytes from remove
- */
- void RemoveAtEnd (uint32_t size);
- /**
- * Remove size bytes from the start of the current packet.
- * It is safe to remove more bytes that what is present in
- * the packet.
- *
- * \param size number of bytes from remove
- */
- void RemoveAtStart (uint32_t size);
-@end verbatim
-
-@subsection Miscellaneous
-@verbatim
- /**
- * \returns the size in bytes of the packet (including the zero-filled
- * initial payload)
- */
- uint32_t GetSize (void) const;
- /**
- * If you try to change the content of the buffer
- * returned by this method, you will die.
- *
- * \returns a pointer to the internal buffer of the packet.
- */
- uint8_t const *PeekData (void) const;
- /**
- * A packet is allocated a new uid when it is created
- * empty or with zero-filled payload.
- *
- * \returns an integer identifier which uniquely
- * identifies this packet.
- */
- uint32_t GetUid (void) const;
+ /**
+ * \param tag the tag to store in this packet
+ *
+ * Add a tag to this packet. This method calls the
+ * Tag::GetSerializedSize and, then, Tag::Serialize.
+ *
+ * Note that this method is const, that is, it does not
+ * modify the state of this packet, which is fairly
+ * un-intuitive.
+ */
+ void AddPacketTag (const Tag &tag) const;
+ /**
+ * \param tag the tag to remove from this packet
+ * \returns true if the requested tag is found, false
+ * otherwise.
+ *
+ * Remove a tag from this packet. This method calls
+ * Tag::Deserialize if the tag is found.
+ */
+ bool RemovePacketTag (Tag &tag);
+ /**
+ * \param tag the tag to search in this packet
+ * \returns true if the requested tag is found, false
+ * otherwise.
+ *
+ * Search a matching tag and call Tag::Deserialize if it is found.
+ */
+ bool PeekPacketTag (Tag &tag) const;
+ /**
+ * Remove all packet tags.
+ */
+ void RemoveAllPacketTags (void);
+
+ /**
+ * \param os the stream in which we want to print data.
+ *
+ * Print the list of 'packet' tags.
+ *
+ * \sa Packet::AddPacketTag, Packet::RemovePacketTag, Packet::PeekPacketTag,
+ * Packet::RemoveAllPacketTags
+ */
+ void PrintPacketTags (std::ostream &os) const;
+
+ /**
+ * \returns an object which can be used to iterate over the list of
+ * packet tags.
+ */
+ PacketTagIterator GetPacketTagIterator (void) const;
@end verbatim
-@section Using Headers
-@emph{walk through an example of adding a UDP header}
-
-@section Using Tags
-@emph{walk through an example of adding a flow ID}
-
-@section Using Fragmentation
-@emph{walk through an example of link-layer fragmentation/reassembly}
-
-@section Sample program
-The below sample program (from @code{ns3/samples/main-packet.cc}) illustrates
-some use of the Packet, Header, and Tag classes.
-
+Here is a simple example illustrating the use of tags from the
+code in @code{src/internet-stack/udp-socket-impl.cc}:
@verbatim
-/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */
-#include "ns3/packet.h"
-#include "ns3/header.h"
-#include <iostream>
+ Ptr<Packet> p; // pointer to a pre-existing packet
+ SocketIpTtlTag tag
+ tag.SetTtl (m_ipMulticastTtl); // Convey the TTL from Udp layer to IP layer
+ p->AddPacketTag (tag);
+@end verbatim
-using namespace ns3;
-
-/* A sample Header implementation
- */
-class MyHeader : public Header {
-public:
- MyHeader ();
- virtual ~MyHeader ();
+This tag is read at the IP layer, then stripped (@code{src/internet-stack/ipv4-l3-protocol.cc}:
+@verbatim
+ uint8_t ttl = m_defaultTtl;
+ SocketIpTtlTag tag;
+ bool found = packet->RemovePacketTag (tag);
+ if (found)
+ {
+ ttl = tag.GetTtl ();
+ }
+@end verbatim
- void SetData (uint16_t data);
- uint16_t GetData (void) const;
-private:
- virtual void PrintTo (std::ostream &os) const;
- virtual void SerializeTo (Buffer::Iterator start) const;
- virtual void DeserializeFrom (Buffer::Iterator start);
- virtual uint32_t GetSerializedSize (void) const;
+@subsection Fragmentation and concatenation
- uint16_t m_data;
-};
+Packets may be fragmented or merged together. For example, to
+fragment a packet @code{p} of 90 bytes into two packets, one containing
+the first 10 bytes and the other containing the remaining 80, one may call the
+following code:
+@verbatim
+ Ptr<Packet> frag0 = p->CreateFragment (0, 10);
+ Ptr<Packet> frag1 = p->CreateFragment (10, 90);
+@end verbatim
+
+As discussed above, the packet tags from @code{p} will follow to both
+packet fragments, and the byte tags will follow the byte ranges as needed.
-MyHeader::MyHeader ()
-{}
-MyHeader::~MyHeader ()
-{}
-void
-MyHeader::PrintTo (std::ostream &os) const
-{
- os << "MyHeader data=" << m_data << std::endl;
-}
-uint32_t
-MyHeader::GetSerializedSize (void) const
-{
- return 2;
-}
-void
-MyHeader::SerializeTo (Buffer::Iterator start) const
-{
- // serialize in head of buffer
- start.WriteHtonU16 (m_data);
-}
-void
-MyHeader::DeserializeFrom (Buffer::Iterator start)
-{
- // deserialize from head of buffer
- m_data = start.ReadNtohU16 ();
-}
+Now, to put them back together:
+@verbatim
+ frag0->AddAtEnd (frag1);
+@end verbatim
+Now frag0 should be equivalent to the original packet @code{p}. If,
+however, there were operations on the fragments before being reassembled
+(such as tag operations or header operations), the new packet will not
+be the same.
+
+@subsection Enabling metadata
+
+We mentioned above that packets, being on-the-wire representations of
+byte buffers, present a problem to print out in a structured way
+unless the printing function has access to the context of the header.
+For instance, consider a tcpdump-like printer that wants to pretty-print
+the contents of a packet.
-void
-MyHeader::SetData (uint16_t data)
-{
- m_data = data;
-}
-uint16_t
-MyHeader::GetData (void) const
-{
- return m_data;
-}
-
-/* A sample Tag implementation
- */
-struct MyTag {
- uint16_t m_streamId;
-};
-
-static TagRegistration<struct MyTag> g_MyTagRegistration ("ns3::MyTag", 0);
-
+To enable this usage, packets may have metadata enabled (disabled by
+default for performance reasons). This class is used by the Packet
+class to record every operation performed on the packet's buffer, and
+provides an implementation of @code{Packet::Print ()} method that uses
+the metadata to analyze the content of the packet's buffer.
-static void
-Receive (Packet p)
-{
- MyHeader my;
- p.Peek (my);
- p.Remove (my);
- std::cout << "received data=" << my.GetData () << std::endl;
- struct MyTag myTag;
- p.PeekTag (myTag);
-}
-
+The metadata is also used to perform extensive sanity checks at runtime
+when performing operations on a Packet. For example, this metadata is
+used to verify that when you remove a header from a packet, this
+same header was actually present at the front of the packet. These
+errors will be detected and will abort the program.
-int main (int argc, char *argv[])
-{
- Packet p;
- MyHeader my;
- my.SetData (2);
- std::cout << "send data=2" << std::endl;
- p.Add (my);
- struct MyTag myTag;
- myTag.m_streamId = 5;
- p.AddTag (myTag);
- Receive (p);
- return 0;
-}
+To enable this operation, users will typically insert one or both
+of these statements at the beginning of their programs:
+@verbatim
+ Packet::EnablePrinting ();
+ Packet::EnableChecking ();
@end verbatim
+@section Sample programs
+
+See @code{samples/main-packet.cc} and @code{samples/main-packet-tag.cc}.
+
@section Implementation details
@subsection Private member variables
@@ -457,13 +534,19 @@
A Packet object's interface provides access to some private
data:
@verbatim
- Buffer m_buffer;
- Tags m_tags;
- uint32_t m_uid;
- static uint32_t m_global_uid;
+ Buffer m_buffer;
+ ByteTagList m_byteTagList;
+ PacketTagList m_packetTagList;
+ PacketMetadata m_metadata;
+ mutable uint32_t m_refCount;
+ static uint32_t m_globalUid;
@end verbatim
-Each Packet has a Buffer and a Tags object, and a 32-bit unique ID (m\_uid).
-A static member variable keeps track of the UIDs allocated. Note
+Each Packet has a Buffer and two Tags lists, a PacketMetadata object,
+and a ref count.
+A static member variable keeps track of the UIDs allocated.
+The actual uid of the packet is stored in the PacketMetadata.
+
+Note
that real network packets do not have a UID; the UID is therefore an
instance of data that normally would be stored as a Tag in the packet.
However, it was felt that a UID is a special case that is so often
@@ -525,6 +608,9 @@
then complete their state-changing operation.
@subsection Tags implementation
+
+(XXX revise me)
+
Tags are implemented by a single pointer which points to the start of a
linked list ofTagData data structures. Each TagData structure points
to the next TagData in the list (its next pointer contains zero to
@@ -562,12 +648,8 @@
};
@end verbatim
-@emph{add description of TagRegistration for printing}
-
@subsection Memory management
-@emph{Describe free list.}
-
@emph{Describe dataless vs. data-full packets.}
@subsection Copy-on-write semantics
@@ -590,21 +672,26 @@
Dirty operations:
@itemize @bullet
-@item Packet::RemoveTag()
-@item Packet::Add()
-@item both versions of ns3::Packet::AddAtEnd()
+@item ns3::Packet::AddHeader
+@item ns3::Packet::AddTrailer
+@item both versions of ns3::Packet::AddAtEnd
+@item ns3::Packet::RemovePacketTag
@end itemize
Non-dirty operations:
@itemize @bullet
-@item Packet::AddTag()
-@item Packet::RemoveAllTags()
-@item Packet::PeekTag()
-@item Packet::Peek()
-@item Packet::Remove()
-@item Packet::CreateFragment()
-@item Packet::RemoveAtStart()
-@item Packet::RemoveAtEnd()
+@item ns3::Packet::AddPacketTag
+@item ns3::Packet::PeekPacketTag
+@item ns3::Packet::RemoveAllPacketTags
+@item ns3::Packet::AddByteTag
+@item ns3::Packet::FindFirstMatchingByteTag
+@item ns3::Packet::RemoveAllByteTags
+@item ns3::Packet::RemoveHeader
+@item ns3::Packet::RemoveTrailer
+@item ns3::Packet::CreateFragment
+@item ns3::Packet::RemoveAtStart
+@item ns3::Packet::RemoveAtEnd
+@item ns3::Packet::CopyData
@end itemize
Dirty operations will always be slower than non-dirty operations,
--- a/doc/manual/routing.texi Fri Jun 05 16:06:25 2009 +0400
+++ b/doc/manual/routing.texi Mon Jun 08 15:12:15 2009 +0400
@@ -2,40 +2,213 @@
@chapter Routing overview
@menu
-* Routing-Overview::
-* Support for multiple routing protocols::
-* Roadmap and Future work::
-* Static routing::
+* Routing architecture::
+* Global centralized routing::
* Unicast routing::
* Multicast routing::
-* Global centralized routing::
-* Global Unicast Routing API::
-* Global Routing Implementation::
-* Optimized Link State Routing (OLSR)::
@end menu
-This chapter describes the overall design of routing in the
-@code{src/internet-stack}
-module, and some details about the routing approachs currently
-implemented.
+ns-3 is intended to support traditional routing approaches and protocols,
+support ports of open source routing implementations, and facilitate research
+into unorthodox routing techniques. The overall routing architecture
+is described below in @ref{Routing architecture}. Users who wish to
+just read about how to configure global routing for wired topologies
+can read @ref{Global centralized routing}. Unicast routing protocols
+are described in @ref{Unicast routing}. Multicast routing is documented in
+@ref{Multicast routing}.
+
+@node Routing architecture
+@section Routing architecture
+
+@float Figure,fig:routing
+@caption{Overview of routing}
+@image{figures/routing, 6in}
+@end float
+
+Figure 11-1 shows the overall routing architecture for Ipv4. The key objects
+are Ipv4L3Protocol, Ipv4RoutingProtocol(s) (a class to which all
+routing/forwarding has been delegated from Ipv4L3Protocol), and Ipv4Route(s).
+
+Ipv4L3Protocol must have at least one Ipv4RoutingProtocol added to
+it at simulation setup time. This is done explicitly by calling
+Ipv4::SetRoutingProtocol ().
+
+The abstract base class Ipv4RoutingProtocol () declares a minimal interface,
+consisting of two methods: RouteOutput () and RouteInput ().
+For packets traveling outbound from a host, the transport protocol will query
+Ipv4 for the Ipv4RoutingProtocol object interface, and will request
+a route via Ipv4RoutingProtocol::RouteOutput ().
+A Ptr to Ipv4Route object is returned. This is analagous to a
+dst_cache entry in Linux. The Ipv4Route is carried down to the
+Ipv4L3Protocol to avoid a second lookup there. However, some
+cases (e.g. Ipv4 raw sockets) will require a call to RouteOutput()
+directly from Ipv4L3Protocol.
-@node Routing-Overview
-@section Overview
+For packets received inbound for forwarding or delivery,
+the following steps occur. Ipv4L3Protocol::Receive() calls
+Ipv4RoutingProtocol::RouteInput().
+This passes the packet ownership to the Ipv4RoutingProtocol object. There
+are four callbacks associated with this call:
+@itemize @bullet
+@item LocalDeliver
+@item UnicastForward
+@item MulticastForward
+@item Error
+@end itemize
+The Ipv4RoutingProtocol must eventually call one of these callbacks for each
+packet that it takes responsibility for. This is basically
+how the input routing process works in Linux.
+
+@float Figure,fig:routing-specialization
+@caption{Ipv4Routing specialization}
+@image{figures/routing-specialization, 5in}
+@end float
+
+This overall architecture is designed to support different routing
+approaches, including (in the future) a Linux-like policy-based routing
+implementation, proactive and on-demand routing protocols, and simple
+routing protocols for when the simulation user does not really care
+about routing.
+
+@ref{fig:routing-specialization} illustrates how multiple routing protocols
+derive from this base class. A class Ipv4ListRouting
+(implementation class Ipv4ListRoutingImpl) provides the existing
+list routing approach in ns-3. Its API is the same as base class
+Ipv4Routing except for the ability to add multiple prioritized routing
+protocols
+(Ipv4ListRouting::AddRoutingProtocol(), Ipv4ListRouting::GetRoutingProtocol()).
+
+The details of these routing protocols are described below in
+@ref{Unicast routing}. For now, we will first start with a basic
+unicast routing capability that is intended to globally build routing
+tables at simulation time t=0 for simulation users who do not care
+about dynamic routing.
+
+@node Global centralized routing
+@section Global centralized routing
+
+Global centralized routing is sometimes called ''God'' routing; it
+is a special implementation that walks the simulation topology and
+runs a shortest path algorithm, and populates each node's routing
+tables. No actual protocol overhead (on the simulated links) is incurred
+with this approach. It does have a few constraints:
+
+@itemize @bullet
+@item @strong{Wired only:} It is not intended for use in wireless networks.
+@item @strong{Unicast only:} It does not do multicast.
+@item @strong{Scalability:} Some users of this on large topologies
+(e.g. 1000 nodes)
+have noticed that the current implementation is not very scalable.
+The global centralized routing will be modified in the future to
+reduce computations and runtime performance.
+@end itemize
+
+Presently, global centralized IPv4 unicast routing over both
+point-to-point and shared (CSMA) links is supported.
+
+@subsection Global Unicast Routing API
-We intend to support traditional routing approaches and protocols,
-ports of open source routing implementations, and facilitate research
-into unorthodox routing techniques.
-For simulations that are not primarily focused on routing and that
-simply want correct routing tables to occur somehow, we have an
-global centralized routing capability. A singleton object
-(GlobalRouteManager) be instantiated, builds a network map, and
-populates a forwarding table on each node at time t=0 in the
-simulation. Simulation script writers can use the same node
-API to manually enter routes as well.
+The public API is very minimal. User scripts include the following:
+@verbatim
+#include "ns3/global-route-manager.h"
+@end verbatim
+
+After IP addresses are configured, the following function call will
+cause all of the nodes that have an Ipv4 interface to receive
+forwarding tables entered automatically by the GlobalRouteManager:
+@verbatim
+ GlobalRouteManager::PopulateRoutingTables ();
+@end verbatim
+
+@emph{Note:} A reminder that the wifi NetDevice will work but does not
+take any wireless effects into account. For wireless, we recommend
+OLSR dynamic routing described below.
+
+It is possible to call this function again in the midst of a simulation
+using the following additional public function:
+@verbatim
+ GlobalRouteManager::RecomputeRoutingTables ();
+@end verbatim
+which flushes the old tables, queries the nodes for new interface information,
+and rebuilds the routes.
+
+For instance, this scheduling call will cause the tables to be rebuilt
+at time 5 seconds:
+@verbatim
+ Simulator::Schedule (Seconds (5),&GlobalRouteManager::RecomputeRoutingTables);
+@end verbatim
+
+@subsection Global Routing Implementation
+
+This section is for those readers who care about how this is implemented.
+A singleton object (GlobalRouteManager) is responsible for populating
+the static routes on each node, using the public Ipv4 API of that node.
+It queries each node in the topology for a "globalRouter" interface.
+If found, it uses the API of that interface to obtain a "link state
+advertisement (LSA)" for the router. Link State Advertisements
+are used in OSPF routing, and we follow their formatting.
+
+The GlobalRouteManager populates a link state database with LSAs
+gathered from the entire topology. Then, for each router in the topology,
+the GlobalRouteManager executes the OSPF shortest path first (SPF)
+computation on the database, and populates the routing tables on each
+node.
-@node Support for multiple routing protocols
-@section Support for multiple routing protocols
+The quagga (http://www.quagga.net) OSPF implementation was used as the
+basis for the routing computation logic.
+One benefit of following an existing OSPF SPF implementation is that
+OSPF already has defined link state advertisements for all common
+types of network links:
+@itemize @bullet
+@item point-to-point (serial links)
+@item point-to-multipoint (Frame Relay, ad hoc wireless)
+@item non-broadcast multiple access (ATM)
+@item broadcast (Ethernet)
+@end itemize
+Therefore, we think that enabling these other link types will be more
+straightforward now that the underlying OSPF SPF framework is in place.
+
+Presently, we can handle IPv4 point-to-point, numbered links, as well
+as shared broadcast (CSMA) links, and we do not do equal-cost multipath.
+The GlobalRouteManager first walks the list of nodes and aggregates
+a GlobalRouter interface to each one as follows:
+@verbatim
+ typedef std::vector < Ptr<Node> >::iterator Iterator;
+ for (Iterator i = NodeList::Begin (); i != NodeList::End (); i++)
+ {
+ Ptr<Node> node = *i;
+ Ptr<GlobalRouter> globalRouter = CreateObject<GlobalRouter> (node);
+ node->AggregateObject (globalRouter);
+ }
+@end verbatim
+
+This interface is later queried and used to generate a Link State
+Advertisement for each router, and this link state database is
+fed into the OSPF shortest path computation logic. The Ipv4 API
+is finally used to populate the routes themselves.
+
+@node Unicast routing
+@section Unicast routing
+
+There are presently four routing protocols defined:
+@itemize @bullet
+@item class Ipv4StaticRouting (covering both unicast and multicast)
+@item Optimized Link State Routing (a MANET protocol defined in
+@uref{http://www.ietf.org/rfc/rfc3626.txt,,RFC 3626})
+@item class Ipv4ListRouting (used to store a prioritized list of routing
+protocols)
+@item class Ipv4GlobalRouting (used to store routes computed by the global
+route manager, if that is used)
+@end itemize
+
+In the future, this architecture should also allow someone to implement
+a Linux-like implementation with routing cache, or a Click modular
+router, but those are out of scope for now.
+
+@subsection Ipv4ListRouting
+
+This section describes the current default ns-3 Ipv4RoutingProtocol.
Typically, multiple routing protocols are supported in user space and
coordinate to write a single forwarding table in the kernel. Presently
in @command{ns-3}, the implementation instead allows for multiple routing
@@ -50,163 +223,54 @@
routing) is used to determine the next hop, and on-demand
routing approaches where packets must be cached.
-There are presently two routing protocols defined:
-@itemize @bullet
-@item class Ipv4StaticRouting (covering both unicast and multicast)
-@item Optimized Link State Routing (a MANET protocol defined in
-@uref{http://www.ietf.org/rfc/rfc3626.txt,,RFC 3626})
-@end itemize
-but first we describe how multiple routing protocols are supported.
-
-@subsection class Ipv4RoutingProtocol
-
-@code{class Ipv4RoutingProtocol} derives from ns-3 Object which means
-that it supports interface aggregation and reference counting. Routing
-protocols should inherit from this class, defined in src/node/ipv4.cc.
+@subsubsection Ipv4ListRouting::AddRoutingProtocol
-The main function that must be supported by these protocols is called
-@code{RequestRoute}.
-@verbatim
- * This method is called whenever a node's IPv4 forwarding engine
- * needs to lookup a route for a given packet and IP header.
- *
- * The routing protocol implementation may determine immediately it
- * should not be handling this particular the route request. For
- * instance, a routing protocol may decline to search for routes for
- * certain classes of addresses, like link-local. In this case,
- * RequestRoute() should return false and the routeReply callback
- * must not be invoked.
- *
- * If the routing protocol implementations assumes it can provide
- * the requested route, then it should return true, and the
- * routeReply callback must be invoked, either immediately before
- * returning true (synchronously), or in the future (asynchronous).
- * The routing protocol may use any information available in the IP
- * header and packet as routing key, although most routing protocols
- * use only the destination address (as given by
- * ipHeader.GetDestination ()). The routing protocol is also
- * allowed to add a new header to the packet, which will appear
- * immediately after the IP header, although most routing do not
- * insert any extra header.
- */
- virtual bool RequestRoute (uint32_t interface,
- const Ipv4Header &ipHeader,
- Ptr<Packet> packet,
- RouteReplyCallback routeReply) = 0;
-@end verbatim
-
-This class also provides a typedef (used above) for a special Callback
-that will pass to the callback function the Ipv4Route that is found (see the
-Doxygen documentation):
-@verbatim
- typedef Callback<void, bool, const Ipv4Route&, Ptr<Packet>, const Ipv4Header&> RouteReplyCallback;
-@end verbatim
-
-@subsection Ipv4::AddRoutingProtocol
-
-Class Ipv4 provides a pure virtual function declaration for the
+Class Ipv4ListRouting provides a pure virtual function declaration for the
method that allows one to add a routing protocol:
@verbatim
void AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
int16_t priority);
@end verbatim
-This method is implemented by class Ipv4L3Protocol in the internet-stack
+This method is implemented by class Ipv4ListRoutingImpl in the internet-stack
module.
The priority variable above governs the priority in which the routing
protocols are inserted. Notice that it is a signed int.
-When the class Ipv4L3Protocol is instantiated, a single routing
-protocol (Ipv4StaticRouting, introduced below) is added at priority
-zero. Internally, a list of Ipv4RoutingProtocols is stored, and
+By default in ns-3, the helper classes will instantiate a Ipv4ListRoutingImpl
+object, and add to it an Ipv4StaticRoutingImpl object at priority zero.
+Internally, a list of Ipv4RoutingProtocols is stored, and
and the routing protocols are each consulted in decreasing order
of priority to see whether a match is found. Therefore, if you
want your Ipv4RoutingProtocol to have priority lower than the static
routing, insert it with priority less than 0; e.g.:
@verbatim
- m_ipv4->AddRoutingProtocol (m_routingTable, -10);
-@end verbatim
-
-@subsection Ipv4L3Protocol::Lookup
-
-The main function for obtaining a route is shown below:
-@verbatim
-Ipv4L3Protocol::Lookup (
- uint32_t interface,
- Ipv4Header const &ipHeader,
- Ptr<Packet> packet,
- Ipv4RoutingProtocol::RouteReplyCallback routeReply)
-@end verbatim
-
-This function will search the list of routing protocols, in priority order,
-until a route is found. It will then invoke the RouteReplyCallback
-and no further routing protocols will be searched. If the caller does
-not want to constrain the possible interface, it can be wildcarded
-as such:
-@verbatim
- Lookup (Ipv4RoutingProtocol::IF_INDEX_ANY, ipHeader, packet, routeReply);
+ Ptr<MyRoutingProtocol> myRoutingProto = CreateObject<MyRoutingProtocol> ();
+ listRoutingPtr->AddRoutingProtocol (myRoutingProto, -10);
@end verbatim
-@node Roadmap and Future work
-@section Roadmap and Future work
+Upon calls to RouteOutput() or RouteInput(), the list routing object will
+search the list of routing protocols, in priority order, until a route
+is found. Such routing protocol will invoke the appropriate callback
+and no further routing protocols will be searched.
+
+@subsection Optimized Link State Routing (OLSR)
-Some goals for future support are:
+This is the first dynamic routing protocol for @command{ns-3}. The implementation
+is found in the src/routing/olsr directory, and an example script is in
+examples/simple-point-to-point-olsr.cc.
-Users should be able to trace (either debug print, or redirect to a trace
-file) the routing table in a format such as used in an
-Unix implementation:
+The following commands will enable OLSR in a simulation.
+
@verbatim
-# netstat -nr (or # route -n)
-Kernel IP routing table
-Destination Gateway Genmask Flags MSS Window irtt Iface
-127.0.0.1 * 255.255.255.255 UH 0 0 0 lo
-172.16.1.0 * 255.255.255.0 U 0 0 0 eth0
-172.16.2.0 172.16.1.1 255.255.255.0 UG 0 0 0 eth0
-
-# ip route show
-192.168.99.0/24 dev eth0 scope link
-127.0.0.0/8 dev lo scope link
-default via 192.168.99.254 dev eth0
+ olsr::EnableAllNodes (); // Start OLSR on all nodes
+ olsr::EnableNodes(InputIterator begin, InputIterator end); // Start on
+ // a list of nodes
+ olsr::EnableNode (Ptr<Node> node); // Start OLSR on "node" only
@end verbatim
-Global computation of multicast routing should be implemented as well.
-This would ignore group membership and ensure that a copy of every
-sourced multicast datagram would be delivered to each node.
-This might be implemented as an RPF mechanism that functioned on-demand
-by querying the forwarding table,
-and perhaps optimized by a small multicast forwarding cache. It is
-a bit trickier to implement over wireless links where the input
-interface is the same as the output interface; other aspects of the
-packet must be considered and the forwarding logic slightly changed
-to allow for forwarding out the same interface.
-
-In the future, work on bringing XORP or quagga routing to ns, but it will
-take several months to port and enable.
-
-There are presently no roadmap plans for IPv6.
-
-@node Static routing
-@section Static routing
-
-The internet-stack module provides one routing protocol (Ipv4StaticRouting)
-by default. This routing protocol allows one to add unicast or multicast
-static routes to a node.
-
-@node Unicast routing
-@section Unicast routing
-
-The unicast static routing API may be accessed via the functions
-@verbatim
-void Ipv4::AddHostRouteTo ()
-void Ipv4::AddNetworkRouteTo ()
-void Ipv4::SetDefaultRoute ()
-uint32_t Ipv4::GetNRoutes ()
-Ipv4Route Ipv4::GetRoute ()
-@end verbatim
-
-@uref{http://www.nsnam.org/doxygen/index.html,,Doxygen} documentation
-provides full documentation of these methods. These methods are forwarding
-functions to the actual implementation in Ipv4StaticRouting, when using
-the internet-stack module.
+Once instantiated, the agent can be started with the Start() command,
+and the OLSR "main interface" can be set with the SetMainInterface()
+command. A number of protocol constants are defined in olsr-agent-impl.cc.
@node Multicast routing
@section Multicast routing
@@ -288,113 +352,4 @@
void RemoveMulticastRoute (uint32_t index);
@end verbatim
-@node Global centralized routing
-@section Global centralized routing
-Presently, global centralized IPv4 @emph{unicast} routing over both
-point-to-point and shared (CSMA) links is supported.
-The global centralized routing will be modified in the future to
-reduce computations once profiling finds the performance bottlenecks.
-
-@node Global Unicast Routing API
-@section Global Unicast Routing API
-
-The public API is very minimal. User scripts include the following:
-@verbatim
-#include "ns3/global-route-manager.h"
-@end verbatim
-
-After IP addresses are configured, the following function call will
-cause all of the nodes that have an Ipv4 interface to receive
-forwarding tables entered automatically by the GlobalRouteManager:
-@verbatim
- GlobalRouteManager::PopulateRoutingTables ();
-@end verbatim
-
-@emph{Note:} A reminder that the wifi NetDevice is not yet supported
-(only CSMA and PointToPoint).
-
-It is possible to call this function again in the midst of a simulation
-using the following additional public function:
-@verbatim
- GlobalRouteManager::RecomputeRoutingTables ();
-@end verbatim
-which flushes the old tables, queries the nodes for new interface information,
-and rebuilds the routes.
-
-For instance, this scheduling call will cause the tables to be rebuilt
-at time 5 seconds:
-@verbatim
- Simulator::Schedule (Seconds (5),&GlobalRouteManager::RecomputeRoutingTables);
-@end verbatim
-
-@node Global Routing Implementation
-@section Global Routing Implementation
-
-A singleton object (GlobalRouteManager) is responsible for populating
-the static routes on each node, using the public Ipv4 API of that node.
-It queries each node in the topology for a "globalRouter" interface.
-If found, it uses the API of that interface to obtain a "link state
-advertisement (LSA)" for the router. Link State Advertisements
-are used in OSPF routing, and we follow their formatting.
-
-The GlobalRouteManager populates a link state database with LSAs
-gathered from the entire topology. Then, for each router in the topology,
-the GlobalRouteManager executes the OSPF shortest path first (SPF)
-computation on the database, and populates the routing tables on each
-node.
-
-The quagga (http://www.quagga.net) OSPF implementation was used as the
-basis for the routing computation logic.
-One benefit of following an existing OSPF SPF implementation is that
-OSPF already has defined link state advertisements for all common
-types of network links:
-@itemize @bullet
-@item point-to-point (serial links)
-@item point-to-multipoint (Frame Relay, ad hoc wireless)
-@item non-broadcast multiple access (ATM)
-@item broadcast (Ethernet)
-@end itemize
-Therefore, we think that enabling these other link types will be more
-straightforward now that the underlying OSPF SPF framework is in place.
-
-Presently, we can handle IPv4 point-to-point, numbered links, as well
-as shared broadcast (CSMA) links, and we do not do equal-cost multipath.
-
-The GlobalRouteManager first walks the list of nodes and aggregates
-a GlobalRouter interface to each one as follows:
-@verbatim
- typedef std::vector < Ptr<Node> >::iterator Iterator;
- for (Iterator i = NodeList::Begin (); i != NodeList::End (); i++)
- {
- Ptr<Node> node = *i;
- Ptr<GlobalRouter> globalRouter = CreateObject<GlobalRouter> (node);
- node->AggregateObject (globalRouter);
- }
-@end verbatim
-
-This interface is later queried and used to generate a Link State
-Advertisement for each router, and this link state database is
-fed into the OSPF shortest path computation logic. The Ipv4 API
-is finally used to populate the routes themselves.
-
-@node Optimized Link State Routing (OLSR)
-@section Optimized Link State Routing (OLSR)
-
-This is the first dynamic routing protocol for @command{ns-3}. The implementation
-is found in the src/routing/olsr directory, and an example script is in
-examples/simple-point-to-point-olsr.cc.
-
-The following commands will enable OLSR in a simulation.
-
-@verbatim
- olsr::EnableAllNodes (); // Start OLSR on all nodes
- olsr::EnableNodes(InputIterator begin, InputIterator end); // Start on
- // a list of nodes
- olsr::EnableNode (Ptr<Node> node); // Start OLSR on "node" only
-@end verbatim
-
-Once instantiated, the agent can be started with the Start() command,
-and the OLSR "main interface" can be set with the SetMainInterface()
-command. A number of protocol constants are defined in olsr-agent-impl.cc.
-
--- a/examples/mixed-wireless.cc Fri Jun 05 16:06:25 2009 +0400
+++ b/examples/mixed-wireless.cc Mon Jun 08 15:12:15 2009 +0400
@@ -392,9 +392,9 @@
// Let's do a pcap trace on the application source and sink, ifIndex 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);
+ wifiPhy.EnablePcap ("mixed-wireless", appSink->GetId (), 0);
+ wifiPhy.EnablePcap ("mixed-wireless", 9, 2);
+ wifiPhy.EnablePcap ("mixed-wireless", 9, 0);
}
if (useCourseChangeCallback == true)
--- a/examples/object-names.cc Fri Jun 05 16:06:25 2009 +0400
+++ b/examples/object-names.cc Mon Jun 08 15:12:15 2009 +0400
@@ -151,7 +151,7 @@
// prefix is always required since the _Config_ system always expects to
// see a fully qualified path name
//
- Config::Connect ("/Names/client/eth0/Rx", MakeCallback (&RxEvent));
+ Config::Connect ("/Names/client/eth0/MacRx", MakeCallback (&RxEvent));
Simulator::Run ();
Simulator::Destroy ();
--- a/examples/simple-wifi-frame-aggregation.cc Fri Jun 05 16:06:25 2009 +0400
+++ b/examples/simple-wifi-frame-aggregation.cc Mon Jun 08 15:12:15 2009 +0400
@@ -141,7 +141,7 @@
Simulator::Stop (Seconds (10.0));
- YansWifiPhyHelper::EnablePcap ("test-802.11n",
+ phy.EnablePcap ("test-802.11n",
wifiNodes.Get (nWifi - 1)->GetId (), 0);
Simulator::Run ();
--- a/examples/third.cc Fri Jun 05 16:06:25 2009 +0400
+++ b/examples/third.cc Mon Jun 08 15:12:15 2009 +0400
@@ -164,7 +164,7 @@
Simulator::Stop (Seconds (10.0));
PointToPointHelper::EnablePcapAll ("third");
- YansWifiPhyHelper::EnablePcap ("third", apDevices.Get (0));
+ phy.EnablePcap ("third", apDevices.Get (0));
CsmaHelper::EnablePcap ("third", csmaDevices.Get (0), true);
Simulator::Run ();
--- a/examples/wifi-wired-bridging.cc Fri Jun 05 16:06:25 2009 +0400
+++ b/examples/wifi-wired-bridging.cc Mon Jun 08 15:12:15 2009 +0400
@@ -89,6 +89,10 @@
backboneDevices = csma.Install (backboneNodes);
double wifiX = 0.0;
+
+ YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
+ wifiPhy.SetPcapFormat(YansWifiPhyHelper::PCAP_FORMAT_80211_RADIOTAP);
+
for (uint32_t i = 0; i < nWifis; ++i)
{
// calculate ssid for wifi subnetwork
@@ -105,7 +109,6 @@
BridgeHelper bridge;
WifiHelper wifi = WifiHelper::Default ();
NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
- YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
wifiPhy.SetChannel (wifiChannel.Create ());
@@ -182,8 +185,8 @@
apps.Start (Seconds (0.5));
apps.Stop (Seconds (3.0));
- YansWifiPhyHelper::EnablePcap ("wifi-wired-bridging", apDevices[0]);
- YansWifiPhyHelper::EnablePcap ("wifi-wired-bridging", apDevices[1]);
+ wifiPhy.EnablePcap ("wifi-wired-bridging", apDevices[0]);
+ wifiPhy.EnablePcap ("wifi-wired-bridging", apDevices[1]);
std::ofstream os;
os.open ("wifi-wired-bridging.mob");
--- a/samples/wscript Fri Jun 05 16:06:25 2009 +0400
+++ b/samples/wscript Mon Jun 08 15:12:15 2009 +0400
@@ -10,6 +10,9 @@
obj = bld.create_ns3_program('main-simulator')
obj.source = 'main-simulator.cc'
+ obj = bld.create_ns3_program('main-ptr')
+ obj.source = 'main-ptr.cc'
+
obj = bld.create_ns3_program('main-random-variable')
obj.source = 'main-random-variable.cc'
--- a/src/applications/udp-echo/udp-echo-server.cc Fri Jun 05 16:06:25 2009 +0400
+++ b/src/applications/udp-echo/udp-echo-server.cc Mon Jun 08 15:12:15 2009 +0400
@@ -125,6 +125,7 @@
address.GetIpv4());
packet->RemoveAllPacketTags ();
+ packet->RemoveAllByteTags ();
NS_LOG_LOGIC ("Echoing packet");
socket->SendTo (packet, 0, from);
--- a/src/common/packet.cc Fri Jun 05 16:06:25 2009 +0400
+++ b/src/common/packet.cc Mon Jun 08 15:12:15 2009 +0400
@@ -218,8 +218,8 @@
void
Packet::AddHeader (const Header &header)
{
- NS_LOG_FUNCTION (this << &header);
uint32_t size = header.GetSerializedSize ();
+ NS_LOG_FUNCTION (this << header.GetInstanceTypeId ().GetName () << size);
uint32_t orgStart = m_buffer.GetCurrentStartOffset ();
bool resized = m_buffer.AddAtStart (size);
if (resized)
@@ -233,8 +233,8 @@
uint32_t
Packet::RemoveHeader (Header &header)
{
- NS_LOG_FUNCTION (this << &header);
uint32_t deserialized = header.Deserialize (m_buffer.Begin ());
+ NS_LOG_FUNCTION (this << header.GetInstanceTypeId ().GetName () << deserialized);
m_buffer.RemoveAtStart (deserialized);
m_metadata.RemoveHeader (header, deserialized);
return deserialized;
@@ -242,15 +242,15 @@
uint32_t
Packet::PeekHeader (Header &header) const
{
- NS_LOG_FUNCTION (this << &header);
uint32_t deserialized = header.Deserialize (m_buffer.Begin ());
+ NS_LOG_FUNCTION (this << header.GetInstanceTypeId ().GetName () << deserialized);
return deserialized;
}
void
Packet::AddTrailer (const Trailer &trailer)
{
- NS_LOG_FUNCTION (this << &trailer);
uint32_t size = trailer.GetSerializedSize ();
+ NS_LOG_FUNCTION (this << trailer.GetInstanceTypeId ().GetName () << size);
uint32_t orgStart = m_buffer.GetCurrentStartOffset ();
bool resized = m_buffer.AddAtEnd (size);
if (resized)
@@ -265,8 +265,8 @@
uint32_t
Packet::RemoveTrailer (Trailer &trailer)
{
- NS_LOG_FUNCTION (this << &trailer);
uint32_t deserialized = trailer.Deserialize (m_buffer.End ());
+ NS_LOG_FUNCTION (this << trailer.GetInstanceTypeId ().GetName () << deserialized);
m_buffer.RemoveAtEnd (deserialized);
m_metadata.RemoveTrailer (trailer, deserialized);
return deserialized;
@@ -274,15 +274,15 @@
uint32_t
Packet::PeekTrailer (Trailer &trailer)
{
- NS_LOG_FUNCTION (this << &trailer);
uint32_t deserialized = trailer.Deserialize (m_buffer.End ());
+ NS_LOG_FUNCTION (this << trailer.GetInstanceTypeId ().GetName () << deserialized);
return deserialized;
}
void
Packet::AddAtEnd (Ptr<const Packet> packet)
{
- NS_LOG_FUNCTION (this << packet);
+ NS_LOG_FUNCTION (this << packet << packet->GetSize ());
uint32_t aStart = m_buffer.GetCurrentStartOffset ();
uint32_t bEnd = packet->m_buffer.GetCurrentEndOffset ();
m_buffer.AddAtEnd (packet->m_buffer);
@@ -333,7 +333,14 @@
uint8_t const *
Packet::PeekData (void) const
{
- return m_buffer.PeekData ();
+ NS_LOG_FUNCTION (this);
+ uint32_t oldStart = m_buffer.GetCurrentStartOffset ();
+ uint8_t const * data = m_buffer.PeekData ();
+ uint32_t newStart = m_buffer.GetCurrentStartOffset ();
+
+ // Update tag offsets if buffer offsets were changed
+ const_cast<ByteTagList &>(m_byteTagList).AddAtStart (newStart - oldStart, newStart);
+ return data;
}
uint32_t
@@ -579,7 +586,7 @@
void
Packet::AddByteTag (const Tag &tag) const
{
- NS_LOG_FUNCTION (this << &tag);
+ NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ().GetName () << tag.GetSerializedSize ());
ByteTagList *list = const_cast<ByteTagList *> (&m_byteTagList);
TagBuffer buffer = list->Add (tag.GetInstanceTypeId (), tag.GetSerializedSize (),
m_buffer.GetCurrentStartOffset (),
@@ -612,11 +619,13 @@
void
Packet::AddPacketTag (const Tag &tag) const
{
+ NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ().GetName () << tag.GetSerializedSize ());
m_packetTagList.Add (tag);
}
bool
Packet::RemovePacketTag (Tag &tag)
{
+ NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ().GetName () << tag.GetSerializedSize ());
bool found = m_packetTagList.Remove (tag);
return found;
}
@@ -629,6 +638,7 @@
void
Packet::RemoveAllPacketTags (void)
{
+ NS_LOG_FUNCTION (this);
m_packetTagList.RemoveAll ();
}
@@ -1073,6 +1083,19 @@
NS_TEST_ASSERT (!p.PeekPacketTag (b));
}
+ {
+ // bug 572
+ Ptr<Packet> tmp = Create<Packet> (1000);
+ tmp->AddByteTag (ATestTag<20> ());
+ CHECK (tmp, 1, E (20, 0, 1000));
+ tmp->AddHeader (ATestHeader<2> ());
+ CHECK (tmp, 1, E (20, 2, 1002));
+ tmp->RemoveAtStart (1);
+ CHECK (tmp, 1, E (20, 1, 1001));
+ tmp->PeekData ();
+ CHECK (tmp, 1, E (20, 1, 1001));
+ }
+
return result;
}
--- a/src/common/packet.h Fri Jun 05 16:06:25 2009 +0400
+++ b/src/common/packet.h Mon Jun 08 15:12:15 2009 +0400
@@ -166,8 +166,10 @@
* - The metadata describes the type of the headers and trailers which
* were serialized in the byte buffer. The maintenance of metadata is
* optional and disabled by default. To enable it, you must call
- * Packet::EnableMetadata and this will allow you to get non-empty
- * output from Packet::Print and Packet::Print.
+ * Packet::EnablePrinting and this will allow you to get non-empty
+ * output from Packet::Print and Packet::Print. If you wish to only enable
+ * checking of metadata, and do not need any printing capability, you can
+ * call Packet::EnableChecking: its runtime cost is lower than Packet::EnablePrinting.
*
* - The set of tags contain simulation-specific information which cannot
* be stored in the packet byte buffer because the protocol headers or trailers
@@ -176,9 +178,14 @@
* while 'packet' tags are used to tag the packet itself. The main difference
* between these two kinds of tags is what happens when packets are copied,
* fragmented, and reassembled: 'byte' tags follow bytes while 'packet' tags
- * follow packets. A classic example of a 'byte' tag is a FlowIdTag
- * which contains a flow id: the set of bytes tagged by this tag implicitely
- * belong to the attached flow id.
+ * follow packets. Another important difference between these two kinds of tags
+ * is that byte tags cannot be removed and are expected to be written once,
+ * and read many times, while packet tags are expected to be written once,
+ * read many times, and removed exactly once. An example of a 'byte'
+ * tag is a FlowIdTag which contains a flow id and is set by the application
+ * generating traffic. An example of a 'packet' tag is a cross-layer
+ * qos class id set by an application and processed by a lower-level MAC
+ * layer.
*
* Implementing a new type of Header or Trailer for a new protocol is
* pretty easy and is a matter of creating a subclass of the ns3::Header
@@ -471,8 +478,6 @@
* Note that this method is const, that is, it does not
* modify the state of this packet, which is fairly
* un-intuitive.
- *
- * \sa AddTag
*/
void AddPacketTag (const Tag &tag) const;
/**
@@ -546,11 +551,12 @@
* - ns3::Packet::RemovePacketTag
*
* Non-dirty operations:
- * - ns3::Packet::AddTag
- * - ns3::Packet::RemoveAllTags
- * - ns3::Packet::PeekTag
+ * - ns3::Packet::AddPacketTag
+ * - ns3::Packet::PeekPacketTag
* - ns3::Packet::RemoveAllPacketTags
- * - ns3::Packet::PeekPacketTag
+ * - ns3::Packet::AddByteTag
+ * - ns3::Packet::FindFirstMatchingByteTag
+ * - ns3::Packet::RemoveAllByteTags
* - ns3::Packet::RemoveHeader
* - ns3::Packet::RemoveTrailer
* - ns3::Packet::CreateFragment
--- a/src/common/pcap-writer.cc Fri Jun 05 16:06:25 2009 +0400
+++ b/src/common/pcap-writer.cc Mon Jun 08 15:12:15 2009 +0400
@@ -41,6 +41,8 @@
PCAP_PPP = 9,
PCAP_RAW_IP = 101,
PCAP_80211 = 105,
+ PCAP_80211_PRISM = 119,
+ PCAP_80211_RADIOTAP = 127,
};
PcapWriter::PcapWriter ()
@@ -115,6 +117,20 @@
WriteHeader (PCAP_80211);
}
+void
+PcapWriter::WriteWifiRadiotapHeader (void)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ WriteHeader (PCAP_80211_RADIOTAP);
+}
+
+void
+PcapWriter::WriteWifiPrismHeader (void)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ WriteHeader (PCAP_80211_PRISM);
+}
+
void
PcapWriter::WritePppHeader (void)
{
@@ -133,6 +149,7 @@
Write32 (0);
Write32 (0xffff);
Write32 (network);
+ m_pcapMode = network;
}
void
@@ -151,12 +168,298 @@
}
}
+
+void PcapWriter::WriteWifiMonitorPacket(Ptr<const Packet> packet, uint16_t channelFreqMhz,
+ uint32_t rate, bool isShortPreamble, bool isTx,
+ double signalDbm, double noiseDbm)
+{
+ NS_LOG_FUNCTION (this << packet->GetSize() << channelFreqMhz << rate << isShortPreamble << isTx << signalDbm << noiseDbm);
+
+ if (m_writer == 0)
+ {
+ return;
+ }
+
+ if (m_pcapMode == PCAP_80211)
+ {
+ WritePacket (packet);
+ return;
+ }
+
+ /* the following is common between PRISM and RADIOTAP */
+
+ uint64_t current = Simulator::Now ().GetMicroSeconds ();
+ uint64_t s = current / 1000000;
+ uint64_t us = current % 1000000;
+ Write32 (s & 0xffffffff);
+ Write32 (us & 0xffffffff);
+
+
+ // MAC timestamp. Actually according to radiotap specifications
+ // (http://www.radiotap.org/defined-fields/TSFT) this should be
+ // the time "when the first bit of the MPDU arrived at the
+ // MAC". This is not exactly what we're doing here, but to handle
+ // this properly we would need to first of all investigate how
+ // real devices (e.g. madwifi) handle this case, especially for TX
+ // packets (radiotap specs says TSFT is not used for TX packets,
+ // but madwifi actually uses it).
+ uint64_t tsft = current;
+
+ if (m_pcapMode == PCAP_80211_PRISM)
+ {
+
+#define PRISM_MSG_CODE 0x00000044
+#define PRISM_MSG_LENGTH 144
+#define PRISM_DID_HOSTTIME 0x00010044
+#define PRISM_DID_MACTIME 0x00020044
+#define PRISM_DID_CHANNEL 0x00030044
+#define PRISM_DID_RSSI 0x00040044
+#define PRISM_DID_SQ 0x00050044
+#define PRISM_DID_SIGNAL 0x00060044
+#define PRISM_DID_NOISE 0x00070044
+#define PRISM_DID_RATE 0x00080044
+#define PRISM_DID_ISTX 0x00090044
+#define PRISM_DID_FRMLEN 0x000A0044
+
+#define PRISM_STATUS_PRESENT 0
+#define PRISM_STATUS_ABSENT 1
+#define PRISM_ITEM_LENGTH 4
+
+
+
+ uint32_t size = packet->GetSize () + PRISM_MSG_LENGTH;
+ Write32 (size); // total packet size
+ Write32 (size); // captured size
+
+ Write32(PRISM_MSG_CODE);
+ Write32(PRISM_MSG_LENGTH);
+ WriteData((const uint8_t *)"unknown wifi device!!!!!!!!", 16);
+
+ Write32(PRISM_DID_HOSTTIME);
+ Write16(PRISM_STATUS_PRESENT);
+ Write16(PRISM_ITEM_LENGTH);
+ // madwifi reports hosttime in jiffies.
+ // We calculate jiffies assuming HZ = 10
+ Write32((uint32_t) (Now ().GetMilliSeconds () / 10 ) );
+
+ Write32(PRISM_DID_MACTIME);
+ Write16(PRISM_STATUS_PRESENT);
+ Write16(PRISM_ITEM_LENGTH);
+ // This looses precision, which is a well-known issue of the prism
+ // header format.
+ Write32((uint32_t) tsft);
+
+ Write32(PRISM_DID_CHANNEL);
+ Write16(PRISM_STATUS_PRESENT);
+ Write16(PRISM_ITEM_LENGTH);
+ // convert from frequency to channel number. This conversion is
+ // correct only for IEEE 802.11b/g channels 1-13.
+ Write32((channelFreqMhz - 2407) / 5);
+
+ Write32(PRISM_DID_RSSI);
+ Write16(PRISM_STATUS_PRESENT);
+ Write16(PRISM_ITEM_LENGTH);
+ // madwifi here reports a value which is said to be "the value in
+ // dBm above noise". Apart from the fact that this is incorrect
+ // (if it is relative to a value in dBm, then it must be in dB,
+ // not in dBm again), this means that in fact it is not a RSSI
+ // (which stands for Received Signal Strength Indicator) but it is
+ // rather a Signal to Noise Ratio (SNR), of course in dB.
+ // Anyway, in the end we calculate the value exactly as madwifi does.
+ Write32((uint32_t)round(signalDbm - noiseDbm));
+
+ // SQ field not used. I would expect a PRISM_STATUS_ABSENT to be
+ // needed here, but if you look at the prism header that madwifi
+ // produces you'll just see that the whole field structure is
+ // zeroed.
+ Write32(0);
+ Write16(0);
+ Write16(0);
+ Write32(0);
+
+ Write32(PRISM_DID_SIGNAL);
+ Write16(PRISM_STATUS_PRESENT);
+ Write16(PRISM_ITEM_LENGTH);
+ Write32((uint32_t)round(signalDbm));
+
+ Write32(PRISM_DID_NOISE);
+ Write16(PRISM_STATUS_PRESENT);
+ Write16(PRISM_ITEM_LENGTH);
+ Write32((uint32_t)round(noiseDbm));
+
+ Write32(PRISM_DID_RATE);
+ Write16(PRISM_STATUS_PRESENT);
+ Write16(PRISM_ITEM_LENGTH);
+ Write32(rate);
+
+ Write32(PRISM_DID_ISTX);
+ Write16(PRISM_STATUS_PRESENT);
+ Write16(PRISM_ITEM_LENGTH);
+ Write32(isTx ? 1 : 0);
+
+ Write32(PRISM_DID_FRMLEN);
+ Write16(PRISM_STATUS_ABSENT);
+ Write16(PRISM_ITEM_LENGTH);
+ Write32(packet->GetSize ());
+
+
+
+ } // PCAP_80211_PRISM
+
+ else if (m_pcapMode == PCAP_80211_RADIOTAP)
+ {
+ NS_LOG_LOGIC("writing radiotap packet");
+
+#define RADIOTAP_TSFT 0x00000001
+#define RADIOTAP_FLAGS 0x00000002
+#define RADIOTAP_RATE 0x00000004
+#define RADIOTAP_CHANNEL 0x00000008
+#define RADIOTAP_FHSS 0x00000010
+#define RADIOTAP_DBM_ANTSIGNAL 0x00000020
+#define RADIOTAP_DBM_ANTNOISE 0x00000040
+#define RADIOTAP_LOCK_QUALITY 0x00000080
+#define RADIOTAP_TX_ATTENUATION 0x00000100
+#define RADIOTAP_DB_TX_ATTENUATION 0x00000200
+#define RADIOTAP_DBM_TX_POWER 0x00000200
+#define RADIOTAP_ANTENNA 0x00000400
+#define RADIOTAP_DB_ANTSIGNAL 0x00000800
+#define RADIOTAP_DB_ANTNOISE 0x00001000
+#define RADIOTAP_EXT 0x10000000
+
+#define RADIOTAP_FLAG_NONE 0x00
+#define RADIOTAP_FLAG_CFP 0x01
+#define RADIOTAP_FLAG_SHORTPRE 0x02
+#define RADIOTAP_FLAG_WEP 0x04
+#define RADIOTAP_FLAG_FRAG 0x08
+#define RADIOTAP_FLAG_FCS 0x10
+#define RADIOTAP_FLAG_DATAPAD 0x20
+#define RADIOTAP_FLAG_BADFCS 0x40
+
+#define RADIOTAP_CHANNEL_TURBO 0x0010
+#define RADIOTAP_CHANNEL_CCK 0x0020
+#define RADIOTAP_CHANNEL_OFDM 0x0040
+#define RADIOTAP_CHANNEL_2GHZ 0x0080
+#define RADIOTAP_CHANNEL_5GHZ 0x0100
+#define RADIOTAP_CHANNEL_PASSIVE 0x0200
+#define RADIOTAP_CHANNEL_DYN 0x0400
+#define RADIOTAP_CHANNEL_GFSK 0x0800
+
+#define RADIOTAP_RX_PRESENT (RADIOTAP_TSFT | RADIOTAP_FLAGS | RADIOTAP_RATE | RADIOTAP_CHANNEL | RADIOTAP_DBM_ANTSIGNAL | RADIOTAP_DBM_ANTNOISE)
+#define RADIOTAP_RX_LENGTH (8+8+1+1+2+2+1+1)
+
+#define RADIOTAP_TX_PRESENT (RADIOTAP_TSFT | RADIOTAP_FLAGS | RADIOTAP_RATE | RADIOTAP_CHANNEL)
+#define RADIOTAP_TX_LENGTH (8+8+1+1+2+2)
+
+ uint32_t size;
+ if (isTx)
+ {
+ size = packet->GetSize () + RADIOTAP_TX_LENGTH;
+ }
+ else
+ {
+ size = packet->GetSize () + RADIOTAP_RX_LENGTH;
+ }
+ Write32 (size); // total packet size
+ Write32 (size); // captured size
+
+ Write8(0); // radiotap version
+ Write8(0); // padding
+
+ if (isTx)
+ {
+ Write16(RADIOTAP_TX_LENGTH);
+ Write32(RADIOTAP_TX_PRESENT);
+ }
+ else
+ {
+ Write16(RADIOTAP_RX_LENGTH);
+ Write32(RADIOTAP_RX_PRESENT);
+ }
+
+ Write64(tsft);
+
+ uint8_t flags = RADIOTAP_FLAG_NONE;
+ if (isShortPreamble)
+ {
+ flags |= RADIOTAP_FLAG_SHORTPRE;
+ }
+ Write8(flags);
+
+
+ Write8(rate);
+
+ Write16((uint16_t) channelFreqMhz);
+
+ // we might want to make this setting depend on the WifiMode and
+ // on the ChannelFrequency at some time in the future. But for now
+ // I think a fixed setting is more than enough for most purposes.
+ Write16(RADIOTAP_CHANNEL_OFDM | RADIOTAP_CHANNEL_2GHZ);
+
+ if (!isTx)
+ {
+
+ Write8 (RoundToInt8 (signalDbm));
+ Write8 (RoundToInt8 (noiseDbm));
+ }
+
+ } // PCAP_80211_RADIOTAP
+
+
+ else
+ {
+ NS_LOG_ERROR("unknown PCAP mode");
+ return;
+ }
+
+ // finally, write rest of packet
+ WriteData (packet->PeekData (), packet->GetSize ());
+}
+
+
+
+
+int8_t
+PcapWriter::RoundToInt8 (double value)
+{
+ if (value < -128)
+ {
+ return -128;
+ }
+ if (value > 127)
+ {
+ return 127;
+ }
+ return ((int8_t) round(value));
+}
+
+
+
+
+
+
void
PcapWriter::WriteData (uint8_t const*buffer, uint32_t size)
{
+ NS_LOG_FUNCTION(this << size);
m_writer->write ((char const *)buffer, size);
}
+
+void
+PcapWriter::Write64 (uint64_t data)
+{
+ uint8_t buffer[8];
+ buffer[0] = (data >> 0) & 0xff;
+ buffer[1] = (data >> 8) & 0xff;
+ buffer[2] = (data >> 16) & 0xff;
+ buffer[3] = (data >> 24) & 0xff;
+ buffer[4] = (data >> 32) & 0xff;
+ buffer[5] = (data >> 40) & 0xff;
+ buffer[6] = (data >> 48) & 0xff;
+ buffer[7] = (data >> 56) & 0xff;
+ WriteData (buffer, 8);
+}
+
void
PcapWriter::Write32 (uint32_t data)
{
@@ -177,4 +480,12 @@
WriteData (buffer, 2);
}
+void
+PcapWriter::Write8 (uint8_t data)
+{
+ WriteData (&data, 1);
+}
+
+
+
} // namespace ns3
--- a/src/common/pcap-writer.h Fri Jun 05 16:06:25 2009 +0400
+++ b/src/common/pcap-writer.h Mon Jun 08 15:12:15 2009 +0400
@@ -76,6 +76,24 @@
/**
* Write a pcap header in the output file which specifies
+ * that the content of the file will be 802.11 Packets preceded by a
+ * radiotap header providing PHY layer info. This method should be
+ * invoked before ns3::PcapWriter::WritePacket and after
+ * ns3::PcapWriter::Open.
+ */
+ void WriteWifiRadiotapHeader (void);
+
+ /**
+ * Write a pcap header in the output file which specifies
+ * that the content of the file will be 802.11 Packets preceded by a
+ * prism header providing PHY layer info. This method should be
+ * invoked before ns3::PcapWriter::WritePacket and after
+ * ns3::PcapWriter::Open.
+ */
+ void WriteWifiPrismHeader (void);
+
+ /**
+ * Write a pcap header in the output file which specifies
* that the content of the file will be ppp Packets. This
* method should be invoked before ns3::PcapWriter::WritePacket
* and after ns3::PcapWriter::Open.
@@ -87,12 +105,42 @@
*/
void WritePacket (Ptr<const Packet> packet);
+ /**
+ * Write a Packet, possibly adding wifi PHY layer information to it
+ *
+ * @param packet the packet being received
+ * @param channelFreqMhz the frequency in MHz at which the packet is
+ * received. Note that in real devices this is normally the
+ * frequency to which the receiver is tuned, and this can be
+ * different than the frequency at which the packet was originally
+ * transmitted. This is because it is possible to have the receiver
+ * tuned on a given channel and still to be able to receive packets
+ * on a nearby channel.
+ * @param rate the PHY data rate in units of 500kbps (i.e., the same
+ * units used both for the radiotap and for the prism header)
+ * @param isPreambleShort true if short preamble is used, false otherwise
+ * @param isTx true if packet is being transmitted, false when
+ * packet is being received
+ * @param signalDbm signal power in dBm
+ * @param noiseDbm noise power in dBm
+ */
+ void WriteWifiMonitorPacket(Ptr<const Packet> packet, uint16_t channelFreqMhz,
+ uint32_t rate, bool isShortPreamble, bool isTx,
+ double signalDbm, double noiseDbm);
+
+
+
+
private:
void WriteData (uint8_t const*buffer, uint32_t size);
+ void Write64 (uint64_t data);
void Write32 (uint32_t data);
void Write16 (uint16_t data);
+ void Write8 (uint8_t data);
void WriteHeader (uint32_t network);
+ int8_t RoundToInt8 (double value);
std::ofstream *m_writer;
+ uint32_t m_pcapMode;
};
} // namespace ns3
--- a/src/core/command-line.cc Fri Jun 05 16:06:25 2009 +0400
+++ b/src/core/command-line.cc Mon Jun 08 15:12:15 2009 +0400
@@ -100,7 +100,6 @@
std::cout << " --" << (*i)->m_name << ": " << (*i)->m_help << std::endl;
}
}
- exit (0);
}
void
@@ -115,7 +114,6 @@
std::cout << v.Get () << "]: "
<< (*i)->GetHelp () << std::endl;
}
- exit (0);
}
void
@@ -134,7 +132,6 @@
std::cout << initial->SerializeToString (checker) << "]: "
<< tid.GetAttributeHelp (i) << std::endl;
}
- exit (0);
}
@@ -149,7 +146,6 @@
std::cout << " --PrintAttributes=" <<tid.GetName ()<<std::endl;
}
}
- exit (0);
}
void
@@ -160,7 +156,6 @@
TypeId tid = TypeId::GetRegistered (i);
std::cout << " --PrintAttributes=" <<tid.GetName ()<<std::endl;
}
- exit (0);
}
void
@@ -193,7 +188,6 @@
{
std::cout << " --PrintGroup="<<*k<<std::endl;
}
- exit (0);
}
void
@@ -204,52 +198,62 @@
{
// method below never returns.
PrintHelp ();
- }
- if (name == "PrintGroups")
+ exit (0);
+ }
+ else if (name == "PrintGroups")
{
// method below never returns.
PrintGroups ();
+ exit (0);
}
- if (name == "PrintTypeIds")
+ else if (name == "PrintTypeIds")
{
// method below never returns.
PrintTypeIds ();
+ exit (0);
}
- if (name == "PrintGlobals")
+ else if (name == "PrintGlobals")
{
// method below never returns.
PrintGlobals ();
+ exit (0);
}
- if (name == "PrintGroup")
+ else if (name == "PrintGroup")
{
// method below never returns.
PrintGroup (value);
+ exit (0);
}
- if (name == "PrintAttributes")
+ else if (name == "PrintAttributes")
{
// method below never returns.
PrintAttributes (value);
+ exit (0);
}
- for (Items::const_iterator i = m_items.begin (); i != m_items.end (); ++i)
+ else
{
- if ((*i)->m_name == name)
- {
- if (!(*i)->Parse (value))
- {
- std::cerr << "Invalid argument value: "<<name<<"="<<value << std::endl;
- return;
- }
- else
- {
- return;
- }
- }
+ for (Items::const_iterator i = m_items.begin (); i != m_items.end (); ++i)
+ {
+ if ((*i)->m_name == name)
+ {
+ if (!(*i)->Parse (value))
+ {
+ std::cerr << "Invalid argument value: "<<name<<"="<<value << std::endl;
+ exit (1);
+ }
+ else
+ {
+ return;
+ }
+ }
+ }
}
if (!Config::SetGlobalFailSafe (name, StringValue (value))
&& !Config::SetDefaultFailSafe (name, StringValue (value)))
{
std::cerr << "Invalid command-line arguments: --"<<name<<"="<<value<<std::endl;
PrintHelp ();
+ exit (1);
}
}
--- a/src/core/names.cc Fri Jun 05 16:06:25 2009 +0400
+++ b/src/core/names.cc Mon Jun 08 15:12:15 2009 +0400
@@ -83,7 +83,7 @@
NamesPriv ();
~NamesPriv ();
- bool Add (std::string name, Ptr<Object> obj);
+ bool Add (std::string name, Ptr<Object> object);
bool Add (std::string path, std::string name, Ptr<Object> object);
bool Add (Ptr<Object> context, std::string name, Ptr<Object> object);
--- a/src/core/names.h Fri Jun 05 16:06:25 2009 +0400
+++ b/src/core/names.h Mon Jun 08 15:12:15 2009 +0400
@@ -45,7 +45,7 @@
* ("/Names") in the path.
*
* As well as specifying a name at the root of the "/Names" namespace, the
- * the <name> parameter can contain a path that fully qualifies the name to
+ * name parameter can contain a path that fully qualifies the name to
* be added. For example, if you previously have named an object "client"
* in the root namespace as above, you could name an object "under" that
* name by making a call like Names::Add ("/Names/client/eth0", obj). This
@@ -63,9 +63,9 @@
*
* \param name The name of the object you want to associate; which may be
* prepended with a path to that object.
- * \param obj A smart pointer to the object itself.
+ * \param object A smart pointer to the object itself.
*/
- static void Add (std::string name, Ptr<Object> obj);
+ static void Add (std::string name, Ptr<Object> object);
/**
* \brief An intermediate form of Names::Add allowing you to provide a path to
@@ -94,7 +94,7 @@
* \param path A path name describing a previously named object under which
* you want this new name to be defined.
* \param name The name of the object you want to associate.
- * \param obj A smart pointer to the object itself.
+ * \param object A smart pointer to the object itself.
*
* \see Names::Add (Ptr<Object> context, std::string name, Ptr<Object> object);
*/
@@ -145,7 +145,7 @@
* \param context A smart pointer to an object that is used in place of the path
* under which you want this new name to be defined.
* \param name The name of the object you want to associate.
- * \param obj A smart pointer to the object itself.
+ * \param object A smart pointer to the object itself.
*/
static void Add (Ptr<Object> context, std::string name, Ptr<Object> object);
@@ -162,7 +162,7 @@
* level ("/Names") in the path.
*
* As well as specifying a name at the root of the "/Names" namespace, the
- * the <name> parameter can contain a path that fully qualifies the name to
+ * name parameter can contain a path that fully qualifies the name to
* be changed. For example, if you previously have (re)named an object
* "server" in the root namespace as above, you could then rename an object
* "under" that name by making a call like Names::Rename ("/Names/server/csma", "eth0").
--- a/src/devices/emu/emu-net-device.cc Fri Jun 05 16:06:25 2009 +0400
+++ b/src/devices/emu/emu-net-device.cc Mon Jun 08 15:12:15 2009 +0400
@@ -173,7 +173,9 @@
m_sock (-1),
m_readThread (0),
m_ifIndex (std::numeric_limits<uint32_t>::max ()), // absurdly large value
- m_sll_ifindex (-1)
+ m_sll_ifindex (-1),
+ m_isBroadcast (true),
+ m_isMulticast (false)
{
NS_LOG_FUNCTION (this);
Start (m_tStart);
@@ -293,7 +295,19 @@
{
NS_FATAL_ERROR ("EmuNetDevice::StartDevice(): " << m_deviceName << " is not in promiscuous mode");
}
-
+ if ((ifr.ifr_flags & IFF_BROADCAST) != IFF_BROADCAST)
+ {
+ // We default m_isBroadcast to true but turn it off here if not
+ // supported, because in the common case, overlying IP code will
+ // assert during configuration time if this is false, before this
+ // method has a chance to set it during runtime
+ m_isBroadcast = false;
+ }
+ if ((ifr.ifr_flags & IFF_MULTICAST) == IFF_MULTICAST)
+ {
+ // This one is OK to enable at runtime
+ m_isMulticast = true;
+ }
//
// Now spin up a read thread to read packets.
//
@@ -918,7 +932,7 @@
bool
EmuNetDevice::IsBroadcast (void) const
{
- return true;
+ return m_isBroadcast;
}
Address
@@ -930,7 +944,7 @@
bool
EmuNetDevice::IsMulticast (void) const
{
- return false;
+ return m_isMulticast;
}
Address
--- a/src/devices/emu/emu-net-device.h Fri Jun 05 16:06:25 2009 +0400
+++ b/src/devices/emu/emu-net-device.h Mon Jun 08 15:12:15 2009 +0400
@@ -453,6 +453,18 @@
bool m_linkUp;
/**
+ * Flag indicating whether or not the underlying net device supports
+ * broadcast.
+ */
+ bool m_isBroadcast;
+
+ /**
+ * Flag indicating whether or not the underlying net device supports
+ * multicast.
+ */
+ bool m_isMulticast;
+
+ /**
* Callback to fire if the link changes state (up or down).
*/
Callback<void> m_linkChangeCallback;
--- a/src/devices/wifi/msdu-aggregator.cc Fri Jun 05 16:06:25 2009 +0400
+++ b/src/devices/wifi/msdu-aggregator.cc Mon Jun 08 15:12:15 2009 +0400
@@ -44,33 +44,31 @@
DeaggregatedMsdus set;
AmsduSubframeHeader hdr;
+ Ptr<Packet> extractedMsdu = Create<Packet> ();
uint32_t maxSize = aggregatedPacket->GetSize ();
- // The worst condition is: two aggregated packets with no padding.
- // 28 bytes is the size of two Amsdu subframe headers.
- uint8_t *buffer = new uint8_t[maxSize-28];
+ uint16_t extractedLength;
uint32_t padding;
uint32_t deserialized = 0;
while (deserialized < maxSize)
{
deserialized += aggregatedPacket->RemoveHeader (hdr);
- deserialized += aggregatedPacket->CopyData (buffer, hdr.GetLength ());
- aggregatedPacket->RemoveAtStart (hdr.GetLength ());
+ extractedLength = hdr.GetLength ();
+ extractedMsdu = aggregatedPacket->CreateFragment (0, static_cast<uint32_t>(extractedLength));
+ aggregatedPacket->RemoveAtStart (extractedLength);
+ deserialized += extractedLength;
- padding = (4 - ((hdr.GetLength () + 14) %4 )) % 4;
+ padding = (4 - ((extractedLength + 14) %4 )) % 4;
if (padding > 0 && deserialized < maxSize)
{
aggregatedPacket->RemoveAtStart (padding);
deserialized += padding;
}
- //a new packet is created with the content of extracted msdu
- Ptr<Packet> p = Create<Packet> (buffer, hdr.GetLength ());
- std::pair<Ptr<Packet>, AmsduSubframeHeader> packetHdr (p,hdr);
+ std::pair<Ptr<Packet>, AmsduSubframeHeader> packetHdr (extractedMsdu, hdr);
set.push_back (packetHdr);
}
- delete [] buffer;
NS_LOG_INFO ("Deaggreated A-MSDU: extracted "<< set.size () << " MSDUs");
return set;
}
--- a/src/devices/wifi/propagation-loss-model.h Fri Jun 05 16:06:25 2009 +0400
+++ b/src/devices/wifi/propagation-loss-model.h Mon Jun 08 15:12:15 2009 +0400
@@ -355,7 +355,7 @@
FixedRssLossModel ();
virtual ~FixedRssLossModel ();
/**
- * \param RSS (dBm) the received signal strength
+ * \param rss (dBm) the received signal strength
*
* Set the RSS.
*/
--- a/src/devices/wifi/wifi-phy.cc Fri Jun 05 16:06:25 2009 +0400
+++ b/src/devices/wifi/wifi-phy.cc Mon Jun 08 15:12:15 2009 +0400
@@ -73,9 +73,12 @@
.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))
+ .AddTraceSource ("PromiscSnifferRx",
+ "Trace source simulating a wifi device in monitor mode sniffing all received frames",
+ MakeTraceSourceAccessor (&WifiPhy::m_phyPromiscSniffRxTrace))
+ .AddTraceSource ("PromiscSnifferTx",
+ "Trace source simulating the capability of a wifi device in monitor mode to sniff all frames being transmitted",
+ MakeTraceSourceAccessor (&WifiPhy::m_phyPromiscSniffTxTrace))
;
return tid;
}
@@ -194,9 +197,15 @@
}
void
-WifiPhy::NotifyPromiscSniff (Ptr<const Packet> packet)
+WifiPhy::NotifyPromiscSniffRx (Ptr<const Packet> packet, uint16_t channelFreqMhz, uint32_t rate, bool isShortPreamble, double signalDbm, double noiseDbm)
{
- m_phyPromiscSnifferTrace (packet);
+ m_phyPromiscSniffRxTrace (packet, channelFreqMhz, rate, isShortPreamble, signalDbm, noiseDbm);
+}
+
+void
+WifiPhy::NotifyPromiscSniffTx (Ptr<const Packet> packet, uint16_t channelFreqMhz, uint32_t rate, bool isShortPreamble)
+{
+ m_phyPromiscSniffTxTrace (packet, channelFreqMhz, rate, isShortPreamble);
}
WifiMode
--- a/src/devices/wifi/wifi-phy.h Fri Jun 05 16:06:25 2009 +0400
+++ b/src/devices/wifi/wifi-phy.h Mon Jun 08 15:12:15 2009 +0400
@@ -294,11 +294,47 @@
*/
void NotifyRxDrop (Ptr<const Packet> packet);
- /**
- * Public method used to fire a PromiscSniffer trace. Implemented for encapsulation
+ /**
+ *
+ * Public method used to fire a PromiscSniffer trace for a wifi packet being received. Implemented for encapsulation
* purposes.
+ *
+ * @param packet the packet being received
+ * @param channelFreqMhz the frequency in MHz at which the packet is
+ * received. Note that in real devices this is normally the
+ * frequency to which the receiver is tuned, and this can be
+ * different than the frequency at which the packet was originally
+ * transmitted. This is because it is possible to have the receiver
+ * tuned on a given channel and still to be able to receive packets
+ * on a nearby channel.
+ * @param rate the PHY data rate in units of 500kbps (i.e., the same
+ * units used both for the radiotap and for the prism header)
+ * @param isPreambleShort true if short preamble is used, false otherwise
+ * @param signalDbm signal power in dBm
+ * @param noiseDbm noise power in dBm
*/
- void NotifyPromiscSniff (Ptr<const Packet> packet);
+ void NotifyPromiscSniffRx (Ptr<const Packet> packet, uint16_t channelFreqMhz, uint32_t rate, bool isShortPreamble,
+ double signalDbm, double noiseDbm);
+
+ /**
+ *
+ * Public method used to fire a PromiscSniffer trace for a wifi packet being transmitted. Implemented for encapsulation
+ * purposes.
+ *
+ * @param packet the packet being received
+ * @param channelFreqMhz the frequency in MHz at which the packet is
+ * received. Note that in real devices this is normally the
+ * frequency to which the receiver is tuned, and this can be
+ * different than the frequency at which the packet was originally
+ * transmitted. This is because it is possible to have the receiver
+ * tuned on a given channel and still to be able to receive packets
+ * on a nearby channel.
+ * @param rate the PHY data rate in units of 500kbps (i.e., the same
+ * units used both for the radiotap and for the prism header)
+ * @param isPreambleShort true if short preamble is used, false otherwise
+ */
+ void NotifyPromiscSniffTx (Ptr<const Packet> packet, uint16_t channelFreqMhz, uint32_t rate, bool isShortPreamble);
+
private:
/**
@@ -349,24 +385,29 @@
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.
+ * A trace source that emulates a wifi device in monitor mode
+ * sniffing a packet being received.
+ *
+ * As a reference with the real world, firing this trace
+ * corresponds in the madwifi driver to calling the function
+ * ieee80211_input_monitor()
*
* \see class CallBackTraceSource
*/
- TracedCallback<Ptr<const Packet> > m_phyPromiscSnifferTrace;
+ TracedCallback<Ptr<const Packet>, uint16_t, uint32_t, bool, double, double> m_phyPromiscSniffRxTrace;
+
+ /**
+ * A trace source that emulates a wifi device in monitor mode
+ * sniffing a packet being transmitted.
+ *
+ * As a reference with the real world, firing this trace
+ * corresponds in the madwifi driver to calling the function
+ * ieee80211_input_monitor()
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet>, uint16_t, uint32_t, bool> m_phyPromiscSniffTxTrace;
+
};
} // namespace ns3
--- a/src/devices/wifi/wifi.h Fri Jun 05 16:06:25 2009 +0400
+++ b/src/devices/wifi/wifi.h Mon Jun 08 15:12:15 2009 +0400
@@ -7,7 +7,7 @@
* The set of 802.11 models provided in ns-3 attempts to provide
* an accurate MAC-level implementation of the 802.11 specification
* and to provide a not-so-slow PHY-level model of the 802.11a
- * specification.
+ * and 802.11b specifications.
*
* The current implementation provides roughly 4 levels of models:
* - the PHY layer models
@@ -52,7 +52,7 @@
* <td><b> Access class </b></td>
* </tr>
* <tr>
- * <td> 7 </b></td>
+ * <td> 7 </td>
* <td> AC_VO </td>
* </tr>
* <tr>
@@ -96,9 +96,9 @@
*
* The PHY layer implements a single model in the ns3::WifiPhy class: the
* physical layer model implemented there is described fully in a paper titled
- * "Yet Another Network Simulator", available there: http://cutebugs.net/files/wns2-yans.pdf
- *
- * It also provides a set of Rate control algorithms:
+ * "Yet Another Network Simulator", available at: http://cutebugs.net/files/wns2-yans.pdf and recently extended to cover 802.11b physical layer.
+ *
+ * The Wifi Model also provides a set of Rate control algorithms:
* - ns3::ArfMacStations
* - ns3::AArfMacStations
* - ns3::IdealMacStations
--- a/src/devices/wifi/yans-error-rate-model.cc Fri Jun 05 16:06:25 2009 +0400
+++ b/src/devices/wifi/yans-error-rate-model.cc Mon Jun 08 15:12:15 2009 +0400
@@ -27,6 +27,11 @@
NS_OBJECT_ENSURE_REGISTERED (YansErrorRateModel);
+#ifndef ENABLE_GSL
+const double YansErrorRateModel::WLAN_SIR_PERFECT = 10.0;
+const double YansErrorRateModel::WLAN_SIR_IMPOSSIBLE = 0.1;
+#endif
+
TypeId
YansErrorRateModel::GetTypeId (void)
{
--- a/src/devices/wifi/yans-error-rate-model.h Fri Jun 05 16:06:25 2009 +0400
+++ b/src/devices/wifi/yans-error-rate-model.h Mon Jun 08 15:12:15 2009 +0400
@@ -100,11 +100,11 @@
#ifdef ENABLE_GSL
double SymbolErrorProb16Cck (double e2) const; /// equation (18) in Pursley's paper
double SymbolErrorProb256Cck (double e1) const; /// equation (17) in Pursley's paper
-#endif
-
+#else
private:
- static const double WLAN_SIR_PERFECT = 10.0;
- static const double WLAN_SIR_IMPOSSIBLE = 0.1;
+ static const double WLAN_SIR_PERFECT;
+ static const double WLAN_SIR_IMPOSSIBLE;
+#endif
};
--- a/src/devices/wifi/yans-wifi-phy.h Fri Jun 05 16:06:25 2009 +0400
+++ b/src/devices/wifi/yans-wifi-phy.h Mon Jun 08 15:12:15 2009 +0400
@@ -160,6 +160,7 @@
double m_txPowerBaseDbm;
double m_txPowerEndDbm;
uint32_t m_nTxPower;
+ uint16_t m_channelFreqMhz;
Ptr<YansWifiChannel> m_channel;
uint16_t m_channelId;
--- a/src/helper/mobility-helper.h Fri Jun 05 16:06:25 2009 +0400
+++ b/src/helper/mobility-helper.h Mon Jun 08 15:12:15 2009 +0400
@@ -125,7 +125,7 @@
* The input item should be a node instance to which a mobility model
* has already been aggregated (usually by a call to Install).
*
- * If this this stack is not empty when MobilityHelper::Install
+ * If this stack is not empty when MobilityHelper::Install
* is called, the model from the top of the stack is used
* to create a ns3::HierarchicalMobilityModel to make the
* newly-created models define their positions relative to that
@@ -138,13 +138,13 @@
*/
void PushReferenceMobilityModel (Ptr<Object> reference);
/**
- * \param reference item to push.
+ * \param referenceName named item to push.
*
* Push an item on the top of the stack of "reference mobility models".
* The input item should be a node instance to which a mobility model
* has already been aggregated (usually by a call to Install).
*
- * If this this stack is not empty when MobilityHelper::Install
+ * If this stack is not empty when MobilityHelper::Install
* is called, the model from the top of the stack is used
* to create a ns3::HierarchicalMobilityModel to make the
* newly-created models define their positions relative to that
--- a/src/helper/on-off-helper.h Fri Jun 05 16:06:25 2009 +0400
+++ b/src/helper/on-off-helper.h Mon Jun 08 15:12:15 2009 +0400
@@ -76,7 +76,7 @@
* Install an ns3::OnOffApplication on the node configured with all the
* attributes set with SetAttribute.
*
- * \param node The node on which an OnOffApplication will be installed.
+ * \param nodeName The node on which an OnOffApplication will be installed.
* \returns Container of Ptr to the applications installed.
*/
ApplicationContainer Install (std::string nodeName) const;
--- a/src/helper/point-to-point-helper.h Fri Jun 05 16:06:25 2009 +0400
+++ b/src/helper/point-to-point-helper.h Mon Jun 08 15:12:15 2009 +0400
@@ -218,8 +218,8 @@
NetDeviceContainer Install (std::string aName, Ptr<Node> b);
/**
- * \param aName Name of first node
- * \param bName Name of second node
+ * \param aNode Name of first node
+ * \param bNode Name of second node
*
* Saves you from having to construct a temporary NodeContainer.
*/
--- a/src/helper/yans-wifi-helper.cc Fri Jun 05 16:06:25 2009 +0400
+++ b/src/helper/yans-wifi-helper.cc Mon Jun 08 15:12:15 2009 +0400
@@ -31,11 +31,21 @@
namespace ns3 {
-static void PcapSnifferEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet)
+static void PcapSniffTxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet, uint16_t channelFreqMhz,
+ uint32_t rate, bool isShortPreamble)
{
- writer->WritePacket (packet);
+ const double unusedValue = 0;
+ writer->WriteWifiMonitorPacket(packet, channelFreqMhz, rate, isShortPreamble, true, unusedValue, unusedValue);
}
+
+static void PcapSniffRxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet, uint16_t channelFreqMhz,
+ uint32_t rate, bool isShortPreamble, double signalDbm, double noiseDbm)
+{
+ writer->WriteWifiMonitorPacket(packet, channelFreqMhz, rate, isShortPreamble, false, signalDbm, noiseDbm);
+}
+
+
static void AsciiPhyTxEvent (std::ostream *os, std::string context,
Ptr<const Packet> packet,
WifiMode mode, WifiPreamble preamble,
@@ -137,7 +147,9 @@
YansWifiPhyHelper::YansWifiPhyHelper ()
- : m_channel (0)
+ : m_channel (0),
+ m_pcapFormat(PCAP_FORMAT_80211)
+
{
m_phy.SetTypeId ("ns3::YansWifiPhy");
}
@@ -202,6 +214,14 @@
return phy;
}
+
+void
+YansWifiPhyHelper::SetPcapFormat (enum PcapFormat format)
+{
+ m_pcapFormat = format;
+}
+
+
void
YansWifiPhyHelper::EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid)
{
@@ -218,11 +238,28 @@
// with the locally-defined WifiPhyHelper::Create method.
Ptr<PcapWriter> pcap = ::ns3::Create<PcapWriter> ();
pcap->Open (oss.str ());
- pcap->WriteWifiHeader ();
+
+ switch (m_pcapFormat) {
+ case PCAP_FORMAT_80211:
+ pcap->WriteWifiHeader ();
+ break;
+ case PCAP_FORMAT_80211_RADIOTAP:
+ pcap->WriteWifiRadiotapHeader ();
+ break;
+ case PCAP_FORMAT_80211_PRISM:
+ pcap->WriteWifiPrismHeader ();
+ break;
+ }
+
oss.str ("");
oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid;
- oss << "/$ns3::WifiNetDevice/Phy/PromiscSniffer";
- Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&PcapSnifferEvent, pcap));
+ oss << "/$ns3::WifiNetDevice/Phy/PromiscSnifferTx";
+ Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&PcapSniffTxEvent, pcap));
+
+ oss.str ("");
+ oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid;
+ oss << "/$ns3::WifiNetDevice/Phy/PromiscSnifferRx";
+ Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&PcapSniffRxEvent, pcap));
}
void
--- a/src/helper/yans-wifi-helper.h Fri Jun 05 16:06:25 2009 +0400
+++ b/src/helper/yans-wifi-helper.h Mon Jun 08 15:12:15 2009 +0400
@@ -198,18 +198,45 @@
std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
/**
+ * PCAP formats
+ *
+ */
+ enum PcapFormat {
+ PCAP_FORMAT_80211 = 1,
+ PCAP_FORMAT_80211_PRISM = 2,
+ PCAP_FORMAT_80211_RADIOTAP = 3,
+ };
+
+ /**
+ * Set the format of PCAP traces to be used. This function has to be
+ * called before EnablePcap(), so that the header of the pcap file
+ * can be written correctly.
+ *
+ * In madwifi, this corresponds to setting
+ * /proc/sys/net/ath0/dev_type to a particular value. See
+ * http://madwifi-project.org/wiki/UserDocs/MonitorModeInterface for
+ * more information.
+ *
+ * @param format the PcapFormat to be used
+ */
+ void SetPcapFormat (enum PcapFormat format);
+
+ /**
* \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.
*
* Generate a pcap file which contains the link-level data observed
* by the specified deviceid within the specified nodeid. The pcap
- * data is stored in the file prefix-nodeid-deviceid.pcap.
+ * data is stored in the file prefix-nodeid-deviceid.pcap. By
+ * default, no PHY layer information is provided. An optional header
+ * with PHY layer information, such as the radiotap or the prism
+ * header, can be used by invoking SetPcapFormat().
*
* 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);
+ void EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid);
/**
* \param filename filename prefix to use for pcap files.
@@ -218,7 +245,7 @@
* Enable pcap output on each input device which is of the
* ns3::WifiNetDevice type.
*/
- static void EnablePcap (std::string filename, Ptr<NetDevice> nd);
+ void EnablePcap (std::string filename, Ptr<NetDevice> nd);
/**
* \param filename filename prefix to use for pcap files.
@@ -227,7 +254,7 @@
* Enable pcap output on each input device which is of the
* ns3::WifiNetDevice type.
*/
- static void EnablePcap (std::string filename, std::string ndName);
+ void EnablePcap (std::string filename, std::string ndName);
/**
* \param filename filename prefix to use for pcap files.
@@ -236,7 +263,7 @@
* Enable pcap output on each input device which is of the
* ns3::WifiNetDevice type.
*/
- static void EnablePcap (std::string filename, NetDeviceContainer d);
+ void EnablePcap (std::string filename, NetDeviceContainer d);
/**
* \param filename filename prefix to use for pcap files.
@@ -246,7 +273,7 @@
* ns3::WifiNetDevice type and which is located in one of the
* input nodes.
*/
- static void EnablePcap (std::string filename, NodeContainer n);
+ void EnablePcap (std::string filename, NodeContainer n);
/**
* \param filename filename prefix to use for pcap files.
@@ -254,7 +281,7 @@
* Enable pcap output on each device which is of the
* ns3::WifiNetDevice type
*/
- static void EnablePcapAll (std::string filename);
+ void EnablePcapAll (std::string filename);
/**
* \param os output stream
@@ -311,6 +338,7 @@
ObjectFactory m_phy;
ObjectFactory m_errorRateModel;
Ptr<YansWifiChannel> m_channel;
+ enum PcapFormat m_pcapFormat;
};
} // namespace ns3
--- a/src/internet-stack/ipv4-interface.h Fri Jun 05 16:06:25 2009 +0400
+++ b/src/internet-stack/ipv4-interface.h Mon Jun 08 15:12:15 2009 +0400
@@ -130,7 +130,7 @@
uint32_t AddAddress (Ipv4InterfaceAddress address);
/**
- * \param i Index of Ipv4InterfaceAddress to return
+ * \param index Index of Ipv4InterfaceAddress to return
* \returns The Ipv4InterfaceAddress address whose index is i
*/
Ipv4InterfaceAddress GetAddress (uint32_t index) const;
@@ -141,7 +141,7 @@
uint32_t GetNAddresses (void) const;
/**
- * \param i index of Ipv4InterfaceAddress to remove from address list.
+ * \param index index of Ipv4InterfaceAddress to remove from address list.
*/
void RemoveAddress (uint32_t index);
--- a/src/internet-stack/ipv4-l3-protocol.cc Fri Jun 05 16:06:25 2009 +0400
+++ b/src/internet-stack/ipv4-l3-protocol.cc Mon Jun 08 15:12:15 2009 +0400
@@ -164,10 +164,10 @@
}
void
-Ipv4L3Protocol::SetRoutingProtocol (Ptr<Ipv4RoutingProtocol> routing)
+Ipv4L3Protocol::SetRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol)
{
NS_LOG_FUNCTION (this);
- m_routingProtocol = routing;
+ m_routingProtocol = routingProtocol;
// XXX should check all interfaces to see if any were set to Up state
// prior to a routing protocol being added
if (GetStaticRouting () != 0)
@@ -482,7 +482,7 @@
bool mayFragment = true;
uint8_t ttl = m_defaultTtl;
SocketIpTtlTag tag;
- bool found = packet->FindFirstMatchingByteTag (tag);
+ bool found = packet->RemovePacketTag (tag);
if (found)
{
ttl = tag.GetTtl ();
--- a/src/internet-stack/ipv4-l3-protocol.h Fri Jun 05 16:06:25 2009 +0400
+++ b/src/internet-stack/ipv4-l3-protocol.h Mon Jun 08 15:12:15 2009 +0400
@@ -67,7 +67,8 @@
void SetNode (Ptr<Node> node);
// functions defined in base class Ipv4
- void SetRoutingProtocol (Ptr<Ipv4RoutingProtocol> routing);
+
+ void SetRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol);
Ptr<Ipv4RoutingProtocol> GetRoutingProtocol (void) const;
Ptr<Socket> CreateRawSocket (void);
--- a/src/internet-stack/nsc-tcp-socket-impl.cc Fri Jun 05 16:06:25 2009 +0400
+++ b/src/internet-stack/nsc-tcp-socket-impl.cc Mon Jun 08 15:12:15 2009 +0400
@@ -263,7 +263,7 @@
NscTcpSocketImpl::ShutdownRecv (void)
{
NS_LOG_FUNCTION_NOARGS ();
- m_shutdownRecv = false;
+ m_shutdownRecv = true;
return 0;
}
--- a/src/internet-stack/tcp-socket-impl.cc Fri Jun 05 16:06:25 2009 +0400
+++ b/src/internet-stack/tcp-socket-impl.cc Mon Jun 08 15:12:15 2009 +0400
@@ -303,7 +303,7 @@
TcpSocketImpl::ShutdownRecv (void)
{
NS_LOG_FUNCTION_NOARGS ();
- m_shutdownRecv = false;
+ m_shutdownRecv = true;
return 0;
}
@@ -563,6 +563,9 @@
m_rxBufSize += i->second->GetSize()-avail;
}
}
+ SocketAddressTag tag;
+ tag.SetAddress (InetSocketAddress (m_remoteAddress, m_remotePort));
+ outPacket->AddPacketTag (tag);
return outPacket;
}
@@ -577,7 +580,7 @@
Ptr<Packet>
TcpSocketImpl::RecvFrom (uint32_t maxSize, uint32_t flags,
- Address &fromAddress)
+ Address &fromAddress)
{
NS_LOG_FUNCTION (this << maxSize << flags);
Ptr<Packet> packet = Recv (maxSize, flags);
@@ -586,7 +589,7 @@
{
SocketAddressTag tag;
bool found;
- found = packet->FindFirstMatchingByteTag (tag);
+ found = packet->PeekPacketTag (tag);
NS_ASSERT (found);
fromAddress = tag.GetAddress ();
}
@@ -1196,9 +1199,6 @@
p = p->CreateFragment (0,s);
m_nextRxSequence += s; // Advance next expected sequence
NS_LOG_LOGIC("Case 1, advanced nrxs to " << m_nextRxSequence );
- SocketAddressTag tag;
- tag.SetAddress (fromAddress);
- p->AddByteTag (tag);
//buffer this, it'll be read by call to Recv
UnAckData_t::iterator i =
m_bufferedData.find (tcpHeader.GetSequenceNumber () );
@@ -1266,9 +1266,6 @@
}
}
// Save for later delivery
- SocketAddressTag tag;
- tag.SetAddress (fromAddress);
- p->AddByteTag (tag);
m_bufferedData[startSeq] = p;
i = m_bufferedData.find (startSeq);
next = i;
@@ -1295,9 +1292,6 @@
p = p->CreateFragment (m_nextRxSequence - tcpHeader.GetSequenceNumber (),s);
SequenceNumber start = m_nextRxSequence;
m_nextRxSequence += s; // Advance next expected sequence
- SocketAddressTag tag;
- tag.SetAddress (fromAddress);
- p->AddByteTag (tag);
//buffer the new fragment, it'll be read by call to Recv
UnAckData_t::iterator i = m_bufferedData.find (start);
if (i != m_bufferedData.end () ) //we found it already in the buffer
--- a/src/internet-stack/udp-socket-impl.cc Fri Jun 05 16:06:25 2009 +0400
+++ b/src/internet-stack/udp-socket-impl.cc Mon Jun 08 15:12:15 2009 +0400
@@ -198,7 +198,7 @@
UdpSocketImpl::ShutdownRecv (void)
{
NS_LOG_FUNCTION_NOARGS ();
- m_shutdownRecv = false;
+ m_shutdownRecv = true;
return 0;
}
@@ -325,17 +325,17 @@
{
SocketIpTtlTag tag;
tag.SetTtl (m_ipMulticastTtl);
- p->AddByteTag (tag);
+ p->AddPacketTag (tag);
}
else if (m_ipTtl != 0 && !dest.IsMulticast () && !dest.IsBroadcast ())
{
SocketIpTtlTag tag;
tag.SetTtl (m_ipTtl);
- p->AddByteTag (tag);
+ p->AddPacketTag (tag);
}
{
SocketSetDontFragmentTag tag;
- bool found = p->FindFirstMatchingByteTag (tag);
+ bool found = p->RemovePacketTag (tag);
if (!found)
{
if (m_mtuDiscover)
@@ -346,7 +346,7 @@
{
tag.Disable ();
}
- p->AddByteTag (tag);
+ p->AddPacketTag (tag);
}
}
//
@@ -490,7 +490,7 @@
{
SocketAddressTag tag;
bool found;
- found = packet->FindFirstMatchingByteTag (tag);
+ found = packet->PeekPacketTag (tag);
NS_ASSERT (found);
fromAddress = tag.GetAddress ();
}
@@ -554,7 +554,7 @@
Address address = InetSocketAddress (ipv4, port);
SocketAddressTag tag;
tag.SetAddress (address);
- packet->AddByteTag (tag);
+ packet->AddPacketTag (tag);
m_deliveryQueue.push (packet);
m_rxAvailable += packet->GetSize ();
NotifyDataRecv ();
--- a/src/node/ipv4-list-routing.h Fri Jun 05 16:06:25 2009 +0400
+++ b/src/node/ipv4-list-routing.h Mon Jun 08 15:12:15 2009 +0400
@@ -24,10 +24,8 @@
namespace ns3 {
/**
- * \ingroup ipv4
- */
-
-/**
+ * \ingroup ipv4-routing
+ *
* This class is a specialization of Ipv4RoutingProtocol that allows
* other instances of Ipv4RoutingProtocol to be inserted in a
* prioritized list. Routing protocols in the list are consulted one
@@ -50,9 +48,16 @@
* Values may range between -32768 and +32767.
*/
virtual void AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol, int16_t priority) = 0;
-
+ /**
+ * \return number of routing protocols in the list
+ */
virtual uint32_t GetNRoutingProtocols (void) const = 0;
-
+ /**
+ * \return pointer to routing protocol indexed by
+ * \param index index of protocol to return
+ * \param priority output parameter, set to the priority of the protocol
+ being returned
+ */
virtual Ptr<Ipv4RoutingProtocol> GetRoutingProtocol (uint32_t index, int16_t& priority) const = 0;
};
--- a/src/node/ipv4-route.h Fri Jun 05 16:06:25 2009 +0400
+++ b/src/node/ipv4-route.h Mon Jun 08 15:12:15 2009 +0400
@@ -31,25 +31,53 @@
class NetDevice;
/**
+ * \ingroup ipv4-routing
+ *
*\brief Ipv4 route cache entry (similar to Linux struct rtable)
*
- * In the future, we will add other entries from struct dst_entry, struct rtable, and struct dst_ops as needed.
+ * This is a reference counted object. In the future, we will add other
+ * entries from struct dst_entry, struct rtable, and struct dst_ops as needed.
*/
class Ipv4Route : public RefCountBase {
public:
Ipv4Route ();
+ /**
+ * \param dest Destination Ipv4Address
+ */
void SetDestination (Ipv4Address dest);
+ /**
+ * \return Destination Ipv4Address of the route
+ */
Ipv4Address GetDestination (void) const;
+ /**
+ * \param src Source Ipv4Address
+ */
void SetSource (Ipv4Address src);
+ /**
+ * \return Source Ipv4Address of the route
+ */
Ipv4Address GetSource (void) const;
+ /**
+ * \param gw Gateway (next hop) Ipv4Address
+ */
void SetGateway (Ipv4Address gw);
+ /**
+ * \return Ipv4Address of the gateway (next hop)
+ */
Ipv4Address GetGateway (void) const;
- // dst_entry.dev
+ /**
+ * Equivalent in Linux to dst_entry.dev
+ *
+ * \param outputDevice pointer to NetDevice for outgoing packets
+ */
void SetOutputDevice (Ptr<NetDevice> outputDevice);
+ /**
+ * \return pointer to NetDevice for outgoing packets
+ */
Ptr<NetDevice> GetOutputDevice (void) const;
#ifdef NOTYET
@@ -71,26 +99,54 @@
std::ostream& operator<< (std::ostream& os, Ipv4Route const& route);
/**
- *\brief Ipv4 multicast route cache entry (similar to Linux struct mfc_cache)
+ * \ingroup ipv4-routing
+ *
+ * \brief Ipv4 multicast route cache entry (similar to Linux struct mfc_cache)
*/
class Ipv4MulticastRoute : public RefCountBase {
public:
Ipv4MulticastRoute ();
+ /**
+ * \param group Ipv4Address of the multicast group
+ */
void SetGroup (const Ipv4Address group);
+ /**
+ * \return Ipv4Address of the multicast group
+ */
Ipv4Address GetGroup (void) const;
- void SetOrigin (const Ipv4Address group);
+ /**
+ * \param origin Ipv4Address of the origin address
+ */
+ void SetOrigin (const Ipv4Address origin);
+ /**
+ * \return Ipv4Address of the origin address
+ */
Ipv4Address GetOrigin (void) const;
+ /**
+ * \param iif Parent (input interface) for this route
+ */
void SetParent (uint32_t iif);
+ /**
+ * \return Parent (input interface) for this route
+ */
uint32_t GetParent (void) const;
+ /**
+ * \param oif Outgoing interface index
+ * \param ttl time-to-live for this route
+ */
void SetOutputTtl (uint32_t oif, uint32_t ttl);
+ /**
+ * \param oif outgoing interface
+ * \return TTL for this route
+ */
uint32_t GetOutputTtl (uint32_t oif) const;
- static const uint32_t MAX_INTERFACES = 16;
- static const uint32_t MAX_TTL = 255;
+ static const uint32_t MAX_INTERFACES = 16; // Maximum number of multicast interfaces on a router
+ static const uint32_t MAX_TTL = 255; // Maximum time-to-live (TTL)
private:
Ipv4Address m_group; // Group
--- a/src/node/ipv4-routing-protocol.h Fri Jun 05 16:06:25 2009 +0400
+++ b/src/node/ipv4-routing-protocol.h Mon Jun 08 15:12:15 2009 +0400
@@ -31,7 +31,9 @@
class NetDevice;
/**
- * \ingroup ipv4
+ * \ingroup node
+ * \defgroup ipv4-routing Ipv4 Routing
+ *
* Abstract base class for Ipv4 routing protocols. Defines two
* virtual functions for packet routing and forwarding. The first,
* RouteOutput(), is used for locally originated packets, and the second,
--- a/src/node/ipv4-routing-table-entry.h Fri Jun 05 16:06:25 2009 +0400
+++ b/src/node/ipv4-routing-table-entry.h Mon Jun 08 15:12:15 2009 +0400
@@ -29,8 +29,10 @@
namespace ns3 {
/**
- * \ingroup internetStack
- * \brief A record of an IPv4 routing table entry for Ipv4GlobalRouting and Ipv4StaticRouting
+ * \ingroup ipv4-routing
+ *
+ * A record of an IPv4 routing table entry for Ipv4GlobalRouting and
+ * Ipv4StaticRouting. This is not a reference counted object.
*/
class Ipv4RoutingTableEntry {
public:
@@ -38,50 +40,95 @@
* \brief This constructor does nothing
*/
Ipv4RoutingTableEntry ();
-
/**
* \brief Copy Constructor
* \param route The route to copy
*/
Ipv4RoutingTableEntry (Ipv4RoutingTableEntry const &route);
-
/**
* \brief Copy Constructor
* \param route The route to copy
*/
Ipv4RoutingTableEntry (Ipv4RoutingTableEntry const *route);
-
+ /**
+ * \return True if this route is a host route; false otherwise
+ */
bool IsHost (void) const;
/**
* \return The IPv4 address of the destination of this route
*/
- Ipv4Address GetDest (void) const;
-
bool IsNetwork (void) const;
- Ipv4Address GetDestNetwork (void) const;
- Ipv4Mask GetDestNetworkMask (void) const;
/**
* \return True if this route is a default route; false otherwise
*/
bool IsDefault (void) const;
-
+ /**
+ * \return True if this route is a gateway route; false otherwise
+ */
bool IsGateway (void) const;
+ /**
+ * \return address of the gateway stored in this entry
+ */
Ipv4Address GetGateway (void) const;
-
+ /**
+ * \return The IPv4 address of the destination of this route
+ */
+ Ipv4Address GetDest (void) const;
+ /**
+ * \return The IPv4 network number of the destination of this route
+ */
+ Ipv4Address GetDestNetwork (void) const;
+ /**
+ * \return The IPv4 network mask of the destination of this route
+ */
+ Ipv4Mask GetDestNetworkMask (void) const;
+ /**
+ * \return The Ipv4 interface number used for sending outgoing packets
+ */
uint32_t GetInterface (void) const;
-
+ /**
+ * \return An Ipv4RoutingTableEntry object corresponding to the input parameters.
+ * \param dest Ipv4Address of the destination
+ * \param nextHop Ipv4Address of the next hop
+ * \param interface Outgoing interface
+ */
static Ipv4RoutingTableEntry CreateHostRouteTo (Ipv4Address dest,
Ipv4Address nextHop,
uint32_t interface);
+ /**
+ * \return An Ipv4RoutingTableEntry object corresponding to the input parameters.
+ * \param dest Ipv4Address of the destination
+ * \param interface Outgoing interface
+ */
static Ipv4RoutingTableEntry CreateHostRouteTo (Ipv4Address dest,
uint32_t interface);
+ /**
+ * \return An Ipv4RoutingTableEntry object corresponding to the input parameters.
+ * \param network Ipv4Address of the destination network
+ * \param networkMask Ipv4Mask of the destination network mask
+ * \param nextHop Ipv4Address of the next hop
+ * \param interface Outgoing interface
+ */
static Ipv4RoutingTableEntry CreateNetworkRouteTo (Ipv4Address network,
Ipv4Mask networkMask,
Ipv4Address nextHop,
uint32_t interface);
+ /**
+ * \return An Ipv4RoutingTableEntry object corresponding to the input parameters.
+ * \param network Ipv4Address of the destination network
+ * \param networkMask Ipv4Mask of the destination network mask
+ * \param interface Outgoing interface
+ */
static Ipv4RoutingTableEntry CreateNetworkRouteTo (Ipv4Address network,
Ipv4Mask networkMask,
uint32_t interface);
+ /**
+ * \return An Ipv4RoutingTableEntry object corresponding to the input
+ * parameters. This route is distinguished; it will match any
+ * destination for which a more specific route does not exist.
+ * \param nextHop Ipv4Address of the next hop
+ * \param interface Outgoing interface
+ */
static Ipv4RoutingTableEntry CreateDefaultRoute (Ipv4Address nextHop,
uint32_t interface);
@@ -108,7 +155,8 @@
std::ostream& operator<< (std::ostream& os, Ipv4RoutingTableEntry const& route);
/**
- * \ingroup internetStack
+ * \ingroup ipv4-routing
+ *
* \brief A record of an IPv4 multicast route for Ipv4GlobalRouting and Ipv4StaticRouting
*/
class Ipv4MulticastRoutingTableEntry {
@@ -123,43 +171,42 @@
* \param route The route to copy
*/
Ipv4MulticastRoutingTableEntry (Ipv4MulticastRoutingTableEntry const &route);
-
/**
* \brief Copy Constructor
* \param route The route to copy
*/
Ipv4MulticastRoutingTableEntry (Ipv4MulticastRoutingTableEntry const *route);
-
/**
* \return The IPv4 address of the source of this route
*/
Ipv4Address GetOrigin (void) const;
-
/**
* \return The IPv4 address of the multicast group of this route
*/
Ipv4Address GetGroup (void) const;
-
/**
* \return The IPv4 address of the input interface of this route
*/
uint32_t GetInputInterface (void) const;
-
/**
* \return The number of output interfaces of this route
*/
uint32_t GetNOutputInterfaces (void) const;
-
/**
* \return A specified output interface.
*/
uint32_t GetOutputInterface (uint32_t n) const;
-
/**
* \return A vector of all of the output interfaces of this route.
*/
std::vector<uint32_t> GetOutputInterfaces (void) const;
-
+ /**
+ * \return Ipv4MulticastRoutingTableEntry corresponding to the input parameters.
+ * \param origin Source address for the multicast route
+ * \param group Group destination address for the multicast route
+ * \param inputInterface Input interface that multicast datagram must be received on
+ * \param outputInterfaces vector of output interfaces to copy and forward the datagram to
+ */
static Ipv4MulticastRoutingTableEntry CreateMulticastRoute (Ipv4Address origin,
Ipv4Address group, uint32_t inputInterface,
std::vector<uint32_t> outputInterfaces);
--- a/src/node/ipv4-static-routing.h Fri Jun 05 16:06:25 2009 +0400
+++ b/src/node/ipv4-static-routing.h Mon Jun 08 15:12:15 2009 +0400
@@ -44,6 +44,8 @@
class Ipv4MulticastRoutingTableEntry;
/**
+ * \ingroup ipv4-routing
+ *
* \brief Static routing protocol for IP version 4 stacks.
*
* In ns-3 we have the concept of a pluggable routing protocol. Routing
--- a/src/node/ipv4.h Fri Jun 05 16:06:25 2009 +0400
+++ b/src/node/ipv4.h Mon Jun 08 15:12:15 2009 +0400
@@ -37,9 +37,7 @@
/**
* \ingroup node
* \defgroup ipv4 Ipv4
- */
-
-/**
+ *
* \brief Access to the Ipv4 forwarding table, interfaces, and configuration
*
* This class defines the API to manipulate the following aspects of
@@ -84,7 +82,7 @@
* registered. If you want to add multiple routing protocols, you must
* add them to a Ipv4ListRoutingProtocol directly.
*
- * \param routing smart pointer to Ipv4RoutingProtocol object
+ * \param routingProtocol smart pointer to Ipv4RoutingProtocol object
*/
virtual void SetRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol) = 0;
@@ -132,7 +130,8 @@
* has an Ipv4 address within the prefix specified by the input
* address and mask parameters
*
- * \param addr The IP address assigned to the interface of interest.
+ * \param address The IP address assigned to the interface of interest.
+ * \param mask The IP prefix to use in the mask
* \returns The interface number of the Ipv4 interface with the given
* address or -1 if not found.
*
@@ -206,7 +205,7 @@
virtual bool IsUp (uint32_t interface) const = 0;
/**
- * \param i interface Interface number of Ipv4 interface
+ * \param interface Interface number of Ipv4 interface
*
* Set the interface into the "up" state. In this state, it is
* considered valid during Ipv4 forwarding.
--- a/src/node/net-device.h Fri Jun 05 16:06:25 2009 +0400
+++ b/src/node/net-device.h Mon Jun 08 15:12:15 2009 +0400
@@ -91,7 +91,9 @@
/**
* \return the channel this NetDevice is connected to. The value
* returned can be zero if the NetDevice is not yet connected
- * to any channel.
+ * to any channel or if the underlying NetDevice has no
+ * concept of a channel. i.e., callers _must_ check for zero
+ * and be ready to handle it.
*/
virtual Ptr<Channel> GetChannel (void) const = 0;
--- a/src/node/wscript Fri Jun 05 16:06:25 2009 +0400
+++ b/src/node/wscript Mon Jun 08 15:12:15 2009 +0400
@@ -52,7 +52,6 @@
'mac48-address.h',
'mac64-address.h',
'inet-socket-address.h',
- 'ipv4-interface-address.h',
'packet-socket-address.h',
'node.h',
'ipv4-address.h',
--- a/src/routing/olsr/olsr-repositories.h Fri Jun 05 16:06:25 2009 +0400
+++ b/src/routing/olsr/olsr-repositories.h Mon Jun 08 15:12:15 2009 +0400
@@ -21,7 +21,7 @@
*/
///
-/// \file OLSR_olsr-repositories.h
+/// \file olsr-repositories.h
/// \brief Here are defined all data structures needed by an OLSR node.
///