1.1 --- a/AUTHORS Tue Jun 09 18:00:24 2009 +0100
1.2 +++ b/AUTHORS Tue Jun 09 18:00:52 2009 +0100
1.3 @@ -1,3 +1,5 @@
1.4 +Nicola Baldo (nbaldo@cttc.es)
1.5 +Mirko Banchi (mk.banchi@gmail.com)
1.6 Raj Bhattacharjea (raj.b@gatech.edu)
1.7 Gustavo Carneiro (gjc@inescporto.pt, gjcarneiro@gmail.com)
1.8 Craig Dowell (craigdo@ee.washington.edu)
1.9 @@ -24,4 +26,5 @@
1.10 Liu Jian (liujatp@gmail.com)
1.11 Andrey Hippo (ahippo@yandex.ru)
1.12 Francesco Malandrino (francesco.malandrino@gmail.com)
1.13 -
1.14 +Faker Moatamri (faker.moatamri@sophia.inria.fr)
1.15 +Guangyu Pei (guangyu.pei@boeing.com)
2.1 --- a/CHANGES.html Tue Jun 09 18:00:24 2009 +0100
2.2 +++ b/CHANGES.html Tue Jun 09 18:00:52 2009 +0100
2.3 @@ -51,16 +51,82 @@
2.4 </ul>
2.5
2.6 <h2>New API:</h2>
2.7 +
2.8 <ul>
2.9 +<li><b>YansWifiPhyHelper supporting radiotap and prism PCAP output</b>
2.10 +<p>The newly supported pcap formats can be adopted by calling the following new method of YansWifiPhyHelper:</p>
2.11 +<pre>
2.12 + + void SetPcapFormat (enum PcapFormat format);
2.13 +</pre>
2.14 +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>
2.15 +</li>
2.16 +
2.17 <li> <b>attributes for class Ipv4</b>
2.18 <p> class Ipv4 now contains attributes in ipv4.cc; the first one
2.19 is called "IpForward" that will enable/disable Ipv4 forwarding.
2.20 </li>
2.21 +
2.22 +<li> <b>packet tags</b>
2.23 +<p>class Packet now contains AddPacketTag, RemovePacketTag and PeekPacketTag
2.24 +which can be used to attach a tag to a packet, as opposed to the old
2.25 +AddTag method which attached a tag to a set of bytes. The main
2.26 +semantic difference is in how these tags behave in the presence of
2.27 +fragmentation and reassembly.
2.28 +</li>
2.29 +
2.30 </ul>
2.31
2.32 <h2>Changes to existing API:</h2>
2.33 <ul>
2.34
2.35 +<li> <b>packet byte tags renaming</b>
2.36 + <ul>
2.37 + <li>Packet::AddTag to Packet::AddByteTag</li>
2.38 + <li>Packet::FindFirstMatchingTag to Packet::FindFirstMatchingByteTag</li>
2.39 + <li>Packet::RemoveAllTags to Packet::RemoveAllByteTags</li>
2.40 + <li>Packet::PrintTags to Packet::PrintByteTags</li>
2.41 + <li>Packet::GetTagIterator to Packet::GetByteTagIterator</li>
2.42 + </ul>
2.43 +</li>
2.44 +
2.45 +<li><b>YansWifiPhyHelper::EnablePcap* methods not static any more</b>
2.46 +<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:
2.47 +<pre>
2.48 +- static void EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid);
2.49 ++ void EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid);
2.50 +- static void EnablePcap (std::string filename, Ptr<NetDevice> nd);
2.51 ++ void EnablePcap (std::string filename, Ptr<NetDevice> nd);
2.52 +- static void EnablePcap (std::string filename, std::string ndName);
2.53 ++ void EnablePcap (std::string filename, std::string ndName);
2.54 +- static void EnablePcap (std::string filename, NetDeviceContainer d);
2.55 ++ void EnablePcap (std::string filename, NetDeviceContainer d);
2.56 +- static void EnablePcap (std::string filename, NodeContainer n);
2.57 ++ void EnablePcap (std::string filename, NodeContainer n);
2.58 +- static void EnablePcapAll (std::string filename);
2.59 ++ void EnablePcapAll (std::string filename);
2.60 +</pre>
2.61 +</p>
2.62 +</li>
2.63 +
2.64 +<li><b>Wifi Promisc Sniff interface modified </b>
2.65 +<p>
2.66 +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:
2.67 +<pre>
2.68 +- void NotifyPromiscSniff (Ptr<const Packet> packet);
2.69 ++ void NotifyPromiscSniffRx (Ptr<const Packet> packet, uint16_t channelFreqMhz, uint32_t rate, bool isShortPreamble, double signalDbm, double noiseDbm);
2.70 ++ void NotifyPromiscSniffTx (Ptr<const Packet> packet, uint16_t channelFreqMhz, uint32_t rate, bool isShortPreamble);
2.71 +- TracedCallback<Ptr<const Packet> > m_phyPromiscSnifferTrace;
2.72 ++ TracedCallback<Ptr<const Packet>, uint16_t, uint32_t, bool, double, double> m_phyPromiscSniffRxTrace;
2.73 ++ TracedCallback<Ptr<const Packet>, uint16_t, uint32_t, bool> m_phyPromiscSniffTxTrace;
2.74 +</pre>
2.75 +The above mentioned callbacks are expected to be used to call the following method to write Wifi PCAP traces in promiscuous mode:
2.76 +<pre>
2.77 ++ void WriteWifiMonitorPacket(Ptr<const Packet> packet, uint16_t channelFreqMhz, uint32_t rate, bool isShortPreamble, bool isTx, double signalDbm, double noiseDbm);
2.78 +</pre>
2.79 +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
2.80 +</p>
2.81 +</li>
2.82 +
2.83 <li><b> Routing decoupled from class Ipv4</b>
2.84 <p> All calls of the form "Ipv4::AddHostRouteTo ()" etc. (i.e. to
2.85 add static routes, both unicast and multicast) have been moved to a new
3.1 --- a/RELEASE_NOTES Tue Jun 09 18:00:24 2009 +0100
3.2 +++ b/RELEASE_NOTES Tue Jun 09 18:00:52 2009 +0100
3.3 @@ -25,6 +25,7 @@
3.4 b) 802.11 PHY:
3.5 - 802.11b PHY support (Gary Pei)
3.6 - Nakagami propagation loss model (Timo Bingmann)
3.7 + - radiotap and prism headers for PCAP output (Nicola Baldo)
3.8 c) GammaVariable and ErlangVariable (Timo Bingmann)
3.9
3.10 API changes from ns-3.4
4.1 --- a/bindings/python/ns3_module_common.py Tue Jun 09 18:00:24 2009 +0100
4.2 +++ b/bindings/python/ns3_module_common.py Tue Jun 09 18:00:52 2009 +0100
4.3 @@ -9,6 +9,16 @@
4.4 module.add_class('Buffer')
4.5 ## buffer.h: ns3::Buffer::Iterator [class]
4.6 module.add_class('Iterator', outer_class=root_module['ns3::Buffer'])
4.7 + ## packet.h: ns3::ByteTagIterator [class]
4.8 + module.add_class('ByteTagIterator')
4.9 + ## packet.h: ns3::ByteTagIterator::Item [class]
4.10 + module.add_class('Item', outer_class=root_module['ns3::ByteTagIterator'])
4.11 + ## byte-tag-list.h: ns3::ByteTagList [class]
4.12 + module.add_class('ByteTagList')
4.13 + ## byte-tag-list.h: ns3::ByteTagList::Iterator [class]
4.14 + module.add_class('Iterator', outer_class=root_module['ns3::ByteTagList'])
4.15 + ## byte-tag-list.h: ns3::ByteTagList::Iterator::Item [struct]
4.16 + module.add_class('Item', outer_class=root_module['ns3::ByteTagList::Iterator'])
4.17 ## data-rate.h: ns3::DataRate [class]
4.18 module.add_class('DataRate')
4.19 ## packet.h: ns3::Packet [class]
4.20 @@ -21,20 +31,18 @@
4.21 module.add_enum('', ['PAYLOAD', 'HEADER', 'TRAILER'], outer_class=root_module['ns3::PacketMetadata::Item'])
4.22 ## packet-metadata.h: ns3::PacketMetadata::ItemIterator [class]
4.23 module.add_class('ItemIterator', outer_class=root_module['ns3::PacketMetadata'])
4.24 + ## packet.h: ns3::PacketTagIterator [class]
4.25 + module.add_class('PacketTagIterator')
4.26 + ## packet.h: ns3::PacketTagIterator::Item [class]
4.27 + module.add_class('Item', outer_class=root_module['ns3::PacketTagIterator'])
4.28 + ## packet-tag-list.h: ns3::PacketTagList [class]
4.29 + module.add_class('PacketTagList')
4.30 + ## packet-tag-list.h: ns3::PacketTagList::TagData [struct]
4.31 + module.add_class('TagData', outer_class=root_module['ns3::PacketTagList'])
4.32 ## tag.h: ns3::Tag [class]
4.33 module.add_class('Tag', parent=root_module['ns3::ObjectBase'])
4.34 ## tag-buffer.h: ns3::TagBuffer [class]
4.35 module.add_class('TagBuffer')
4.36 - ## packet.h: ns3::TagIterator [class]
4.37 - module.add_class('TagIterator')
4.38 - ## packet.h: ns3::TagIterator::Item [class]
4.39 - module.add_class('Item', outer_class=root_module['ns3::TagIterator'])
4.40 - ## tag-list.h: ns3::TagList [class]
4.41 - module.add_class('TagList')
4.42 - ## tag-list.h: ns3::TagList::Iterator [class]
4.43 - module.add_class('Iterator', outer_class=root_module['ns3::TagList'])
4.44 - ## tag-list.h: ns3::TagList::Iterator::Item [struct]
4.45 - module.add_class('Item', outer_class=root_module['ns3::TagList::Iterator'])
4.46 ## chunk.h: ns3::Chunk [class]
4.47 module.add_class('Chunk', parent=root_module['ns3::ObjectBase'])
4.48 ## data-rate.h: ns3::DataRateChecker [class]
4.49 @@ -107,18 +115,22 @@
4.50 def register_methods(root_module):
4.51 register_Ns3Buffer_methods(root_module, root_module['ns3::Buffer'])
4.52 register_Ns3BufferIterator_methods(root_module, root_module['ns3::Buffer::Iterator'])
4.53 + register_Ns3ByteTagIterator_methods(root_module, root_module['ns3::ByteTagIterator'])
4.54 + register_Ns3ByteTagIteratorItem_methods(root_module, root_module['ns3::ByteTagIterator::Item'])
4.55 + register_Ns3ByteTagList_methods(root_module, root_module['ns3::ByteTagList'])
4.56 + register_Ns3ByteTagListIterator_methods(root_module, root_module['ns3::ByteTagList::Iterator'])
4.57 + register_Ns3ByteTagListIteratorItem_methods(root_module, root_module['ns3::ByteTagList::Iterator::Item'])
4.58 register_Ns3DataRate_methods(root_module, root_module['ns3::DataRate'])
4.59 register_Ns3Packet_methods(root_module, root_module['ns3::Packet'])
4.60 register_Ns3PacketMetadata_methods(root_module, root_module['ns3::PacketMetadata'])
4.61 register_Ns3PacketMetadataItem_methods(root_module, root_module['ns3::PacketMetadata::Item'])
4.62 register_Ns3PacketMetadataItemIterator_methods(root_module, root_module['ns3::PacketMetadata::ItemIterator'])
4.63 + register_Ns3PacketTagIterator_methods(root_module, root_module['ns3::PacketTagIterator'])
4.64 + register_Ns3PacketTagIteratorItem_methods(root_module, root_module['ns3::PacketTagIterator::Item'])
4.65 + register_Ns3PacketTagList_methods(root_module, root_module['ns3::PacketTagList'])
4.66 + register_Ns3PacketTagListTagData_methods(root_module, root_module['ns3::PacketTagList::TagData'])
4.67 register_Ns3Tag_methods(root_module, root_module['ns3::Tag'])
4.68 register_Ns3TagBuffer_methods(root_module, root_module['ns3::TagBuffer'])
4.69 - register_Ns3TagIterator_methods(root_module, root_module['ns3::TagIterator'])
4.70 - register_Ns3TagIteratorItem_methods(root_module, root_module['ns3::TagIterator::Item'])
4.71 - register_Ns3TagList_methods(root_module, root_module['ns3::TagList'])
4.72 - register_Ns3TagListIterator_methods(root_module, root_module['ns3::TagList::Iterator'])
4.73 - register_Ns3TagListIteratorItem_methods(root_module, root_module['ns3::TagList::Iterator::Item'])
4.74 register_Ns3Chunk_methods(root_module, root_module['ns3::Chunk'])
4.75 register_Ns3DataRateChecker_methods(root_module, root_module['ns3::DataRateChecker'])
4.76 register_Ns3DataRateValue_methods(root_module, root_module['ns3::DataRateValue'])
4.77 @@ -191,6 +203,11 @@
4.78 'int32_t',
4.79 [],
4.80 is_const=True)
4.81 + ## buffer.h: void ns3::Buffer::CopyData(std::ostream * os, uint32_t size) const [member function]
4.82 + cls.add_method('CopyData',
4.83 + 'void',
4.84 + [param('std::ostream *', 'os'), param('uint32_t', 'size')],
4.85 + is_const=True)
4.86 ## buffer.h: ns3::Buffer::Buffer(ns3::Buffer const & o) [copy constructor]
4.87 cls.add_constructor([param('ns3::Buffer const &', 'o')])
4.88 ## buffer.h: ns3::Buffer::Buffer() [constructor]
4.89 @@ -346,6 +363,113 @@
4.90 is_const=True)
4.91 return
4.92
4.93 +def register_Ns3ByteTagIterator_methods(root_module, cls):
4.94 + ## packet.h: ns3::ByteTagIterator::ByteTagIterator(ns3::ByteTagIterator const & arg0) [copy constructor]
4.95 + cls.add_constructor([param('ns3::ByteTagIterator const &', 'arg0')])
4.96 + ## packet.h: bool ns3::ByteTagIterator::HasNext() const [member function]
4.97 + cls.add_method('HasNext',
4.98 + 'bool',
4.99 + [],
4.100 + is_const=True)
4.101 + ## packet.h: ns3::ByteTagIterator::Item ns3::ByteTagIterator::Next() [member function]
4.102 + cls.add_method('Next',
4.103 + 'ns3::ByteTagIterator::Item',
4.104 + [])
4.105 + return
4.106 +
4.107 +def register_Ns3ByteTagIteratorItem_methods(root_module, cls):
4.108 + ## packet.h: ns3::ByteTagIterator::Item::Item(ns3::ByteTagIterator::Item const & arg0) [copy constructor]
4.109 + cls.add_constructor([param('ns3::ByteTagIterator::Item const &', 'arg0')])
4.110 + ## packet.h: ns3::TypeId ns3::ByteTagIterator::Item::GetTypeId() const [member function]
4.111 + cls.add_method('GetTypeId',
4.112 + 'ns3::TypeId',
4.113 + [],
4.114 + is_const=True)
4.115 + ## packet.h: uint32_t ns3::ByteTagIterator::Item::GetStart() const [member function]
4.116 + cls.add_method('GetStart',
4.117 + 'uint32_t',
4.118 + [],
4.119 + is_const=True)
4.120 + ## packet.h: uint32_t ns3::ByteTagIterator::Item::GetEnd() const [member function]
4.121 + cls.add_method('GetEnd',
4.122 + 'uint32_t',
4.123 + [],
4.124 + is_const=True)
4.125 + ## packet.h: void ns3::ByteTagIterator::Item::GetTag(ns3::Tag & tag) const [member function]
4.126 + cls.add_method('GetTag',
4.127 + 'void',
4.128 + [param('ns3::Tag &', 'tag')],
4.129 + is_const=True)
4.130 + return
4.131 +
4.132 +def register_Ns3ByteTagList_methods(root_module, cls):
4.133 + ## byte-tag-list.h: ns3::ByteTagList::ByteTagList() [constructor]
4.134 + cls.add_constructor([])
4.135 + ## byte-tag-list.h: ns3::ByteTagList::ByteTagList(ns3::ByteTagList const & o) [copy constructor]
4.136 + cls.add_constructor([param('ns3::ByteTagList const &', 'o')])
4.137 + ## byte-tag-list.h: ns3::TagBuffer ns3::ByteTagList::Add(ns3::TypeId tid, uint32_t bufferSize, int32_t start, int32_t end) [member function]
4.138 + cls.add_method('Add',
4.139 + 'ns3::TagBuffer',
4.140 + [param('ns3::TypeId', 'tid'), param('uint32_t', 'bufferSize'), param('int32_t', 'start'), param('int32_t', 'end')])
4.141 + ## byte-tag-list.h: void ns3::ByteTagList::Add(ns3::ByteTagList const & o) [member function]
4.142 + cls.add_method('Add',
4.143 + 'void',
4.144 + [param('ns3::ByteTagList const &', 'o')])
4.145 + ## byte-tag-list.h: void ns3::ByteTagList::RemoveAll() [member function]
4.146 + cls.add_method('RemoveAll',
4.147 + 'void',
4.148 + [])
4.149 + ## byte-tag-list.h: ns3::ByteTagList::Iterator ns3::ByteTagList::Begin(int32_t offsetStart, int32_t offsetEnd) const [member function]
4.150 + cls.add_method('Begin',
4.151 + 'ns3::ByteTagList::Iterator',
4.152 + [param('int32_t', 'offsetStart'), param('int32_t', 'offsetEnd')],
4.153 + is_const=True)
4.154 + ## byte-tag-list.h: void ns3::ByteTagList::AddAtEnd(int32_t adjustment, int32_t appendOffset) [member function]
4.155 + cls.add_method('AddAtEnd',
4.156 + 'void',
4.157 + [param('int32_t', 'adjustment'), param('int32_t', 'appendOffset')])
4.158 + ## byte-tag-list.h: void ns3::ByteTagList::AddAtStart(int32_t adjustment, int32_t prependOffset) [member function]
4.159 + cls.add_method('AddAtStart',
4.160 + 'void',
4.161 + [param('int32_t', 'adjustment'), param('int32_t', 'prependOffset')])
4.162 + return
4.163 +
4.164 +def register_Ns3ByteTagListIterator_methods(root_module, cls):
4.165 + ## byte-tag-list.h: ns3::ByteTagList::Iterator::Iterator(ns3::ByteTagList::Iterator const & arg0) [copy constructor]
4.166 + cls.add_constructor([param('ns3::ByteTagList::Iterator const &', 'arg0')])
4.167 + ## byte-tag-list.h: bool ns3::ByteTagList::Iterator::HasNext() const [member function]
4.168 + cls.add_method('HasNext',
4.169 + 'bool',
4.170 + [],
4.171 + is_const=True)
4.172 + ## byte-tag-list.h: ns3::ByteTagList::Iterator::Item ns3::ByteTagList::Iterator::Next() [member function]
4.173 + cls.add_method('Next',
4.174 + 'ns3::ByteTagList::Iterator::Item',
4.175 + [])
4.176 + ## byte-tag-list.h: uint32_t ns3::ByteTagList::Iterator::GetOffsetStart() const [member function]
4.177 + cls.add_method('GetOffsetStart',
4.178 + 'uint32_t',
4.179 + [],
4.180 + is_const=True)
4.181 + return
4.182 +
4.183 +def register_Ns3ByteTagListIteratorItem_methods(root_module, cls):
4.184 + ## byte-tag-list.h: ns3::ByteTagList::Iterator::Item::tid [variable]
4.185 + cls.add_instance_attribute('tid', 'ns3::TypeId', is_const=False)
4.186 + ## byte-tag-list.h: ns3::ByteTagList::Iterator::Item::size [variable]
4.187 + cls.add_instance_attribute('size', 'uint32_t', is_const=False)
4.188 + ## byte-tag-list.h: ns3::ByteTagList::Iterator::Item::start [variable]
4.189 + cls.add_instance_attribute('start', 'int32_t', is_const=False)
4.190 + ## byte-tag-list.h: ns3::ByteTagList::Iterator::Item::end [variable]
4.191 + cls.add_instance_attribute('end', 'int32_t', is_const=False)
4.192 + ## byte-tag-list.h: ns3::ByteTagList::Iterator::Item::buf [variable]
4.193 + cls.add_instance_attribute('buf', 'ns3::TagBuffer', is_const=False)
4.194 + ## byte-tag-list.h: ns3::ByteTagList::Iterator::Item::Item(ns3::ByteTagList::Iterator::Item const & arg0) [copy constructor]
4.195 + cls.add_constructor([param('ns3::ByteTagList::Iterator::Item const &', 'arg0')])
4.196 + ## byte-tag-list.h: ns3::ByteTagList::Iterator::Item::Item(ns3::TagBuffer buf) [constructor]
4.197 + cls.add_constructor([param('ns3::TagBuffer', 'buf')])
4.198 + return
4.199 +
4.200 def register_Ns3DataRate_methods(root_module, cls):
4.201 cls.add_output_stream_operator()
4.202 cls.add_binary_comparison_operator('!=')
4.203 @@ -388,19 +512,24 @@
4.204 cls.add_method('AddAtEnd',
4.205 'void',
4.206 [param('ns3::Ptr< ns3::Packet const >', 'packet')])
4.207 + ## packet.h: void ns3::Packet::AddByteTag(ns3::Tag const & tag) const [member function]
4.208 + cls.add_method('AddByteTag',
4.209 + 'void',
4.210 + [param('ns3::Tag const &', 'tag')],
4.211 + is_const=True)
4.212 ## packet.h: void ns3::Packet::AddHeader(ns3::Header const & header) [member function]
4.213 cls.add_method('AddHeader',
4.214 'void',
4.215 [param('ns3::Header const &', 'header')])
4.216 + ## packet.h: void ns3::Packet::AddPacketTag(ns3::Tag const & tag) const [member function]
4.217 + cls.add_method('AddPacketTag',
4.218 + 'void',
4.219 + [param('ns3::Tag const &', 'tag')],
4.220 + is_const=True)
4.221 ## packet.h: void ns3::Packet::AddPaddingAtEnd(uint32_t size) [member function]
4.222 cls.add_method('AddPaddingAtEnd',
4.223 'void',
4.224 [param('uint32_t', 'size')])
4.225 - ## packet.h: void ns3::Packet::AddTag(ns3::Tag const & tag) const [member function]
4.226 - cls.add_method('AddTag',
4.227 - 'void',
4.228 - [param('ns3::Tag const &', 'tag')],
4.229 - is_const=True)
4.230 ## packet.h: void ns3::Packet::AddTrailer(ns3::Trailer const & trailer) [member function]
4.231 cls.add_method('AddTrailer',
4.232 'void',
4.233 @@ -420,6 +549,11 @@
4.234 'uint32_t',
4.235 [param('uint8_t *', 'buffer'), param('uint32_t', 'size')],
4.236 is_const=True)
4.237 + ## packet.h: void ns3::Packet::CopyData(std::ostream * os, uint32_t size) const [member function]
4.238 + cls.add_method('CopyData',
4.239 + 'void',
4.240 + [param('std::ostream *', 'os'), param('uint32_t', 'size')],
4.241 + is_const=True)
4.242 ## packet.h: ns3::Ptr<ns3::Packet> ns3::Packet::CreateFragment(uint32_t start, uint32_t length) const [member function]
4.243 cls.add_method('CreateFragment',
4.244 'ns3::Ptr< ns3::Packet >',
4.245 @@ -439,21 +573,26 @@
4.246 'void',
4.247 [],
4.248 is_static=True)
4.249 - ## packet.h: bool ns3::Packet::FindFirstMatchingTag(ns3::Tag & tag) const [member function]
4.250 - cls.add_method('FindFirstMatchingTag',
4.251 + ## packet.h: bool ns3::Packet::FindFirstMatchingByteTag(ns3::Tag & tag) const [member function]
4.252 + cls.add_method('FindFirstMatchingByteTag',
4.253 'bool',
4.254 [param('ns3::Tag &', 'tag')],
4.255 is_const=True)
4.256 + ## packet.h: ns3::ByteTagIterator ns3::Packet::GetByteTagIterator() const [member function]
4.257 + cls.add_method('GetByteTagIterator',
4.258 + 'ns3::ByteTagIterator',
4.259 + [],
4.260 + is_const=True)
4.261 + ## packet.h: ns3::PacketTagIterator ns3::Packet::GetPacketTagIterator() const [member function]
4.262 + cls.add_method('GetPacketTagIterator',
4.263 + 'ns3::PacketTagIterator',
4.264 + [],
4.265 + is_const=True)
4.266 ## packet.h: uint32_t ns3::Packet::GetSize() const [member function]
4.267 cls.add_method('GetSize',
4.268 'uint32_t',
4.269 [],
4.270 is_const=True)
4.271 - ## packet.h: ns3::TagIterator ns3::Packet::GetTagIterator() const [member function]
4.272 - cls.add_method('GetTagIterator',
4.273 - 'ns3::TagIterator',
4.274 - [],
4.275 - is_const=True)
4.276 ## packet.h: uint32_t ns3::Packet::GetUid() const [member function]
4.277 cls.add_method('GetUid',
4.278 'uint32_t',
4.279 @@ -469,6 +608,11 @@
4.280 'uint32_t',
4.281 [param('ns3::Header &', 'header')],
4.282 is_const=True)
4.283 + ## packet.h: bool ns3::Packet::PeekPacketTag(ns3::Tag & tag) const [member function]
4.284 + cls.add_method('PeekPacketTag',
4.285 + 'bool',
4.286 + [param('ns3::Tag &', 'tag')],
4.287 + is_const=True)
4.288 ## packet.h: uint32_t ns3::Packet::PeekTrailer(ns3::Trailer & trailer) [member function]
4.289 cls.add_method('PeekTrailer',
4.290 'uint32_t',
4.291 @@ -478,13 +622,22 @@
4.292 'void',
4.293 [param('std::ostream &', 'os')],
4.294 is_const=True)
4.295 - ## packet.h: void ns3::Packet::PrintTags(std::ostream & os) const [member function]
4.296 - cls.add_method('PrintTags',
4.297 + ## packet.h: void ns3::Packet::PrintByteTags(std::ostream & os) const [member function]
4.298 + cls.add_method('PrintByteTags',
4.299 'void',
4.300 [param('std::ostream &', 'os')],
4.301 is_const=True)
4.302 - ## packet.h: void ns3::Packet::RemoveAllTags() [member function]
4.303 - cls.add_method('RemoveAllTags',
4.304 + ## packet.h: void ns3::Packet::PrintPacketTags(std::ostream & os) const [member function]
4.305 + cls.add_method('PrintPacketTags',
4.306 + 'void',
4.307 + [param('std::ostream &', 'os')],
4.308 + is_const=True)
4.309 + ## packet.h: void ns3::Packet::RemoveAllByteTags() [member function]
4.310 + cls.add_method('RemoveAllByteTags',
4.311 + 'void',
4.312 + [])
4.313 + ## packet.h: void ns3::Packet::RemoveAllPacketTags() [member function]
4.314 + cls.add_method('RemoveAllPacketTags',
4.315 'void',
4.316 [])
4.317 ## packet.h: void ns3::Packet::RemoveAtEnd(uint32_t size) [member function]
4.318 @@ -499,6 +652,10 @@
4.319 cls.add_method('RemoveHeader',
4.320 'uint32_t',
4.321 [param('ns3::Header &', 'header')])
4.322 + ## packet.h: bool ns3::Packet::RemovePacketTag(ns3::Tag & tag) [member function]
4.323 + cls.add_method('RemovePacketTag',
4.324 + 'bool',
4.325 + [param('ns3::Tag &', 'tag')])
4.326 ## packet.h: uint32_t ns3::Packet::RemoveTrailer(ns3::Trailer & trailer) [member function]
4.327 cls.add_method('RemoveTrailer',
4.328 'uint32_t',
4.329 @@ -623,6 +780,80 @@
4.330 [])
4.331 return
4.332
4.333 +def register_Ns3PacketTagIterator_methods(root_module, cls):
4.334 + ## packet.h: ns3::PacketTagIterator::PacketTagIterator(ns3::PacketTagIterator const & arg0) [copy constructor]
4.335 + cls.add_constructor([param('ns3::PacketTagIterator const &', 'arg0')])
4.336 + ## packet.h: bool ns3::PacketTagIterator::HasNext() const [member function]
4.337 + cls.add_method('HasNext',
4.338 + 'bool',
4.339 + [],
4.340 + is_const=True)
4.341 + ## packet.h: ns3::PacketTagIterator::Item ns3::PacketTagIterator::Next() [member function]
4.342 + cls.add_method('Next',
4.343 + 'ns3::PacketTagIterator::Item',
4.344 + [])
4.345 + return
4.346 +
4.347 +def register_Ns3PacketTagIteratorItem_methods(root_module, cls):
4.348 + ## packet.h: ns3::PacketTagIterator::Item::Item(ns3::PacketTagIterator::Item const & arg0) [copy constructor]
4.349 + cls.add_constructor([param('ns3::PacketTagIterator::Item const &', 'arg0')])
4.350 + ## packet.h: ns3::TypeId ns3::PacketTagIterator::Item::GetTypeId() const [member function]
4.351 + cls.add_method('GetTypeId',
4.352 + 'ns3::TypeId',
4.353 + [],
4.354 + is_const=True)
4.355 + ## packet.h: void ns3::PacketTagIterator::Item::GetTag(ns3::Tag & tag) const [member function]
4.356 + cls.add_method('GetTag',
4.357 + 'void',
4.358 + [param('ns3::Tag &', 'tag')],
4.359 + is_const=True)
4.360 + return
4.361 +
4.362 +def register_Ns3PacketTagList_methods(root_module, cls):
4.363 + ## packet-tag-list.h: ns3::PacketTagList::PacketTagList() [constructor]
4.364 + cls.add_constructor([])
4.365 + ## packet-tag-list.h: ns3::PacketTagList::PacketTagList(ns3::PacketTagList const & o) [copy constructor]
4.366 + cls.add_constructor([param('ns3::PacketTagList const &', 'o')])
4.367 + ## packet-tag-list.h: void ns3::PacketTagList::Add(ns3::Tag const & tag) const [member function]
4.368 + cls.add_method('Add',
4.369 + 'void',
4.370 + [param('ns3::Tag const &', 'tag')],
4.371 + is_const=True)
4.372 + ## packet-tag-list.h: bool ns3::PacketTagList::Remove(ns3::Tag & tag) [member function]
4.373 + cls.add_method('Remove',
4.374 + 'bool',
4.375 + [param('ns3::Tag &', 'tag')])
4.376 + ## packet-tag-list.h: bool ns3::PacketTagList::Peek(ns3::Tag & tag) const [member function]
4.377 + cls.add_method('Peek',
4.378 + 'bool',
4.379 + [param('ns3::Tag &', 'tag')],
4.380 + is_const=True)
4.381 + ## packet-tag-list.h: void ns3::PacketTagList::RemoveAll() [member function]
4.382 + cls.add_method('RemoveAll',
4.383 + 'void',
4.384 + [])
4.385 + ## packet-tag-list.h: ns3::PacketTagList::TagData const * ns3::PacketTagList::Head() const [member function]
4.386 + cls.add_method('Head',
4.387 + 'ns3::PacketTagList::TagData const *',
4.388 + [],
4.389 + is_const=True)
4.390 + return
4.391 +
4.392 +def register_Ns3PacketTagListTagData_methods(root_module, cls):
4.393 + ## packet-tag-list.h: ns3::PacketTagList::TagData::data [variable]
4.394 + cls.add_instance_attribute('data', 'uint8_t [ 20 ]', is_const=False)
4.395 + ## packet-tag-list.h: ns3::PacketTagList::TagData::next [variable]
4.396 + cls.add_instance_attribute('next', 'ns3::PacketTagList::TagData *', is_const=False)
4.397 + ## packet-tag-list.h: ns3::PacketTagList::TagData::tid [variable]
4.398 + cls.add_instance_attribute('tid', 'ns3::TypeId', is_const=False)
4.399 + ## packet-tag-list.h: ns3::PacketTagList::TagData::count [variable]
4.400 + cls.add_instance_attribute('count', 'uint32_t', is_const=False)
4.401 + ## packet-tag-list.h: ns3::PacketTagList::TagData::TagData(ns3::PacketTagList::TagData const & arg0) [copy constructor]
4.402 + cls.add_constructor([param('ns3::PacketTagList::TagData const &', 'arg0')])
4.403 + ## packet-tag-list.h: ns3::PacketTagList::TagData::TagData() [constructor]
4.404 + cls.add_constructor([])
4.405 + return
4.406 +
4.407 def register_Ns3Tag_methods(root_module, cls):
4.408 ## tag.h: ns3::Tag::Tag(ns3::Tag const & arg0) [copy constructor]
4.409 cls.add_constructor([param('ns3::Tag const &', 'arg0')])
4.410 @@ -718,113 +949,6 @@
4.411 [param('uint8_t *', 'buffer'), param('uint32_t', 'size')])
4.412 return
4.413
4.414 -def register_Ns3TagIterator_methods(root_module, cls):
4.415 - ## packet.h: ns3::TagIterator::TagIterator(ns3::TagIterator const & arg0) [copy constructor]
4.416 - cls.add_constructor([param('ns3::TagIterator const &', 'arg0')])
4.417 - ## packet.h: bool ns3::TagIterator::HasNext() const [member function]
4.418 - cls.add_method('HasNext',
4.419 - 'bool',
4.420 - [],
4.421 - is_const=True)
4.422 - ## packet.h: ns3::TagIterator::Item ns3::TagIterator::Next() [member function]
4.423 - cls.add_method('Next',
4.424 - 'ns3::TagIterator::Item',
4.425 - [])
4.426 - return
4.427 -
4.428 -def register_Ns3TagIteratorItem_methods(root_module, cls):
4.429 - ## packet.h: ns3::TagIterator::Item::Item(ns3::TagIterator::Item const & arg0) [copy constructor]
4.430 - cls.add_constructor([param('ns3::TagIterator::Item const &', 'arg0')])
4.431 - ## packet.h: ns3::TypeId ns3::TagIterator::Item::GetTypeId() const [member function]
4.432 - cls.add_method('GetTypeId',
4.433 - 'ns3::TypeId',
4.434 - [],
4.435 - is_const=True)
4.436 - ## packet.h: uint32_t ns3::TagIterator::Item::GetStart() const [member function]
4.437 - cls.add_method('GetStart',
4.438 - 'uint32_t',
4.439 - [],
4.440 - is_const=True)
4.441 - ## packet.h: uint32_t ns3::TagIterator::Item::GetEnd() const [member function]
4.442 - cls.add_method('GetEnd',
4.443 - 'uint32_t',
4.444 - [],
4.445 - is_const=True)
4.446 - ## packet.h: void ns3::TagIterator::Item::GetTag(ns3::Tag & tag) const [member function]
4.447 - cls.add_method('GetTag',
4.448 - 'void',
4.449 - [param('ns3::Tag &', 'tag')],
4.450 - is_const=True)
4.451 - return
4.452 -
4.453 -def register_Ns3TagList_methods(root_module, cls):
4.454 - ## tag-list.h: ns3::TagList::TagList() [constructor]
4.455 - cls.add_constructor([])
4.456 - ## tag-list.h: ns3::TagList::TagList(ns3::TagList const & o) [copy constructor]
4.457 - cls.add_constructor([param('ns3::TagList const &', 'o')])
4.458 - ## tag-list.h: ns3::TagBuffer ns3::TagList::Add(ns3::TypeId tid, uint32_t bufferSize, int32_t start, int32_t end) [member function]
4.459 - cls.add_method('Add',
4.460 - 'ns3::TagBuffer',
4.461 - [param('ns3::TypeId', 'tid'), param('uint32_t', 'bufferSize'), param('int32_t', 'start'), param('int32_t', 'end')])
4.462 - ## tag-list.h: void ns3::TagList::Add(ns3::TagList const & o) [member function]
4.463 - cls.add_method('Add',
4.464 - 'void',
4.465 - [param('ns3::TagList const &', 'o')])
4.466 - ## tag-list.h: void ns3::TagList::RemoveAll() [member function]
4.467 - cls.add_method('RemoveAll',
4.468 - 'void',
4.469 - [])
4.470 - ## tag-list.h: ns3::TagList::Iterator ns3::TagList::Begin(int32_t offsetStart, int32_t offsetEnd) const [member function]
4.471 - cls.add_method('Begin',
4.472 - 'ns3::TagList::Iterator',
4.473 - [param('int32_t', 'offsetStart'), param('int32_t', 'offsetEnd')],
4.474 - is_const=True)
4.475 - ## tag-list.h: void ns3::TagList::AddAtEnd(int32_t adjustment, int32_t appendOffset) [member function]
4.476 - cls.add_method('AddAtEnd',
4.477 - 'void',
4.478 - [param('int32_t', 'adjustment'), param('int32_t', 'appendOffset')])
4.479 - ## tag-list.h: void ns3::TagList::AddAtStart(int32_t adjustment, int32_t prependOffset) [member function]
4.480 - cls.add_method('AddAtStart',
4.481 - 'void',
4.482 - [param('int32_t', 'adjustment'), param('int32_t', 'prependOffset')])
4.483 - return
4.484 -
4.485 -def register_Ns3TagListIterator_methods(root_module, cls):
4.486 - ## tag-list.h: ns3::TagList::Iterator::Iterator(ns3::TagList::Iterator const & arg0) [copy constructor]
4.487 - cls.add_constructor([param('ns3::TagList::Iterator const &', 'arg0')])
4.488 - ## tag-list.h: bool ns3::TagList::Iterator::HasNext() const [member function]
4.489 - cls.add_method('HasNext',
4.490 - 'bool',
4.491 - [],
4.492 - is_const=True)
4.493 - ## tag-list.h: ns3::TagList::Iterator::Item ns3::TagList::Iterator::Next() [member function]
4.494 - cls.add_method('Next',
4.495 - 'ns3::TagList::Iterator::Item',
4.496 - [])
4.497 - ## tag-list.h: uint32_t ns3::TagList::Iterator::GetOffsetStart() const [member function]
4.498 - cls.add_method('GetOffsetStart',
4.499 - 'uint32_t',
4.500 - [],
4.501 - is_const=True)
4.502 - return
4.503 -
4.504 -def register_Ns3TagListIteratorItem_methods(root_module, cls):
4.505 - ## tag-list.h: ns3::TagList::Iterator::Item::tid [variable]
4.506 - cls.add_instance_attribute('tid', 'ns3::TypeId', is_const=False)
4.507 - ## tag-list.h: ns3::TagList::Iterator::Item::size [variable]
4.508 - cls.add_instance_attribute('size', 'uint32_t', is_const=False)
4.509 - ## tag-list.h: ns3::TagList::Iterator::Item::start [variable]
4.510 - cls.add_instance_attribute('start', 'int32_t', is_const=False)
4.511 - ## tag-list.h: ns3::TagList::Iterator::Item::end [variable]
4.512 - cls.add_instance_attribute('end', 'int32_t', is_const=False)
4.513 - ## tag-list.h: ns3::TagList::Iterator::Item::buf [variable]
4.514 - cls.add_instance_attribute('buf', 'ns3::TagBuffer', is_const=False)
4.515 - ## tag-list.h: ns3::TagList::Iterator::Item::Item(ns3::TagList::Iterator::Item const & arg0) [copy constructor]
4.516 - cls.add_constructor([param('ns3::TagList::Iterator::Item const &', 'arg0')])
4.517 - ## tag-list.h: ns3::TagList::Iterator::Item::Item(ns3::TagBuffer buf) [constructor]
4.518 - cls.add_constructor([param('ns3::TagBuffer', 'buf')])
4.519 - return
4.520 -
4.521 def register_Ns3Chunk_methods(root_module, cls):
4.522 ## chunk.h: ns3::Chunk::Chunk(ns3::Chunk const & arg0) [copy constructor]
4.523 cls.add_constructor([param('ns3::Chunk const &', 'arg0')])
4.524 @@ -941,6 +1065,14 @@
4.525 cls.add_method('WriteWifiHeader',
4.526 'void',
4.527 [])
4.528 + ## pcap-writer.h: void ns3::PcapWriter::WriteWifiRadiotapHeader() [member function]
4.529 + cls.add_method('WriteWifiRadiotapHeader',
4.530 + 'void',
4.531 + [])
4.532 + ## pcap-writer.h: void ns3::PcapWriter::WriteWifiPrismHeader() [member function]
4.533 + cls.add_method('WriteWifiPrismHeader',
4.534 + 'void',
4.535 + [])
4.536 ## pcap-writer.h: void ns3::PcapWriter::WritePppHeader() [member function]
4.537 cls.add_method('WritePppHeader',
4.538 'void',
4.539 @@ -949,6 +1081,10 @@
4.540 cls.add_method('WritePacket',
4.541 'void',
4.542 [param('ns3::Ptr< ns3::Packet const >', 'packet')])
4.543 + ## 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]
4.544 + cls.add_method('WriteWifiMonitorPacket',
4.545 + 'void',
4.546 + [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')])
4.547 return
4.548
4.549 def register_Ns3Trailer_methods(root_module, cls):
5.1 --- a/bindings/python/ns3_module_core.py Tue Jun 09 18:00:24 2009 +0100
5.2 +++ b/bindings/python/ns3_module_core.py Tue Jun 09 18:00:52 2009 +0100
5.3 @@ -495,10 +495,10 @@
5.4 cls.add_constructor([param('ns3::Names const &', 'arg0')])
5.5 ## names.h: ns3::Names::Names() [constructor]
5.6 cls.add_constructor([])
5.7 - ## names.h: static void ns3::Names::Add(std::string name, ns3::Ptr<ns3::Object> obj) [member function]
5.8 + ## names.h: static void ns3::Names::Add(std::string name, ns3::Ptr<ns3::Object> object) [member function]
5.9 cls.add_method('Add',
5.10 'void',
5.11 - [param('std::string', 'name'), param('ns3::Ptr< ns3::Object >', 'obj')],
5.12 + [param('std::string', 'name'), param('ns3::Ptr< ns3::Object >', 'object')],
5.13 is_static=True)
5.14 ## names.h: static void ns3::Names::Add(std::string path, std::string name, ns3::Ptr<ns3::Object> object) [member function]
5.15 cls.add_method('Add',
5.16 @@ -2043,7 +2043,7 @@
5.17 cls.add_method('ConnectWithoutContext',
5.18 'void',
5.19 [param('ns3::CallbackBase const &', 'cb')])
5.20 - ## 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]
5.21 + ## traced-value.h: void ns3::TracedValue<unsigned int>::Connect(ns3::CallbackBase const & cb, std::string path) [member function]
5.22 cls.add_method('Connect',
5.23 'void',
5.24 [param('ns3::CallbackBase const &', 'cb'), param('std::string', 'path')])
5.25 @@ -2051,7 +2051,7 @@
5.26 cls.add_method('DisconnectWithoutContext',
5.27 'void',
5.28 [param('ns3::CallbackBase const &', 'cb')])
5.29 - ## 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]
5.30 + ## traced-value.h: void ns3::TracedValue<unsigned int>::Disconnect(ns3::CallbackBase const & cb, std::string path) [member function]
5.31 cls.add_method('Disconnect',
5.32 'void',
5.33 [param('ns3::CallbackBase const &', 'cb'), param('std::string', 'path')])
5.34 @@ -2199,7 +2199,7 @@
5.35 module.add_function('TypeNameGet',
5.36 'std::string',
5.37 [],
5.38 - template_parameters=['long'])
5.39 + template_parameters=['long long'])
5.40 ## type-name.h: extern std::string ns3::TypeNameGet() [free function]
5.41 module.add_function('TypeNameGet',
5.42 'std::string',
5.43 @@ -2219,7 +2219,7 @@
5.44 module.add_function('TypeNameGet',
5.45 'std::string',
5.46 [],
5.47 - template_parameters=['unsigned long'])
5.48 + template_parameters=['unsigned long long'])
5.49 ## type-name.h: extern std::string ns3::TypeNameGet() [free function]
5.50 module.add_function('TypeNameGet',
5.51 'std::string',
6.1 --- a/bindings/python/ns3_module_helper.py Tue Jun 09 18:00:24 2009 +0100
6.2 +++ b/bindings/python/ns3_module_helper.py Tue Jun 09 18:00:52 2009 +0100
6.3 @@ -55,6 +55,8 @@
6.4 module.add_class('YansWifiChannelHelper', allow_subclassing=False)
6.5 ## yans-wifi-helper.h: ns3::YansWifiPhyHelper [class]
6.6 module.add_class('YansWifiPhyHelper', allow_subclassing=False, parent=root_module['ns3::WifiPhyHelper'])
6.7 + ## yans-wifi-helper.h: ns3::YansWifiPhyHelper::PcapFormat [enumeration]
6.8 + module.add_enum('PcapFormat', ['PCAP_FORMAT_80211', 'PCAP_FORMAT_80211_PRISM', 'PCAP_FORMAT_80211_RADIOTAP'], outer_class=root_module['ns3::YansWifiPhyHelper'])
6.9 ## nqos-wifi-mac-helper.h: ns3::NqosWifiMacHelper [class]
6.10 module.add_class('NqosWifiMacHelper', allow_subclassing=False, parent=root_module['ns3::WifiMacHelper'])
6.11 ## qos-wifi-mac-helper.h: ns3::QosWifiMacHelper [class]
6.12 @@ -1160,36 +1162,34 @@
6.13 cls.add_method('SetErrorRateModel',
6.14 'void',
6.15 [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()')])
6.16 - ## yans-wifi-helper.h: static void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, uint32_t nodeid, uint32_t deviceid) [member function]
6.17 + ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::SetPcapFormat(ns3::YansWifiPhyHelper::PcapFormat format) [member function]
6.18 + cls.add_method('SetPcapFormat',
6.19 + 'void',
6.20 + [param('ns3::YansWifiPhyHelper::PcapFormat', 'format')])
6.21 + ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, uint32_t nodeid, uint32_t deviceid) [member function]
6.22 cls.add_method('EnablePcap',
6.23 'void',
6.24 - [param('std::string', 'filename'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')],
6.25 - is_static=True)
6.26 - ## yans-wifi-helper.h: static void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, ns3::Ptr<ns3::NetDevice> nd) [member function]
6.27 + [param('std::string', 'filename'), param('uint32_t', 'nodeid'), param('uint32_t', 'deviceid')])
6.28 + ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, ns3::Ptr<ns3::NetDevice> nd) [member function]
6.29 cls.add_method('EnablePcap',
6.30 'void',
6.31 - [param('std::string', 'filename'), param('ns3::Ptr< ns3::NetDevice >', 'nd')],
6.32 - is_static=True)
6.33 - ## yans-wifi-helper.h: static void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, std::string ndName) [member function]
6.34 + [param('std::string', 'filename'), param('ns3::Ptr< ns3::NetDevice >', 'nd')])
6.35 + ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, std::string ndName) [member function]
6.36 cls.add_method('EnablePcap',
6.37 'void',
6.38 - [param('std::string', 'filename'), param('std::string', 'ndName')],
6.39 - is_static=True)
6.40 - ## yans-wifi-helper.h: static void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, ns3::NetDeviceContainer d) [member function]
6.41 + [param('std::string', 'filename'), param('std::string', 'ndName')])
6.42 + ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, ns3::NetDeviceContainer d) [member function]
6.43 cls.add_method('EnablePcap',
6.44 'void',
6.45 - [param('std::string', 'filename'), param('ns3::NetDeviceContainer', 'd')],
6.46 - is_static=True)
6.47 - ## yans-wifi-helper.h: static void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, ns3::NodeContainer n) [member function]
6.48 + [param('std::string', 'filename'), param('ns3::NetDeviceContainer', 'd')])
6.49 + ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::EnablePcap(std::string filename, ns3::NodeContainer n) [member function]
6.50 cls.add_method('EnablePcap',
6.51 'void',
6.52 - [param('std::string', 'filename'), param('ns3::NodeContainer', 'n')],
6.53 - is_static=True)
6.54 - ## yans-wifi-helper.h: static void ns3::YansWifiPhyHelper::EnablePcapAll(std::string filename) [member function]
6.55 + [param('std::string', 'filename'), param('ns3::NodeContainer', 'n')])
6.56 + ## yans-wifi-helper.h: void ns3::YansWifiPhyHelper::EnablePcapAll(std::string filename) [member function]
6.57 cls.add_method('EnablePcapAll',
6.58 'void',
6.59 - [param('std::string', 'filename')],
6.60 - is_static=True)
6.61 + [param('std::string', 'filename')])
6.62 ## yans-wifi-helper.h: static void ns3::YansWifiPhyHelper::EnableAscii(std::ostream & os, uint32_t nodeid, uint32_t deviceid) [member function]
6.63 cls.add_method('EnableAscii',
6.64 'void',
7.1 --- a/bindings/python/ns3_module_internet_stack.py Tue Jun 09 18:00:24 2009 +0100
7.2 +++ b/bindings/python/ns3_module_internet_stack.py Tue Jun 09 18:00:52 2009 +0100
7.3 @@ -181,10 +181,10 @@
7.4 'uint16_t',
7.5 [],
7.6 is_const=True)
7.7 - ## icmpv4.h: ns3::Ptr<ns3::Packet const> ns3::Icmpv4Echo::GetData() const [member function]
7.8 + ## icmpv4.h: uint32_t ns3::Icmpv4Echo::GetData(uint8_t * payload) const [member function]
7.9 cls.add_method('GetData',
7.10 - 'ns3::Ptr< ns3::Packet const >',
7.11 - [],
7.12 + 'uint32_t',
7.13 + [param('uint8_t *', 'payload')],
7.14 is_const=True)
7.15 ## icmpv4.h: static ns3::TypeId ns3::Icmpv4Echo::GetTypeId() [member function]
7.16 cls.add_method('GetTypeId',
8.1 --- a/bindings/python/ns3_module_node.py Tue Jun 09 18:00:24 2009 +0100
8.2 +++ b/bindings/python/ns3_module_node.py Tue Jun 09 18:00:52 2009 +0100
8.3 @@ -1443,10 +1443,10 @@
8.4 'ns3::Ipv4Address',
8.5 [],
8.6 is_const=True)
8.7 - ## ipv4-route.h: void ns3::Ipv4MulticastRoute::SetOrigin(ns3::Ipv4Address const group) [member function]
8.8 + ## ipv4-route.h: void ns3::Ipv4MulticastRoute::SetOrigin(ns3::Ipv4Address const origin) [member function]
8.9 cls.add_method('SetOrigin',
8.10 'void',
8.11 - [param('ns3::Ipv4Address const', 'group')])
8.12 + [param('ns3::Ipv4Address const', 'origin')])
8.13 ## ipv4-route.h: ns3::Ipv4Address ns3::Ipv4MulticastRoute::GetOrigin() const [member function]
8.14 cls.add_method('GetOrigin',
8.15 'ns3::Ipv4Address',
9.1 --- a/bindings/python/ns3_module_olsr.py Tue Jun 09 18:00:24 2009 +0100
9.2 +++ b/bindings/python/ns3_module_olsr.py Tue Jun 09 18:00:52 2009 +0100
9.3 @@ -102,13 +102,13 @@
9.4 module.add_container('std::vector< ns3::olsr::MessageHeader::Hello::LinkMessage >', 'ns3::olsr::MessageHeader::Hello::LinkMessage', container_type='vector')
9.5 module.add_container('std::vector< ns3::olsr::MessageHeader::Hna::Association >', 'ns3::olsr::MessageHeader::Hna::Association', container_type='vector')
9.6 typehandlers.add_type_alias('std::vector< ns3::olsr::DuplicateTuple, std::allocator< ns3::olsr::DuplicateTuple > >', 'ns3::olsr::DuplicateSet')
9.7 - typehandlers.add_type_alias('std::vector< ns3::olsr::TopologyTuple, std::allocator< ns3::olsr::TopologyTuple > >', 'ns3::olsr::TopologySet')
9.8 typehandlers.add_type_alias('std::set< ns3::Ipv4Address, std::less< ns3::Ipv4Address >, std::allocator< ns3::Ipv4Address > >', 'ns3::olsr::MprSet')
9.9 typehandlers.add_type_alias('std::vector< ns3::olsr::MprSelectorTuple, std::allocator< ns3::olsr::MprSelectorTuple > >', 'ns3::olsr::MprSelectorSet')
9.10 typehandlers.add_type_alias('std::vector< ns3::olsr::MessageHeader, std::allocator< ns3::olsr::MessageHeader > >', 'ns3::olsr::MessageList')
9.11 typehandlers.add_type_alias('std::vector< ns3::olsr::IfaceAssocTuple, std::allocator< ns3::olsr::IfaceAssocTuple > >', 'ns3::olsr::IfaceAssocSet')
9.12 typehandlers.add_type_alias('std::vector< ns3::olsr::NeighborTuple, std::allocator< ns3::olsr::NeighborTuple > >', 'ns3::olsr::NeighborSet')
9.13 typehandlers.add_type_alias('std::vector< ns3::olsr::TwoHopNeighborTuple, std::allocator< ns3::olsr::TwoHopNeighborTuple > >', 'ns3::olsr::TwoHopNeighborSet')
9.14 + typehandlers.add_type_alias('std::vector< ns3::olsr::TopologyTuple, std::allocator< ns3::olsr::TopologyTuple > >', 'ns3::olsr::TopologySet')
9.15 typehandlers.add_type_alias('std::vector< ns3::olsr::LinkTuple, std::allocator< ns3::olsr::LinkTuple > >', 'ns3::olsr::LinkSet')
9.16
9.17 def register_methods(root_module):
10.1 --- a/bindings/python/ns3_module_wifi.py Tue Jun 09 18:00:24 2009 +0100
10.2 +++ b/bindings/python/ns3_module_wifi.py Tue Jun 09 18:00:52 2009 +0100
10.3 @@ -8,7 +8,7 @@
10.4 ## wifi-preamble.h: ns3::WifiPreamble [enumeration]
10.5 module.add_enum('WifiPreamble', ['WIFI_PREAMBLE_LONG', 'WIFI_PREAMBLE_SHORT'])
10.6 ## wifi-phy-standard.h: ns3::WifiPhyStandard [enumeration]
10.7 - module.add_enum('WifiPhyStandard', ['WIFI_PHY_STANDARD_80211a', 'WIFI_PHY_STANDARD_holland'])
10.8 + module.add_enum('WifiPhyStandard', ['WIFI_PHY_STANDARD_80211a', 'WIFI_PHY_STANDARD_80211b', 'WIFI_PHY_STANDARD_holland'])
10.9 ## qos-utils.h: ns3::AccessClass [enumeration]
10.10 module.add_enum('AccessClass', ['AC_VO', 'AC_VI', 'AC_BE', 'AC_BK', 'AC_UNDEF'])
10.11 ## edca-txop-n.h: ns3::TypeOfStation [enumeration]
10.12 @@ -26,7 +26,7 @@
10.13 ## wifi-mode.h: ns3::WifiMode [class]
10.14 module.add_class('WifiMode')
10.15 ## wifi-mode.h: ns3::WifiMode::ModulationType [enumeration]
10.16 - module.add_enum('ModulationType', ['BPSK', 'QAM'], outer_class=root_module['ns3::WifiMode'])
10.17 + module.add_enum('ModulationType', ['BPSK', 'DBPSK', 'DQPSK', 'QAM'], outer_class=root_module['ns3::WifiMode'])
10.18 ## wifi-mode.h: ns3::WifiModeFactory [class]
10.19 module.add_class('WifiModeFactory')
10.20 ## wifi-phy.h: ns3::WifiPhyListener [class]
10.21 @@ -101,6 +101,8 @@
10.22 module.add_class('EdcaTxopN', parent=root_module['ns3::Object'])
10.23 ## error-rate-model.h: ns3::ErrorRateModel [class]
10.24 module.add_class('ErrorRateModel', parent=root_module['ns3::Object'])
10.25 + ## propagation-loss-model.h: ns3::FixedRssLossModel [class]
10.26 + module.add_class('FixedRssLossModel', parent=root_module['ns3::PropagationLossModel'])
10.27 ## propagation-loss-model.h: ns3::FriisPropagationLossModel [class]
10.28 module.add_class('FriisPropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
10.29 ## ideal-wifi-manager.h: ns3::IdealWifiManager [class]
10.30 @@ -111,6 +113,8 @@
10.31 module.add_class('LogDistancePropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
10.32 ## msdu-aggregator.h: ns3::MsduAggregator [class]
10.33 module.add_class('MsduAggregator', parent=root_module['ns3::Object'])
10.34 + ## propagation-loss-model.h: ns3::NakagamiPropagationLossModel [class]
10.35 + module.add_class('NakagamiPropagationLossModel', parent=root_module['ns3::PropagationLossModel'])
10.36 ## nqap-wifi-mac.h: ns3::NqapWifiMac [class]
10.37 module.add_class('NqapWifiMac', parent=root_module['ns3::WifiMac'])
10.38 ## nqsta-wifi-mac.h: ns3::NqstaWifiMac [class]
10.39 @@ -228,11 +232,13 @@
10.40 register_Ns3DcaTxop_methods(root_module, root_module['ns3::DcaTxop'])
10.41 register_Ns3EdcaTxopN_methods(root_module, root_module['ns3::EdcaTxopN'])
10.42 register_Ns3ErrorRateModel_methods(root_module, root_module['ns3::ErrorRateModel'])
10.43 + register_Ns3FixedRssLossModel_methods(root_module, root_module['ns3::FixedRssLossModel'])
10.44 register_Ns3FriisPropagationLossModel_methods(root_module, root_module['ns3::FriisPropagationLossModel'])
10.45 register_Ns3IdealWifiManager_methods(root_module, root_module['ns3::IdealWifiManager'])
10.46 register_Ns3JakesPropagationLossModel_methods(root_module, root_module['ns3::JakesPropagationLossModel'])
10.47 register_Ns3LogDistancePropagationLossModel_methods(root_module, root_module['ns3::LogDistancePropagationLossModel'])
10.48 register_Ns3MsduAggregator_methods(root_module, root_module['ns3::MsduAggregator'])
10.49 + register_Ns3NakagamiPropagationLossModel_methods(root_module, root_module['ns3::NakagamiPropagationLossModel'])
10.50 register_Ns3NqapWifiMac_methods(root_module, root_module['ns3::NqapWifiMac'])
10.51 register_Ns3NqstaWifiMac_methods(root_module, root_module['ns3::NqstaWifiMac'])
10.52 register_Ns3OnoeWifiManager_methods(root_module, root_module['ns3::OnoeWifiManager'])
10.53 @@ -267,6 +273,10 @@
10.54 cls.add_method('Configure80211aParameters',
10.55 'void',
10.56 [])
10.57 + ## interference-helper.h: void ns3::InterferenceHelper::Configure80211bParameters() [member function]
10.58 + cls.add_method('Configure80211bParameters',
10.59 + 'void',
10.60 + [])
10.61 ## interference-helper.h: ns3::Time ns3::InterferenceHelper::GetEnergyDuration(double energyW) [member function]
10.62 cls.add_method('GetEnergyDuration',
10.63 'ns3::Time',
10.64 @@ -487,6 +497,16 @@
10.65 'ns3::WifiMode',
10.66 [param('std::string', 'uniqueName'), param('bool', 'isMandatory'), param('uint32_t', 'bandwidth'), param('uint32_t', 'dataRate'), param('uint32_t', 'phyRate'), param('uint8_t', 'constellationSize')],
10.67 is_static=True)
10.68 + ## 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]
10.69 + cls.add_method('CreateDbpsk',
10.70 + 'ns3::WifiMode',
10.71 + [param('std::string', 'uniqueName'), param('bool', 'isMandatory'), param('uint32_t', 'bandwidth'), param('uint32_t', 'dataRate'), param('uint32_t', 'phyRate')],
10.72 + is_static=True)
10.73 + ## 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]
10.74 + cls.add_method('CreateDqpsk',
10.75 + 'ns3::WifiMode',
10.76 + [param('std::string', 'uniqueName'), param('bool', 'isMandatory'), param('uint32_t', 'bandwidth'), param('uint32_t', 'dataRate'), param('uint32_t', 'phyRate')],
10.77 + is_static=True)
10.78 return
10.79
10.80 def register_Ns3WifiPhyListener_methods(root_module, cls):
10.81 @@ -2013,6 +2033,26 @@
10.82 'ns3::WifiMode',
10.83 [],
10.84 is_static=True)
10.85 + ## wifi-phy.h: static ns3::WifiMode ns3::WifiPhy::Get1mbb() [member function]
10.86 + cls.add_method('Get1mbb',
10.87 + 'ns3::WifiMode',
10.88 + [],
10.89 + is_static=True)
10.90 + ## wifi-phy.h: static ns3::WifiMode ns3::WifiPhy::Get2mbb() [member function]
10.91 + cls.add_method('Get2mbb',
10.92 + 'ns3::WifiMode',
10.93 + [],
10.94 + is_static=True)
10.95 + ## wifi-phy.h: static ns3::WifiMode ns3::WifiPhy::Get5_5mbb() [member function]
10.96 + cls.add_method('Get5_5mbb',
10.97 + 'ns3::WifiMode',
10.98 + [],
10.99 + is_static=True)
10.100 + ## wifi-phy.h: static ns3::WifiMode ns3::WifiPhy::Get11mbb() [member function]
10.101 + cls.add_method('Get11mbb',
10.102 + 'ns3::WifiMode',
10.103 + [],
10.104 + is_static=True)
10.105 ## wifi-phy.h: void ns3::WifiPhy::NotifyTxBegin(ns3::Ptr<ns3::Packet const> packet) [member function]
10.106 cls.add_method('NotifyTxBegin',
10.107 'void',
10.108 @@ -2037,10 +2077,14 @@
10.109 cls.add_method('NotifyRxDrop',
10.110 'void',
10.111 [param('ns3::Ptr< ns3::Packet const >', 'packet')])
10.112 - ## wifi-phy.h: void ns3::WifiPhy::NotifyPromiscSniff(ns3::Ptr<ns3::Packet const> packet) [member function]
10.113 - cls.add_method('NotifyPromiscSniff',
10.114 - 'void',
10.115 - [param('ns3::Ptr< ns3::Packet const >', 'packet')])
10.116 + ## 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]
10.117 + cls.add_method('NotifyPromiscSniffRx',
10.118 + 'void',
10.119 + [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('uint16_t', 'channelFreqMhz'), param('uint32_t', 'rate'), param('bool', 'isShortPreamble'), param('double', 'signalDbm'), param('double', 'noiseDbm')])
10.120 + ## wifi-phy.h: void ns3::WifiPhy::NotifyPromiscSniffTx(ns3::Ptr<ns3::Packet const> packet, uint16_t channelFreqMhz, uint32_t rate, bool isShortPreamble) [member function]
10.121 + cls.add_method('NotifyPromiscSniffTx',
10.122 + 'void',
10.123 + [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('uint16_t', 'channelFreqMhz'), param('uint32_t', 'rate'), param('bool', 'isShortPreamble')])
10.124 return
10.125
10.126 def register_Ns3WifiRemoteStationManager_methods(root_module, cls):
10.127 @@ -2972,6 +3016,25 @@
10.128 is_pure_virtual=True, is_const=True, is_virtual=True)
10.129 return
10.130
10.131 +def register_Ns3FixedRssLossModel_methods(root_module, cls):
10.132 + ## propagation-loss-model.h: static ns3::TypeId ns3::FixedRssLossModel::GetTypeId() [member function]
10.133 + cls.add_method('GetTypeId',
10.134 + 'ns3::TypeId',
10.135 + [],
10.136 + is_static=True)
10.137 + ## propagation-loss-model.h: ns3::FixedRssLossModel::FixedRssLossModel() [constructor]
10.138 + cls.add_constructor([])
10.139 + ## propagation-loss-model.h: void ns3::FixedRssLossModel::SetRss(double rss) [member function]
10.140 + cls.add_method('SetRss',
10.141 + 'void',
10.142 + [param('double', 'rss')])
10.143 + ## propagation-loss-model.h: double ns3::FixedRssLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
10.144 + cls.add_method('DoCalcRxPower',
10.145 + 'double',
10.146 + [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')],
10.147 + is_const=True, visibility='private', is_virtual=True)
10.148 + return
10.149 +
10.150 def register_Ns3FriisPropagationLossModel_methods(root_module, cls):
10.151 ## propagation-loss-model.h: static ns3::TypeId ns3::FriisPropagationLossModel::GetTypeId() [member function]
10.152 cls.add_method('GetTypeId',
10.153 @@ -3122,6 +3185,21 @@
10.154 is_static=True)
10.155 return
10.156
10.157 +def register_Ns3NakagamiPropagationLossModel_methods(root_module, cls):
10.158 + ## propagation-loss-model.h: static ns3::TypeId ns3::NakagamiPropagationLossModel::GetTypeId() [member function]
10.159 + cls.add_method('GetTypeId',
10.160 + 'ns3::TypeId',
10.161 + [],
10.162 + is_static=True)
10.163 + ## propagation-loss-model.h: ns3::NakagamiPropagationLossModel::NakagamiPropagationLossModel() [constructor]
10.164 + cls.add_constructor([])
10.165 + ## propagation-loss-model.h: double ns3::NakagamiPropagationLossModel::DoCalcRxPower(double txPowerDbm, ns3::Ptr<ns3::MobilityModel> a, ns3::Ptr<ns3::MobilityModel> b) const [member function]
10.166 + cls.add_method('DoCalcRxPower',
10.167 + 'double',
10.168 + [param('double', 'txPowerDbm'), param('ns3::Ptr< ns3::MobilityModel >', 'a'), param('ns3::Ptr< ns3::MobilityModel >', 'b')],
10.169 + is_const=True, visibility='private', is_virtual=True)
10.170 + return
10.171 +
10.172 def register_Ns3NqapWifiMac_methods(root_module, cls):
10.173 ## nqap-wifi-mac.h: static ns3::TypeId ns3::NqapWifiMac::GetTypeId() [member function]
10.174 cls.add_method('GetTypeId',
11.1 --- a/doc/manual/Makefile Tue Jun 09 18:00:24 2009 +0100
11.2 +++ b/doc/manual/Makefile Tue Jun 09 18:00:52 2009 +0100
11.3 @@ -17,6 +17,8 @@
11.4 $(FIGURES)/node.eps \
11.5 $(FIGURES)/buffer.eps \
11.6 $(FIGURES)/sockets-overview.eps \
11.7 + $(FIGURES)/routing.eps \
11.8 + $(FIGURES)/routing-specialization.eps \
11.9 $(FIGURES)/testbed.eps \
11.10 $(FIGURES)/emulated-channel.eps \
11.11 $(FIGURES)/snir.eps \
12.1 Binary file doc/manual/figures/packet.dia has changed
13.1 Binary file doc/manual/figures/routing-specialization.dia has changed
14.1 Binary file doc/manual/figures/routing.dia has changed
15.1 --- a/doc/manual/packets.texi Tue Jun 09 18:00:24 2009 +0100
15.2 +++ b/doc/manual/packets.texi Tue Jun 09 18:00:52 2009 +0100
15.3 @@ -15,11 +15,14 @@
15.4 emulated applications
15.5 @end itemize
15.6
15.7 -@emph{ns} Packet objects contain a buffer of bytes: protocol headers and
15.8 -trailers are serialized in this buffer of bytes using user-provided
15.9 -serialization and deserialization routines. The content of this byte
15.10 -buffer is expected to match bit-for-bit the content of a real packet on
15.11 -a real network implementing the protocol of interest.
15.12 +Each network packet contains a byte buffer, a set of byte tags, a set of
15.13 +packet tags, and metadata.
15.14 +
15.15 +The byte buffer stores the serialized content of the headers and trailers
15.16 +added to a packet. The serialized representation of these headers is expected
15.17 +to match that of real network packets bit for bit (although nothing
15.18 +forces you to do this) which means that the content of a packet buffer
15.19 +is expected to be that of a real packet.
15.20
15.21 Fragmentation and defragmentation are quite natural to implement within
15.22 this context: since we have a buffer of real bytes, we can split it in
15.23 @@ -29,19 +32,37 @@
15.24 the simulator. We also expect that performing a real-time plug of the
15.25 simulator to a real-world network will be easy.
15.26
15.27 -Because we understand that simulation developers often wish to store in
15.28 -packet objects data which is not found in the real packets (such as
15.29 -timestamps or any kind of similar in-band data), the @emph{ns} Packet class
15.30 -can also store extra per-packet "Tags" which are 16 bytes blobs of data.
15.31 -Any Packet can store any number of unique Tags, each of which is
15.32 -uniquely identified by its C++ type. These tags make it easy to attach
15.33 -per-model data to a packet without having to patch the main Packet
15.34 -class or Packet facilities.
15.35 +One problem that this design choice raises is that it is difficult to
15.36 +pretty-print the packet headers without context. The packet metadata
15.37 +describes the type of the headers and trailers which
15.38 +were serialized in the byte buffer. The maintenance of metadata is
15.39 +optional and disabled by default. To enable it, you must call
15.40 +Packet::EnableMetadata() and this will allow you to get non-empty
15.41 +output from Packet::Print and Packet::Print.
15.42
15.43 +Also, developers often want to store data in packet objects that is not found
15.44 +in the real packets (such as timestamps or flow-ids). The Packet class
15.45 +deals with this requirement by storing a set of tags (class Tag).
15.46 +We have found two classes of use cases for these tags, which leads to
15.47 +two different types of tags. So-called
15.48 +'byte' tags are used to tag a subset of the bytes in the packet byte buffer
15.49 +while 'packet' tags are used to tag the packet itself. The main difference
15.50 +between these two kinds of tags is what happens when packets are copied,
15.51 +fragmented, and reassembled: 'byte' tags follow bytes while 'packet' tags
15.52 +follow packets. Another important difference between these two kinds of tags
15.53 +is that byte tags cannot be removed and are expected to be written once,
15.54 +and read many times, while packet tags are expected to be written once,
15.55 +read many times, and removed exactly once. An example of a 'byte'
15.56 +tag is a FlowIdTag which contains a flow id and is set by the application
15.57 +generating traffic. An example of a 'packet' tag is a cross-layer
15.58 +QoS class id set by an application and processed by a lower-level MAC
15.59 +layer.
15.60 +
15.61 Memory management of Packet objects is entirely automatic and extremely
15.62 efficient: memory for the application-level payload can be modelized by
15.63 a virtual buffer of zero-filled bytes for which memory is never allocated
15.64 -unless explicitely requested by the user or unless the packet is fragmented.
15.65 +unless explicitly requested by the user or unless the packet is fragmented
15.66 +or serialized out to a real network device.
15.67 Furthermore, copying, adding, and, removing headers or trailers to a packet
15.68 has been optimized to be virtually free through a technique known as
15.69 Copy On Write.
15.70 @@ -54,32 +75,12 @@
15.71 tension between ease-of-use, performance, and safe interface
15.72 design.
15.73
15.74 -There are a few requirements on this object design:
15.75 -@itemize @bullet
15.76 -@item Creation, management, and deletion of this object
15.77 -should be as simple as possible, while avoiding the
15.78 -chance for memory leaks and/or heap corruption;
15.79 -@item Packets should support serialization and deserialization
15.80 -so that network emulation is supported;
15.81 -@item Packets should support fragmentation and concatenation
15.82 -(multiple packets in a data link frame), especially for wireless
15.83 -support;
15.84 -@item It should be natural for packets to carry actual application
15.85 -data, or if there is only an emulated application and there is
15.86 -no need to carry dummy bytes, smaller packets could be used with
15.87 -just the headers and a record of the payload size, but not actual
15.88 -application bytes, conveyed in the simulated packet.
15.89 -@item Packets should facilitate BSD-like operations on mbufs, for
15.90 -support of ported operating system stacks.
15.91 -@item Additional side-information should be supported, such as
15.92 -a tag for cross-layer information.
15.93 -@end itemize
15.94 -
15.95 @section Packet design overview
15.96
15.97 Unlike @emph{ns-2}, in which Packet objects contain a buffer of C++
15.98 structures corresponding to protocol headers, each network packet in
15.99 -@emph{ns-3} contains a byte Buffer and a list of Tags:
15.100 +@emph{ns-3} contains a byte Buffer, a list of byte Tags, a list of
15.101 +packet Tags, and a PacketMetadata object:
15.102 @itemize @bullet
15.103 @item The byte buffer stores the serialized content of the chunks
15.104 added to a packet. The serialized representation of these chunks is
15.105 @@ -88,16 +89,12 @@
15.106 of a packet buffer is expected to be that of a real packet.
15.107 Packets can also be created with an arbitrary zero-filled payload
15.108 for which no real memory is allocated.
15.109 -@item The list of tags stores an arbitrarily large set of arbitrary
15.110 +@item Each list of tags stores an arbitrarily large set of arbitrary
15.111 user-provided data structures in the packet. Each Tag is uniquely
15.112 identified by its type; only one instance of each
15.113 type of data structure is allowed in a list of tags. These tags typically
15.114 contain per-packet cross-layer information or flow identifiers (i.e.,
15.115 -things that you wouldn't find in the bits on the wire). Each tag
15.116 -stored in the tag list can be at most 16 bytes.
15.117 -Trying to attach bigger data structures will trigger
15.118 -crashes at runtime. The 16 byte limit is a modifiable compilation
15.119 -constant.
15.120 +things that you wouldn't find in the bits on the wire).
15.121 @end itemize
15.122
15.123 @float Figure,fig:packets
15.124 @@ -110,17 +107,29 @@
15.125 is provided later in Figure @ref{fig:buffer}.
15.126 In \nsthree, the Packet byte buffer is analogous to a Linux skbuff
15.127 or BSD mbuf; it is a serialized representation of the actual
15.128 -data in the packet. The tag list is a container for extra
15.129 +data in the packet. The tag lists are containers for extra
15.130 items useful for simulation convenience; if a Packet is converted
15.131 to an emulated packet and put over an actual network, the tags
15.132 are stripped off and the byte buffer is copied directly
15.133 into a real packet.
15.134
15.135 -The Packet class has value semantics: it can be freely copied around,
15.136 -allocated on the stack, and passed to functions as arguments. Whenever
15.137 -an instance is copied, the full underlying data is not copied; it
15.138 -has ``copy-on-write'' (COW) semantics. Packet instances can be passed
15.139 -by value to function arguments without any performance hit.
15.140 +Packets are reference counted objects. They are handled with smart
15.141 +pointer (Ptr) objects like many of the objects in the ns-3 system.
15.142 +One small difference you will see is that class Packet does not
15.143 +inherit from class Object or class RefCountBase, and implements the
15.144 +Ref() and Unref() methods directly. This was designed to avoid the overhead
15.145 +of a vtable in class Packet.
15.146 +
15.147 +The Packet class is designed to be copied cheaply; the overall design
15.148 +is based on Copy on Write (COW). When there are multiple references
15.149 +to a packet object, and there is an operation on one of them, only
15.150 +so-called "dirty" operations will trigger a deep copy of the packet:
15.151 +@itemize @bullet
15.152 +@item @code{ns3::Packet::AddHeader()}
15.153 +@item @code{ns3::Packet::AddTrailer()}
15.154 +@item @code{both versions of ns3::Packet::AddAtEnd()}
15.155 +@item @code{Packet::RemovePacketTag()}
15.156 +@end itemize
15.157
15.158 The fundamental classes for adding to and removing from the byte
15.159 buffer are @code{class Header} and @code{class Trailer}.
15.160 @@ -149,78 +158,203 @@
15.161
15.162 Similarly, user-defined Tags can be appended to the packet.
15.163 Unlike Headers, Tags are not serialized into a contiguous buffer
15.164 -but are stored in an array. By default, Tags are limited to 16 bytes in
15.165 -size. Tags can be flexibly defined to be any type, but there
15.166 +but are stored in lists. Tags can be flexibly defined to be any
15.167 +type, but there
15.168 can only be one instance of any particular object type in
15.169 the Tags buffer at any time.
15.170
15.171 -@section Packet interface
15.172 +@section Using the packet interface
15.173
15.174 -The public member functions of a Packet object are as follows:
15.175 +This section describes how to create and use the @code{ns3::Packet} object.
15.176
15.177 -@subsection Constructors
15.178 +@subsection Creating a new packet
15.179 +
15.180 +The following command will create a new packet with a new unique
15.181 +Id.
15.182 +
15.183 @verbatim
15.184 - /**
15.185 - * Create an empty packet with a new uid (as returned
15.186 - * by getUid).
15.187 - */
15.188 - Packet ();
15.189 - /**
15.190 - * Create a packet with a zero-filled payload.
15.191 - * The memory necessary for the payload is not allocated:
15.192 - * it will be allocated at any later point if you attempt
15.193 - * to fragment this packet or to access the zero-filled
15.194 - * bytes. The packet is allocated with a new uid (as
15.195 - * returned by getUid).
15.196 - *
15.197 - * \param size the size of the zero-filled payload
15.198 - */
15.199 - Packet (uint32_t size);
15.200 + Ptr<Packet> pkt = Create<Packet> ();
15.201 @end verbatim
15.202
15.203 +What is the Uid (unique Id)? It is an internal id that the
15.204 +system uses to identify packets. It can be fetched via the following
15.205 +method:
15.206 +@verbatim
15.207 + uint32_t uid = pkt->GetUid ();
15.208 +@end verbatim
15.209 +
15.210 +But please note the following. This uid is an internal uid and cannot
15.211 +be counted on to provide an accurate counter of how many
15.212 +"simulated packets" of a particular protocol are in the system.
15.213 +It is not trivial to make this uid into such a counter, because of
15.214 +questions such as what should the uid be when the packet is
15.215 +sent over broadcast media, or when fragmentation occurs. If a user
15.216 +wants to trace actual packet counts, he or she should look at
15.217 +e.g. the IP ID field or transport sequence numbers, or other packet
15.218 +or frame counters at other protocol layers.
15.219 +
15.220 +We mentioned above that it is possible to create packets with zero-filled
15.221 +payloads that do not actually require a memory allocation (i.e.,
15.222 +the packet may behave, when delays such as serialization or transmission
15.223 +delays are computed, to have a certain number of payload bytes, but
15.224 +the bytes will only be allocated on-demand when needed). The command to do
15.225 +this is, when the packet
15.226 +is created:
15.227 +@verbatim
15.228 + Ptr<Packet> pkt = Create<Packet> (N);
15.229 +@end verbatim
15.230 +where N is a positive integer.
15.231 +
15.232 +The packet now has a size of N bytes, which can be verified by the GetSize()
15.233 +method:
15.234 +@verbatim
15.235 + /**
15.236 + * \returns the size in bytes of the packet (including the zero-filled
15.237 + * initial payload)
15.238 + */
15.239 + uint32_t GetSize (void) const;
15.240 +@end verbatim
15.241 +
15.242 +You can also initialize a packet with a character buffer. The input
15.243 +data is copied and the input buffer is untouched. The constructor
15.244 +applied is:
15.245 +@verbatim
15.246 + Packet (uint8_t const *buffer, uint32_t size);
15.247 +@end verbatim
15.248 +Here is an example:
15.249 +@verbatim
15.250 + Ptr<Packet> pkt1 = Create<Packet> (reinterpret_cast<const uint8_t*> ("hello"), 5);
15.251 +@end verbatim
15.252 +
15.253 +Packets are freed when there are no more references to them, as with
15.254 +all ns-3 objects referenced by the Ptr class.
15.255 +
15.256 @subsection Adding and removing Buffer data
15.257 -The below code is reproduced for Header class only; similar functions
15.258 -exist for Trailers.
15.259 +
15.260 +After the initial packet creation (which may possibly create some
15.261 +fake initial bytes of payload), all subsequent buffer data is added by adding
15.262 +objects of class Header or class Trailer. Note that, even if you are
15.263 +in the application layer, handling packets, and want to write application
15.264 +data, you write it as an ns3::Header or ns3::Trailer. If you add a Header,
15.265 +it is prepended to the packet, and if you add a Trailer, it is added to
15.266 +the end of the packet. If you have no data in the packet, then it
15.267 +makes no difference whether you add a Header or Trailer. Since the
15.268 +APIs and classes for header and trailer are pretty much identical, we'll
15.269 +just look at class Header here.
15.270 +
15.271 +The first step is to create a new header class. All new Header classes
15.272 +must inherit from class Header, and implement the following methods:
15.273 +@itemize @bullet
15.274 +@item @code{Serialize ()}
15.275 +@item @code{Deserialize ()}
15.276 +@item @code{GetSerializedSize ()}
15.277 +@item @code{Print ()}
15.278 +@end itemize
15.279 +
15.280 +To see a simple example of how these are done, look at the UdpHeader
15.281 +class headers src/internet-stack/udp-header.cc. There are many other
15.282 +examples within the source code.
15.283 +
15.284 +Once you have a header (or you have a preexisting header), the following
15.285 +Packet API can be used to add or remove such headers.
15.286 +
15.287 @verbatim
15.288 - /**
15.289 - * Add header to this packet. This method invokes the
15.290 - * ns3::Header::serializeTo method to request the header to serialize
15.291 - * itself in the packet buffer.
15.292 - *
15.293 - * \param header a reference to the header to add to this packet.
15.294 - */
15.295 - void Add (Header const &header);
15.296 - /**
15.297 - * Deserialize header from this packet. This method invokes the
15.298 - * ns3::Header::deserializeFrom method to request the header to deserialize
15.299 - * itself from the packet buffer. This method does not remove
15.300 - * the data from the buffer. It merely reads it.
15.301 - *
15.302 - * \param header a reference to the header to deserialize from the buffer
15.303 - */
15.304 - void Peek (Header &header);
15.305 - /**
15.306 - * Remove a deserialized header from the internal buffer.
15.307 - * This method removes the bytes read by Packet::peek from
15.308 - * the packet buffer.
15.309 - *
15.310 - * \param header a reference to the header to remove from the internal buffer.
15.311 - */
15.312 - void Remove (Header const &header);
15.313 - /**
15.314 - * Add trailer to this packet. This method invokes the
15.315 - * ns3::Trailer::serializeTo method to request the trailer to serialize
15.316 - * itself in the packet buffer.
15.317 - *
15.318 - * \param trailer a reference to the trailer to add to this packet.
15.319 - */
15.320 + /**
15.321 + * Add header to this packet. This method invokes the
15.322 + * Header::GetSerializedSize and Header::Serialize
15.323 + * methods to reserve space in the buffer and request the
15.324 + * header to serialize itself in the packet buffer.
15.325 + *
15.326 + * \param header a reference to the header to add to this packet.
15.327 + */
15.328 + void AddHeader (const Header & header);
15.329 + /**
15.330 + * Deserialize and remove the header from the internal buffer.
15.331 + * This method invokes Header::Deserialize.
15.332 + *
15.333 + * \param header a reference to the header to remove from the internal buffer.
15.334 + * \returns the number of bytes removed from the packet.
15.335 + */
15.336 + uint32_t RemoveHeader (Header &header);
15.337 + /**
15.338 + * Deserialize but does _not_ remove the header from the internal buffer.
15.339 + * This method invokes Header::Deserialize.
15.340 + *
15.341 + * \param header a reference to the header to read from the internal buffer.
15.342 + * \returns the number of bytes read from the packet.
15.343 + */
15.344 + uint32_t PeekHeader (Header &header) const;
15.345 +@end verbatim
15.346 +
15.347 +For instance, here are the typical operations to add and remove a UDP header.
15.348 +
15.349 +@verbatim
15.350 + // add header
15.351 + Ptr<Packet> packet = Create<Packet> ();
15.352 + UdpHeader udpHeader;
15.353 + // Fill out udpHeader fields appropriately
15.354 + packet->AddHeader (udpHeader);
15.355 + ...
15.356 + // remove header
15.357 + UdpHeader udpHeader;
15.358 + packet->RemoveHeader (udpHeader);
15.359 + // Read udpHeader fields as needed
15.360 @end verbatim
15.361
15.362 @subsection Adding and removing Tags
15.363
15.364 -@strong{Note: This part of ns-3 will change for ns-3.5; see this mail message:
15.365 -http://mailman.isi.edu/pipermail/ns-developers/2009-March/005557.html}
15.366 +There is a single base class of Tag that all packet tags must derive from.
15.367 +They are used in two different tag lists in the packet; the lists have
15.368 +different semantics and different expected use cases.
15.369
15.370 +As the names imply, ByteTags follow bytes and PacketTags follow packets.
15.371 +What this means is that when operations are done on packets, such as
15.372 +fragmentation, concatenation, and appending or removing headers, the
15.373 +byte tags keep track of which packet bytes they cover. For instance,
15.374 +if a user creates a TCP segment, and applies a ByteTag to the segment,
15.375 +each byte of the TCP segment will be tagged. However, if the next
15.376 +layer down inserts an IPv4 header, this ByteTag will not cover those
15.377 +bytes. The converse is true for the PacketTag; it covers a packet
15.378 +despite the operations on it.
15.379 +
15.380 +PacketTags are limited in size to 20 bytes. This is a modifiable
15.381 +compile-time constant in @code{src/common/packet-tag-list.h}. ByteTags
15.382 +have no such restriction.
15.383 +
15.384 +Each tag type must subclass @code{ns3::Tag}, and only one instance of
15.385 +each Tag type may be in each tag list. Here are a few differences
15.386 +in the behavior of packet tags and byte tags.
15.387 +@itemize @bullet
15.388 +@item @strong{Fragmentation:} As mentioned above, when a packet is fragmented,
15.389 +each packet fragment (which is a new packet) will get a copy of all packet
15.390 +tags, and byte tags will follow the new packet boundaries (i.e. if the
15.391 +fragmented packets fragment across a buffer region covered by the byte
15.392 +tag, both packet fragments will still have the appropriate buffer regions
15.393 +byte tagged).
15.394 +@item @strong{Concatenation:} When packets are combined, two different
15.395 +buffer regions will become one. For byte tags, the byte tags simply
15.396 +follow the respective buffer regions. For packet tags, only the
15.397 +tags on the first packet survive the merge.
15.398 +@item @strong{Finding and Printing:} Both classes allow you to iterate
15.399 +over all of the tags and print them.
15.400 +@item @strong{Removal:} Users can add and remove the same packet tag
15.401 +multiple times on a single packet (AddPacketTag () and RemovePacketTag ()).
15.402 +The packet However, once a byte tag is added,
15.403 +it can only be removed by stripping all byte tags from the packet.
15.404 +Removing one of possibly multiple byte tags is not supported by the
15.405 +current API.
15.406 +@end itemize
15.407 +
15.408 +As of ns-3.5, Tags are not serialized and deserialized to a buffer when
15.409 +@code{Packet::Serialize ()} and @code{Packet::Deserialize ()} are called;
15.410 +this is an open bug.
15.411 +
15.412 +If a user wants to take an existing packet object and reuse it as a new
15.413 +packet, he or she should remove all byte tags and packet tags before doing so.
15.414 +An example is the UdpEchoServer class, which takes the received packet
15.415 +and "turns it around" to send back to the echo client.
15.416 +
15.417 +The Packet API for byte tags is given below.
15.418 @verbatim
15.419 /**
15.420 * \param tag the new tag to add to this packet
15.421 @@ -228,7 +362,7 @@
15.422 * Tag each byte included in this packet with the
15.423 * new tag.
15.424 *
15.425 - * Note that adding a tag is a const operation which is pretty
15.426 + * Note that adding a tag is a const operation which is pretty
15.427 * un-intuitive. The rationale is that the content and behavior of
15.428 * a packet is _not_ changed when a tag is added to a packet: any
15.429 * code which was not aware of the new tag is going to work just
15.430 @@ -239,216 +373,159 @@
15.431 * totally evil to allow a trace sink to modify the content of a
15.432 * packet).
15.433 */
15.434 - void AddTag (const Tag &tag) const;
15.435 + void AddByteTag (const Tag &tag) const;
15.436 /**
15.437 - * \returns an iterator over the set of tags included in this packet.
15.438 + * \returns an iterator over the set of byte tags included in this packet.
15.439 */
15.440 - TagIterator GetTagIterator (void) const;
15.441 + ByteTagIterator GetByteTagIterator (void) const;
15.442 /**
15.443 * \param tag the tag to search in this packet
15.444 * \returns true if the requested tag type was found, false otherwise.
15.445 *
15.446 - * If the requested tag type is found, it is copied in the user's
15.447 + * If the requested tag type is found, it is copied in the user's
15.448 * provided tag instance.
15.449 */
15.450 - bool FindFirstMatchingTag (Tag &tag) const;
15.451 -
15.452 + bool FindFirstMatchingByteTag (Tag &tag) const;
15.453 +
15.454 /**
15.455 * Remove all the tags stored in this packet.
15.456 */
15.457 - void RemoveAllTags (void);
15.458 + void RemoveAllByteTags (void);
15.459 +
15.460 + /**
15.461 + * \param os output stream in which the data should be printed.
15.462 + *
15.463 + * Iterate over the tags present in this packet, and
15.464 + * invoke the Print method of each tag stored in the packet.
15.465 + */
15.466 + void PrintByteTags (std::ostream &os) const;
15.467 @end verbatim
15.468
15.469 -@subsection Fragmentation
15.470 +The Packet API for packet tags is given below.
15.471 @verbatim
15.472 - /**
15.473 - * Create a new packet which contains a fragment of the original
15.474 - * packet. The returned packet shares the same uid as this packet.
15.475 - *
15.476 - * \param start offset from start of packet to start of fragment to create
15.477 - * \param length length of fragment to create
15.478 - * \returns a fragment of the original packet
15.479 - */
15.480 - Packet CreateFragment (uint32_t start, uint32_t length) const;
15.481 -
15.482 - /**
15.483 - * Concatenate the input packet at the end of the current
15.484 - * packet. This does not alter the uid of either packet.
15.485 - *
15.486 - * \param packet packet to concatenate
15.487 - */
15.488 - void addAtEnd (Packet packet);
15.489 -
15.490 - /oncatenate the input packet at the end of the current
15.491 - * packet. This does not alter the uid of either packet.
15.492 - *
15.493 - * \param packet packet to concatenate
15.494 - */
15.495 - void AddAtEnd (Packet packet);
15.496 - /**
15.497 - * Concatenate the fragment of the input packet identified
15.498 - * by the offset and size parameters at the end of the current
15.499 - * packet. This does not alter the uid of either packet.
15.500 - *
15.501 - * \param packet to concatenate
15.502 - * \param offset offset of fragment to copy from the start of the input packet
15.503 - * \param size size of fragment of input packet to copy.
15.504 - */
15.505 - void AddAtEnd (Packet packet, uint32_t offset, uint32_t size);
15.506 - /**
15.507 - * Remove size bytes from the end of the current packet
15.508 - * It is safe to remove more bytes that what is present in
15.509 - * the packet.
15.510 - *
15.511 - * \param size number of bytes from remove
15.512 - */
15.513 - void RemoveAtEnd (uint32_t size);
15.514 - /**
15.515 - * Remove size bytes from the start of the current packet.
15.516 - * It is safe to remove more bytes that what is present in
15.517 - * the packet.
15.518 - *
15.519 - * \param size number of bytes from remove
15.520 - */
15.521 - void RemoveAtStart (uint32_t size);
15.522 + /**
15.523 + * \param tag the tag to store in this packet
15.524 + *
15.525 + * Add a tag to this packet. This method calls the
15.526 + * Tag::GetSerializedSize and, then, Tag::Serialize.
15.527 + *
15.528 + * Note that this method is const, that is, it does not
15.529 + * modify the state of this packet, which is fairly
15.530 + * un-intuitive.
15.531 + */
15.532 + void AddPacketTag (const Tag &tag) const;
15.533 + /**
15.534 + * \param tag the tag to remove from this packet
15.535 + * \returns true if the requested tag is found, false
15.536 + * otherwise.
15.537 + *
15.538 + * Remove a tag from this packet. This method calls
15.539 + * Tag::Deserialize if the tag is found.
15.540 + */
15.541 + bool RemovePacketTag (Tag &tag);
15.542 + /**
15.543 + * \param tag the tag to search in this packet
15.544 + * \returns true if the requested tag is found, false
15.545 + * otherwise.
15.546 + *
15.547 + * Search a matching tag and call Tag::Deserialize if it is found.
15.548 + */
15.549 + bool PeekPacketTag (Tag &tag) const;
15.550 + /**
15.551 + * Remove all packet tags.
15.552 + */
15.553 + void RemoveAllPacketTags (void);
15.554 +
15.555 + /**
15.556 + * \param os the stream in which we want to print data.
15.557 + *
15.558 + * Print the list of 'packet' tags.
15.559 + *
15.560 + * \sa Packet::AddPacketTag, Packet::RemovePacketTag, Packet::PeekPacketTag,
15.561 + * Packet::RemoveAllPacketTags
15.562 + */
15.563 + void PrintPacketTags (std::ostream &os) const;
15.564 +
15.565 + /**
15.566 + * \returns an object which can be used to iterate over the list of
15.567 + * packet tags.
15.568 + */
15.569 + PacketTagIterator GetPacketTagIterator (void) const;
15.570 @end verbatim
15.571
15.572 -@subsection Miscellaneous
15.573 +Here is a simple example illustrating the use of tags from the
15.574 +code in @code{src/internet-stack/udp-socket-impl.cc}:
15.575 @verbatim
15.576 - /**
15.577 - * \returns the size in bytes of the packet (including the zero-filled
15.578 - * initial payload)
15.579 - */
15.580 - uint32_t GetSize (void) const;
15.581 - /**
15.582 - * If you try to change the content of the buffer
15.583 - * returned by this method, you will die.
15.584 - *
15.585 - * \returns a pointer to the internal buffer of the packet.
15.586 - */
15.587 - uint8_t const *PeekData (void) const;
15.588 - /**
15.589 - * A packet is allocated a new uid when it is created
15.590 - * empty or with zero-filled payload.
15.591 - *
15.592 - * \returns an integer identifier which uniquely
15.593 - * identifies this packet.
15.594 - */
15.595 - uint32_t GetUid (void) const;
15.596 + Ptr<Packet> p; // pointer to a pre-existing packet
15.597 + SocketIpTtlTag tag
15.598 + tag.SetTtl (m_ipMulticastTtl); // Convey the TTL from Udp layer to IP layer
15.599 + p->AddPacketTag (tag);
15.600 @end verbatim
15.601
15.602 -@section Using Headers
15.603 -@emph{walk through an example of adding a UDP header}
15.604 +This tag is read at the IP layer, then stripped (@code{src/internet-stack/ipv4-l3-protocol.cc}:
15.605 +@verbatim
15.606 + uint8_t ttl = m_defaultTtl;
15.607 + SocketIpTtlTag tag;
15.608 + bool found = packet->RemovePacketTag (tag);
15.609 + if (found)
15.610 + {
15.611 + ttl = tag.GetTtl ();
15.612 + }
15.613 +@end verbatim
15.614
15.615 -@section Using Tags
15.616 -@emph{walk through an example of adding a flow ID}
15.617 +@subsection Fragmentation and concatenation
15.618
15.619 -@section Using Fragmentation
15.620 -@emph{walk through an example of link-layer fragmentation/reassembly}
15.621 +Packets may be fragmented or merged together. For example, to
15.622 +fragment a packet @code{p} of 90 bytes into two packets, one containing
15.623 +the first 10 bytes and the other containing the remaining 80, one may call the
15.624 +following code:
15.625 +@verbatim
15.626 + Ptr<Packet> frag0 = p->CreateFragment (0, 10);
15.627 + Ptr<Packet> frag1 = p->CreateFragment (10, 90);
15.628 +@end verbatim
15.629
15.630 -@section Sample program
15.631 -The below sample program (from @code{ns3/samples/main-packet.cc}) illustrates
15.632 -some use of the Packet, Header, and Tag classes.
15.633 +As discussed above, the packet tags from @code{p} will follow to both
15.634 +packet fragments, and the byte tags will follow the byte ranges as needed.
15.635
15.636 +Now, to put them back together:
15.637 @verbatim
15.638 -/* -*- Mode:C++; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */
15.639 -#include "ns3/packet.h"
15.640 -#include "ns3/header.h"
15.641 -#include <iostream>
15.642 + frag0->AddAtEnd (frag1);
15.643 +@end verbatim
15.644 +Now frag0 should be equivalent to the original packet @code{p}. If,
15.645 +however, there were operations on the fragments before being reassembled
15.646 +(such as tag operations or header operations), the new packet will not
15.647 +be the same.
15.648
15.649 -using namespace ns3;
15.650 +@subsection Enabling metadata
15.651
15.652 -/* A sample Header implementation
15.653 - */
15.654 -class MyHeader : public Header {
15.655 -public:
15.656 - MyHeader ();
15.657 - virtual ~MyHeader ();
15.658 +We mentioned above that packets, being on-the-wire representations of
15.659 +byte buffers, present a problem to print out in a structured way
15.660 +unless the printing function has access to the context of the header.
15.661 +For instance, consider a tcpdump-like printer that wants to pretty-print
15.662 +the contents of a packet.
15.663
15.664 - void SetData (uint16_t data);
15.665 - uint16_t GetData (void) const;
15.666 -private:
15.667 - virtual void PrintTo (std::ostream &os) const;
15.668 - virtual void SerializeTo (Buffer::Iterator start) const;
15.669 - virtual void DeserializeFrom (Buffer::Iterator start);
15.670 - virtual uint32_t GetSerializedSize (void) const;
15.671 +To enable this usage, packets may have metadata enabled (disabled by
15.672 +default for performance reasons). This class is used by the Packet
15.673 +class to record every operation performed on the packet's buffer, and
15.674 +provides an implementation of @code{Packet::Print ()} method that uses
15.675 +the metadata to analyze the content of the packet's buffer.
15.676
15.677 - uint16_t m_data;
15.678 -};
15.679 +The metadata is also used to perform extensive sanity checks at runtime
15.680 +when performing operations on a Packet. For example, this metadata is
15.681 +used to verify that when you remove a header from a packet, this
15.682 +same header was actually present at the front of the packet. These
15.683 +errors will be detected and will abort the program.
15.684
15.685 -MyHeader::MyHeader ()
15.686 -{}
15.687 -MyHeader::~MyHeader ()
15.688 -{}
15.689 -void
15.690 -MyHeader::PrintTo (std::ostream &os) const
15.691 -{
15.692 - os << "MyHeader data=" << m_data << std::endl;
15.693 -}
15.694 -uint32_t
15.695 -MyHeader::GetSerializedSize (void) const
15.696 -{
15.697 - return 2;
15.698 -}
15.699 -void
15.700 -MyHeader::SerializeTo (Buffer::Iterator start) const
15.701 -{
15.702 - // serialize in head of buffer
15.703 - start.WriteHtonU16 (m_data);
15.704 -}
15.705 -void
15.706 -MyHeader::DeserializeFrom (Buffer::Iterator start)
15.707 -{
15.708 - // deserialize from head of buffer
15.709 - m_data = start.ReadNtohU16 ();
15.710 -}
15.711 +To enable this operation, users will typically insert one or both
15.712 +of these statements at the beginning of their programs:
15.713 +@verbatim
15.714 + Packet::EnablePrinting ();
15.715 + Packet::EnableChecking ();
15.716 +@end verbatim
15.717
15.718 -void
15.719 -MyHeader::SetData (uint16_t data)
15.720 -{
15.721 - m_data = data;
15.722 -}
15.723 -uint16_t
15.724 -MyHeader::GetData (void) const
15.725 -{
15.726 - return m_data;
15.727 -}
15.728 +@section Sample programs
15.729
15.730 -/* A sample Tag implementation
15.731 - */
15.732 -struct MyTag {
15.733 - uint16_t m_streamId;
15.734 -};
15.735 -
15.736 -static TagRegistration<struct MyTag> g_MyTagRegistration ("ns3::MyTag", 0);
15.737 -
15.738 -
15.739 -static void
15.740 -Receive (Packet p)
15.741 -{
15.742 - MyHeader my;
15.743 - p.Peek (my);
15.744 - p.Remove (my);
15.745 - std::cout << "received data=" << my.GetData () << std::endl;
15.746 - struct MyTag myTag;
15.747 - p.PeekTag (myTag);
15.748 -}
15.749 -
15.750 -
15.751 -int main (int argc, char *argv[])
15.752 -{
15.753 - Packet p;
15.754 - MyHeader my;
15.755 - my.SetData (2);
15.756 - std::cout << "send data=2" << std::endl;
15.757 - p.Add (my);
15.758 - struct MyTag myTag;
15.759 - myTag.m_streamId = 5;
15.760 - p.AddTag (myTag);
15.761 - Receive (p);
15.762 - return 0;
15.763 -}
15.764 -@end verbatim
15.765 +See @code{samples/main-packet.cc} and @code{samples/main-packet-tag.cc}.
15.766
15.767 @section Implementation details
15.768
15.769 @@ -457,13 +534,19 @@
15.770 A Packet object's interface provides access to some private
15.771 data:
15.772 @verbatim
15.773 - Buffer m_buffer;
15.774 - Tags m_tags;
15.775 - uint32_t m_uid;
15.776 - static uint32_t m_global_uid;
15.777 + Buffer m_buffer;
15.778 + ByteTagList m_byteTagList;
15.779 + PacketTagList m_packetTagList;
15.780 + PacketMetadata m_metadata;
15.781 + mutable uint32_t m_refCount;
15.782 + static uint32_t m_globalUid;
15.783 @end verbatim
15.784 -Each Packet has a Buffer and a Tags object, and a 32-bit unique ID (m\_uid).
15.785 -A static member variable keeps track of the UIDs allocated. Note
15.786 +Each Packet has a Buffer and two Tags lists, a PacketMetadata object,
15.787 +and a ref count.
15.788 +A static member variable keeps track of the UIDs allocated.
15.789 +The actual uid of the packet is stored in the PacketMetadata.
15.790 +
15.791 +Note
15.792 that real network packets do not have a UID; the UID is therefore an
15.793 instance of data that normally would be stored as a Tag in the packet.
15.794 However, it was felt that a UID is a special case that is so often
15.795 @@ -525,6 +608,9 @@
15.796 then complete their state-changing operation.
15.797
15.798 @subsection Tags implementation
15.799 +
15.800 +(XXX revise me)
15.801 +
15.802 Tags are implemented by a single pointer which points to the start of a
15.803 linked list ofTagData data structures. Each TagData structure points
15.804 to the next TagData in the list (its next pointer contains zero to
15.805 @@ -562,12 +648,8 @@
15.806 };
15.807 @end verbatim
15.808
15.809 -@emph{add description of TagRegistration for printing}
15.810 -
15.811 @subsection Memory management
15.812
15.813 -@emph{Describe free list.}
15.814 -
15.815 @emph{Describe dataless vs. data-full packets.}
15.816
15.817 @subsection Copy-on-write semantics
15.818 @@ -590,21 +672,26 @@
15.819
15.820 Dirty operations:
15.821 @itemize @bullet
15.822 -@item Packet::RemoveTag()
15.823 -@item Packet::Add()
15.824 -@item both versions of ns3::Packet::AddAtEnd()
15.825 +@item ns3::Packet::AddHeader
15.826 +@item ns3::Packet::AddTrailer
15.827 +@item both versions of ns3::Packet::AddAtEnd
15.828 +@item ns3::Packet::RemovePacketTag
15.829 @end itemize
15.830
15.831 Non-dirty operations:
15.832 @itemize @bullet
15.833 -@item Packet::AddTag()
15.834 -@item Packet::RemoveAllTags()
15.835 -@item Packet::PeekTag()
15.836 -@item Packet::Peek()
15.837 -@item Packet::Remove()
15.838 -@item Packet::CreateFragment()
15.839 -@item Packet::RemoveAtStart()
15.840 -@item Packet::RemoveAtEnd()
15.841 +@item ns3::Packet::AddPacketTag
15.842 +@item ns3::Packet::PeekPacketTag
15.843 +@item ns3::Packet::RemoveAllPacketTags
15.844 +@item ns3::Packet::AddByteTag
15.845 +@item ns3::Packet::FindFirstMatchingByteTag
15.846 +@item ns3::Packet::RemoveAllByteTags
15.847 +@item ns3::Packet::RemoveHeader
15.848 +@item ns3::Packet::RemoveTrailer
15.849 +@item ns3::Packet::CreateFragment
15.850 +@item ns3::Packet::RemoveAtStart
15.851 +@item ns3::Packet::RemoveAtEnd
15.852 +@item ns3::Packet::CopyData
15.853 @end itemize
15.854
15.855 Dirty operations will always be slower than non-dirty operations,
16.1 --- a/doc/manual/routing.texi Tue Jun 09 18:00:24 2009 +0100
16.2 +++ b/doc/manual/routing.texi Tue Jun 09 18:00:52 2009 +0100
16.3 @@ -2,40 +2,213 @@
16.4 @chapter Routing overview
16.5
16.6 @menu
16.7 -* Routing-Overview::
16.8 -* Support for multiple routing protocols::
16.9 -* Roadmap and Future work::
16.10 -* Static routing::
16.11 +* Routing architecture::
16.12 +* Global centralized routing::
16.13 * Unicast routing::
16.14 * Multicast routing::
16.15 -* Global centralized routing::
16.16 -* Global Unicast Routing API::
16.17 -* Global Routing Implementation::
16.18 -* Optimized Link State Routing (OLSR)::
16.19 @end menu
16.20
16.21 -This chapter describes the overall design of routing in the
16.22 -@code{src/internet-stack}
16.23 -module, and some details about the routing approachs currently
16.24 -implemented.
16.25 +ns-3 is intended to support traditional routing approaches and protocols,
16.26 +support ports of open source routing implementations, and facilitate research
16.27 +into unorthodox routing techniques. The overall routing architecture
16.28 +is described below in @ref{Routing architecture}. Users who wish to
16.29 +just read about how to configure global routing for wired topologies
16.30 +can read @ref{Global centralized routing}. Unicast routing protocols
16.31 +are described in @ref{Unicast routing}. Multicast routing is documented in
16.32 +@ref{Multicast routing}.
16.33
16.34 -@node Routing-Overview
16.35 -@section Overview
16.36 +@node Routing architecture
16.37 +@section Routing architecture
16.38
16.39 -We intend to support traditional routing approaches and protocols,
16.40 -ports of open source routing implementations, and facilitate research
16.41 -into unorthodox routing techniques.
16.42 -For simulations that are not primarily focused on routing and that
16.43 -simply want correct routing tables to occur somehow, we have an
16.44 -global centralized routing capability. A singleton object
16.45 -(GlobalRouteManager) be instantiated, builds a network map, and
16.46 -populates a forwarding table on each node at time t=0 in the
16.47 -simulation. Simulation script writers can use the same node
16.48 -API to manually enter routes as well.
16.49 +@float Figure,fig:routing
16.50 +@caption{Overview of routing}
16.51 +@image{figures/routing, 6in}
16.52 +@end float
16.53
16.54 -@node Support for multiple routing protocols
16.55 -@section Support for multiple routing protocols
16.56 +Figure 11-1 shows the overall routing architecture for Ipv4. The key objects
16.57 +are Ipv4L3Protocol, Ipv4RoutingProtocol(s) (a class to which all
16.58 +routing/forwarding has been delegated from Ipv4L3Protocol), and Ipv4Route(s).
16.59
16.60 +Ipv4L3Protocol must have at least one Ipv4RoutingProtocol added to
16.61 +it at simulation setup time. This is done explicitly by calling
16.62 +Ipv4::SetRoutingProtocol ().
16.63 +
16.64 +The abstract base class Ipv4RoutingProtocol () declares a minimal interface,
16.65 +consisting of two methods: RouteOutput () and RouteInput ().
16.66 +For packets traveling outbound from a host, the transport protocol will query
16.67 +Ipv4 for the Ipv4RoutingProtocol object interface, and will request
16.68 +a route via Ipv4RoutingProtocol::RouteOutput ().
16.69 +A Ptr to Ipv4Route object is returned. This is analagous to a
16.70 +dst_cache entry in Linux. The Ipv4Route is carried down to the
16.71 +Ipv4L3Protocol to avoid a second lookup there. However, some
16.72 +cases (e.g. Ipv4 raw sockets) will require a call to RouteOutput()
16.73 +directly from Ipv4L3Protocol.
16.74 +
16.75 +For packets received inbound for forwarding or delivery,
16.76 +the following steps occur. Ipv4L3Protocol::Receive() calls
16.77 +Ipv4RoutingProtocol::RouteInput().
16.78 +This passes the packet ownership to the Ipv4RoutingProtocol object. There
16.79 +are four callbacks associated with this call:
16.80 +@itemize @bullet
16.81 +@item LocalDeliver
16.82 +@item UnicastForward
16.83 +@item MulticastForward
16.84 +@item Error
16.85 +@end itemize
16.86 +The Ipv4RoutingProtocol must eventually call one of these callbacks for each
16.87 +packet that it takes responsibility for. This is basically
16.88 +how the input routing process works in Linux.
16.89 +
16.90 +@float Figure,fig:routing-specialization
16.91 +@caption{Ipv4Routing specialization}
16.92 +@image{figures/routing-specialization, 5in}
16.93 +@end float
16.94 +
16.95 +This overall architecture is designed to support different routing
16.96 +approaches, including (in the future) a Linux-like policy-based routing
16.97 +implementation, proactive and on-demand routing protocols, and simple
16.98 +routing protocols for when the simulation user does not really care
16.99 +about routing.
16.100 +
16.101 +@ref{fig:routing-specialization} illustrates how multiple routing protocols
16.102 +derive from this base class. A class Ipv4ListRouting
16.103 +(implementation class Ipv4ListRoutingImpl) provides the existing
16.104 +list routing approach in ns-3. Its API is the same as base class
16.105 +Ipv4Routing except for the ability to add multiple prioritized routing
16.106 +protocols
16.107 +(Ipv4ListRouting::AddRoutingProtocol(), Ipv4ListRouting::GetRoutingProtocol()).
16.108 +
16.109 +The details of these routing protocols are described below in
16.110 +@ref{Unicast routing}. For now, we will first start with a basic
16.111 +unicast routing capability that is intended to globally build routing
16.112 +tables at simulation time t=0 for simulation users who do not care
16.113 +about dynamic routing.
16.114 +
16.115 +@node Global centralized routing
16.116 +@section Global centralized routing
16.117 +
16.118 +Global centralized routing is sometimes called ''God'' routing; it
16.119 +is a special implementation that walks the simulation topology and
16.120 +runs a shortest path algorithm, and populates each node's routing
16.121 +tables. No actual protocol overhead (on the simulated links) is incurred
16.122 +with this approach. It does have a few constraints:
16.123 +
16.124 +@itemize @bullet
16.125 +@item @strong{Wired only:} It is not intended for use in wireless networks.
16.126 +@item @strong{Unicast only:} It does not do multicast.
16.127 +@item @strong{Scalability:} Some users of this on large topologies
16.128 +(e.g. 1000 nodes)
16.129 +have noticed that the current implementation is not very scalable.
16.130 +The global centralized routing will be modified in the future to
16.131 +reduce computations and runtime performance.
16.132 +@end itemize
16.133 +
16.134 +Presently, global centralized IPv4 unicast routing over both
16.135 +point-to-point and shared (CSMA) links is supported.
16.136 +
16.137 +@subsection Global Unicast Routing API
16.138 +
16.139 +The public API is very minimal. User scripts include the following:
16.140 +@verbatim
16.141 +#include "ns3/global-route-manager.h"
16.142 +@end verbatim
16.143 +
16.144 +After IP addresses are configured, the following function call will
16.145 +cause all of the nodes that have an Ipv4 interface to receive
16.146 +forwarding tables entered automatically by the GlobalRouteManager:
16.147 +@verbatim
16.148 + GlobalRouteManager::PopulateRoutingTables ();
16.149 +@end verbatim
16.150 +
16.151 +@emph{Note:} A reminder that the wifi NetDevice will work but does not
16.152 +take any wireless effects into account. For wireless, we recommend
16.153 +OLSR dynamic routing described below.
16.154 +
16.155 +It is possible to call this function again in the midst of a simulation
16.156 +using the following additional public function:
16.157 +@verbatim
16.158 + GlobalRouteManager::RecomputeRoutingTables ();
16.159 +@end verbatim
16.160 +which flushes the old tables, queries the nodes for new interface information,
16.161 +and rebuilds the routes.
16.162 +
16.163 +For instance, this scheduling call will cause the tables to be rebuilt
16.164 +at time 5 seconds:
16.165 +@verbatim
16.166 + Simulator::Schedule (Seconds (5),&GlobalRouteManager::RecomputeRoutingTables);
16.167 +@end verbatim
16.168 +
16.169 +@subsection Global Routing Implementation
16.170 +
16.171 +This section is for those readers who care about how this is implemented.
16.172 +A singleton object (GlobalRouteManager) is responsible for populating
16.173 +the static routes on each node, using the public Ipv4 API of that node.
16.174 +It queries each node in the topology for a "globalRouter" interface.
16.175 +If found, it uses the API of that interface to obtain a "link state
16.176 +advertisement (LSA)" for the router. Link State Advertisements
16.177 +are used in OSPF routing, and we follow their formatting.
16.178 +
16.179 +The GlobalRouteManager populates a link state database with LSAs
16.180 +gathered from the entire topology. Then, for each router in the topology,
16.181 +the GlobalRouteManager executes the OSPF shortest path first (SPF)
16.182 +computation on the database, and populates the routing tables on each
16.183 +node.
16.184 +
16.185 +The quagga (http://www.quagga.net) OSPF implementation was used as the
16.186 +basis for the routing computation logic.
16.187 +One benefit of following an existing OSPF SPF implementation is that
16.188 +OSPF already has defined link state advertisements for all common
16.189 +types of network links:
16.190 +@itemize @bullet
16.191 +@item point-to-point (serial links)
16.192 +@item point-to-multipoint (Frame Relay, ad hoc wireless)
16.193 +@item non-broadcast multiple access (ATM)
16.194 +@item broadcast (Ethernet)
16.195 +@end itemize
16.196 +Therefore, we think that enabling these other link types will be more
16.197 +straightforward now that the underlying OSPF SPF framework is in place.
16.198 +
16.199 +Presently, we can handle IPv4 point-to-point, numbered links, as well
16.200 +as shared broadcast (CSMA) links, and we do not do equal-cost multipath.
16.201 +
16.202 +The GlobalRouteManager first walks the list of nodes and aggregates
16.203 +a GlobalRouter interface to each one as follows:
16.204 +@verbatim
16.205 + typedef std::vector < Ptr<Node> >::iterator Iterator;
16.206 + for (Iterator i = NodeList::Begin (); i != NodeList::End (); i++)
16.207 + {
16.208 + Ptr<Node> node = *i;
16.209 + Ptr<GlobalRouter> globalRouter = CreateObject<GlobalRouter> (node);
16.210 + node->AggregateObject (globalRouter);
16.211 + }
16.212 +@end verbatim
16.213 +
16.214 +This interface is later queried and used to generate a Link State
16.215 +Advertisement for each router, and this link state database is
16.216 +fed into the OSPF shortest path computation logic. The Ipv4 API
16.217 +is finally used to populate the routes themselves.
16.218 +
16.219 +@node Unicast routing
16.220 +@section Unicast routing
16.221 +
16.222 +There are presently four routing protocols defined:
16.223 +@itemize @bullet
16.224 +@item class Ipv4StaticRouting (covering both unicast and multicast)
16.225 +@item Optimized Link State Routing (a MANET protocol defined in
16.226 +@uref{http://www.ietf.org/rfc/rfc3626.txt,,RFC 3626})
16.227 +@item class Ipv4ListRouting (used to store a prioritized list of routing
16.228 +protocols)
16.229 +@item class Ipv4GlobalRouting (used to store routes computed by the global
16.230 +route manager, if that is used)
16.231 +@end itemize
16.232 +
16.233 +In the future, this architecture should also allow someone to implement
16.234 +a Linux-like implementation with routing cache, or a Click modular
16.235 +router, but those are out of scope for now.
16.236 +
16.237 +@subsection Ipv4ListRouting
16.238 +
16.239 +This section describes the current default ns-3 Ipv4RoutingProtocol.
16.240 Typically, multiple routing protocols are supported in user space and
16.241 coordinate to write a single forwarding table in the kernel. Presently
16.242 in @command{ns-3}, the implementation instead allows for multiple routing
16.243 @@ -50,163 +223,54 @@
16.244 routing) is used to determine the next hop, and on-demand
16.245 routing approaches where packets must be cached.
16.246
16.247 -There are presently two routing protocols defined:
16.248 -@itemize @bullet
16.249 -@item class Ipv4StaticRouting (covering both unicast and multicast)
16.250 -@item Optimized Link State Routing (a MANET protocol defined in
16.251 -@uref{http://www.ietf.org/rfc/rfc3626.txt,,RFC 3626})
16.252 -@end itemize
16.253 -but first we describe how multiple routing protocols are supported.
16.254 +@subsubsection Ipv4ListRouting::AddRoutingProtocol
16.255
16.256 -@subsection class Ipv4RoutingProtocol
16.257 -
16.258 -@code{class Ipv4RoutingProtocol} derives from ns-3 Object which means
16.259 -that it supports interface aggregation and reference counting. Routing
16.260 -protocols should inherit from this class, defined in src/node/ipv4.cc.
16.261 -
16.262 -The main function that must be supported by these protocols is called
16.263 -@code{RequestRoute}.
16.264 -@verbatim
16.265 - * This method is called whenever a node's IPv4 forwarding engine
16.266 - * needs to lookup a route for a given packet and IP header.
16.267 - *
16.268 - * The routing protocol implementation may determine immediately it
16.269 - * should not be handling this particular the route request. For
16.270 - * instance, a routing protocol may decline to search for routes for
16.271 - * certain classes of addresses, like link-local. In this case,
16.272 - * RequestRoute() should return false and the routeReply callback
16.273 - * must not be invoked.
16.274 - *
16.275 - * If the routing protocol implementations assumes it can provide
16.276 - * the requested route, then it should return true, and the
16.277 - * routeReply callback must be invoked, either immediately before
16.278 - * returning true (synchronously), or in the future (asynchronous).
16.279 - * The routing protocol may use any information available in the IP
16.280 - * header and packet as routing key, although most routing protocols
16.281 - * use only the destination address (as given by
16.282 - * ipHeader.GetDestination ()). The routing protocol is also
16.283 - * allowed to add a new header to the packet, which will appear
16.284 - * immediately after the IP header, although most routing do not
16.285 - * insert any extra header.
16.286 - */
16.287 - virtual bool RequestRoute (uint32_t interface,
16.288 - const Ipv4Header &ipHeader,
16.289 - Ptr<Packet> packet,
16.290 - RouteReplyCallback routeReply) = 0;
16.291 -@end verbatim
16.292 -
16.293 -This class also provides a typedef (used above) for a special Callback
16.294 -that will pass to the callback function the Ipv4Route that is found (see the
16.295 -Doxygen documentation):
16.296 -@verbatim
16.297 - typedef Callback<void, bool, const Ipv4Route&, Ptr<Packet>, const Ipv4Header&> RouteReplyCallback;
16.298 -@end verbatim
16.299 -
16.300 -@subsection Ipv4::AddRoutingProtocol
16.301 -
16.302 -Class Ipv4 provides a pure virtual function declaration for the
16.303 +Class Ipv4ListRouting provides a pure virtual function declaration for the
16.304 method that allows one to add a routing protocol:
16.305 @verbatim
16.306 void AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
16.307 int16_t priority);
16.308 @end verbatim
16.309 -This method is implemented by class Ipv4L3Protocol in the internet-stack
16.310 +This method is implemented by class Ipv4ListRoutingImpl in the internet-stack
16.311 module.
16.312
16.313 The priority variable above governs the priority in which the routing
16.314 protocols are inserted. Notice that it is a signed int.
16.315 -When the class Ipv4L3Protocol is instantiated, a single routing
16.316 -protocol (Ipv4StaticRouting, introduced below) is added at priority
16.317 -zero. Internally, a list of Ipv4RoutingProtocols is stored, and
16.318 +By default in ns-3, the helper classes will instantiate a Ipv4ListRoutingImpl
16.319 +object, and add to it an Ipv4StaticRoutingImpl object at priority zero.
16.320 +Internally, a list of Ipv4RoutingProtocols is stored, and
16.321 and the routing protocols are each consulted in decreasing order
16.322 of priority to see whether a match is found. Therefore, if you
16.323 want your Ipv4RoutingProtocol to have priority lower than the static
16.324 routing, insert it with priority less than 0; e.g.:
16.325 @verbatim
16.326 - m_ipv4->AddRoutingProtocol (m_routingTable, -10);
16.327 + Ptr<MyRoutingProtocol> myRoutingProto = CreateObject<MyRoutingProtocol> ();
16.328 + listRoutingPtr->AddRoutingProtocol (myRoutingProto, -10);
16.329 @end verbatim
16.330
16.331 -@subsection Ipv4L3Protocol::Lookup
16.332 +Upon calls to RouteOutput() or RouteInput(), the list routing object will
16.333 +search the list of routing protocols, in priority order, until a route
16.334 +is found. Such routing protocol will invoke the appropriate callback
16.335 +and no further routing protocols will be searched.
16.336
16.337 -The main function for obtaining a route is shown below:
16.338 +@subsection Optimized Link State Routing (OLSR)
16.339 +
16.340 +This is the first dynamic routing protocol for @command{ns-3}. The implementation
16.341 +is found in the src/routing/olsr directory, and an example script is in
16.342 +examples/simple-point-to-point-olsr.cc.
16.343 +
16.344 +The following commands will enable OLSR in a simulation.
16.345 +
16.346 @verbatim
16.347 -Ipv4L3Protocol::Lookup (
16.348 - uint32_t interface,
16.349 - Ipv4Header const &ipHeader,
16.350 - Ptr<Packet> packet,
16.351 - Ipv4RoutingProtocol::RouteReplyCallback routeReply)
16.352 + olsr::EnableAllNodes (); // Start OLSR on all nodes
16.353 + olsr::EnableNodes(InputIterator begin, InputIterator end); // Start on
16.354 + // a list of nodes
16.355 + olsr::EnableNode (Ptr<Node> node); // Start OLSR on "node" only
16.356 @end verbatim
16.357
16.358 -This function will search the list of routing protocols, in priority order,
16.359 -until a route is found. It will then invoke the RouteReplyCallback
16.360 -and no further routing protocols will be searched. If the caller does
16.361 -not want to constrain the possible interface, it can be wildcarded
16.362 -as such:
16.363 -@verbatim
16.364 - Lookup (Ipv4RoutingProtocol::IF_INDEX_ANY, ipHeader, packet, routeReply);
16.365 -@end verbatim
16.366 -
16.367 -@node Roadmap and Future work
16.368 -@section Roadmap and Future work
16.369 -
16.370 -Some goals for future support are:
16.371 -
16.372 -Users should be able to trace (either debug print, or redirect to a trace
16.373 -file) the routing table in a format such as used in an
16.374 -Unix implementation:
16.375 -@verbatim
16.376 -# netstat -nr (or # route -n)
16.377 -Kernel IP routing table
16.378 -Destination Gateway Genmask Flags MSS Window irtt Iface
16.379 -127.0.0.1 * 255.255.255.255 UH 0 0 0 lo
16.380 -172.16.1.0 * 255.255.255.0 U 0 0 0 eth0
16.381 -172.16.2.0 172.16.1.1 255.255.255.0 UG 0 0 0 eth0
16.382 -
16.383 -# ip route show
16.384 -192.168.99.0/24 dev eth0 scope link
16.385 -127.0.0.0/8 dev lo scope link
16.386 -default via 192.168.99.254 dev eth0
16.387 -@end verbatim
16.388 -
16.389 -Global computation of multicast routing should be implemented as well.
16.390 -This would ignore group membership and ensure that a copy of every
16.391 -sourced multicast datagram would be delivered to each node.
16.392 -This might be implemented as an RPF mechanism that functioned on-demand
16.393 -by querying the forwarding table,
16.394 -and perhaps optimized by a small multicast forwarding cache. It is
16.395 -a bit trickier to implement over wireless links where the input
16.396 -interface is the same as the output interface; other aspects of the
16.397 -packet must be considered and the forwarding logic slightly changed
16.398 -to allow for forwarding out the same interface.
16.399 -
16.400 -In the future, work on bringing XORP or quagga routing to ns, but it will
16.401 -take several months to port and enable.
16.402 -
16.403 -There are presently no roadmap plans for IPv6.
16.404 -
16.405 -@node Static routing
16.406 -@section Static routing
16.407 -
16.408 -The internet-stack module provides one routing protocol (Ipv4StaticRouting)
16.409 -by default. This routing protocol allows one to add unicast or multicast
16.410 -static routes to a node.
16.411 -
16.412 -@node Unicast routing
16.413 -@section Unicast routing
16.414 -
16.415 -The unicast static routing API may be accessed via the functions
16.416 -@verbatim
16.417 -void Ipv4::AddHostRouteTo ()
16.418 -void Ipv4::AddNetworkRouteTo ()
16.419 -void Ipv4::SetDefaultRoute ()
16.420 -uint32_t Ipv4::GetNRoutes ()
16.421 -Ipv4Route Ipv4::GetRoute ()
16.422 -@end verbatim
16.423 -
16.424 -@uref{http://www.nsnam.org/doxygen/index.html,,Doxygen} documentation
16.425 -provides full documentation of these methods. These methods are forwarding
16.426 -functions to the actual implementation in Ipv4StaticRouting, when using
16.427 -the internet-stack module.
16.428 +Once instantiated, the agent can be started with the Start() command,
16.429 +and the OLSR "main interface" can be set with the SetMainInterface()
16.430 +command. A number of protocol constants are defined in olsr-agent-impl.cc.
16.431
16.432 @node Multicast routing
16.433 @section Multicast routing
16.434 @@ -288,113 +352,4 @@
16.435 void RemoveMulticastRoute (uint32_t index);
16.436 @end verbatim
16.437
16.438 -@node Global centralized routing
16.439 -@section Global centralized routing
16.440
16.441 -Presently, global centralized IPv4 @emph{unicast} routing over both
16.442 -point-to-point and shared (CSMA) links is supported.
16.443 -The global centralized routing will be modified in the future to
16.444 -reduce computations once profiling finds the performance bottlenecks.
16.445 -
16.446 -@node Global Unicast Routing API
16.447 -@section Global Unicast Routing API
16.448 -
16.449 -The public API is very minimal. User scripts include the following:
16.450 -@verbatim
16.451 -#include "ns3/global-route-manager.h"
16.452 -@end verbatim
16.453 -
16.454 -After IP addresses are configured, the following function call will
16.455 -cause all of the nodes that have an Ipv4 interface to receive
16.456 -forwarding tables entered automatically by the GlobalRouteManager:
16.457 -@verbatim
16.458 - GlobalRouteManager::PopulateRoutingTables ();
16.459 -@end verbatim
16.460 -
16.461 -@emph{Note:} A reminder that the wifi NetDevice is not yet supported
16.462 -(only CSMA and PointToPoint).
16.463 -
16.464 -It is possible to call this function again in the midst of a simulation
16.465 -using the following additional public function:
16.466 -@verbatim
16.467 - GlobalRouteManager::RecomputeRoutingTables ();
16.468 -@end verbatim
16.469 -which flushes the old tables, queries the nodes for new interface information,
16.470 -and rebuilds the routes.
16.471 -
16.472 -For instance, this scheduling call will cause the tables to be rebuilt
16.473 -at time 5 seconds:
16.474 -@verbatim
16.475 - Simulator::Schedule (Seconds (5),&GlobalRouteManager::RecomputeRoutingTables);
16.476 -@end verbatim
16.477 -
16.478 -@node Global Routing Implementation
16.479 -@section Global Routing Implementation
16.480 -
16.481 -A singleton object (GlobalRouteManager) is responsible for populating
16.482 -the static routes on each node, using the public Ipv4 API of that node.
16.483 -It queries each node in the topology for a "globalRouter" interface.
16.484 -If found, it uses the API of that interface to obtain a "link state
16.485 -advertisement (LSA)" for the router. Link State Advertisements
16.486 -are used in OSPF routing, and we follow their formatting.
16.487 -
16.488 -The GlobalRouteManager populates a link state database with LSAs
16.489 -gathered from the entire topology. Then, for each router in the topology,
16.490 -the GlobalRouteManager executes the OSPF shortest path first (SPF)
16.491 -computation on the database, and populates the routing tables on each
16.492 -node.
16.493 -
16.494 -The quagga (http://www.quagga.net) OSPF implementation was used as the
16.495 -basis for the routing computation logic.
16.496 -One benefit of following an existing OSPF SPF implementation is that
16.497 -OSPF already has defined link state advertisements for all common
16.498 -types of network links:
16.499 -@itemize @bullet
16.500 -@item point-to-point (serial links)
16.501 -@item point-to-multipoint (Frame Relay, ad hoc wireless)
16.502 -@item non-broadcast multiple access (ATM)
16.503 -@item broadcast (Ethernet)
16.504 -@end itemize
16.505 -Therefore, we think that enabling these other link types will be more
16.506 -straightforward now that the underlying OSPF SPF framework is in place.
16.507 -
16.508 -Presently, we can handle IPv4 point-to-point, numbered links, as well
16.509 -as shared broadcast (CSMA) links, and we do not do equal-cost multipath.
16.510 -
16.511 -The GlobalRouteManager first walks the list of nodes and aggregates
16.512 -a GlobalRouter interface to each one as follows:
16.513 -@verbatim
16.514 - typedef std::vector < Ptr<Node> >::iterator Iterator;
16.515 - for (Iterator i = NodeList::Begin (); i != NodeList::End (); i++)
16.516 - {
16.517 - Ptr<Node> node = *i;
16.518 - Ptr<GlobalRouter> globalRouter = CreateObject<GlobalRouter> (node);
16.519 - node->AggregateObject (globalRouter);
16.520 - }
16.521 -@end verbatim
16.522 -
16.523 -This interface is later queried and used to generate a Link State
16.524 -Advertisement for each router, and this link state database is
16.525 -fed into the OSPF shortest path computation logic. The Ipv4 API
16.526 -is finally used to populate the routes themselves.
16.527 -
16.528 -@node Optimized Link State Routing (OLSR)
16.529 -@section Optimized Link State Routing (OLSR)
16.530 -
16.531 -This is the first dynamic routing protocol for @command{ns-3}. The implementation
16.532 -is found in the src/routing/olsr directory, and an example script is in
16.533 -examples/simple-point-to-point-olsr.cc.
16.534 -
16.535 -The following commands will enable OLSR in a simulation.
16.536 -
16.537 -@verbatim
16.538 - olsr::EnableAllNodes (); // Start OLSR on all nodes
16.539 - olsr::EnableNodes(InputIterator begin, InputIterator end); // Start on
16.540 - // a list of nodes
16.541 - olsr::EnableNode (Ptr<Node> node); // Start OLSR on "node" only
16.542 -@end verbatim
16.543 -
16.544 -Once instantiated, the agent can be started with the Start() command,
16.545 -and the OLSR "main interface" can be set with the SetMainInterface()
16.546 -command. A number of protocol constants are defined in olsr-agent-impl.cc.
16.547 -
17.1 --- a/examples/mixed-wireless.cc Tue Jun 09 18:00:24 2009 +0100
17.2 +++ b/examples/mixed-wireless.cc Tue Jun 09 18:00:52 2009 +0100
17.3 @@ -392,9 +392,9 @@
17.4 // Let's do a pcap trace on the application source and sink, ifIndex 0
17.5 // Csma captures in non-promiscuous mode
17.6 CsmaHelper::EnablePcap ("mixed-wireless", appSource->GetId (), 0, false);
17.7 - YansWifiPhyHelper::EnablePcap ("mixed-wireless", appSink->GetId (), 0);
17.8 - YansWifiPhyHelper::EnablePcap ("mixed-wireless", 9, 2);
17.9 - YansWifiPhyHelper::EnablePcap ("mixed-wireless", 9, 0);
17.10 + wifiPhy.EnablePcap ("mixed-wireless", appSink->GetId (), 0);
17.11 + wifiPhy.EnablePcap ("mixed-wireless", 9, 2);
17.12 + wifiPhy.EnablePcap ("mixed-wireless", 9, 0);
17.13 }
17.14
17.15 if (useCourseChangeCallback == true)
18.1 --- a/examples/object-names.cc Tue Jun 09 18:00:24 2009 +0100
18.2 +++ b/examples/object-names.cc Tue Jun 09 18:00:52 2009 +0100
18.3 @@ -151,7 +151,7 @@
18.4 // prefix is always required since the _Config_ system always expects to
18.5 // see a fully qualified path name
18.6 //
18.7 - Config::Connect ("/Names/client/eth0/Rx", MakeCallback (&RxEvent));
18.8 + Config::Connect ("/Names/client/eth0/MacRx", MakeCallback (&RxEvent));
18.9
18.10 Simulator::Run ();
18.11 Simulator::Destroy ();
19.1 --- a/examples/simple-wifi-frame-aggregation.cc Tue Jun 09 18:00:24 2009 +0100
19.2 +++ b/examples/simple-wifi-frame-aggregation.cc Tue Jun 09 18:00:52 2009 +0100
19.3 @@ -141,7 +141,7 @@
19.4
19.5 Simulator::Stop (Seconds (10.0));
19.6
19.7 - YansWifiPhyHelper::EnablePcap ("test-802.11n",
19.8 + phy.EnablePcap ("test-802.11n",
19.9 wifiNodes.Get (nWifi - 1)->GetId (), 0);
19.10
19.11 Simulator::Run ();
20.1 --- a/examples/stats/wifi-example-apps.cc Tue Jun 09 18:00:24 2009 +0100
20.2 +++ b/examples/stats/wifi-example-apps.cc Tue Jun 09 18:00:52 2009 +0100
20.3 @@ -131,7 +131,7 @@
20.4
20.5 TimestampTag timestamp;
20.6 timestamp.SetTimestamp(Simulator::Now());
20.7 - packet->AddTag(timestamp);
20.8 + packet->AddByteTag (timestamp);
20.9
20.10 // Could connect the socket since the address never changes; using SendTo
20.11 // here simply because all of the standard apps do not.
20.12 @@ -250,7 +250,7 @@
20.13 }
20.14
20.15 TimestampTag timestamp;
20.16 - packet->FindFirstMatchingTag(timestamp);
20.17 + packet->FindFirstMatchingByteTag(timestamp);
20.18 Time tx = timestamp.GetTimestamp();
20.19
20.20 if (m_delay != 0) {
21.1 --- a/examples/third.cc Tue Jun 09 18:00:24 2009 +0100
21.2 +++ b/examples/third.cc Tue Jun 09 18:00:52 2009 +0100
21.3 @@ -164,7 +164,7 @@
21.4 Simulator::Stop (Seconds (10.0));
21.5
21.6 PointToPointHelper::EnablePcapAll ("third");
21.7 - YansWifiPhyHelper::EnablePcap ("third", apDevices.Get (0));
21.8 + phy.EnablePcap ("third", apDevices.Get (0));
21.9 CsmaHelper::EnablePcap ("third", csmaDevices.Get (0), true);
21.10
21.11 Simulator::Run ();
22.1 --- a/examples/wifi-wired-bridging.cc Tue Jun 09 18:00:24 2009 +0100
22.2 +++ b/examples/wifi-wired-bridging.cc Tue Jun 09 18:00:52 2009 +0100
22.3 @@ -89,6 +89,10 @@
22.4 backboneDevices = csma.Install (backboneNodes);
22.5
22.6 double wifiX = 0.0;
22.7 +
22.8 + YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
22.9 + wifiPhy.SetPcapFormat(YansWifiPhyHelper::PCAP_FORMAT_80211_RADIOTAP);
22.10 +
22.11 for (uint32_t i = 0; i < nWifis; ++i)
22.12 {
22.13 // calculate ssid for wifi subnetwork
22.14 @@ -105,7 +109,6 @@
22.15 BridgeHelper bridge;
22.16 WifiHelper wifi = WifiHelper::Default ();
22.17 NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
22.18 - YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
22.19 YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
22.20 wifiPhy.SetChannel (wifiChannel.Create ());
22.21
22.22 @@ -182,8 +185,8 @@
22.23 apps.Start (Seconds (0.5));
22.24 apps.Stop (Seconds (3.0));
22.25
22.26 - YansWifiPhyHelper::EnablePcap ("wifi-wired-bridging", apDevices[0]);
22.27 - YansWifiPhyHelper::EnablePcap ("wifi-wired-bridging", apDevices[1]);
22.28 + wifiPhy.EnablePcap ("wifi-wired-bridging", apDevices[0]);
22.29 + wifiPhy.EnablePcap ("wifi-wired-bridging", apDevices[1]);
22.30
22.31 std::ofstream os;
22.32 os.open ("wifi-wired-bridging.mob");
23.1 --- a/samples/main-packet-tag.cc Tue Jun 09 18:00:24 2009 +0100
23.2 +++ b/samples/main-packet-tag.cc Tue Jun 09 18:00:52 2009 +0100
23.3 @@ -101,19 +101,19 @@
23.4
23.5 // store the tag in a packet.
23.6 Ptr<Packet> p = Create<Packet> (100);
23.7 - p->AddTag (tag);
23.8 + p->AddPacketTag (tag);
23.9
23.10 // create a copy of the packet
23.11 Ptr<Packet> aCopy = p->Copy ();
23.12
23.13 // read the tag from the packet copy
23.14 MyTag tagCopy;
23.15 - p->FindFirstMatchingTag (tagCopy);
23.16 + p->PeekPacketTag (tagCopy);
23.17
23.18 // the copy and the original are the same !
23.19 NS_ASSERT (tagCopy.GetSimpleValue () == tag.GetSimpleValue ());
23.20
23.21 - aCopy->PrintTags (std::cout);
23.22 + aCopy->PrintPacketTags (std::cout);
23.23 std::cout << std::endl;
23.24
23.25 return 0;
24.1 --- a/samples/wscript Tue Jun 09 18:00:24 2009 +0100
24.2 +++ b/samples/wscript Tue Jun 09 18:00:52 2009 +0100
24.3 @@ -10,6 +10,9 @@
24.4 obj = bld.create_ns3_program('main-simulator')
24.5 obj.source = 'main-simulator.cc'
24.6
24.7 + obj = bld.create_ns3_program('main-ptr')
24.8 + obj.source = 'main-ptr.cc'
24.9 +
24.10 obj = bld.create_ns3_program('main-random-variable')
24.11 obj.source = 'main-random-variable.cc'
24.12
25.1 --- a/src/applications/packet-sink/packet-sink.cc Tue Jun 09 18:00:24 2009 +0100
25.2 +++ b/src/applications/packet-sink/packet-sink.cc Tue Jun 09 18:00:52 2009 +0100
25.3 @@ -142,8 +142,7 @@
25.4 {
25.5 InetSocketAddress address = InetSocketAddress::ConvertFrom (from);
25.6 NS_LOG_INFO ("Received " << packet->GetSize() << " bytes from " <<
25.7 - address.GetIpv4() << " [" << address << "]---'" <<
25.8 - packet->PeekData() << "'");
25.9 + address.GetIpv4() << " [" << address << "]");
25.10 }
25.11 m_rxTrace (packet, from);
25.12 }
26.1 --- a/src/applications/udp-echo/udp-echo-server.cc Tue Jun 09 18:00:24 2009 +0100
26.2 +++ b/src/applications/udp-echo/udp-echo-server.cc Tue Jun 09 18:00:52 2009 +0100
26.3 @@ -121,7 +121,8 @@
26.4 NS_LOG_INFO ("Received " << packet->GetSize() << " bytes from " <<
26.5 address.GetIpv4());
26.6
26.7 - packet->RemoveAllTags ();
26.8 + packet->RemoveAllPacketTags ();
26.9 + packet->RemoveAllByteTags ();
26.10
26.11 NS_LOG_LOGIC ("Echoing packet");
26.12 socket->SendTo (packet, 0, from);
27.1 --- a/src/applications/v4ping/v4ping.cc Tue Jun 09 18:00:24 2009 +0100
27.2 +++ b/src/applications/v4ping/v4ping.cc Tue Jun 09 18:00:52 2009 +0100
27.3 @@ -87,10 +87,11 @@
27.4 if (echo.GetSequenceNumber () == (m_seq - 1) &&
27.5 echo.GetIdentifier () == 0)
27.6 {
27.7 - Ptr<const Packet> data = echo.GetData ();
27.8 - if (data->GetSize () == 16)
27.9 + uint8_t data[16];
27.10 + uint32_t dataSize = echo.GetData (data);
27.11 + if (dataSize == 16)
27.12 {
27.13 - uint32_t *buf = (uint32_t *)data->PeekData ();
27.14 + uint32_t *buf = (uint32_t *)data;
27.15 if (buf[0] == GetNode ()->GetId () &&
27.16 buf[1] == GetApplicationId ())
27.17 {
28.1 --- a/src/common/buffer.cc Tue Jun 09 18:00:24 2009 +0100
28.2 +++ b/src/common/buffer.cc Tue Jun 09 18:00:52 2009 +0100
28.3 @@ -643,6 +643,32 @@
28.4 return m_data->m_data + m_start;
28.5 }
28.6
28.7 +void
28.8 +Buffer::CopyData(std::ostream *os, uint32_t size) const
28.9 +{
28.10 + if (size == GetSize ())
28.11 + {
28.12 + // fast path
28.13 + os->write((const char*)(m_data->m_data + m_start), m_zeroAreaStart-m_start);
28.14 + char zero = 0;
28.15 + for (uint32_t i = 0; i < m_zeroAreaEnd - m_zeroAreaStart; ++i)
28.16 + {
28.17 + os->write (&zero, 1);
28.18 + }
28.19 + os->write ((const char*)(m_data->m_data + m_zeroAreaStart), m_end - m_zeroAreaEnd);
28.20 + }
28.21 + else
28.22 + {
28.23 + // slow path
28.24 + Buffer::Iterator i = Begin ();
28.25 + while (!i.IsEnd () && size > 0)
28.26 + {
28.27 + char byte = i.ReadU8 ();
28.28 + os->write (&byte, 1);
28.29 + }
28.30 + }
28.31 +}
28.32 +
28.33 /******************************************************
28.34 * The buffer iterator below.
28.35 ******************************************************/
29.1 --- a/src/common/buffer.h Tue Jun 09 18:00:24 2009 +0100
29.2 +++ b/src/common/buffer.h Tue Jun 09 18:00:52 2009 +0100
29.3 @@ -22,6 +22,7 @@
29.4
29.5 #include <stdint.h>
29.6 #include <vector>
29.7 +#include <ostream>
29.8
29.9 #define BUFFER_HEURISTICS 1
29.10 #define BUFFER_USE_INLINE 1
29.11 @@ -486,6 +487,8 @@
29.12 int32_t GetCurrentStartOffset (void) const;
29.13 int32_t GetCurrentEndOffset (void) const;
29.14
29.15 + void CopyData (std::ostream *os, uint32_t size) const;
29.16 +
29.17 Buffer (Buffer const &o);
29.18 Buffer &operator = (Buffer const &o);
29.19 Buffer ();
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
30.2 +++ b/src/common/byte-tag-list.cc Tue Jun 09 18:00:52 2009 +0100
30.3 @@ -0,0 +1,421 @@
30.4 +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
30.5 +/*
30.6 + * Copyright (c) 2008 INRIA
30.7 + *
30.8 + * This program is free software; you can redistribute it and/or modify
30.9 + * it under the terms of the GNU General Public License version 2 as
30.10 + * published by the Free Software Foundation;
30.11 + *
30.12 + * This program is distributed in the hope that it will be useful,
30.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
30.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30.15 + * GNU General Public License for more details.
30.16 + *
30.17 + * You should have received a copy of the GNU General Public License
30.18 + * along with this program; if not, write to the Free Software
30.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30.20 + *
30.21 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
30.22 + */
30.23 +#include "byte-tag-list.h"
30.24 +#include "ns3/log.h"
30.25 +#include <vector>
30.26 +#include <string.h>
30.27 +
30.28 +NS_LOG_COMPONENT_DEFINE ("ByteTagList");
30.29 +
30.30 +#define USE_FREE_LIST 1
30.31 +#define FREE_LIST_SIZE 1000
30.32 +#define OFFSET_MAX (2147483647)
30.33 +
30.34 +namespace ns3 {
30.35 +
30.36 +struct ByteTagListData {
30.37 + uint32_t size;
30.38 + uint32_t count;
30.39 + uint32_t dirty;
30.40 + uint8_t data[4];
30.41 +};
30.42 +
30.43 +#ifdef USE_FREE_LIST
30.44 +static class ByteTagListDataFreeList : public std::vector<struct ByteTagListData *>
30.45 +{
30.46 +public:
30.47 + ~ByteTagListDataFreeList ();
30.48 +} g_freeList;
30.49 +static uint32_t g_maxSize = 0;
30.50 +
30.51 +ByteTagListDataFreeList::~ByteTagListDataFreeList ()
30.52 +{
30.53 + for (ByteTagListDataFreeList::iterator i = begin ();
30.54 + i != end (); i++)
30.55 + {
30.56 + uint8_t *buffer = (uint8_t *)(*i);
30.57 + delete [] buffer;
30.58 + }
30.59 +}
30.60 +#endif /* USE_FREE_LIST */
30.61 +
30.62 +ByteTagList::Iterator::Item::Item (TagBuffer buf_)
30.63 + : buf (buf_)
30.64 +{}
30.65 +
30.66 +bool
30.67 +ByteTagList::Iterator::HasNext (void) const
30.68 +{
30.69 + return m_current < m_end;
30.70 +}
30.71 +struct ByteTagList::Iterator::Item
30.72 +ByteTagList::Iterator::Next (void)
30.73 +{
30.74 + NS_ASSERT (HasNext ());
30.75 + struct Item item = Item (TagBuffer (m_current+16, m_end));
30.76 + item.tid.SetUid (m_nextTid);
30.77 + item.size = m_nextSize;
30.78 + item.start = std::max (m_nextStart, m_offsetStart);
30.79 + item.end = std::min (m_nextEnd, m_offsetEnd);
30.80 + m_current += 4 + 4 + 4 + 4 + item.size;
30.81 + item.buf.TrimAtEnd (m_end - m_current);
30.82 + PrepareForNext ();
30.83 + return item;
30.84 +}
30.85 +void
30.86 +ByteTagList::Iterator::PrepareForNext (void)
30.87 +{
30.88 + while (m_current < m_end)
30.89 + {
30.90 + TagBuffer buf = TagBuffer (m_current, m_end);
30.91 + m_nextTid = buf.ReadU32 ();
30.92 + m_nextSize = buf.ReadU32 ();
30.93 + m_nextStart = buf.ReadU32 ();
30.94 + m_nextEnd = buf.ReadU32 ();
30.95 + if (m_nextStart >= m_offsetEnd || m_nextEnd <= m_offsetStart)
30.96 + {
30.97 + m_current += 4 + 4 + 4 + 4 + m_nextSize;
30.98 + }
30.99 + else
30.100 + {
30.101 + break;
30.102 + }
30.103 + }
30.104 +}
30.105 +ByteTagList::Iterator::Iterator (uint8_t *start, uint8_t *end, int32_t offsetStart, int32_t offsetEnd)
30.106 + : m_current (start),
30.107 + m_end (end),
30.108 + m_offsetStart (offsetStart),
30.109 + m_offsetEnd (offsetEnd)
30.110 +{
30.111 + PrepareForNext ();
30.112 +}
30.113 +
30.114 +uint32_t
30.115 +ByteTagList::Iterator::GetOffsetStart (void) const
30.116 +{
30.117 + return m_offsetStart;
30.118 +}
30.119 +
30.120 +
30.121 +ByteTagList::ByteTagList ()
30.122 + : m_used (0),
30.123 + m_data (0)
30.124 +{
30.125 + NS_LOG_FUNCTION (this);
30.126 +}
30.127 +ByteTagList::ByteTagList (const ByteTagList &o)
30.128 + : m_used (o.m_used),
30.129 + m_data (o.m_data)
30.130 +{
30.131 + NS_LOG_FUNCTION (this << &o);
30.132 + if (m_data != 0)
30.133 + {
30.134 + m_data->count++;
30.135 + }
30.136 +}
30.137 +ByteTagList &
30.138 +ByteTagList::operator = (const ByteTagList &o)
30.139 +{
30.140 + NS_LOG_FUNCTION (this << &o);
30.141 + if (this == &o)
30.142 + {
30.143 + return *this;
30.144 + }
30.145 +
30.146 + Deallocate (m_data);
30.147 + m_data = o.m_data;
30.148 + m_used = o.m_used;
30.149 + if (m_data != 0)
30.150 + {
30.151 + m_data->count++;
30.152 + }
30.153 + return *this;
30.154 +}
30.155 +ByteTagList::~ByteTagList ()
30.156 +{
30.157 + NS_LOG_FUNCTION (this);
30.158 + Deallocate (m_data);
30.159 + m_data = 0;
30.160 + m_used = 0;
30.161 +}
30.162 +
30.163 +TagBuffer
30.164 +ByteTagList::Add (TypeId tid, uint32_t bufferSize, int32_t start, int32_t end)
30.165 +{
30.166 + NS_LOG_FUNCTION (this << tid << bufferSize << start << end);
30.167 + uint32_t spaceNeeded = m_used + bufferSize + 4 + 4 + 4 + 4;
30.168 + NS_ASSERT (m_used <= spaceNeeded);
30.169 + if (m_data == 0)
30.170 + {
30.171 + m_data = Allocate (spaceNeeded);
30.172 + m_used = 0;
30.173 + }
30.174 + else if (m_data->size < spaceNeeded ||
30.175 + (m_data->count != 1 && m_data->dirty != m_used))
30.176 + {
30.177 + struct ByteTagListData *newData = Allocate (spaceNeeded);
30.178 + memcpy (&newData->data, &m_data->data, m_used);
30.179 + Deallocate (m_data);
30.180 + m_data = newData;
30.181 + }
30.182 + TagBuffer tag = TagBuffer (&m_data->data[m_used],
30.183 + &m_data->data[spaceNeeded]);
30.184 + tag.WriteU32 (tid.GetUid ());
30.185 + tag.WriteU32 (bufferSize);
30.186 + tag.WriteU32 (start);
30.187 + tag.WriteU32 (end);
30.188 + m_used = spaceNeeded;
30.189 + m_data->dirty = m_used;
30.190 + return tag;
30.191 +}
30.192 +
30.193 +void
30.194 +ByteTagList::Add (const ByteTagList &o)
30.195 +{
30.196 + NS_LOG_FUNCTION (this << &o);
30.197 + ByteTagList::Iterator i = o.BeginAll ();
30.198 + while (i.HasNext ())
30.199 + {
30.200 + ByteTagList::Iterator::Item item = i.Next ();
30.201 + TagBuffer buf = Add (item.tid, item.size, item.start, item.end);
30.202 + buf.CopyFrom (item.buf);
30.203 + }
30.204 +}
30.205 +
30.206 +void
30.207 +ByteTagList::RemoveAll (void)
30.208 +{
30.209 + NS_LOG_FUNCTION (this);
30.210 + Deallocate (m_data);
30.211 + m_data = 0;
30.212 + m_used = 0;
30.213 +}
30.214 +
30.215 +ByteTagList::Iterator
30.216 +ByteTagList::BeginAll (void) const
30.217 +{
30.218 + NS_LOG_FUNCTION (this);
30.219 + // I am not totally sure but I might need to use
30.220 + // INT32_MIN instead of zero below.
30.221 + return Begin (0, OFFSET_MAX);
30.222 +}
30.223 +
30.224 +ByteTagList::Iterator
30.225 +ByteTagList::Begin (int32_t offsetStart, int32_t offsetEnd) const
30.226 +{
30.227 + NS_LOG_FUNCTION (this << offsetStart << offsetEnd);
30.228 + if (m_data == 0)
30.229 + {
30.230 + return Iterator (0, 0, offsetStart, offsetEnd);
30.231 + }
30.232 + else
30.233 + {
30.234 + return Iterator (m_data->data, &m_data->data[m_used], offsetStart, offsetEnd);
30.235 + }
30.236 +}
30.237 +
30.238 +bool
30.239 +ByteTagList::IsDirtyAtEnd (int32_t appendOffset)
30.240 +{
30.241 + NS_LOG_FUNCTION (this << appendOffset);
30.242 + ByteTagList::Iterator i = BeginAll ();
30.243 + while (i.HasNext ())
30.244 + {
30.245 + ByteTagList::Iterator::Item item = i.Next ();
30.246 + if (item.end > appendOffset)
30.247 + {
30.248 + return true;
30.249 + }
30.250 + }
30.251 + return false;
30.252 +}
30.253 +
30.254 +bool
30.255 +ByteTagList::IsDirtyAtStart (int32_t prependOffset)
30.256 +{
30.257 + NS_LOG_FUNCTION (this << prependOffset);
30.258 + ByteTagList::Iterator i = BeginAll ();
30.259 + while (i.HasNext ())
30.260 + {
30.261 + ByteTagList::Iterator::Item item = i.Next ();
30.262 + if (item.start < prependOffset)
30.263 + {
30.264 + return true;
30.265 + }
30.266 + }
30.267 + return false;
30.268 +}
30.269 +
30.270 +void
30.271 +ByteTagList::AddAtEnd (int32_t adjustment, int32_t appendOffset)
30.272 +{
30.273 + NS_LOG_FUNCTION (this << adjustment << appendOffset);
30.274 + if (adjustment == 0 && !IsDirtyAtEnd (appendOffset))
30.275 + {
30.276 + return;
30.277 + }
30.278 + ByteTagList list;
30.279 + ByteTagList::Iterator i = BeginAll ();
30.280 + while (i.HasNext ())
30.281 + {
30.282 + ByteTagList::Iterator::Item item = i.Next ();
30.283 + item.start += adjustment;
30.284 + item.end += adjustment;
30.285 +
30.286 + if (item.start >= appendOffset)
30.287 + {
30.288 + continue;
30.289 + }
30.290 + else if (item.start < appendOffset && item.end > appendOffset)
30.291 + {
30.292 + item.end = appendOffset;
30.293 + }
30.294 + else
30.295 + {
30.296 + // nothing to do.
30.297 + }
30.298 + TagBuffer buf = list.Add (item.tid, item.size, item.start, item.end);
30.299 + buf.CopyFrom (item.buf);
30.300 + }
30.301 + *this = list;
30.302 +}
30.303 +
30.304 +void
30.305 +ByteTagList::AddAtStart (int32_t adjustment, int32_t prependOffset)
30.306 +{
30.307 + NS_LOG_FUNCTION (this << adjustment << prependOffset);
30.308 + if (adjustment == 0 && !IsDirtyAtStart (prependOffset))
30.309 + {
30.310 + return;
30.311 + }
30.312 + ByteTagList list;
30.313 + ByteTagList::Iterator i = BeginAll ();
30.314 + while (i.HasNext ())
30.315 + {
30.316 + ByteTagList::Iterator::Item item = i.Next ();
30.317 + item.start += adjustment;
30.318 + item.end += adjustment;
30.319 +
30.320 + if (item.end <= prependOffset)
30.321 + {
30.322 + continue;
30.323 + }
30.324 + else if (item.end > prependOffset && item.start < prependOffset)
30.325 + {
30.326 + item.start = prependOffset;
30.327 + }
30.328 + else
30.329 + {
30.330 + // nothing to do.
30.331 + }
30.332 + TagBuffer buf = list.Add (item.tid, item.size, item.start, item.end);
30.333 + buf.CopyFrom (item.buf);
30.334 + }
30.335 + *this = list;
30.336 +}
30.337 +
30.338 +#ifdef USE_FREE_LIST
30.339 +
30.340 +struct ByteTagListData *
30.341 +ByteTagList::Allocate (uint32_t size)
30.342 +{
30.343 + NS_LOG_FUNCTION (this << size);
30.344 + while (!g_freeList.empty ())
30.345 + {
30.346 + struct ByteTagListData *data = g_freeList.back ();
30.347 + g_freeList.pop_back ();
30.348 + NS_ASSERT (data != 0);
30.349 + if (data->size >= size)
30.350 + {
30.351 + data->count = 1;
30.352 + data->dirty = 0;
30.353 + return data;
30.354 + }
30.355 + uint8_t *buffer = (uint8_t *)data;
30.356 + delete [] buffer;
30.357 + }
30.358 + uint8_t *buffer = new uint8_t [std::max (size, g_maxSize) + sizeof (struct ByteTagListData) - 4];
30.359 + struct ByteTagListData *data = (struct ByteTagListData *)buffer;
30.360 + data->count = 1;
30.361 + data->size = size;
30.362 + data->dirty = 0;
30.363 + return data;
30.364 +}
30.365 +
30.366 +void
30.367 +ByteTagList::Deallocate (struct ByteTagListData *data)
30.368 +{
30.369 + NS_LOG_FUNCTION (this << data);
30.370 + if (data == 0)
30.371 + {
30.372 + return;
30.373 + }
30.374 + g_maxSize = std::max (g_maxSize, data->size);
30.375 + data->count--;
30.376 + if (data->count == 0)
30.377 + {
30.378 + if (g_freeList.size () > FREE_LIST_SIZE ||
30.379 + data->size < g_maxSize)
30.380 + {
30.381 + uint8_t *buffer = (uint8_t *)data;
30.382 + delete [] buffer;
30.383 + }
30.384 + else
30.385 + {
30.386 + g_freeList.push_back (data);
30.387 + }
30.388 + }
30.389 +}
30.390 +
30.391 +#else /* USE_FREE_LIST */
30.392 +
30.393 +struct ByteTagListData *
30.394 +ByteTagList::Allocate (uint32_t size)
30.395 +{
30.396 + NS_LOG_FUNCTION (this << size);
30.397 + uint8_t *buffer = new uint8_t [size + sizeof (struct ByteTagListData) - 4];
30.398 + struct ByteTagListData *data = (struct ByteTagListData *)buffer;
30.399 + data->count = 1;
30.400 + data->size = size;
30.401 + data->dirty = 0;
30.402 + return data;
30.403 +}
30.404 +
30.405 +void
30.406 +ByteTagList::Deallocate (struct ByteTagListData *data)
30.407 +{
30.408 + NS_LOG_FUNCTION (this << data);
30.409 + if (data == 0)
30.410 + {
30.411 + return;
30.412 + }
30.413 + data->count--;
30.414 + if (data->count == 0)
30.415 + {
30.416 + uint8_t *buffer = (uint8_t *)data;
30.417 + delete [] buffer;
30.418 + }
30.419 +}
30.420 +
30.421 +#endif /* USE_FREE_LIST */
30.422 +
30.423 +
30.424 +} // namespace ns3
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
31.2 +++ b/src/common/byte-tag-list.h Tue Jun 09 18:00:52 2009 +0100
31.3 @@ -0,0 +1,170 @@
31.4 +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
31.5 +/*
31.6 + * Copyright (c) 2008 INRIA
31.7 + *
31.8 + * This program is free software; you can redistribute it and/or modify
31.9 + * it under the terms of the GNU General Public License version 2 as
31.10 + * published by the Free Software Foundation;
31.11 + *
31.12 + * This program is distributed in the hope that it will be useful,
31.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
31.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31.15 + * GNU General Public License for more details.
31.16 + *
31.17 + * You should have received a copy of the GNU General Public License
31.18 + * along with this program; if not, write to the Free Software
31.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31.20 + *
31.21 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
31.22 + */
31.23 +#ifndef BYTE_TAG_LIST_H
31.24 +#define BYTE_TAG_LIST_H
31.25 +
31.26 +#include <stdint.h>
31.27 +#include "ns3/type-id.h"
31.28 +#include "tag-buffer.h"
31.29 +
31.30 +namespace ns3 {
31.31 +
31.32 +struct ByteTagListData;
31.33 +
31.34 +/**
31.35 + * \ingroup packet
31.36 + *
31.37 + * \brief keep track of the tags stored in a packet.
31.38 + *
31.39 + * This class is mostly private to the Packet implementation and users
31.40 + * should never have to access it directly.
31.41 + *
31.42 + * \internal
31.43 + * The implementation of this class is a bit tricky so, there are a couple
31.44 + * of things to keep in mind here:
31.45 + *
31.46 + * - it stores all tags in a single byte buffer: each tag is stored
31.47 + * as 4 32bit integers (TypeId, tag data size, start, end) followed
31.48 + * by the tag data as generated by Tag::Serialize.
31.49 + *
31.50 + * - the struct ByteTagListData structure which contains the tag byte buffer
31.51 + * is shared and, thus, reference-counted. This data structure is unshared
31.52 + * as-needed to emulate COW semantics.
31.53 + *
31.54 + * - each tag tags a unique set of bytes identified by the pair of offsets
31.55 + * (start,end). These offsets are provided by Buffer::GetCurrentStartOffset
31.56 + * and Buffer::GetCurrentEndOffset which means that they are relative to
31.57 + * the start of the 'virtual byte buffer' as explained in the documentation
31.58 + * for the ns3::Buffer class. Whenever the origin of the offset of the Buffer
31.59 + * instance associated to this ByteTagList instance changes, the Buffer class
31.60 + * reports this to its container Packet class as a bool return value
31.61 + * in Buffer::AddAtStart and Buffer::AddAtEnd. In both cases, when this happens
31.62 + * the Packet class calls ByteTagList::AddAtEnd and ByteTagList::AddAtStart to update
31.63 + * the byte offsets of each tag in the ByteTagList.
31.64 + *
31.65 + * - whenever bytes are removed from the packet byte buffer, the ByteTagList offsets
31.66 + * are never updated because we rely on the fact that they will be updated in
31.67 + * either the next call to Packet::AddHeader or Packet::AddTrailer or when
31.68 + * the user iterates the tag list with Packet::GetTagIterator and
31.69 + * TagIterator::Next.
31.70 + */
31.71 +class ByteTagList
31.72 +{
31.73 +public:
31.74 +
31.75 + class Iterator
31.76 + {
31.77 + public:
31.78 + struct Item
31.79 + {
31.80 + TypeId tid;
31.81 + uint32_t size;
31.82 + int32_t start;
31.83 + int32_t end;
31.84 + TagBuffer buf;
31.85 + Item (TagBuffer buf);
31.86 + private:
31.87 + friend class ByteTagList;
31.88 + friend class ByteTagList::Iterator;
31.89 + };
31.90 + bool HasNext (void) const;
31.91 + struct ByteTagList::Iterator::Item Next (void);
31.92 + uint32_t GetOffsetStart (void) const;
31.93 + private:
31.94 + friend class ByteTagList;
31.95 + Iterator (uint8_t *start, uint8_t *end, int32_t offsetStart, int32_t offsetEnd);
31.96 + void PrepareForNext (void);
31.97 + uint8_t *m_current;
31.98 + uint8_t *m_end;
31.99 + int32_t m_offsetStart;
31.100 + int32_t m_offsetEnd;
31.101 + uint32_t m_nextTid;
31.102 + uint32_t m_nextSize;
31.103 + int32_t m_nextStart;
31.104 + int32_t m_nextEnd;
31.105 + };
31.106 +
31.107 + ByteTagList ();
31.108 + ByteTagList (const ByteTagList &o);
31.109 + ByteTagList &operator = (const ByteTagList &o);
31.110 + ~ByteTagList ();
31.111 +
31.112 + /**
31.113 + * \param tid the typeid of the tag added
31.114 + * \param bufferSize the size of the tag when its serialization will
31.115 + * be completed. Typically, the return value of Tag::GetSerializedSize
31.116 + * \param start offset which uniquely identifies the first byte tagged by this tag.
31.117 + * \param end offset which uniquely identifies the last byte tagged by this tag.
31.118 + * \returns a buffer which can be used to write the tag data.
31.119 + *
31.120 + *
31.121 + */
31.122 + TagBuffer Add (TypeId tid, uint32_t bufferSize, int32_t start, int32_t end);
31.123 +
31.124 + /**
31.125 + * \param o the other list of tags to aggregate.
31.126 + *
31.127 + * Aggregate the two lists of tags.
31.128 + */
31.129 + void Add (const ByteTagList &o);
31.130 +
31.131 + void RemoveAll (void);
31.132 +
31.133 + /**
31.134 + * \param offsetStart the offset which uniquely identifies the first data byte
31.135 + * present in the byte buffer associated to this ByteTagList.
31.136 + * \param offsetEnd the offset which uniquely identifies the last data byte
31.137 + * present in the byte buffer associated to this ByteTagList.
31.138 + * \returns an iterator
31.139 + *
31.140 + * The returned iterator will allow you to loop through the set of tags present
31.141 + * in this list: the boundaries of each tag as reported by their start and
31.142 + * end offsets will be included within the input offsetStart and offsetEnd.
31.143 + */
31.144 + ByteTagList::Iterator Begin (int32_t offsetStart, int32_t offsetEnd) const;
31.145 +
31.146 + /**
31.147 + * Adjust the offsets stored internally by the adjustment delta and
31.148 + * make sure that all offsets are smaller than appendOffset which represents
31.149 + * the location where new bytes have been added to the byte buffer.
31.150 + */
31.151 + void AddAtEnd (int32_t adjustment, int32_t appendOffset);
31.152 + /**
31.153 + * Adjust the offsets stored internally by the adjustment delta and
31.154 + * make sure that all offsets are bigger than prependOffset which represents
31.155 + * the location where new bytes have been added to the byte buffer.
31.156 + */
31.157 + void AddAtStart (int32_t adjustment, int32_t prependOffset);
31.158 +
31.159 +private:
31.160 + bool IsDirtyAtEnd (int32_t appendOffset);
31.161 + bool IsDirtyAtStart (int32_t prependOffset);
31.162 + ByteTagList::Iterator BeginAll (void) const;
31.163 +
31.164 + struct ByteTagListData *Allocate (uint32_t size);
31.165 + void Deallocate (struct ByteTagListData *data);
31.166 +
31.167 + uint16_t m_used;
31.168 + struct ByteTagListData *m_data;
31.169 +};
31.170 +
31.171 +} // namespace ns3
31.172 +
31.173 +#endif /* BYTE_TAG_LIST_H */
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
32.2 +++ b/src/common/packet-tag-list.cc Tue Jun 09 18:00:52 2009 +0100
32.3 @@ -0,0 +1,177 @@
32.4 +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
32.5 +/*
32.6 + * Copyright (c) 2006 INRIA
32.7 + *
32.8 + * This program is free software; you can redistribute it and/or modify
32.9 + * it under the terms of the GNU General Public License version 2 as
32.10 + * published by the Free Software Foundation;
32.11 + *
32.12 + * This program is distributed in the hope that it will be useful,
32.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
32.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32.15 + * GNU General Public License for more details.
32.16 + *
32.17 + * You should have received a copy of the GNU General Public License
32.18 + * along with this program; if not, write to the Free Software
32.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32.20 + *
32.21 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
32.22 + */
32.23 +#include "packet-tag-list.h"
32.24 +#include "tag-buffer.h"
32.25 +#include "tag.h"
32.26 +#include "ns3/fatal-error.h"
32.27 +#include "ns3/log.h"
32.28 +#include <string.h>
32.29 +
32.30 +NS_LOG_COMPONENT_DEFINE ("PacketTagList");
32.31 +
32.32 +namespace ns3 {
32.33 +
32.34 +#ifdef USE_FREE_LIST
32.35 +
32.36 +struct PacketTagList::TagData *PacketTagList::g_free = 0;
32.37 +uint32_t PacketTagList::g_nfree = 0;
32.38 +
32.39 +struct PacketTagList::TagData *
32.40 +PacketTagList::AllocData (void) const
32.41 +{
32.42 + NS_LOG_FUNCTION (g_nfree);
32.43 + struct PacketTagList::TagData *retval;
32.44 + if (g_free != 0)
32.45 + {
32.46 + retval = g_free;
32.47 + g_free = g_free->m_next;
32.48 + g_nfree--;
32.49 + }
32.50 + else
32.51 + {
32.52 + retval = new struct PacketTagList::TagData ();
32.53 + }
32.54 + return retval;
32.55 +}
32.56 +
32.57 +void
32.58 +PacketTagList::FreeData (struct TagData *data) const
32.59 +{
32.60 + NS_LOG_FUNCTION (g_nfree << data);
32.61 + if (g_nfree > 1000)
32.62 + {
32.63 + delete data;
32.64 + return;
32.65 + }
32.66 + g_nfree++;
32.67 + data->next = g_free;
32.68 + data->tid = TypeId ();
32.69 + g_free = data;
32.70 +}
32.71 +#else
32.72 +struct PacketTagList::TagData *
32.73 +PacketTagList::AllocData (void) const
32.74 +{
32.75 + NS_LOG_FUNCTION_NOARGS ();
32.76 + struct PacketTagList::TagData *retval;
32.77 + retval = new struct PacketTagList::TagData ();
32.78 + return retval;
32.79 +}
32.80 +
32.81 +void
32.82 +PacketTagList::FreeData (struct TagData *data) const
32.83 +{
32.84 + NS_LOG_FUNCTION (data);
32.85 + delete data;
32.86 +}
32.87 +#endif
32.88 +
32.89 +bool
32.90 +PacketTagList::Remove (Tag &tag)
32.91 +{
32.92 + NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ());
32.93 + TypeId tid = tag.GetInstanceTypeId ();
32.94 + bool found = false;
32.95 + for (struct TagData *cur = m_next; cur != 0; cur = cur->next)
32.96 + {
32.97 + if (cur->tid == tid)
32.98 + {
32.99 + found = true;
32.100 + tag.Deserialize (TagBuffer (cur->data, cur->data+PACKET_TAG_MAX_SIZE));
32.101 + }
32.102 + }
32.103 + if (!found)
32.104 + {
32.105 + return false;
32.106 + }
32.107 + struct TagData *start = 0;
32.108 + struct TagData **prevNext = &start;
32.109 + for (struct TagData *cur = m_next; cur != 0; cur = cur->next)
32.110 + {
32.111 + if (cur->tid == tid)
32.112 + {
32.113 + /**
32.114 + * XXX
32.115 + * Note: I believe that we could optimize this to
32.116 + * avoid copying each TagData located after the target id
32.117 + * and just link the already-copied list to the next tag.
32.118 + */
32.119 + continue;
32.120 + }
32.121 + struct TagData *copy = AllocData ();
32.122 + copy->tid = cur->tid;
32.123 + copy->count = 1;
32.124 + copy->next = 0;
32.125 + memcpy (copy->data, cur->data, PACKET_TAG_MAX_SIZE);
32.126 + *prevNext = copy;
32.127 + prevNext = ©->next;
32.128 + }
32.129 + *prevNext = 0;
32.130 + RemoveAll ();
32.131 + m_next = start;
32.132 + return true;
32.133 +}
32.134 +
32.135 +void
32.136 +PacketTagList::Add (const Tag &tag) const
32.137 +{
32.138 + NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ());
32.139 + // ensure this id was not yet added
32.140 + for (struct TagData *cur = m_next; cur != 0; cur = cur->next)
32.141 + {
32.142 + NS_ASSERT (cur->tid != tag.GetInstanceTypeId ());
32.143 + }
32.144 + struct TagData *head = AllocData ();
32.145 + head->count = 1;
32.146 + head->next = 0;
32.147 + head->tid = tag.GetInstanceTypeId ();
32.148 + head->next = m_next;
32.149 + NS_ASSERT (tag.GetSerializedSize () < PACKET_TAG_MAX_SIZE);
32.150 + tag.Serialize (TagBuffer (head->data, head->data+tag.GetSerializedSize ()));
32.151 +
32.152 + const_cast<PacketTagList *> (this)->m_next = head;
32.153 +}
32.154 +
32.155 +bool
32.156 +PacketTagList::Peek (Tag &tag) const
32.157 +{
32.158 + NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ());
32.159 + TypeId tid = tag.GetInstanceTypeId ();
32.160 + for (struct TagData *cur = m_next; cur != 0; cur = cur->next)
32.161 + {
32.162 + if (cur->tid == tid)
32.163 + {
32.164 + /* found tag */
32.165 + tag.Deserialize (TagBuffer (cur->data, cur->data+PACKET_TAG_MAX_SIZE));
32.166 + return true;
32.167 + }
32.168 + }
32.169 + /* no tag found */
32.170 + return false;
32.171 +}
32.172 +
32.173 +const struct PacketTagList::TagData *
32.174 +PacketTagList::Head (void) const
32.175 +{
32.176 + return m_next;
32.177 +}
32.178 +
32.179 +} // namespace ns3
32.180 +
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
33.2 +++ b/src/common/packet-tag-list.h Tue Jun 09 18:00:52 2009 +0100
33.3 @@ -0,0 +1,142 @@
33.4 +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
33.5 +/*
33.6 + * Copyright (c) 2006 INRIA
33.7 + *
33.8 + * This program is free software; you can redistribute it and/or modify
33.9 + * it under the terms of the GNU General Public License version 2 as
33.10 + * published by the Free Software Foundation;
33.11 + *
33.12 + * This program is distributed in the hope that it will be useful,
33.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
33.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33.15 + * GNU General Public License for more details.
33.16 + *
33.17 + * You should have received a copy of the GNU General Public License
33.18 + * along with this program; if not, write to the Free Software
33.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33.20 + *
33.21 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
33.22 + */
33.23 +#ifndef PACKET_TAG_LIST_H
33.24 +#define PACKET_TAG_LIST_H
33.25 +
33.26 +#include <stdint.h>
33.27 +#include <ostream>
33.28 +#include "ns3/type-id.h"
33.29 +
33.30 +namespace ns3 {
33.31 +
33.32 +class Tag;
33.33 +
33.34 +/**
33.35 + * \ingroup constants
33.36 + * \brief Tag maximum size
33.37 + * The maximum size (in bytes) of a Tag is stored
33.38 + * in this constant.
33.39 + */
33.40 +#define PACKET_TAG_MAX_SIZE 20
33.41 +
33.42 +class PacketTagList
33.43 +{
33.44 +public:
33.45 + struct TagData {
33.46 + uint8_t data[PACKET_TAG_MAX_SIZE];
33.47 + struct TagData *next;
33.48 + TypeId tid;
33.49 + uint32_t count;
33.50 + };
33.51 +
33.52 + inline PacketTagList ();
33.53 + inline PacketTagList (PacketTagList const &o);
33.54 + inline PacketTagList &operator = (PacketTagList const &o);
33.55 + inline ~PacketTagList ();
33.56 +
33.57 + void Add (Tag const&tag) const;
33.58 + bool Remove (Tag &tag);
33.59 + bool Peek (Tag &tag) const;
33.60 + inline void RemoveAll (void);
33.61 +
33.62 + const struct PacketTagList::TagData *Head (void) const;
33.63 +
33.64 +private:
33.65 +
33.66 + bool Remove (TypeId tid);
33.67 + struct PacketTagList::TagData *AllocData (void) const;
33.68 + void FreeData (struct TagData *data) const;
33.69 +
33.70 + static struct PacketTagList::TagData *g_free;
33.71 + static uint32_t g_nfree;
33.72 +
33.73 + struct TagData *m_next;
33.74 +};
33.75 +
33.76 +} // namespace ns3
33.77 +
33.78 +/****************************************************
33.79 + * Implementation of inline methods for performance
33.80 + ****************************************************/
33.81 +
33.82 +namespace ns3 {
33.83 +
33.84 +PacketTagList::PacketTagList ()
33.85 + : m_next ()
33.86 +{}
33.87 +
33.88 +PacketTagList::PacketTagList (PacketTagList const &o)
33.89 + : m_next (o.m_next)
33.90 +{
33.91 + if (m_next != 0)
33.92 + {
33.93 + m_next->count++;
33.94 + }
33.95 +}
33.96 +
33.97 +PacketTagList &
33.98 +PacketTagList::operator = (PacketTagList const &o)
33.99 +{
33.100 + // self assignment
33.101 + if (m_next == o.m_next)
33.102 + {
33.103 + return *this;
33.104 + }
33.105 + RemoveAll ();
33.106 + m_next = o.m_next;
33.107 + if (m_next != 0)
33.108 + {
33.109 + m_next->count++;
33.110 + }
33.111 + return *this;
33.112 +}
33.113 +
33.114 +PacketTagList::~PacketTagList ()
33.115 +{
33.116 + RemoveAll ();
33.117 +}
33.118 +
33.119 +void
33.120 +PacketTagList::RemoveAll (void)
33.121 +{
33.122 + struct TagData *prev = 0;
33.123 + for (struct TagData *cur = m_next; cur != 0; cur = cur->next)
33.124 + {
33.125 + cur->count--;
33.126 + if (cur->count > 0)
33.127 + {
33.128 + break;
33.129 + }
33.130 + if (prev != 0)
33.131 + {
33.132 + FreeData (prev);
33.133 + }
33.134 + prev = cur;
33.135 + }
33.136 + if (prev != 0)
33.137 + {
33.138 + FreeData (prev);
33.139 + }
33.140 + m_next = 0;
33.141 +}
33.142 +
33.143 +} // namespace ns3
33.144 +
33.145 +#endif /* PACKET_TAG_LIST_H */
34.1 --- a/src/common/packet.cc Tue Jun 09 18:00:24 2009 +0100
34.2 +++ b/src/common/packet.cc Tue Jun 09 18:00:52 2009 +0100
34.3 @@ -28,22 +28,22 @@
34.4 uint32_t Packet::m_globalUid = 0;
34.5
34.6 TypeId
34.7 -TagIterator::Item::GetTypeId (void) const
34.8 +ByteTagIterator::Item::GetTypeId (void) const
34.9 {
34.10 return m_tid;
34.11 }
34.12 uint32_t
34.13 -TagIterator::Item::GetStart (void) const
34.14 +ByteTagIterator::Item::GetStart (void) const
34.15 {
34.16 return m_start;
34.17 }
34.18 uint32_t
34.19 -TagIterator::Item::GetEnd (void) const
34.20 +ByteTagIterator::Item::GetEnd (void) const
34.21 {
34.22 return m_end;
34.23 }
34.24 void
34.25 -TagIterator::Item::GetTag (Tag &tag) const
34.26 +ByteTagIterator::Item::GetTag (Tag &tag) const
34.27 {
34.28 if (tag.GetInstanceTypeId () != GetTypeId ())
34.29 {
34.30 @@ -51,31 +51,64 @@
34.31 }
34.32 tag.Deserialize (m_buffer);
34.33 }
34.34 -TagIterator::Item::Item (TypeId tid, uint32_t start, uint32_t end, TagBuffer buffer)
34.35 +ByteTagIterator::Item::Item (TypeId tid, uint32_t start, uint32_t end, TagBuffer buffer)
34.36 : m_tid (tid),
34.37 m_start (start),
34.38 m_end (end),
34.39 m_buffer (buffer)
34.40 {}
34.41 bool
34.42 -TagIterator::HasNext (void) const
34.43 +ByteTagIterator::HasNext (void) const
34.44 {
34.45 return m_current.HasNext ();
34.46 }
34.47 -TagIterator::Item
34.48 -TagIterator::Next (void)
34.49 +ByteTagIterator::Item
34.50 +ByteTagIterator::Next (void)
34.51 {
34.52 - TagList::Iterator::Item i = m_current.Next ();
34.53 - return TagIterator::Item (i.tid,
34.54 - i.start-m_current.GetOffsetStart (),
34.55 - i.end-m_current.GetOffsetStart (),
34.56 - i.buf);
34.57 + ByteTagList::Iterator::Item i = m_current.Next ();
34.58 + return ByteTagIterator::Item (i.tid,
34.59 + i.start-m_current.GetOffsetStart (),
34.60 + i.end-m_current.GetOffsetStart (),
34.61 + i.buf);
34.62 }
34.63 -TagIterator::TagIterator (TagList::Iterator i)
34.64 +ByteTagIterator::ByteTagIterator (ByteTagList::Iterator i)
34.65 : m_current (i)
34.66 {}
34.67
34.68
34.69 +PacketTagIterator::PacketTagIterator (const struct PacketTagList::TagData *head)
34.70 + : m_current (head)
34.71 +{}
34.72 +bool
34.73 +PacketTagIterator::HasNext (void) const
34.74 +{
34.75 + return m_current != 0;
34.76 +}
34.77 +PacketTagIterator::Item
34.78 +PacketTagIterator::Next (void)
34.79 +{
34.80 + NS_ASSERT (HasNext ());
34.81 + const struct PacketTagList::TagData *prev = m_current;
34.82 + m_current = m_current->next;
34.83 + return PacketTagIterator::Item (prev);
34.84 +}
34.85 +
34.86 +PacketTagIterator::Item::Item (const struct PacketTagList::TagData *data)
34.87 + : m_data (data)
34.88 +{}
34.89 +TypeId
34.90 +PacketTagIterator::Item::GetTypeId (void) const
34.91 +{
34.92 + return m_data->tid;
34.93 +}
34.94 +void
34.95 +PacketTagIterator::Item::GetTag (Tag &tag) const
34.96 +{
34.97 + NS_ASSERT (tag.GetInstanceTypeId () == m_data->tid);
34.98 + tag.Deserialize (TagBuffer ((uint8_t*)m_data->data, (uint8_t*)m_data->data+PACKET_TAG_MAX_SIZE));
34.99 +}
34.100 +
34.101 +
34.102 void
34.103 Packet::Ref (void) const
34.104 {
34.105 @@ -102,7 +135,8 @@
34.106
34.107 Packet::Packet ()
34.108 : m_buffer (),
34.109 - m_tagList (),
34.110 + m_byteTagList (),
34.111 + m_packetTagList (),
34.112 m_metadata (m_globalUid, 0),
34.113 m_refCount (1)
34.114 {
34.115 @@ -111,7 +145,8 @@
34.116
34.117 Packet::Packet (const Packet &o)
34.118 : m_buffer (o.m_buffer),
34.119 - m_tagList (o.m_tagList),
34.120 + m_byteTagList (o.m_byteTagList),
34.121 + m_packetTagList (o.m_packetTagList),
34.122 m_metadata (o.m_metadata),
34.123 m_refCount (1)
34.124 {}
34.125 @@ -124,14 +159,16 @@
34.126 return *this;
34.127 }
34.128 m_buffer = o.m_buffer;
34.129 - m_tagList = o.m_tagList;
34.130 + m_byteTagList = o.m_byteTagList;
34.131 + m_packetTagList = o.m_packetTagList;
34.132 m_metadata = o.m_metadata;
34.133 return *this;
34.134 }
34.135
34.136 Packet::Packet (uint32_t size)
34.137 : m_buffer (size),
34.138 - m_tagList (),
34.139 + m_byteTagList (),
34.140 + m_packetTagList (),
34.141 m_metadata (m_globalUid, size),
34.142 m_refCount (1)
34.143 {
34.144 @@ -139,7 +176,8 @@
34.145 }
34.146 Packet::Packet (uint8_t const*buffer, uint32_t size)
34.147 : m_buffer (),
34.148 - m_tagList (),
34.149 + m_byteTagList (),
34.150 + m_packetTagList (),
34.151 m_metadata (m_globalUid, size),
34.152 m_refCount (1)
34.153 {
34.154 @@ -149,9 +187,11 @@
34.155 i.Write (buffer, size);
34.156 }
34.157
34.158 -Packet::Packet (const Buffer &buffer, const TagList &tagList, const PacketMetadata &metadata)
34.159 +Packet::Packet (const Buffer &buffer, const ByteTagList &byteTagList,
34.160 + const PacketTagList &packetTagList, const PacketMetadata &metadata)
34.161 : m_buffer (buffer),
34.162 - m_tagList (tagList),
34.163 + m_byteTagList (byteTagList),
34.164 + m_packetTagList (packetTagList),
34.165 m_metadata (metadata),
34.166 m_refCount (1)
34.167 {}
34.168 @@ -166,7 +206,7 @@
34.169 PacketMetadata metadata = m_metadata.CreateFragment (start, end);
34.170 // again, call the constructor directly rather than
34.171 // through Create because it is private.
34.172 - return Ptr<Packet> (new Packet (buffer, m_tagList, metadata), false);
34.173 + return Ptr<Packet> (new Packet (buffer, m_byteTagList, m_packetTagList, metadata), false);
34.174 }
34.175
34.176 uint32_t
34.177 @@ -178,14 +218,14 @@
34.178 void
34.179 Packet::AddHeader (const Header &header)
34.180 {
34.181 - NS_LOG_FUNCTION (this << &header);
34.182 uint32_t size = header.GetSerializedSize ();
34.183 + NS_LOG_FUNCTION (this << header.GetInstanceTypeId ().GetName () << size);
34.184 uint32_t orgStart = m_buffer.GetCurrentStartOffset ();
34.185 bool resized = m_buffer.AddAtStart (size);
34.186 if (resized)
34.187 {
34.188 - m_tagList.AddAtStart (m_buffer.GetCurrentStartOffset () + size - orgStart,
34.189 - m_buffer.GetCurrentStartOffset () + size);
34.190 + m_byteTagList.AddAtStart (m_buffer.GetCurrentStartOffset () + size - orgStart,
34.191 + m_buffer.GetCurrentStartOffset () + size);
34.192 }
34.193 header.Serialize (m_buffer.Begin ());
34.194 m_metadata.AddHeader (header, size);
34.195 @@ -193,8 +233,8 @@
34.196 uint32_t
34.197 Packet::RemoveHeader (Header &header)
34.198 {
34.199 - NS_LOG_FUNCTION (this << &header);
34.200 uint32_t deserialized = header.Deserialize (m_buffer.Begin ());
34.201 + NS_LOG_FUNCTION (this << header.GetInstanceTypeId ().GetName () << deserialized);
34.202 m_buffer.RemoveAtStart (deserialized);
34.203 m_metadata.RemoveHeader (header, deserialized);
34.204 return deserialized;
34.205 @@ -202,21 +242,21 @@
34.206 uint32_t
34.207 Packet::PeekHeader (Header &header) const
34.208 {
34.209 - NS_LOG_FUNCTION (this << &header);
34.210 uint32_t deserialized = header.Deserialize (m_buffer.Begin ());
34.211 + NS_LOG_FUNCTION (this << header.GetInstanceTypeId ().GetName () << deserialized);
34.212 return deserialized;
34.213 }
34.214 void
34.215 Packet::AddTrailer (const Trailer &trailer)
34.216 {
34.217 - NS_LOG_FUNCTION (this << &trailer);
34.218 uint32_t size = trailer.GetSerializedSize ();
34.219 + NS_LOG_FUNCTION (this << trailer.GetInstanceTypeId ().GetName () << size);
34.220 uint32_t orgStart = m_buffer.GetCurrentStartOffset ();
34.221 bool resized = m_buffer.AddAtEnd (size);
34.222 if (resized)
34.223 {
34.224 - m_tagList.AddAtEnd (m_buffer.GetCurrentStartOffset () - orgStart,
34.225 - m_buffer.GetCurrentEndOffset () - size);
34.226 + m_byteTagList.AddAtEnd (m_buffer.GetCurrentStartOffset () - orgStart,
34.227 + m_buffer.GetCurrentEndOffset () - size);
34.228 }
34.229 Buffer::Iterator end = m_buffer.End ();
34.230 trailer.Serialize (end);
34.231 @@ -225,8 +265,8 @@
34.232 uint32_t
34.233 Packet::RemoveTrailer (Trailer &trailer)
34.234 {
34.235 - NS_LOG_FUNCTION (this << &trailer);
34.236 uint32_t deserialized = trailer.Deserialize (m_buffer.End ());
34.237 + NS_LOG_FUNCTION (this << trailer.GetInstanceTypeId ().GetName () << deserialized);
34.238 m_buffer.RemoveAtEnd (deserialized);
34.239 m_metadata.RemoveTrailer (trailer, deserialized);
34.240 return deserialized;
34.241 @@ -234,25 +274,25 @@
34.242 uint32_t
34.243 Packet::PeekTrailer (Trailer &trailer)
34.244 {
34.245 - NS_LOG_FUNCTION (this << &trailer);
34.246 uint32_t deserialized = trailer.Deserialize (m_buffer.End ());
34.247 + NS_LOG_FUNCTION (this << trailer.GetInstanceTypeId ().GetName () << deserialized);
34.248 return deserialized;
34.249 }
34.250
34.251 void
34.252 Packet::AddAtEnd (Ptr<const Packet> packet)
34.253 {
34.254 - NS_LOG_FUNCTION (this << packet);
34.255 + NS_LOG_FUNCTION (this << packet << packet->GetSize ());
34.256 uint32_t aStart = m_buffer.GetCurrentStartOffset ();
34.257 uint32_t bEnd = packet->m_buffer.GetCurrentEndOffset ();
34.258 m_buffer.AddAtEnd (packet->m_buffer);
34.259 uint32_t appendPrependOffset = m_buffer.GetCurrentEndOffset () - packet->m_buffer.GetSize ();
34.260 - m_tagList.AddAtEnd (m_buffer.GetCurrentStartOffset () - aStart,
34.261 - appendPrependOffset);
34.262 - TagList copy = packet->m_tagList;
34.263 + m_byteTagList.AddAtEnd (m_buffer.GetCurrentStartOffset () - aStart,
34.264 + appendPrependOffset);
34.265 + ByteTagList copy = packet->m_byteTagList;
34.266 copy.AddAtStart (m_buffer.GetCurrentEndOffset () - bEnd,
34.267 appendPrependOffset);
34.268 - m_tagList.Add (copy);
34.269 + m_byteTagList.Add (copy);
34.270 m_metadata.AddAtEnd (packet->m_metadata);
34.271 }
34.272 void
34.273 @@ -263,8 +303,8 @@
34.274 bool resized = m_buffer.AddAtEnd (size);
34.275 if (resized)
34.276 {
34.277 - m_tagList.AddAtEnd (m_buffer.GetCurrentEndOffset () - orgEnd,
34.278 - m_buffer.GetCurrentEndOffset () - size);
34.279 + m_byteTagList.AddAtEnd (m_buffer.GetCurrentEndOffset () - orgEnd,
34.280 + m_buffer.GetCurrentEndOffset () - size);
34.281 }
34.282 m_metadata.AddPaddingAtEnd (size);
34.283 }
34.284 @@ -284,16 +324,23 @@
34.285 }
34.286
34.287 void
34.288 -Packet::RemoveAllTags (void)
34.289 +Packet::RemoveAllByteTags (void)
34.290 {
34.291 NS_LOG_FUNCTION (this);
34.292 - m_tagList.RemoveAll ();
34.293 + m_byteTagList.RemoveAll ();
34.294 }
34.295
34.296 uint8_t const *
34.297 Packet::PeekData (void) const
34.298 {
34.299 - return m_buffer.PeekData ();
34.300 + NS_LOG_FUNCTION (this);
34.301 + uint32_t oldStart = m_buffer.GetCurrentStartOffset ();
34.302 + uint8_t const * data = m_buffer.PeekData ();
34.303 + uint32_t newStart = m_buffer.GetCurrentStartOffset ();
34.304 +
34.305 + // Update tag offsets if buffer offsets were changed
34.306 + const_cast<ByteTagList &>(m_byteTagList).AddAtStart (newStart - oldStart, newStart);
34.307 + return data;
34.308 }
34.309
34.310 uint32_t
34.311 @@ -309,6 +356,12 @@
34.312 return cur;
34.313 }
34.314
34.315 +void
34.316 +Packet::CopyData(std::ostream *os, uint32_t size) const
34.317 +{
34.318 + return m_buffer.CopyData (os, size);
34.319 +}
34.320 +
34.321 uint32_t
34.322 Packet::GetUid (void) const
34.323 {
34.324 @@ -316,12 +369,12 @@
34.325 }
34.326
34.327 void
34.328 -Packet::PrintTags (std::ostream &os) const
34.329 +Packet::PrintByteTags (std::ostream &os) const
34.330 {
34.331 - TagIterator i = GetTagIterator ();
34.332 + ByteTagIterator i = GetByteTagIterator ();
34.333 while (i.HasNext ())
34.334 {
34.335 - TagIterator::Item item = i.Next ();
34.336 + ByteTagIterator::Item item = i.Next ();
34.337 os << item.GetTypeId ().GetName () << " [" << item.GetStart () << "-" << item.GetEnd () << "]";
34.338 Callback<ObjectBase *> constructor = item.GetTypeId ().GetConstructor ();
34.339 if (constructor.IsNull ())
34.340 @@ -537,29 +590,29 @@
34.341 }
34.342
34.343 void
34.344 -Packet::AddTag (const Tag &tag) const
34.345 +Packet::AddByteTag (const Tag &tag) const
34.346 {
34.347 - NS_LOG_FUNCTION (this << &tag);
34.348 - TagList *list = const_cast<TagList *> (&m_tagList);
34.349 + NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ().GetName () << tag.GetSerializedSize ());
34.350 + ByteTagList *list = const_cast<ByteTagList *> (&m_byteTagList);
34.351 TagBuffer buffer = list->Add (tag.GetInstanceTypeId (), tag.GetSerializedSize (),
34.352 - m_buffer.GetCurrentStartOffset (),
34.353 - m_buffer.GetCurrentEndOffset ());
34.354 + m_buffer.GetCurrentStartOffset (),
34.355 + m_buffer.GetCurrentEndOffset ());
34.356 tag.Serialize (buffer);
34.357 }
34.358 -TagIterator
34.359 -Packet::GetTagIterator (void) const
34.360 +ByteTagIterator
34.361 +Packet::GetByteTagIterator (void) const
34.362 {
34.363 - return TagIterator (m_tagList.Begin (m_buffer.GetCurrentStartOffset (), m_buffer.GetCurrentEndOffset ()));
34.364 + return ByteTagIterator (m_byteTagList.Begin (m_buffer.GetCurrentStartOffset (), m_buffer.GetCurrentEndOffset ()));
34.365 }
34.366
34.367 bool
34.368 -Packet::FindFirstMatchingTag (Tag &tag) const
34.369 +Packet::FindFirstMatchingByteTag (Tag &tag) const
34.370 {
34.371 TypeId tid = tag.GetInstanceTypeId ();
34.372 - TagIterator i = GetTagIterator ();
34.373 + ByteTagIterator i = GetByteTagIterator ();
34.374 while (i.HasNext ())
34.375 {
34.376 - TagIterator::Item item = i.Next ();
34.377 + ByteTagIterator::Item item = i.Next ();
34.378 if (tid == item.GetTypeId ())
34.379 {
34.380 item.GetTag (tag);
34.381 @@ -569,6 +622,62 @@
34.382 return false;
34.383 }
34.384
34.385 +void
34.386 +Packet::AddPacketTag (const Tag &tag) const
34.387 +{
34.388 + NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ().GetName () << tag.GetSerializedSize ());
34.389 + m_packetTagList.Add (tag);
34.390 +}
34.391 +bool
34.392 +Packet::RemovePacketTag (Tag &tag)
34.393 +{