--- a/AUTHORS Tue Aug 25 20:12:53 2009 +0400
+++ b/AUTHORS Wed Aug 26 15:29:03 2009 +0400
@@ -27,6 +27,6 @@
Providence Salumu Munga (Providence.Salumu@gmail.com, Providence.Salumu_Munga@it-sudparis.eu)
Kulin Shah (m.kulin@gmail.com)
Mauro Tortonesi (mauro.tortonesi@unife.it)
-Sebastien Vincent (vincent@lsiit.u-strasbg.fr)
+Sebastien Vincent (vincent@clarinet.u-strasbg.fr)
Guillaume Vu-Brugier (gvubrugier@gmail.com)
Florian Westphal (fw@strlen.de)
--- a/CHANGES.html Tue Aug 25 20:12:53 2009 +0400
+++ b/CHANGES.html Wed Aug 26 15:29:03 2009 +0400
@@ -52,6 +52,26 @@
<h2>New API:</h2>
<ul>
+<li><b>Athstats</b>
+<p>New classes AthstatsWifiTraceSink and AthstatsHelper.
+</p>
+</li>
+<li><b>WifiRemoteStationManager </b>
+<p>New trace sources exported by WifiRemoteStationManager: MacTxRtsFailed, MacTxDataFailed, MacTxFinalRtsFailed and MacTxFinalDataFailed.
+</p>
+</li>
+<li><b> IPv6 additions</b>
+<p> Add an IPv6 protocol and ICMPv6 capability.
+<ul>
+<li> new classes Ipv6, Ipv6Interface, Ipv6L3Protocol, Ipv6L4Protocol
+<li> Ipv6RawSocket (no UDP or TCP capability yet)
+<li> a set of classes to implement Icmpv6, including neighbor discovery,
+router solicitation, DAD
+<li> new applications Ping6 and Radvd
+<li> routing objects Ipv6Route and Ipv6MulticastRoute
+<li> routing protocols Ipv6ListRouting and Ipv6StaticRouting
+<li> examples: icmpv6-redirect.cc, ping6.cc, radvd.cc, radvd-two-prefix.cc, simple-routing-ping6.cc
+</ul>
</ul>
<h2>Changes to existing API:</h2>
--- a/RELEASE_NOTES Tue Aug 25 20:12:53 2009 +0400
+++ b/RELEASE_NOTES Wed Aug 26 15:29:03 2009 +0400
@@ -30,13 +30,30 @@
New user-visible features
-------------------------
- - Add an implementation of the minstrel rate control algorithm
- (Duy Nguyen for gsoc)
+ a) Add an implementation of the minstrel rate control algorithm
+ (Duy Nguyen for gsoc)
+
+ b) IPv6 models:
+ - IPv6 interface;
+ - IPv6 layer;
+ - IPv6 raw socket;
+ - Static IPv6 routing;
+ - ICMPv6 layer;
+ - Some ICMPv6 error messages (destination unreachable, ...);
+ - Neighbor Discovery Protocol (NS/NA, RS/RA, redirection);
+ - Ping6 application (send Echo request);
+ - Radvd application (send RA);
+ - Examples (ping6, simple-routing-ping6, radvd, radvd-two-prefix,
+ icmpv6-redirect).
+ c) added AthstatsHelper, which enables the wifi device to produce
+ periodic reports similar to the ones generated by madwifi's
+ athstats tool (Nicola Baldo)
+
API changes from ns-3.5
-----------------------
-API changes for this release are documented in the file CHANGES.html.
+API changes for this release are documented in the file CHANGES.html.
XXX
Known issues
--- a/bindings/python/ns3_module_core.py Tue Aug 25 20:12:53 2009 +0400
+++ b/bindings/python/ns3_module_core.py Wed Aug 26 15:29:03 2009 +0400
@@ -2199,7 +2199,7 @@
cls.add_method('ConnectWithoutContext',
'void',
[param('ns3::CallbackBase const &', 'cb')])
- ## traced-value.h: void ns3::TracedValue<unsigned int>::Connect(ns3::CallbackBase const & cb, std::string path) [member function]
+ ## traced-value.h: void ns3::TracedValue<unsigned int>::Connect(ns3::CallbackBase const & cb, std::basic_string<char,std::char_traits<char>,std::allocator<char> > path) [member function]
cls.add_method('Connect',
'void',
[param('ns3::CallbackBase const &', 'cb'), param('std::string', 'path')])
@@ -2207,7 +2207,7 @@
cls.add_method('DisconnectWithoutContext',
'void',
[param('ns3::CallbackBase const &', 'cb')])
- ## traced-value.h: void ns3::TracedValue<unsigned int>::Disconnect(ns3::CallbackBase const & cb, std::string path) [member function]
+ ## traced-value.h: void ns3::TracedValue<unsigned int>::Disconnect(ns3::CallbackBase const & cb, std::basic_string<char,std::char_traits<char>,std::allocator<char> > path) [member function]
cls.add_method('Disconnect',
'void',
[param('ns3::CallbackBase const &', 'cb'), param('std::string', 'path')])
@@ -2375,7 +2375,7 @@
module.add_function('TypeNameGet',
'std::string',
[],
- template_parameters=['long long'])
+ template_parameters=['long'])
## type-name.h: extern std::string ns3::TypeNameGet() [free function]
module.add_function('TypeNameGet',
'std::string',
@@ -2395,7 +2395,7 @@
module.add_function('TypeNameGet',
'std::string',
[],
- template_parameters=['unsigned long long'])
+ template_parameters=['unsigned long'])
## type-name.h: extern std::string ns3::TypeNameGet() [free function]
module.add_function('TypeNameGet',
'std::string',
--- a/bindings/python/ns3_module_node.py Tue Aug 25 20:12:53 2009 +0400
+++ b/bindings/python/ns3_module_node.py Wed Aug 26 15:29:03 2009 +0400
@@ -650,6 +650,11 @@
'ns3::Ipv4Mask',
[],
is_static=True)
+ ## ipv4-address.h: uint16_t ns3::Ipv4Mask::GetPrefixLength() const [member function]
+ cls.add_method('GetPrefixLength',
+ 'uint16_t',
+ [],
+ is_const=True)
## ipv4-address.h: static ns3::Ipv4Mask ns3::Ipv4Mask::GetZero() [member function]
cls.add_method('GetZero',
'ns3::Ipv4Mask',
--- a/bindings/python/ns3_module_olsr.py Tue Aug 25 20:12:53 2009 +0400
+++ b/bindings/python/ns3_module_olsr.py Wed Aug 26 15:29:03 2009 +0400
@@ -102,13 +102,13 @@
module.add_container('std::vector< ns3::olsr::MessageHeader::Hello::LinkMessage >', 'ns3::olsr::MessageHeader::Hello::LinkMessage', container_type='vector')
module.add_container('std::vector< ns3::olsr::MessageHeader::Hna::Association >', 'ns3::olsr::MessageHeader::Hna::Association', container_type='vector')
typehandlers.add_type_alias('std::vector< ns3::olsr::DuplicateTuple, std::allocator< ns3::olsr::DuplicateTuple > >', 'ns3::olsr::DuplicateSet')
+ typehandlers.add_type_alias('std::vector< ns3::olsr::NeighborTuple, std::allocator< ns3::olsr::NeighborTuple > >', 'ns3::olsr::NeighborSet')
typehandlers.add_type_alias('std::set< ns3::Ipv4Address, std::less< ns3::Ipv4Address >, std::allocator< ns3::Ipv4Address > >', 'ns3::olsr::MprSet')
typehandlers.add_type_alias('std::vector< ns3::olsr::MprSelectorTuple, std::allocator< ns3::olsr::MprSelectorTuple > >', 'ns3::olsr::MprSelectorSet')
+ typehandlers.add_type_alias('std::vector< ns3::olsr::TopologyTuple, std::allocator< ns3::olsr::TopologyTuple > >', 'ns3::olsr::TopologySet')
typehandlers.add_type_alias('std::vector< ns3::olsr::MessageHeader, std::allocator< ns3::olsr::MessageHeader > >', 'ns3::olsr::MessageList')
typehandlers.add_type_alias('std::vector< ns3::olsr::IfaceAssocTuple, std::allocator< ns3::olsr::IfaceAssocTuple > >', 'ns3::olsr::IfaceAssocSet')
- typehandlers.add_type_alias('std::vector< ns3::olsr::NeighborTuple, std::allocator< ns3::olsr::NeighborTuple > >', 'ns3::olsr::NeighborSet')
typehandlers.add_type_alias('std::vector< ns3::olsr::TwoHopNeighborTuple, std::allocator< ns3::olsr::TwoHopNeighborTuple > >', 'ns3::olsr::TwoHopNeighborSet')
- typehandlers.add_type_alias('std::vector< ns3::olsr::TopologyTuple, std::allocator< ns3::olsr::TopologyTuple > >', 'ns3::olsr::TopologySet')
typehandlers.add_type_alias('std::vector< ns3::olsr::LinkTuple, std::allocator< ns3::olsr::LinkTuple > >', 'ns3::olsr::LinkSet')
def register_methods(root_module):
--- a/bindings/python/ns3_module_wifi.py Tue Aug 25 20:12:53 2009 +0400
+++ b/bindings/python/ns3_module_wifi.py Wed Aug 26 15:29:03 2009 +0400
@@ -10,7 +10,7 @@
## wifi-phy-standard.h: ns3::WifiPhyStandard [enumeration]
module.add_enum('WifiPhyStandard', ['WIFI_PHY_STANDARD_80211a', 'WIFI_PHY_STANDARD_80211b', 'WIFI_PHY_STANDARD_80211_10Mhz', 'WIFI_PHY_STANDARD_80211_5Mhz', 'WIFI_PHY_STANDARD_holland', 'WIFI_PHY_UNKNOWN'])
## qos-utils.h: ns3::AccessClass [enumeration]
- module.add_enum('AccessClass', ['AC_VO', 'AC_VI', 'AC_BE', 'AC_BK', 'AC_UNDEF'])
+ module.add_enum('AccessClass', ['AC_VO', 'AC_VI', 'AC_BE', 'AC_BK', 'AC_BE_NQOS', 'AC_UNDEF'])
## edca-txop-n.h: ns3::TypeOfStation [enumeration]
module.add_enum('TypeOfStation', ['STA', 'AP', 'ADHOC_STA'])
## capability-information.h: ns3::CapabilityInformation [class]
@@ -123,10 +123,10 @@
module.add_class('ConstantRateWifiManager', parent=root_module['ns3::WifiRemoteStationManager'])
## propagation-delay-model.h: ns3::ConstantSpeedPropagationDelayModel [class]
module.add_class('ConstantSpeedPropagationDelayModel', parent=root_module['ns3::PropagationDelayModel'])
- ## dca-txop.h: ns3::DcaTxop [class]
- module.add_class('DcaTxop', parent=root_module['ns3::Object'])
+ ## dcf.h: ns3::Dcf [class]
+ module.add_class('Dcf', parent=root_module['ns3::Object'])
## edca-txop-n.h: ns3::EdcaTxopN [class]
- module.add_class('EdcaTxopN', parent=root_module['ns3::Object'])
+ module.add_class('EdcaTxopN', parent=root_module['ns3::Dcf'])
## error-rate-model.h: ns3::ErrorRateModel [class]
module.add_class('ErrorRateModel', parent=root_module['ns3::Object'])
## propagation-loss-model.h: ns3::FixedRssLossModel [class]
@@ -173,6 +173,8 @@
module.add_class('YansWifiChannel', parent=root_module['ns3::WifiChannel'])
## aarf-wifi-manager.h: ns3::AarfWifiManager [class]
module.add_class('AarfWifiManager', parent=root_module['ns3::ArfWifiManager'])
+ ## dca-txop.h: ns3::DcaTxop [class]
+ module.add_class('DcaTxop', parent=root_module['ns3::Dcf'])
typehandlers.add_type_alias('std::vector< ns3::RateInfo, std::allocator< ns3::RateInfo > >', 'ns3::MinstrelRate')
typehandlers.add_type_alias('std::vector< std::vector< unsigned int, std::allocator< unsigned int > >, std::allocator< std::vector< unsigned int, std::allocator< unsigned int > > > >', 'ns3::SampleRate')
typehandlers.add_type_alias('std::vector< ns3::ThresholdsItem, std::allocator< ns3::ThresholdsItem > >', 'ns3::Thresholds')
@@ -279,7 +281,7 @@
register_Ns3ArfWifiManager_methods(root_module, root_module['ns3::ArfWifiManager'])
register_Ns3ConstantRateWifiManager_methods(root_module, root_module['ns3::ConstantRateWifiManager'])
register_Ns3ConstantSpeedPropagationDelayModel_methods(root_module, root_module['ns3::ConstantSpeedPropagationDelayModel'])
- register_Ns3DcaTxop_methods(root_module, root_module['ns3::DcaTxop'])
+ register_Ns3Dcf_methods(root_module, root_module['ns3::Dcf'])
register_Ns3EdcaTxopN_methods(root_module, root_module['ns3::EdcaTxopN'])
register_Ns3ErrorRateModel_methods(root_module, root_module['ns3::ErrorRateModel'])
register_Ns3FixedRssLossModel_methods(root_module, root_module['ns3::FixedRssLossModel'])
@@ -304,6 +306,7 @@
register_Ns3YansErrorRateModel_methods(root_module, root_module['ns3::YansErrorRateModel'])
register_Ns3YansWifiChannel_methods(root_module, root_module['ns3::YansWifiChannel'])
register_Ns3AarfWifiManager_methods(root_module, root_module['ns3::AarfWifiManager'])
+ register_Ns3DcaTxop_methods(root_module, root_module['ns3::DcaTxop'])
return
def register_Ns3CapabilityInformation_methods(root_module, cls):
@@ -2290,6 +2293,11 @@
cls.add_method('ConfigureStandard',
'void',
[param('ns3::WifiPhyStandard', 'standard')])
+ ## wifi-mac.h: void ns3::WifiMac::ConfigureDcf(ns3::Ptr<ns3::Dcf> dcf, uint32_t cwmin, uint32_t cwmax, ns3::AccessClass ac) [member function]
+ cls.add_method('ConfigureDcf',
+ 'void',
+ [param('ns3::Ptr< ns3::Dcf >', 'dcf'), param('uint32_t', 'cwmin'), param('uint32_t', 'cwmax'), param('ns3::AccessClass', 'ac')],
+ visibility='protected')
## wifi-mac.h: void ns3::WifiMac::FinishConfigureStandard(ns3::WifiPhyStandard standard) [member function]
cls.add_method('FinishConfigureStandard',
'void',
@@ -3683,78 +3691,46 @@
is_const=True)
return
-def register_Ns3DcaTxop_methods(root_module, cls):
- ## dca-txop.h: static ns3::TypeId ns3::DcaTxop::GetTypeId() [member function]
+def register_Ns3Dcf_methods(root_module, cls):
+ ## dcf.h: ns3::Dcf::Dcf(ns3::Dcf const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::Dcf const &', 'arg0')])
+ ## dcf.h: ns3::Dcf::Dcf() [constructor]
+ cls.add_constructor([])
+ ## dcf.h: static ns3::TypeId ns3::Dcf::GetTypeId() [member function]
cls.add_method('GetTypeId',
'ns3::TypeId',
[],
is_static=True)
- ## dca-txop.h: ns3::DcaTxop::DcaTxop() [constructor]
- cls.add_constructor([])
- ## dca-txop.h: void ns3::DcaTxop::SetLow(ns3::Ptr<ns3::MacLow> low) [member function]
- cls.add_method('SetLow',
- 'void',
- [param('ns3::Ptr< ns3::MacLow >', 'low')])
- ## dca-txop.h: void ns3::DcaTxop::SetManager(ns3::DcfManager * manager) [member function]
- cls.add_method('SetManager',
- 'void',
- [param('ns3::DcfManager *', 'manager')])
- ## dca-txop.h: void ns3::DcaTxop::SetWifiRemoteStationManager(ns3::Ptr<ns3::WifiRemoteStationManager> remoteManager) [member function]
- cls.add_method('SetWifiRemoteStationManager',
- 'void',
- [param('ns3::Ptr< ns3::WifiRemoteStationManager >', 'remoteManager')])
- ## dca-txop.h: void ns3::DcaTxop::SetTxOkCallback(ns3::Callback<void, ns3::WifiMacHeader const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> callback) [member function]
- cls.add_method('SetTxOkCallback',
- 'void',
- [param('ns3::Callback< void, ns3::WifiMacHeader const &, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')])
- ## dca-txop.h: void ns3::DcaTxop::SetTxFailedCallback(ns3::Callback<void, ns3::WifiMacHeader const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> callback) [member function]
- cls.add_method('SetTxFailedCallback',
- 'void',
- [param('ns3::Callback< void, ns3::WifiMacHeader const &, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')])
- ## dca-txop.h: void ns3::DcaTxop::SetMaxQueueSize(uint32_t size) [member function]
- cls.add_method('SetMaxQueueSize',
- 'void',
- [param('uint32_t', 'size')])
- ## dca-txop.h: void ns3::DcaTxop::SetMaxQueueDelay(ns3::Time delay) [member function]
- cls.add_method('SetMaxQueueDelay',
- 'void',
- [param('ns3::Time', 'delay')])
- ## dca-txop.h: void ns3::DcaTxop::SetMinCw(uint32_t minCw) [member function]
+ ## dcf.h: void ns3::Dcf::SetMinCw(uint32_t minCw) [member function]
cls.add_method('SetMinCw',
'void',
- [param('uint32_t', 'minCw')])
- ## dca-txop.h: void ns3::DcaTxop::SetMaxCw(uint32_t maxCw) [member function]
+ [param('uint32_t', 'minCw')],
+ is_pure_virtual=True, is_virtual=True)
+ ## dcf.h: void ns3::Dcf::SetMaxCw(uint32_t maxCw) [member function]
cls.add_method('SetMaxCw',
'void',
- [param('uint32_t', 'maxCw')])
- ## dca-txop.h: void ns3::DcaTxop::SetAifsn(uint32_t aifsn) [member function]
+ [param('uint32_t', 'maxCw')],
+ is_pure_virtual=True, is_virtual=True)
+ ## dcf.h: void ns3::Dcf::SetAifsn(uint32_t aifsn) [member function]
cls.add_method('SetAifsn',
'void',
- [param('uint32_t', 'aifsn')])
- ## dca-txop.h: uint32_t ns3::DcaTxop::GetMinCw() const [member function]
+ [param('uint32_t', 'aifsn')],
+ is_pure_virtual=True, is_virtual=True)
+ ## dcf.h: uint32_t ns3::Dcf::GetMinCw() const [member function]
cls.add_method('GetMinCw',
'uint32_t',
[],
- is_const=True)
- ## dca-txop.h: uint32_t ns3::DcaTxop::GetMaxCw() const [member function]
+ is_pure_virtual=True, is_const=True, is_virtual=True)
+ ## dcf.h: uint32_t ns3::Dcf::GetMaxCw() const [member function]
cls.add_method('GetMaxCw',
'uint32_t',
[],
- is_const=True)
- ## dca-txop.h: uint32_t ns3::DcaTxop::GetAifsn() const [member function]
+ is_pure_virtual=True, is_const=True, is_virtual=True)
+ ## dcf.h: uint32_t ns3::Dcf::GetAifsn() const [member function]
cls.add_method('GetAifsn',
'uint32_t',
[],
- is_const=True)
- ## dca-txop.h: void ns3::DcaTxop::Queue(ns3::Ptr<ns3::Packet const> packet, ns3::WifiMacHeader const & hdr) [member function]
- cls.add_method('Queue',
- 'void',
- [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::WifiMacHeader const &', 'hdr')])
- ## dca-txop.h: void ns3::DcaTxop::DoDispose() [member function]
- cls.add_method('DoDispose',
- 'void',
- [],
- visibility='private', is_virtual=True)
+ is_pure_virtual=True, is_const=True, is_virtual=True)
return
def register_Ns3EdcaTxopN_methods(root_module, cls):
@@ -3814,30 +3790,33 @@
## edca-txop-n.h: void ns3::EdcaTxopN::SetMinCw(uint32_t minCw) [member function]
cls.add_method('SetMinCw',
'void',
- [param('uint32_t', 'minCw')])
+ [param('uint32_t', 'minCw')],
+ is_virtual=True)
## edca-txop-n.h: void ns3::EdcaTxopN::SetMaxCw(uint32_t maxCw) [member function]
cls.add_method('SetMaxCw',
'void',
- [param('uint32_t', 'maxCw')])
+ [param('uint32_t', 'maxCw')],
+ is_virtual=True)
## edca-txop-n.h: void ns3::EdcaTxopN::SetAifsn(uint32_t aifsn) [member function]
cls.add_method('SetAifsn',
'void',
- [param('uint32_t', 'aifsn')])
+ [param('uint32_t', 'aifsn')],
+ is_virtual=True)
## edca-txop-n.h: uint32_t ns3::EdcaTxopN::GetMinCw() const [member function]
cls.add_method('GetMinCw',
'uint32_t',
[],
- is_const=True)
+ is_const=True, is_virtual=True)
## edca-txop-n.h: uint32_t ns3::EdcaTxopN::GetMaxCw() const [member function]
cls.add_method('GetMaxCw',
'uint32_t',
[],
- is_const=True)
+ is_const=True, is_virtual=True)
## edca-txop-n.h: uint32_t ns3::EdcaTxopN::GetAifsn() const [member function]
cls.add_method('GetAifsn',
'uint32_t',
[],
- is_const=True)
+ is_const=True, is_virtual=True)
## edca-txop-n.h: ns3::Ptr<ns3::MacLow> ns3::EdcaTxopN::Low() [member function]
cls.add_method('Low',
'ns3::Ptr< ns3::MacLow >',
@@ -5395,6 +5374,83 @@
visibility='private', is_virtual=True)
return
+def register_Ns3DcaTxop_methods(root_module, cls):
+ ## dca-txop.h: static ns3::TypeId ns3::DcaTxop::GetTypeId() [member function]
+ cls.add_method('GetTypeId',
+ 'ns3::TypeId',
+ [],
+ is_static=True)
+ ## dca-txop.h: ns3::DcaTxop::DcaTxop() [constructor]
+ cls.add_constructor([])
+ ## dca-txop.h: void ns3::DcaTxop::SetLow(ns3::Ptr<ns3::MacLow> low) [member function]
+ cls.add_method('SetLow',
+ 'void',
+ [param('ns3::Ptr< ns3::MacLow >', 'low')])
+ ## dca-txop.h: void ns3::DcaTxop::SetManager(ns3::DcfManager * manager) [member function]
+ cls.add_method('SetManager',
+ 'void',
+ [param('ns3::DcfManager *', 'manager')])
+ ## dca-txop.h: void ns3::DcaTxop::SetWifiRemoteStationManager(ns3::Ptr<ns3::WifiRemoteStationManager> remoteManager) [member function]
+ cls.add_method('SetWifiRemoteStationManager',
+ 'void',
+ [param('ns3::Ptr< ns3::WifiRemoteStationManager >', 'remoteManager')])
+ ## dca-txop.h: void ns3::DcaTxop::SetTxOkCallback(ns3::Callback<void, ns3::WifiMacHeader const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> callback) [member function]
+ cls.add_method('SetTxOkCallback',
+ 'void',
+ [param('ns3::Callback< void, ns3::WifiMacHeader const &, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')])
+ ## dca-txop.h: void ns3::DcaTxop::SetTxFailedCallback(ns3::Callback<void, ns3::WifiMacHeader const&, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> callback) [member function]
+ cls.add_method('SetTxFailedCallback',
+ 'void',
+ [param('ns3::Callback< void, ns3::WifiMacHeader const &, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')])
+ ## dca-txop.h: void ns3::DcaTxop::SetMaxQueueSize(uint32_t size) [member function]
+ cls.add_method('SetMaxQueueSize',
+ 'void',
+ [param('uint32_t', 'size')])
+ ## dca-txop.h: void ns3::DcaTxop::SetMaxQueueDelay(ns3::Time delay) [member function]
+ cls.add_method('SetMaxQueueDelay',
+ 'void',
+ [param('ns3::Time', 'delay')])
+ ## dca-txop.h: void ns3::DcaTxop::SetMinCw(uint32_t minCw) [member function]
+ cls.add_method('SetMinCw',
+ 'void',
+ [param('uint32_t', 'minCw')],
+ is_virtual=True)
+ ## dca-txop.h: void ns3::DcaTxop::SetMaxCw(uint32_t maxCw) [member function]
+ cls.add_method('SetMaxCw',
+ 'void',
+ [param('uint32_t', 'maxCw')],
+ is_virtual=True)
+ ## dca-txop.h: void ns3::DcaTxop::SetAifsn(uint32_t aifsn) [member function]
+ cls.add_method('SetAifsn',
+ 'void',
+ [param('uint32_t', 'aifsn')],
+ is_virtual=True)
+ ## dca-txop.h: uint32_t ns3::DcaTxop::GetMinCw() const [member function]
+ cls.add_method('GetMinCw',
+ 'uint32_t',
+ [],
+ is_const=True, is_virtual=True)
+ ## dca-txop.h: uint32_t ns3::DcaTxop::GetMaxCw() const [member function]
+ cls.add_method('GetMaxCw',
+ 'uint32_t',
+ [],
+ is_const=True, is_virtual=True)
+ ## dca-txop.h: uint32_t ns3::DcaTxop::GetAifsn() const [member function]
+ cls.add_method('GetAifsn',
+ 'uint32_t',
+ [],
+ is_const=True, is_virtual=True)
+ ## dca-txop.h: void ns3::DcaTxop::Queue(ns3::Ptr<ns3::Packet const> packet, ns3::WifiMacHeader const & hdr) [member function]
+ cls.add_method('Queue',
+ 'void',
+ [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::WifiMacHeader const &', 'hdr')])
+ ## dca-txop.h: void ns3::DcaTxop::DoDispose() [member function]
+ cls.add_method('DoDispose',
+ 'void',
+ [],
+ visibility='private', is_virtual=True)
+ return
+
def register_functions(root_module):
module = root_module
## ssid.h: extern ns3::Ptr<ns3::AttributeChecker const> ns3::MakeSsidChecker() [free function]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/icmpv6-redirect.cc Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,176 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: David Gross <david.gross@eturs.u-strasbg.fr>
+ */
+
+// Network topology
+//
+// STA2
+// |
+// |
+// R1 R2
+// | |
+// | |
+// ------------
+// |
+// |
+// STA 1
+//
+// - Initial configuration :
+// - STA1 default route : R1
+// - R1 static route to STA2 : R2
+// - STA2 default route : R2
+// - STA1 send Echo Request to STA2 using its default route to R1
+// - R1 receive Echo Request from STA1, and forward it to R2
+// - R1 send an ICMPv6 Redirection to STA1 with Target STA2 and Destination R2
+// - Next Echo Request from STA1 to STA2 are directly sent to R2
+
+#include <fstream>
+#include "ns3/core-module.h"
+#include "ns3/simulator-module.h"
+#include "ns3/helper-module.h"
+
+#include "ns3/ipv6-routing-table-entry.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("Icmpv6RedirectExample");
+
+class StackHelper
+{
+ public:
+ /**
+ * \brief Print the routing table.
+ * \param n the node
+ */
+ inline void PrintRoutingTable (Ptr<Node>& n)
+ {
+ Ptr<Ipv6StaticRouting> routing = 0;
+ Ipv6StaticRoutingHelper routingHelper;
+ Ptr<Ipv6> ipv6 = n->GetObject<Ipv6> ();
+ uint32_t nbRoutes = 0;
+ Ipv6RoutingTableEntry route;
+
+ routing = routingHelper.GetStaticRouting (ipv6);
+
+ std::cout << "Routing table of " << n << " : " << std::endl;
+ std::cout << "Destination\t\t\t\t" << "Gateway\t\t\t\t\t" << "Interface\t" << std::endl;
+
+ nbRoutes = routing->GetNRoutes ();
+ for(uint32_t i = 0 ; i < nbRoutes ; i++)
+ {
+ route = routing->GetRoute (i);
+ std::cout << route.GetDest () << "\t"
+ << route.GetGateway () << "\t"
+ << route.GetInterface () << "\t" << std::endl;
+ }
+ }
+
+ inline void AddHostRouteTo (Ptr<Node>& n, Ipv6Address dst, Ipv6Address nextHop, uint32_t interface)
+ {
+ Ptr<Ipv6StaticRouting> routing = 0;
+ Ipv6StaticRoutingHelper routingHelper;
+ Ptr<Ipv6> ipv6 = n->GetObject<Ipv6> ();
+
+ routing = routingHelper.GetStaticRouting (ipv6);
+
+ routing->AddHostRouteTo (dst, nextHop, interface);
+ }
+};
+
+
+int main (int argc, char **argv)
+{
+#if 0
+ LogComponentEnable ("Icmpv6RedirectExample", LOG_LEVEL_INFO);
+ LogComponentEnable ("Icmpv6L4Protocol", LOG_LEVEL_INFO);
+ LogComponentEnable("Ipv6L3Protocol", LOG_LEVEL_ALL);
+ LogComponentEnable("Ipv6StaticRouting", LOG_LEVEL_ALL);
+ LogComponentEnable("Ipv6Interface", LOG_LEVEL_ALL);
+ LogComponentEnable("Icmpv6L4Protocol", LOG_LEVEL_ALL);
+ LogComponentEnable("NdiscCache", LOG_LEVEL_ALL);
+#endif
+
+ CommandLine cmd;
+ cmd.Parse (argc, argv);
+
+ NS_LOG_INFO ("Create nodes.");
+ Ptr<Node> sta1 = CreateObject<Node> ();
+ Ptr<Node> r1 = CreateObject<Node> ();
+ Ptr<Node> r2 = CreateObject<Node> ();
+ Ptr<Node> sta2 = CreateObject<Node> ();
+ NodeContainer net1(sta1, r1, r2);
+ NodeContainer net2(r2, sta2);
+ NodeContainer all(sta1, r1, r2, sta2);
+
+ StackHelper stackHelper;
+
+ InternetStackHelper internetv6;
+ internetv6.Install (all);
+
+ NS_LOG_INFO ("Create channels.");
+ CsmaHelper csma;
+ csma.SetChannelAttribute ("DataRate", DataRateValue(5000000));
+ csma.SetChannelAttribute ("Delay", TimeValue(MilliSeconds (2)));
+ NetDeviceContainer ndc1 = csma.Install (net1);
+ NetDeviceContainer ndc2 = csma.Install (net2);
+
+ NS_LOG_INFO ("Assign IPv6 Addresses.");
+ Ipv6AddressHelper ipv6;
+
+ ipv6.NewNetwork (Ipv6Address ("2001:1::"), 64);
+ Ipv6InterfaceContainer iic1 = ipv6.Assign (ndc1);
+ iic1.SetRouter (2, true);
+ iic1.SetRouter (1, true);
+
+ ipv6.NewNetwork (Ipv6Address ("2001:2::"), 64);
+ Ipv6InterfaceContainer iic2 = ipv6.Assign (ndc2);
+ iic2.SetRouter (0, true);
+
+ stackHelper.AddHostRouteTo (r1, iic2.GetAddress (1, 1), iic1.GetAddress (2, 1), iic1.GetInterfaceIndex (1));
+
+ Simulator::Schedule(Seconds(0.0), &StackHelper::PrintRoutingTable, &stackHelper, r1);
+ Simulator::Schedule(Seconds(3.0), &StackHelper::PrintRoutingTable, &stackHelper, sta1);
+
+ NS_LOG_INFO ("Create Applications.");
+ uint32_t packetSize = 1024;
+ uint32_t maxPacketCount = 5;
+ Time interPacketInterval = Seconds (1.);
+ Ping6Helper ping6;
+
+ ping6.SetLocal (iic1.GetAddress(0, 1));
+ ping6.SetRemote (iic2.GetAddress(1, 1));
+ ping6.SetAttribute ("MaxPackets", UintegerValue (maxPacketCount));
+ ping6.SetAttribute ("Interval", TimeValue(interPacketInterval));
+ ping6.SetAttribute ("PacketSize", UintegerValue (packetSize));
+ ApplicationContainer apps = ping6.Install (sta1);
+ apps.Start (Seconds (2.0));
+ apps.Stop (Seconds (10.0));
+
+ std::ofstream ascii;
+ ascii.open ("icmpv6-redirect.tr");
+ CsmaHelper::EnablePcapAll ("icmpv6-redirect", true);
+ CsmaHelper::EnableAsciiAll (ascii);
+
+ /* Now, do the actual simulation. */
+ NS_LOG_INFO ("Run Simulation.");
+ Simulator::Run ();
+ Simulator::Destroy ();
+ NS_LOG_INFO ("Done.");
+}
+
--- a/examples/multi-rate-first.cc Tue Aug 25 20:12:53 2009 +0400
+++ b/examples/multi-rate-first.cc Wed Aug 26 15:29:03 2009 +0400
@@ -1,10 +1,16 @@
/**
*
* Instructions:
- * ./waf --run multi-rate-first > m.data
- * gnuplot m.data
- * eog *.png
+ * ./waf --run multi-rate-first
+ * gnuplot multi-rate-first-scen*.plt
*
+ * Output:
+ * multi-rate-first-scen1.eps
+ * multi-rate-first-scen2.eps
+ * multi-rate-first-scen3.eps
+ * multi-rate-first-scen4.eps
+ *
+ * Side Note: It may take some time.
*/
#include "ns3/core-module.h"
@@ -15,6 +21,7 @@
#include "ns3/contrib-module.h"
#include <iostream>
+#include <fstream>
NS_LOG_COMPONENT_DEFINE ("Main");
@@ -34,6 +41,7 @@
void AdvancePosition (Ptr<Node> node);
void BackTrackPosition (Ptr<Node> node);
void StationaryPosition (Ptr<Node> node);
+ void MultiPosition (Ptr<Node> node1, Ptr<Node> node2);
Ptr<Socket> SetupPacketReceive (Ptr<Node> node);
uint32_t m_bytesTotal;
@@ -108,6 +116,26 @@
m_output.Add ((Simulator::Now()).GetSeconds(), mbs);
}
+void
+Experiment::MultiPosition (Ptr<Node> n1, Ptr<Node> n2)
+{
+ Vector pos1 = GetPosition(n1);
+ Vector pos2 = GetPosition(n2);
+ double mbs = ((m_bytesTotal * 8.0) / 1000000);
+ m_bytesTotal = 0;
+ m_output.Add ((Simulator::Now()).GetSeconds(), mbs);
+
+ if( pos1.x < 230)
+ {
+ pos1.x += 1.0;
+ SetPosition (n1, pos1);
+ }
+ if( pos2.x > 0)
+ {
+ pos2.x -= 1.0;
+ SetPosition (n2, pos2);
+ }
+}
void
Experiment::ReceivePacket (Ptr<Socket> socket)
@@ -169,21 +197,30 @@
Ptr<Socket> recvSink = SetupPacketReceive (c.Get (1));
- if(positionStep == 1)
+ if (positionStep == 1)
{
Simulator::Schedule (Seconds (1.5), &Experiment::AdvancePosition, this, c.Get (1));
}
- else if(positionStep == -1)
+ else if (positionStep == -1)
{
Simulator::Schedule (Seconds (1.5), &Experiment::BackTrackPosition, this, c.Get (1));
}
- else if(positionStep == 0)
+ else if (positionStep == 0)
{
for(int i = 1; i <= 210; i++)
{
Simulator::Schedule (Seconds (i), &Experiment::StationaryPosition, this, c.Get (1));
}
}
+ else if (positionStep == 2)
+ {
+ for(int i = 1; i <= 210; i++)
+ {
+ Simulator::Schedule (Seconds (i), &Experiment::MultiPosition, this, c.Get(0), c.Get (1));
+ }
+ }
+
+
Simulator::Run ();
Simulator::Destroy ();
@@ -192,6 +229,11 @@
int main (int argc, char *argv[])
{
+ std::ofstream outfile ("multi-rate-first-scen1.plt");
+ std::ofstream outfile2 ("multi-rate-first-scen2.plt");
+ std::ofstream outfile3 ("multi-rate-first-scen3.plt");
+ std::ofstream outfile4 ("multi-rate-first-scen4.plt");
+
// disable fragmentation
Config::SetDefault ("ns3::WifiRemoteStationManager::FragmentationThreshold", StringValue ("2200"));
Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue ("2200"));
@@ -199,119 +241,158 @@
CommandLine cmd;
cmd.Parse (argc, argv);
- Gnuplot gnuplot = Gnuplot ("multi-rate-first.png");
+
+ MobilityHelper mobility;
Experiment experiment;
+ Gnuplot gnuplot;
+ int myPositionStep;
+ Ptr<ListPositionAllocator> positionAlloc;
+ Gnuplot2dDataset dataset;
WifiHelper wifi = WifiHelper::Default ();
NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
- Gnuplot2dDataset dataset;
- int myPositionStep = 0;
-
-/*
- // Scenario 1: moving away from one another
- // Initially set them 5 meters apart
- // Set positionStep parameter of Experiment::Run to 1
- // Set RateErrorModel of Experiment::Run to 0
+ // Scenario 1: two nodes within transmission range about 5 meters apart
+ // Fix a node stationary, move the second node away from it
+
+ // moving forward
myPositionStep = 1;
- MobilityHelper mobility;
- Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
+ gnuplot = Gnuplot ("multi-rate-first-scen1.eps");
+
+ positionAlloc = CreateObject<ListPositionAllocator> ();
positionAlloc->Add (Vector (0.0, 0.0, 0.0));
positionAlloc->Add (Vector (5.0, 0.0, 0.0));
mobility.SetPositionAllocator (positionAlloc);
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
wifiMac.SetType ("ns3::AdhocWifiMac");
-
- gnuplot = Gnuplot ("multi-rate-first.png");
wifi.SetStandard (WIFI_PHY_STANDARD_holland);
- NS_LOG_DEBUG ("minstrel");
experiment = Experiment ("minstrel");
wifi.SetRemoteStationManager ("ns3::MinstrelWifiManager");
dataset = experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel, mobility, myPositionStep);
gnuplot.AddDataset (dataset);
- NS_LOG_DEBUG ("ideal");
experiment = Experiment ("ideal");
wifi.SetRemoteStationManager ("ns3::IdealWifiManager");
dataset = experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel, mobility, myPositionStep);
gnuplot.AddDataset (dataset);
- gnuplot.GenerateOutput (std::cout);
- */
+ gnuplot.SetTerminal ("postscript eps color enh \"Times-BoldItalic\"");
+ gnuplot.SetLegend ("Time (Seconds)", "Throughput(Mbps)");
+ gnuplot.SetExtra ("set xrange [0:250]");
+ gnuplot.SetTitle ("Throughput vs Time");
+ gnuplot.GenerateOutput (outfile);
+ outfile.close ();
- // Scenario 2: two nodes out of range, moving into transmission range range
- // Initially set them 230 meters apart
- // Set positionStep parameter of Experiment::Rung to -1
- // set RateErrorModel of Experiment::Run to 0
+ // Scenario 2: two nodes out of transmission range about 230 meters apart
+ // Fix a node stationary, move the second node into transmission range
+ // moving backward
myPositionStep = -1;
- MobilityHelper mobility;
- Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
+ gnuplot = Gnuplot ("multi-rate-first-scen2.eps");
+
+ positionAlloc = CreateObject<ListPositionAllocator> ();
positionAlloc->Add (Vector (0.0, 0.0, 0.0));
positionAlloc->Add (Vector (230.0, 0.0, 0.0));
mobility.SetPositionAllocator (positionAlloc);
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
wifiMac.SetType ("ns3::AdhocWifiMac");
-
- gnuplot = Gnuplot ("multi-rate-first.png");
wifi.SetStandard (WIFI_PHY_STANDARD_holland);
- NS_LOG_DEBUG ("minstrel");
experiment = Experiment ("minstrel");
wifi.SetRemoteStationManager ("ns3::MinstrelWifiManager");
- dataset = experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel, mobility, myPositionStep);
+ dataset= experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel, mobility, myPositionStep);
gnuplot.AddDataset (dataset);
- NS_LOG_DEBUG ("ideal");
experiment = Experiment ("ideal");
wifi.SetRemoteStationManager ("ns3::IdealWifiManager");
- dataset = experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel, mobility, myPositionStep);
+ dataset= experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel, mobility, myPositionStep);
gnuplot.AddDataset (dataset);
- gnuplot.GenerateOutput (std::cout);
-
-
-/*
- // Scenario 3:
- // Initially set them 25 meters apart, stationary
- // Set positionStep parameter of Experiment::Rung to 0
- // This is a sanity check
+ gnuplot.SetTerminal ("postscript eps color enh \"Times-BoldItalic\"");
+ gnuplot.SetLegend ("Time (Seconds)", "Throughput(Mbps)");
+ gnuplot.SetExtra ("set xrange [0:250]");
+ gnuplot.SetTitle ("Throughput vs Time");
+ gnuplot.GenerateOutput (outfile2);
+ outfile2.close ();
+
+ // Scenario 3: two nodes within transmission range 25 meters part
+ // Set both nodes stationary
+ // this is more like a sanity check
+
+ // Set position stationary
myPositionStep = 0;
- MobilityHelper mobility;
- Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
+
+ gnuplot = Gnuplot ("multi-rate-first-scen3.eps");
+
+ positionAlloc = CreateObject<ListPositionAllocator> ();
positionAlloc->Add (Vector (0.0, 0.0, 0.0));
positionAlloc->Add (Vector (25.0, 0.0, 0.0));
mobility.SetPositionAllocator (positionAlloc);
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
wifiMac.SetType ("ns3::AdhocWifiMac");
-
- gnuplot = Gnuplot ("multi-rate-first.png");
wifi.SetStandard (WIFI_PHY_STANDARD_holland);
- NS_LOG_DEBUG ("minstrel");
experiment = Experiment ("minstrel");
wifi.SetRemoteStationManager ("ns3::MinstrelWifiManager");
- dataset = experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel, mobility, myPositionStep);
+ dataset= experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel, mobility, myPositionStep);
gnuplot.AddDataset (dataset);
- NS_LOG_DEBUG ("ideal");
experiment = Experiment ("ideal");
wifi.SetRemoteStationManager ("ns3::IdealWifiManager");
- dataset = experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel, mobility, myPositionStep);
+ dataset= experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel, mobility, myPositionStep);
gnuplot.AddDataset (dataset);
- gnuplot.GenerateOutput (std::cout);
- */
+ gnuplot.SetTerminal ("postscript eps color enh \"Times-BoldItalic\"");
+ gnuplot.SetLegend ("Time (Seconds)", "Throughput(Mbps)");
+ gnuplot.SetExtra ("set xrange [0:250]");
+ gnuplot.SetTitle ("Throughput vs Time");
+ gnuplot.GenerateOutput (outfile3);
+ outfile3.close ();
+
+ // Scenario 4: Two nodes in opposite direction about 230 meters apart
+ // moving into transmission range and out of transmission range
+ myPositionStep = 2;
+
+ gnuplot = Gnuplot ("multi-rate-first-scen4.eps");
+
+ positionAlloc = CreateObject<ListPositionAllocator> ();
+ // initial position of node 1
+ positionAlloc->Add (Vector (0.0, 25.0, 0.0));
+ // initial position of node 2
+ positionAlloc->Add (Vector (230.0, 0.0, 0.0));
+ mobility.SetPositionAllocator (positionAlloc);
+ mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
+
+ wifiMac.SetType ("ns3::AdhocWifiMac");
+ wifi.SetStandard (WIFI_PHY_STANDARD_holland);
+
+ experiment = Experiment ("minstrel");
+ wifi.SetRemoteStationManager ("ns3::MinstrelWifiManager");
+ dataset= experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel, mobility, myPositionStep);
+ gnuplot.AddDataset (dataset);
+
+ experiment = Experiment ("ideal");
+ wifi.SetRemoteStationManager ("ns3::IdealWifiManager");
+ dataset= experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel, mobility, myPositionStep);
+ gnuplot.AddDataset (dataset);
+
+ gnuplot.SetTerminal ("postscript eps color enh \"Times-BoldItalic\"");
+ gnuplot.SetLegend ("Time (Seconds)", "Throughput(Mbps)");
+ gnuplot.SetExtra ("set xrange [0:250]");
+ gnuplot.SetTitle ("Throughput vs Time");
+ gnuplot.GenerateOutput (outfile4);
+ outfile4.close ();
+
return 0;
}
--- a/examples/multi-rate-second.cc Tue Aug 25 20:12:53 2009 +0400
+++ b/examples/multi-rate-second.cc Wed Aug 26 15:29:03 2009 +0400
@@ -95,13 +95,10 @@
{
Vector pos = GetPosition(node);
- ///to offset the start time
- double offSetTime = 100;
-
if (pktCount > 0)
{
///To simulate nodes moving in and out of transmission constantly
- if(pos.x <= 305 && advanceStep)
+ if(pos.x <= 230 && advanceStep)
{
///keep moving away
pos.x += .1;
@@ -110,7 +107,7 @@
else
{
if(pos.x < 150)
- {
+ {
advanceStep=true;
}
else
@@ -128,7 +125,7 @@
}
else
{
- m_output.Add((Simulator::Now()).GetSeconds() - offSetTime , m_pktsTotal);
+ m_output.Add((Simulator::Now()).GetSeconds(), m_pktsTotal);
}
}
@@ -172,32 +169,30 @@
source->Connect (remote);
uint32_t packetSize = 1014;
uint32_t maxPacketCount = 1000;
- Time interPacketInterval = Seconds (.1);
+ Time interPacketInterval = Seconds (1.);
Ptr<Node> n1 = c.Get(0);
Ptr<Ipv4> ipv41 = n1->GetObject<Ipv4> ();
-
+ // parameters for Ipv4::SetDown and SetUp
+ // The first ifIndex is 0 for loopback, then the first p2p is numbered 1,
+ // then the next p2p is numbered 2
-
+ double downTime = 0.0;
for (int i= 1; i <= 100; i++)
{
Simulator::Schedule (Seconds (i), &Experiment::GenerateTraffic,
this, source, packetSize, maxPacketCount,interPacketInterval, c.Get(1));
-
- if( i % 5 == 0 )
+ if ( i % 10 == 0 )
{
///bring a network interface down
- Simulator::Schedule (Seconds (i+.5), &Ipv4::SetDown, ipv41, 1);
- i++;
- Simulator::Schedule (Seconds (i), &Experiment::GenerateTraffic,
- this, source, packetSize, maxPacketCount,interPacketInterval, c.Get(1));
+ Simulator::Schedule (Seconds (i+.1), &Ipv4::SetDown, ipv41, 1);
+ //duration of the down time
+ downTime += .1;
+
///bring a network interface up
- Simulator::Schedule (Seconds (i+.2), &Ipv4::SetUp, ipv41, 1);
- i++;
- Simulator::Schedule (Seconds (i), &Experiment::GenerateTraffic,
- this, source, packetSize, maxPacketCount,interPacketInterval, c.Get(1));
+ Simulator::Schedule (Seconds (i + downTime), &Ipv4::SetUp, ipv41, 1);
}
}
@@ -209,13 +204,15 @@
int main (int argc, char *argv[])
{
+ std::ofstream outfile ("multi-rate-second.plt");
+
std::vector <std::string> ratesControl;
+ ratesControl.push_back ("Minstrel");
ratesControl.push_back ("Ideal");
- ratesControl.push_back ("Minstrel");
std::vector <std::string> wifiManager;
+ wifiManager.push_back("ns3::MinstrelWifiManager");
wifiManager.push_back("ns3::IdealWifiManager");
- wifiManager.push_back("ns3::MinstrelWifiManager");
// disable fragmentation
Config::SetDefault ("ns3::WifiRemoteStationManager::FragmentationThreshold", StringValue ("2200"));
@@ -228,12 +225,13 @@
for (uint32_t i = 0; i < ratesControl.size(); i++)
{
+ std::cout << ratesControl[i] << std::endl;
+ std::cout << wifiManager[i] << std::endl;
Gnuplot2dDataset dataset (ratesControl[i]);
dataset.SetStyle (Gnuplot2dDataset::LINES);
Experiment experiment;
-
- WifiHelper wifi = WifiHelper::Default ();
+ WifiHelper wifi;
NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
@@ -243,14 +241,18 @@
NS_LOG_DEBUG (ratesControl[i]);
experiment = Experiment (ratesControl[i]);
+ wifi.SetStandard (WIFI_PHY_STANDARD_80211b);
+ wifi.SetRemoteStationManager (wifiManager[i]);
dataset = experiment.Run (wifi, wifiPhy, wifiMac, wifiChannel);
gnuplot.AddDataset (dataset);
}
gnuplot.SetTerminal ("postscript eps color enh \"Times-BoldItalic\"");
- gnuplot.SetLegend ("Time (Seconds)", "Number of packets received");
- gnuplot.SetExtra ("set xrange [0:100]");
- gnuplot.GenerateOutput (std::cout);
+ gnuplot.SetLegend ("Time ", "Number of packets received");
+ gnuplot.SetExtra ("set xrange [1000:1100]");
+ gnuplot.SetTitle ("Number of Packets Received vs Time");
+ gnuplot.GenerateOutput (outfile);
+ outfile.close ();
return 0;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/ping6.cc Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,111 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+// Network topology
+//
+// n0 n1
+// | |
+// =================
+// LAN
+//
+// - ICMPv6 echo request flows from n0 to n1 and back with ICMPv6 echo reply
+// - DropTail queues
+// - Tracing of queues and packet receptions to file "ping6.tr"
+
+#include <fstream>
+#include "ns3/core-module.h"
+#include "ns3/simulator-module.h"
+#include "ns3/helper-module.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("Ping6Example");
+
+int main (int argc, char **argv)
+{
+#if 0
+ LogComponentEnable ("Ping6Example", LOG_LEVEL_INFO);
+ LogComponentEnable ("Ipv6EndPointDemux", LOG_LEVEL_ALL);
+ LogComponentEnable ("Ipv6L3Protocol", LOG_LEVEL_ALL);
+ LogComponentEnable ("Ipv6StaticRouting", LOG_LEVEL_ALL);
+ LogComponentEnable ("Ipv6ListRouting", LOG_LEVEL_ALL);
+ LogComponentEnable ("Ipv6Interface", LOG_LEVEL_ALL);
+ LogComponentEnable ("Icmpv6L4Protocol", LOG_LEVEL_ALL);
+ LogComponentEnable ("Ping6Application", LOG_LEVEL_ALL);
+ LogComponentEnable ("NdiscCache", LOG_LEVEL_ALL);
+#endif
+
+ CommandLine cmd;
+ cmd.Parse (argc, argv);
+
+ NS_LOG_INFO ("Create nodes.");
+ NodeContainer n;
+ n.Create (4);
+
+ /* Install IPv4/IPv6 stack */
+ InternetStackHelper internetv6;
+ internetv6.SetIpv4StackInstall (false);
+ internetv6.Install (n);
+
+ NS_LOG_INFO ("Create channels.");
+ CsmaHelper csma;
+ csma.SetChannelAttribute ("DataRate", DataRateValue (5000000));
+ csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
+ NetDeviceContainer d = csma.Install (n);
+
+ Ipv6AddressHelper ipv6;
+ NS_LOG_INFO ("Assign IPv6 Addresses.");
+ Ipv6InterfaceContainer i = ipv6.Assign (d);
+
+ NS_LOG_INFO ("Create Applications.");
+
+ /* Create a Ping6 application to send ICMPv6 echo request from node zero to
+ * all-nodes (ff02::1).
+ */
+ uint32_t packetSize = 1024;
+ uint32_t maxPacketCount = 5;
+ Time interPacketInterval = Seconds (1.);
+ Ping6Helper ping6;
+
+/*
+ ping6.SetLocal (i.GetAddress (0, 1));
+ ping6.SetRemote (i.GetAddress (1, 1));
+*/
+ ping6.SetIfIndex (i.GetInterfaceIndex (0));
+ ping6.SetRemote (Ipv6Address::GetAllNodesMulticast ());
+
+ ping6.SetAttribute ("MaxPackets", UintegerValue (maxPacketCount));
+ ping6.SetAttribute ("Interval", TimeValue (interPacketInterval));
+ ping6.SetAttribute ("PacketSize", UintegerValue (packetSize));
+ ApplicationContainer apps = ping6.Install (n.Get (0));
+ apps.Start (Seconds (2.0));
+ apps.Stop (Seconds (10.0));
+
+ std::ofstream ascii;
+ ascii.open ("ping6.tr");
+ CsmaHelper::EnablePcapAll (std::string ("ping6"), true);
+ CsmaHelper::EnableAsciiAll (ascii);
+
+ NS_LOG_INFO ("Run Simulation.");
+ Simulator::Run ();
+ Simulator::Destroy ();
+ NS_LOG_INFO ("Done.");
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/radvd-two-prefix.cc Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,216 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: David Gross <gdavid.devel@gmail.com>
+ * Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+// Network topology
+// //
+// // n0 R n1
+// // | _ |
+// // ====|_|====
+// // router
+// // - R sends RA to n0's subnet (2001:1::/64 and 2001:ABCD::/64);
+// // - R interface to n0 has two addresses with following prefixes 2001:1::/64 and 2001:ABCD::/64;
+// // - R sends RA to n1's subnet (2001:2::/64);
+// // - n0 ping6 n1.
+// //
+// // - Tracing of queues and packet receptions to file "radvd-two-prefix.tr"
+
+#include <fstream>
+#include "ns3/core-module.h"
+#include "ns3/simulator-module.h"
+#include "ns3/helper-module.h"
+
+#include "ns3/ipv6-routing-table-entry.h"
+#include "ns3/radvd.h"
+#include "ns3/radvd-interface.h"
+#include "ns3/radvd-prefix.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("RadvdExample");
+
+class StackHelper
+{
+ public:
+
+ /**
+ * \brief Add an address to a IPv6 node.
+ * \param n node
+ * \param interface interface index
+ * \param address IPv6 address to add
+ */
+ inline void AddAddress (Ptr<Node>& n, uint32_t interface, Ipv6Address address)
+ {
+ Ptr<Ipv6> ipv6 = n->GetObject<Ipv6> ();
+ ipv6->AddAddress (interface, address);
+ }
+
+ /**
+ * \brief Print the routing table.
+ * \param n the node
+ */
+ inline void PrintRoutingTable (Ptr<Node>& n)
+ {
+ Ptr<Ipv6StaticRouting> routing = 0;
+ Ipv6StaticRoutingHelper routingHelper;
+ Ptr<Ipv6> ipv6 = n->GetObject<Ipv6> ();
+ uint32_t nbRoutes = 0;
+ Ipv6RoutingTableEntry route;
+
+ routing = routingHelper.GetStaticRouting (ipv6);
+
+ std::cout << "Routing table of " << n << " : " << std::endl;
+ std::cout << "Destination\t\t\t\t" << "Gateway\t\t\t\t\t" << "Interface\t" << std::endl;
+
+ nbRoutes = routing->GetNRoutes ();
+ for (uint32_t i = 0 ; i < nbRoutes ; i++)
+ {
+ route = routing->GetRoute (i);
+ std::cout << route.GetDest () << "\t"
+ << route.GetGateway () << "\t"
+ << route.GetInterface () << "\t" << std::endl;
+ }
+ }
+};
+
+int main (int argc, char** argv)
+{
+#if 0
+ LogComponentEnable ("Ipv6L3Protocol", LOG_LEVEL_ALL);
+ LogComponentEnable ("Ipv6RawSocketImpl", LOG_LEVEL_ALL);
+ LogComponentEnable ("Icmpv6L4Protocol", LOG_LEVEL_ALL);
+ LogComponentEnable ("Ipv6StaticRouting", LOG_LEVEL_ALL);
+ LogComponentEnable ("Ipv6Interface", LOG_LEVEL_ALL);
+ LogComponentEnable ("RadvdApplication", LOG_LEVEL_ALL);
+ LogComponentEnable ("Ping6Application", LOG_LEVEL_ALL);
+#endif
+
+ CommandLine cmd;
+ cmd.Parse (argc, argv);
+
+ NS_LOG_INFO ("Create nodes.");
+ Ptr<Node> n0 = CreateObject<Node> ();
+ Ptr<Node> r = CreateObject<Node> ();
+ Ptr<Node> n1 = CreateObject<Node> ();
+
+ NodeContainer net1 (n0, r);
+ NodeContainer net2 (r, n1);
+ NodeContainer all (n0, r, n1);
+ StackHelper stackHelper;
+
+ NS_LOG_INFO ("Create IPv6 Internet Stack");
+ InternetStackHelper internetv6;
+ internetv6.Install (all);
+
+ NS_LOG_INFO ("Create channels.");
+ CsmaHelper csma;
+ csma.SetChannelAttribute ("DataRate", DataRateValue (5000000));
+ csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
+ NetDeviceContainer d1 = csma.Install (net1); /* n0 - R */
+ NetDeviceContainer d2 = csma.Install (net2); /* R - n1 */
+
+ NS_LOG_INFO ("Create networks and assign IPv6 Addresses.");
+ Ipv6AddressHelper ipv6;
+
+ /* first subnet */
+ ipv6.NewNetwork (Ipv6Address ("2001:1::"), 64);
+ NetDeviceContainer tmp;
+ tmp.Add (d1.Get (0)); /* n0 */
+ Ipv6InterfaceContainer iic1 = ipv6.AssignWithoutAddress (tmp); /* n0 interface */
+
+ NetDeviceContainer tmp2;
+ tmp2.Add (d1.Get (1)); /* R */
+ Ipv6InterfaceContainer iicr1 = ipv6.Assign (tmp2); /* R interface to the first subnet is just statically assigned */
+ iicr1.SetRouter (0, true);
+ iic1.Add (iicr1);
+
+ /* add another IPv6 address for second prefix advertised on first subnet */
+ stackHelper.AddAddress (r, iic1.GetInterfaceIndex (1), Ipv6Address ("2001:ABCD::2"));
+
+ /* second subnet R - n1 */
+ ipv6.NewNetwork (Ipv6Address ("2001:2::"), 64);
+ NetDeviceContainer tmp3;
+ tmp3.Add (d2.Get (0)); /* R */
+ Ipv6InterfaceContainer iicr2 = ipv6.Assign (tmp3); /* R interface */
+ iicr2.SetRouter (0, true);
+
+ NetDeviceContainer tmp4;
+ tmp4.Add (d2.Get (1)); /* n1 */
+ Ipv6InterfaceContainer iic2 = ipv6.AssignWithoutAddress (tmp4);
+ iic2.Add (iicr2);
+
+ /* radvd configuration */
+ Ipv6Address prefix ("2001:1::0"); /* create the prefix */
+ Ipv6Address prefixBis ("2001:ABCD::0"); /* create the prefix */
+ Ipv6Address prefix2 ("2001:2::0"); /* create the prefix */
+ uint32_t indexRouter = iic1.GetInterfaceIndex (1); /* R interface (n0 - R) */
+ uint32_t indexRouter2 = iic2.GetInterfaceIndex (1); /* R interface (R - n1) */
+ Ptr<Radvd> radvd = CreateObject<Radvd> ();
+ Ptr<RadvdInterface> routerInterface = Create<RadvdInterface> (indexRouter, 2000, 1000);
+ Ptr<RadvdPrefix> routerPrefix = Create<RadvdPrefix> (prefix, 64, 3, 5);
+ Ptr<RadvdPrefix> routerPrefixBis = Create<RadvdPrefix> (prefixBis, 64, 3, 5);
+ Ptr<RadvdInterface> routerInterface2 = Create<RadvdInterface> (indexRouter2, 2000, 1000);
+ Ptr<RadvdPrefix> routerPrefix2 = Create<RadvdPrefix> (prefix2, 64, 3, 5);
+
+ /* first interface advertise two prefixes (2001:1::/64 and 2001:ABCD::/64) */
+ /* prefix is added in the inverse order in packet */
+ routerInterface->AddPrefix (routerPrefix);
+ routerInterface->AddPrefix (routerPrefixBis);
+ routerInterface2->AddPrefix (routerPrefix2);
+ radvd->AddConfiguration (routerInterface);
+ radvd->AddConfiguration (routerInterface2);
+
+ r->AddApplication (radvd);
+ radvd->Start (Seconds (1.0));
+ radvd->Stop (Seconds (2.0));
+
+ /* Create a Ping6 application to send ICMPv6 echo request from n0 to n1 via R */
+ uint32_t packetSize = 1024;
+ uint32_t maxPacketCount = 8;
+ Time interPacketInterval = Seconds (1.);
+ Ping6Helper ping6;
+
+ /* ping6.SetLocal (iic1.GetAddress (0, 1)); */
+ ping6.SetRemote (Ipv6Address ("2001:2::200:ff:fe00:4")); /* should be n1 address after autoconfiguration */
+ ping6.SetIfIndex (iic1.GetInterfaceIndex (0));
+
+ ping6.SetAttribute ("MaxPackets", UintegerValue (maxPacketCount));
+ ping6.SetAttribute ("Interval", TimeValue (interPacketInterval));
+ ping6.SetAttribute ("PacketSize", UintegerValue (packetSize));
+ ApplicationContainer apps = ping6.Install (net1.Get (0));
+ apps.Start (Seconds (2.0));
+ apps.Stop (Seconds (9.0));
+
+ /* RA should be received, two prefixes + routes + default route should be present */
+ Simulator::Schedule (Seconds (2.0), &StackHelper::PrintRoutingTable, &stackHelper, n0);
+ /* at the end, RA addresses and routes should be cleared */
+ Simulator::Schedule (Seconds (10.0), &StackHelper::PrintRoutingTable, &stackHelper, n0);
+
+ std::ofstream ascii;
+ ascii.open ("radvd-two-prefix.tr");
+ CsmaHelper::EnablePcapAll (std::string ("radvd-two-prefix"), true);
+ CsmaHelper::EnableAsciiAll (ascii);
+
+ NS_LOG_INFO ("Run Simulation.");
+ Simulator::Run ();
+ Simulator::Destroy ();
+ NS_LOG_INFO ("Done.");
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/radvd.cc Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,156 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: David Gross <gdavid.devel@gmail.com>
+ * Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+// Network topology
+// //
+// // n0 R n1
+// // | _ |
+// // ====|_|====
+// // router
+// // - R sends RA to n0's subnet (2001:1::/64);
+// // - R sends RA to n1's subnet (2001:2::/64);
+// // - n0 ping6 n1.
+// //
+// // - Tracing of queues and packet receptions to file "radvd.tr"
+
+#include <fstream>
+#include "ns3/core-module.h"
+#include "ns3/simulator-module.h"
+#include "ns3/helper-module.h"
+
+#include "ns3/radvd.h"
+#include "ns3/radvd-interface.h"
+#include "ns3/radvd-prefix.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("RadvdExample");
+
+int main (int argc, char** argv)
+{
+#if 0
+ LogComponentEnable ("Ipv6L3Protocol", LOG_LEVEL_ALL);
+ LogComponentEnable ("Ipv6RawSocketImpl", LOG_LEVEL_ALL);
+ LogComponentEnable ("Icmpv6L4Protocol", LOG_LEVEL_ALL);
+ LogComponentEnable ("Ipv6StaticRouting", LOG_LEVEL_ALL);
+ LogComponentEnable ("Ipv6Interface", LOG_LEVEL_ALL);
+ LogComponentEnable ("RadvdApplication", LOG_LEVEL_ALL);
+ LogComponentEnable ("Ping6Application", LOG_LEVEL_ALL);
+#endif
+
+ CommandLine cmd;
+ cmd.Parse (argc, argv);
+
+ NS_LOG_INFO ("Create nodes.");
+ Ptr<Node> n0 = CreateObject<Node> ();
+ Ptr<Node> r = CreateObject<Node> ();
+ Ptr<Node> n1 = CreateObject<Node> ();
+
+ NodeContainer net1 (n0, r);
+ NodeContainer net2 (r, n1);
+ NodeContainer all (n0, r, n1);
+
+ NS_LOG_INFO ("Create IPv6 Internet Stack");
+ InternetStackHelper internetv6;
+ internetv6.Install (all);
+
+ NS_LOG_INFO ("Create channels.");
+ CsmaHelper csma;
+ csma.SetChannelAttribute ("DataRate", DataRateValue (5000000));
+ csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
+ NetDeviceContainer d1 = csma.Install (net1); /* n0 - R */
+ NetDeviceContainer d2 = csma.Install (net2); /* R - n1 */
+
+ NS_LOG_INFO ("Create networks and assign IPv6 Addresses.");
+ Ipv6AddressHelper ipv6;
+
+ /* first subnet */
+ ipv6.NewNetwork (Ipv6Address ("2001:1::"), 64);
+ NetDeviceContainer tmp;
+ tmp.Add (d1.Get (0)); /* n0 */
+ Ipv6InterfaceContainer iic1 = ipv6.AssignWithoutAddress (tmp); /* n0 interface */
+
+ NetDeviceContainer tmp2;
+ tmp2.Add (d1.Get (1)); /* R */
+ Ipv6InterfaceContainer iicr1 = ipv6.Assign (tmp2); /* R interface to the first subnet is just statically assigned */
+ iicr1.SetRouter (0, true);
+ iic1.Add (iicr1);
+
+ /* second subnet R - n1 */
+ ipv6.NewNetwork (Ipv6Address ("2001:2::"), 64);
+ NetDeviceContainer tmp3;
+ tmp3.Add (d2.Get (0)); /* R */
+ Ipv6InterfaceContainer iicr2 = ipv6.Assign (tmp3); /* R interface */
+ iicr2.SetRouter (0, true);
+
+ NetDeviceContainer tmp4;
+ tmp4.Add (d2.Get (1)); /* n1 */
+ Ipv6InterfaceContainer iic2 = ipv6.AssignWithoutAddress (tmp4);
+ iic2.Add (iicr2);
+
+ /* radvd configuration */
+ Ipv6Address prefix ("2001:1::0"); /* create the prefix */
+ Ipv6Address prefix2 ("2001:2::0"); /* create the prefix */
+ uint32_t indexRouter = iic1.GetInterfaceIndex (1); /* R interface (n0 - R) */
+ uint32_t indexRouter2 = iic2.GetInterfaceIndex (1); /* R interface (R - n1) */
+ Ptr<Radvd> radvd = CreateObject<Radvd> ();
+ Ptr<RadvdInterface> routerInterface = Create<RadvdInterface> (indexRouter, 5000, 1000);
+ Ptr<RadvdPrefix> routerPrefix = Create<RadvdPrefix> (prefix, 64, 3, 5);
+ Ptr<RadvdInterface> routerInterface2 = Create<RadvdInterface> (indexRouter2, 5000, 1000);
+ Ptr<RadvdPrefix> routerPrefix2 = Create<RadvdPrefix> (prefix2, 64, 3, 5);
+
+ routerInterface->AddPrefix (routerPrefix);
+ routerInterface2->AddPrefix (routerPrefix2);
+ radvd->AddConfiguration (routerInterface);
+ radvd->AddConfiguration (routerInterface2);
+
+ r->AddApplication (radvd);
+ radvd->Start (Seconds (1.0));
+ radvd->Stop (Seconds (10.0));
+
+ /* Create a Ping6 application to send ICMPv6 echo request from n0 to n1 via R */
+ uint32_t packetSize = 1024;
+ uint32_t maxPacketCount = 5;
+ Time interPacketInterval = Seconds (1.);
+ Ping6Helper ping6;
+
+ /* ping6.SetLocal (iic1.GetAddress (0, 1)); */
+ ping6.SetRemote (Ipv6Address ("2001:2::200:ff:fe00:4")); /* should be n1 address after autoconfiguration */
+ ping6.SetIfIndex (iic1.GetInterfaceIndex (0));
+
+ ping6.SetAttribute ("MaxPackets", UintegerValue (maxPacketCount));
+ ping6.SetAttribute ("Interval", TimeValue (interPacketInterval));
+ ping6.SetAttribute ("PacketSize", UintegerValue (packetSize));
+ ApplicationContainer apps = ping6.Install (net1.Get (0));
+ apps.Start (Seconds (2.0));
+ apps.Stop (Seconds (7.0));
+
+ std::ofstream ascii;
+ ascii.open ("radvd.tr");
+ CsmaHelper::EnablePcapAll (std::string ("radvd"), true);
+ CsmaHelper::EnableAsciiAll (ascii);
+
+ NS_LOG_INFO ("Run Simulation.");
+ Simulator::Run ();
+ Simulator::Destroy ();
+ NS_LOG_INFO ("Done.");
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/simple-routing-ping6.cc Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,110 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: David Gross <david.gross@eturs.u-strasbg.fr>
+ * Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+// Network topology
+// //
+// // n0 r n1
+// // | _ |
+// // ====|_|====
+// // router
+// //
+// // - Tracing of queues and packet receptions to file "simple-routing-ping6.tr"
+
+#include <fstream>
+#include "ns3/core-module.h"
+#include "ns3/simulator-module.h"
+#include "ns3/helper-module.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("SimpleRoutingUdp6Example");
+
+int
+main (int argc, char** argv)
+{
+#if 0
+ LogComponentEnable ("Ipv6L3Protocol", LOG_LEVEL_ALL);
+ LogComponentEnable ("Icmpv6L4Protocol", LOG_LEVEL_ALL);
+ LogComponentEnable ("Ipv6StaticRouting", LOG_LEVEL_ALL);
+ LogComponentEnable ("Ipv6Interface", LOG_LEVEL_ALL);
+ LogComponentEnable ("Ping6Application", LOG_LEVEL_ALL);
+#endif
+
+ CommandLine cmd;
+ cmd.Parse (argc, argv);
+
+ NS_LOG_INFO ("Create nodes.");
+ Ptr<Node> n0 = CreateObject<Node> ();
+ Ptr<Node> r = CreateObject<Node> ();
+ Ptr<Node> n1 = CreateObject<Node> ();
+
+ NodeContainer net1 (n0, r);
+ NodeContainer net2 (r, n1);
+ NodeContainer all (n0, r, n1);
+
+ NS_LOG_INFO ("Create IPv6 Internet Stack");
+ InternetStackHelper internetv6;
+ internetv6.Install (all);
+
+ NS_LOG_INFO ("Create channels.");
+ CsmaHelper csma;
+ csma.SetChannelAttribute ("DataRate", DataRateValue (5000000));
+ csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
+ NetDeviceContainer d1 = csma.Install (net1);
+ NetDeviceContainer d2 = csma.Install (net2);
+
+ NS_LOG_INFO ("Create networks and assign IPv6 Addresses.");
+ Ipv6AddressHelper ipv6;
+ ipv6.NewNetwork (Ipv6Address ("2001:1::"), 64);
+ Ipv6InterfaceContainer i1 = ipv6.Assign (d1);
+ i1.SetRouter (1, true);
+ ipv6.NewNetwork (Ipv6Address ("2001:2::"), 64);
+ Ipv6InterfaceContainer i2 = ipv6.Assign (d2);
+ i2.SetRouter (0, true);
+
+ /* Create a Ping6 application to send ICMPv6 echo request from n0 to n1 via r */
+ uint32_t packetSize = 1024;
+ uint32_t maxPacketCount = 5;
+ Time interPacketInterval = Seconds (1.);
+ Ping6Helper ping6;
+
+ ping6.SetLocal (i1.GetAddress (0, 1));
+ ping6.SetRemote (i2.GetAddress (1, 1));
+ /* ping6.SetRemote (Ipv6Address::GetAllNodesMulticast ()); */
+
+ ping6.SetAttribute ("MaxPackets", UintegerValue (maxPacketCount));
+ ping6.SetAttribute ("Interval", TimeValue (interPacketInterval));
+ ping6.SetAttribute ("PacketSize", UintegerValue (packetSize));
+ ApplicationContainer apps = ping6.Install (net1.Get (0));
+ apps.Start (Seconds (2.0));
+ apps.Stop (Seconds (20.0));
+
+ std::ofstream ascii;
+ ascii.open ("simple-routing-ping6.tr");
+ CsmaHelper::EnablePcapAll (std::string ("simple-routing-ping6"), true);
+ CsmaHelper::EnableAsciiAll (ascii);
+
+ NS_LOG_INFO ("Run Simulation.");
+ Simulator::Run ();
+ Simulator::Destroy ();
+ NS_LOG_INFO ("Done.");
+}
+
--- a/examples/static-routing-slash32.cc Tue Aug 25 20:12:53 2009 +0400
+++ b/examples/static-routing-slash32.cc Wed Aug 26 15:29:03 2009 +0400
@@ -87,12 +87,12 @@
int32_t ifIndexA = ipv4A->AddInterface (deviceA);
int32_t ifIndexC = ipv4C->AddInterface (deviceC);
- Ipv4InterfaceAddress ifInAddrA = Ipv4InterfaceAddress (Ipv4Address ("172.16.1.1"), Ipv4Mask ("255.255.255.255"));
+ Ipv4InterfaceAddress ifInAddrA = Ipv4InterfaceAddress (Ipv4Address ("172.16.1.1"), Ipv4Mask ("/32"));
ipv4A->AddAddress (ifIndexA, ifInAddrA);
ipv4A->SetMetric (ifIndexA, 1);
ipv4A->SetUp (ifIndexA);
- Ipv4InterfaceAddress ifInAddrC = Ipv4InterfaceAddress (Ipv4Address ("192.168.1.1"), Ipv4Mask ("255.255.255.255"));
+ Ipv4InterfaceAddress ifInAddrC = Ipv4InterfaceAddress (Ipv4Address ("192.168.1.1"), Ipv4Mask ("/32"));
ipv4C->AddAddress (ifIndexC, ifInAddrC);
ipv4C->SetMetric (ifIndexC, 1);
ipv4C->SetUp (ifIndexC);
--- a/examples/wifi-ap.cc Tue Aug 25 20:12:53 2009 +0400
+++ b/examples/wifi-ap.cc Wed Aug 26 15:29:03 2009 +0400
@@ -26,6 +26,7 @@
#include "ns3/mobility-module.h"
#include "ns3/contrib-module.h"
#include "ns3/wifi-module.h"
+#include "ns3/athstats-helper.h"
#include <iostream>
@@ -110,6 +111,9 @@
int main (int argc, char *argv[])
{
+ CommandLine cmd;
+ cmd.Parse (argc, argv);
+
Packet::EnablePrinting ();
// enable rts cts all the time.
@@ -175,6 +179,10 @@
Config::Connect ("/NodeList/*/DeviceList/*/Phy/State/RxError", MakeCallback (&PhyRxErrorTrace));
Config::Connect ("/NodeList/*/DeviceList/*/Phy/State/Tx", MakeCallback (&PhyTxTrace));
Config::Connect ("/NodeList/*/DeviceList/*/Phy/State/State", MakeCallback (&PhyStateTrace));
+
+ AthstatsHelper athstats;
+ athstats.EnableAthstats("athstats-sta", stas);
+ athstats.EnableAthstats("athstats-ap", ap);
Simulator::Run ();
--- a/examples/wscript Tue Aug 25 20:12:53 2009 +0400
+++ b/examples/wscript Wed Aug 26 15:29:03 2009 +0400
@@ -151,6 +151,26 @@
['point-to-point', 'internet-stack'])
obj.source = 'test-ipv6.cc'
+ obj = bld.create_ns3_program('ping6',
+ ['csma', 'internet-stack'])
+ obj.source = 'ping6.cc'
+
+ obj = bld.create_ns3_program('simple-routing-ping6',
+ ['csma', 'internet-stack'])
+ obj.source = 'simple-routing-ping6.cc'
+
+ obj = bld.create_ns3_program('icmpv6-redirect',
+ ['csma', 'internet-stack'])
+ obj.source = 'icmpv6-redirect.cc'
+
+ obj = bld.create_ns3_program('radvd',
+ ['csma', 'internet-stack'])
+ obj.source = 'radvd.cc'
+
+ obj = bld.create_ns3_program('radvd-two-prefix',
+ ['csma', 'internet-stack'])
+ obj.source = 'radvd-two-prefix.cc'
+
env = bld.env_of_name('default')
if env['ENABLE_EMU']:
obj = bld.create_ns3_program('emu-udp-echo', ['emu', 'internet-stack'])
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/ping6/ping6.cc Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,236 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#include "ns3/log.h"
+#include "ns3/nstime.h"
+#include "ns3/simulator.h"
+#include "ns3/socket-factory.h"
+#include "ns3/packet.h"
+#include "ns3/socket.h"
+#include "ns3/uinteger.h"
+#include "ns3/ipv6.h"
+#include "ns3/ipv6-address.h"
+#include "ns3/inet6-socket-address.h"
+#include "ns3/icmpv6-header.h"
+#include "ns3/ipv6-raw-socket-factory.h"
+#include "ns3/ipv6-header.h"
+
+#include "ping6.h"
+
+namespace ns3
+{
+
+NS_LOG_COMPONENT_DEFINE ("Ping6Application");
+
+NS_OBJECT_ENSURE_REGISTERED (Ping6);
+
+TypeId Ping6::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ping6")
+ .SetParent<Application>()
+ .AddConstructor<Ping6>()
+ .AddAttribute ("MaxPackets",
+ "The maximum number of packets the application will send",
+ UintegerValue (100),
+ MakeUintegerAccessor (&Ping6::m_count),
+ MakeUintegerChecker<uint32_t>())
+ .AddAttribute ("Interval",
+ "The time to wait between packets",
+ TimeValue (Seconds (1.0)),
+ MakeTimeAccessor (&Ping6::m_interval),
+ MakeTimeChecker ())
+ .AddAttribute ("RemoteIpv6",
+ "The Ipv6Address of the outbound packets",
+ Ipv6AddressValue (),
+ MakeIpv6AddressAccessor (&Ping6::m_peerAddress),
+ MakeIpv6AddressChecker ())
+ .AddAttribute ("LocalIpv6",
+ "Local Ipv6Address of the sender",
+ Ipv6AddressValue (),
+ MakeIpv6AddressAccessor (&Ping6::m_localAddress),
+ MakeIpv6AddressChecker ())
+ .AddAttribute ("PacketSize",
+ "Size of packets generated",
+ UintegerValue (100),
+ MakeUintegerAccessor (&Ping6::m_size),
+ MakeUintegerChecker<uint32_t>())
+ ;
+ return tid;
+}
+
+Ping6::Ping6 ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_sent = 0;
+ m_socket = 0;
+ m_seq = 0;
+ m_sendEvent = EventId ();
+}
+
+Ping6::~Ping6 ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_socket = 0;
+}
+
+void Ping6::DoDispose ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ Application::DoDispose ();
+}
+
+void Ping6::StartApplication ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ if (!m_socket)
+ {
+ TypeId tid = TypeId::LookupByName ("ns3::Ipv6RawSocketFactory");
+ m_socket = Socket::CreateSocket (GetNode (), tid);
+
+ NS_ASSERT (m_socket);
+
+ m_socket->Bind (Inet6SocketAddress (m_localAddress, 0));
+ m_socket->Connect (Inet6SocketAddress (m_peerAddress, 0));
+ m_socket->SetAttribute ("Protocol", UintegerValue (58)); /* ICMPv6 */
+ m_socket->SetRecvCallback (MakeCallback (&Ping6::HandleRead, this));
+ }
+
+ ScheduleTransmit (Seconds (0.));
+}
+
+void Ping6::SetLocal (Ipv6Address ipv6)
+{
+ NS_LOG_FUNCTION (this << ipv6);
+ m_localAddress = ipv6;
+}
+
+void Ping6::SetRemote (Ipv6Address ipv6)
+{
+ NS_LOG_FUNCTION (this << ipv6);
+ m_peerAddress = ipv6;
+}
+
+void Ping6::StopApplication ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ if (m_socket)
+ {
+ m_socket->SetRecvCallback (MakeNullCallback<void, Ptr<Socket> >());
+ }
+
+ Simulator::Cancel (m_sendEvent);
+}
+
+void Ping6::SetIfIndex (uint32_t ifIndex)
+{
+ m_ifIndex = ifIndex;
+}
+
+void Ping6::ScheduleTransmit (Time dt)
+{
+ NS_LOG_FUNCTION (this << dt);
+ m_sendEvent = Simulator::Schedule (dt, &Ping6::Send, this);
+}
+
+void Ping6::Send ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ NS_ASSERT (m_sendEvent.IsExpired ());
+ Ptr<Packet> p = 0;
+ uint8_t data[4];
+ Ipv6Address src;
+ Ptr<Ipv6> ipv6 = GetNode ()->GetObject<Ipv6> ();
+
+ if (m_ifIndex > 0)
+ {
+ /* hack to have ifIndex in Ipv6RawSocketImpl
+ * maybe add a SetIfIndex in Ipv6RawSocketImpl directly
+ */
+ src = GetNode ()->GetObject<Ipv6> ()->GetAddress (m_ifIndex, 0).GetAddress ();
+ }
+ else
+ {
+ src = m_localAddress;
+ }
+
+ data[0] = 0xDE;
+ data[1] = 0xAD;
+ data[2] = 0xBE;
+ data[3] = 0xEF;
+
+ p = Create<Packet>(data, sizeof (data));
+ Icmpv6Echo req (1);
+
+ req.SetId (0xBEEF);
+ req.SetSeq (m_seq);
+ m_seq++;
+
+ /* we do not calculate pseudo header checksum here, because we are not sure about
+ * source IPv6 address. Checksum is calculated in Ipv6RawSocketImpl.
+ */
+
+ p->AddHeader (req);
+ m_socket->Bind (Inet6SocketAddress (src, 0));
+ m_socket->Send (p, 0);
+ ++m_sent;
+
+ NS_LOG_INFO ("Sent " << p->GetSize () << " bytes to " << m_peerAddress);
+
+ if (m_sent < m_count)
+ {
+ ScheduleTransmit (m_interval);
+ }
+}
+
+void Ping6::HandleRead (Ptr<Socket> socket)
+{
+ NS_LOG_FUNCTION (this << socket);
+
+ Ptr<Packet> packet=0;
+ Address from;
+ while (packet = socket->RecvFrom (from))
+ {
+ if (Inet6SocketAddress::IsMatchingType (from))
+ {
+ Ipv6Header hdr;
+ Icmpv6Echo reply (0);
+ Inet6SocketAddress address = Inet6SocketAddress::ConvertFrom (from);
+
+ packet->RemoveHeader (hdr);
+
+ switch (*packet->PeekData ())
+ {
+ case Icmpv6Header::ICMPV6_ECHO_REPLY:
+ packet->RemoveHeader (reply);
+
+ NS_LOG_INFO ("Received Echo Reply size = " << std::dec << packet->GetSize () << " bytes from " << address.GetIpv6 () << " id = " << (uint16_t)reply.GetId () << " seq = " << (uint16_t)reply.GetSeq ());
+ break;
+ default:
+ /* other type, discard */
+ break;
+ }
+ }
+ }
+}
+
+} /* namespace ns3 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/ping6/ping6.h Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,171 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#ifndef PING6_H
+#define PING6_H
+
+#include "ns3/application.h"
+#include "ns3/event-id.h"
+#include "ns3/ptr.h"
+#include "ns3/ipv6-address.h"
+
+namespace ns3
+{
+
+class Packet;
+class Socket;
+
+/**
+ * \class Ping6
+ * \brief A ping6 application.
+ */
+class Ping6 : public Application
+{
+ public:
+ /**
+ * \brief Get the type ID.
+ * \return type ID
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Constructor.
+ */
+ Ping6 ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Ping6 ();
+
+ /**
+ * \brief Set the local address.
+ * \param ipv6 the local IPv6 address
+ */
+ void SetLocal (Ipv6Address ipv6);
+
+ /**
+ * \brief Set the remote peer.
+ * \param ipv6 IPv6 address of the peer
+ */
+ void SetRemote (Ipv6Address ipv6);
+
+ /**
+ * \brief Set the out interface index.
+ * This is to send to link-local (unicast or multicast) address
+ * when a node has multiple interfaces.
+ * \param ifIndex interface index
+ */
+ void SetIfIndex (uint32_t ifIndex);
+
+ protected:
+ /**
+ * \brief Dispose this object;
+ */
+ virtual void DoDispose ();
+
+ private:
+ /**
+ * \brief Start the application.
+ */
+ virtual void StartApplication ();
+
+ /**
+ * \brief Stop the application.
+ */
+ virtual void StopApplication ();
+
+ /**
+ * \brief Schedule sending a packet.
+ * \param dt interval between packet
+ */
+ void ScheduleTransmit (Time dt);
+
+ /**
+ * \brief Send a packet.
+ */
+ void Send ();
+
+ /**
+ * \brief Receive method.
+ * \param socket socket that receive a packet
+ */
+ void HandleRead (Ptr<Socket> socket);
+
+ /**
+ * \brief Peer IPv6 address.
+ */
+ Ipv6Address m_address;
+
+ /**
+ * \brief Number of "Echo request" packets that will be sent.
+ */
+ uint32_t m_count;
+
+ /**
+ * \brief Number of packets sent.
+ */
+ uint32_t m_sent;
+
+ /**
+ * \brief Size of the packet.
+ */
+ uint32_t m_size;
+
+ /**
+ * \brief Intervall between packets sent.
+ */
+ Time m_interval;
+
+ /**
+ * \brief Local address.
+ */
+ Ipv6Address m_localAddress;
+
+ /**
+ * \brief Peer address.
+ */
+ Ipv6Address m_peerAddress;
+
+ /**
+ * \brief Local socket.
+ */
+ Ptr<Socket> m_socket;
+
+ /**
+ * \brief Sequence number.
+ */
+ uint16_t m_seq;
+
+ /**
+ * \brief Event ID.
+ */
+ EventId m_sendEvent;
+
+ /**
+ * \brief Out interface (i.e. for link-local communication).
+ */
+ uint32_t m_ifIndex;
+};
+
+} /* namespace ns3 */
+
+#endif /* PING6_H */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/ping6/waf Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,1 @@
+exec "`dirname "$0"`"/../../../waf "$@"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/ping6/wscript Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,13 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+def build(bld):
+ module = bld.create_ns3_module('ping6', ['internet-stack'])
+ module.source = [
+ 'ping6.cc',
+ ]
+ headers = bld.new_task_gen('ns3header')
+ headers.module = 'ping6'
+ headers.source = [
+ 'ping6.h',
+ ]
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/radvd/radvd-interface.cc Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,292 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#include "radvd-interface.h"
+
+namespace ns3
+{
+
+RadvdInterface::RadvdInterface (uint32_t interface)
+ : m_interface (interface)
+{
+ /* initialize default value as specified in radvd.conf manpage */
+ m_sendAdvert = true;
+ m_maxRtrAdvInterval = 600000;
+ m_minRtrAdvInterval = (uint32_t)(double)(0.33 * m_maxRtrAdvInterval);
+ m_minDelayBetweenRAs = 3000;
+ m_managedFlag = false;
+ m_otherConfigFlag = false;
+ m_linkMtu = 0; /* 0 means not sending MTU option in RA */
+ m_reachableTime = 0; /* means unspecified for the router */
+ m_retransTimer = 0; /* means unspecified for the router */
+ m_curHopLimit = 64;
+ m_defaultLifeTime = 3 * m_maxRtrAdvInterval;
+ m_defaultPreference = 1;
+ m_sourceLLAddress = true;
+ m_homeAgentFlag = false;
+ m_homeAgentInfo = false;
+ m_homeAgentLifeTime = 0;
+ m_homeAgentPreference = 0;
+ m_mobRtrSupportFlag = false;
+ m_intervalOpt = false;
+}
+
+RadvdInterface::RadvdInterface (uint32_t interface, uint32_t maxRtrAdvInterval, uint32_t minRtrAdvInterval)
+ : m_interface (interface)
+{
+ NS_ASSERT (maxRtrAdvInterval > minRtrAdvInterval);
+ m_sendAdvert = true;
+ m_maxRtrAdvInterval = maxRtrAdvInterval;
+ m_minRtrAdvInterval = minRtrAdvInterval;
+ m_minDelayBetweenRAs = 3000;
+ m_managedFlag = false;
+ m_otherConfigFlag = false;
+ m_linkMtu = 0; /* 0 means not sending MTU option in RA */
+ m_reachableTime = 0; /* means unspecified for the router */
+ m_retransTimer = 0; /* means unspecified for the router */
+ m_curHopLimit = 64;
+ m_defaultLifeTime = 3 * m_maxRtrAdvInterval;
+ m_defaultPreference = 1;
+ m_sourceLLAddress = true;
+ m_homeAgentFlag = false;
+ m_homeAgentInfo = false;
+ m_homeAgentLifeTime = 0;
+ m_homeAgentPreference = 0;
+ m_mobRtrSupportFlag = false;
+ m_intervalOpt = false;
+}
+
+RadvdInterface::~RadvdInterface ()
+{
+ /* clear prefixes */
+ for (RadvdPrefixListI it = m_prefixes.begin () ; it != m_prefixes.end () ; ++it)
+ {
+ (*it) = 0;
+ }
+ m_prefixes.clear ();
+}
+
+void RadvdInterface::AddPrefix (Ptr<RadvdPrefix> routerPrefix)
+{
+ m_prefixes.push_back (routerPrefix);
+}
+
+
+uint32_t RadvdInterface::GetInterface () const
+{
+ return m_interface;
+}
+
+std::list<Ptr<RadvdPrefix> > RadvdInterface::GetPrefixes () const
+{
+ return m_prefixes;
+}
+
+bool RadvdInterface::IsSendAdvert () const
+{
+ return m_sendAdvert;
+}
+
+void RadvdInterface::SetSendAdvert (bool sendAdvert)
+{
+ m_sendAdvert = sendAdvert;
+}
+
+uint32_t RadvdInterface::GetMaxRtrAdvInterval () const
+{
+ return m_maxRtrAdvInterval;
+}
+
+void RadvdInterface::SetMaxRtrAdvInterval (uint32_t maxRtrAdvInterval)
+{
+ m_maxRtrAdvInterval = maxRtrAdvInterval;
+}
+
+uint32_t RadvdInterface::GetMinRtrAdvInterval () const
+{
+ return m_minRtrAdvInterval;
+}
+
+void RadvdInterface::SetMinRtrAdvInterval (uint32_t minRtrAdvInterval)
+{
+ m_minRtrAdvInterval = minRtrAdvInterval;
+}
+
+uint32_t RadvdInterface::GetMinDelayBetweenRAs () const
+{
+ return m_minDelayBetweenRAs;
+}
+
+void RadvdInterface::SetMinDelayBetweenRAs (uint32_t minDelayBetweenRAs)
+{
+ m_minDelayBetweenRAs = minDelayBetweenRAs;
+}
+
+bool RadvdInterface::IsManagedFlag () const
+{
+ return m_managedFlag;
+}
+
+void RadvdInterface::SetManagedFlag (bool managedFlag)
+{
+ m_managedFlag = managedFlag;
+}
+
+bool RadvdInterface::IsOtherConfigFlag () const
+{
+ return m_otherConfigFlag;
+}
+
+void RadvdInterface::SetOtherConfigFlag (bool otherConfigFlag)
+{
+ m_otherConfigFlag = otherConfigFlag;
+}
+
+uint32_t RadvdInterface::GetLinkMtu () const
+{
+ return m_linkMtu;
+}
+
+void RadvdInterface::SetLinkMtu (uint32_t linkMtu)
+{
+ m_linkMtu = linkMtu;
+}
+
+uint32_t RadvdInterface::GetReachableTime () const
+{
+ return m_reachableTime;
+}
+
+void RadvdInterface::SetReachableTime (uint32_t reachableTime)
+{
+ m_reachableTime = reachableTime;
+}
+
+uint32_t RadvdInterface::GetDefaultLifeTime () const
+{
+ return m_defaultLifeTime;
+}
+
+void RadvdInterface::SetDefaultLifeTime (uint32_t defaultLifeTime)
+{
+ m_defaultLifeTime = defaultLifeTime;
+}
+
+uint32_t RadvdInterface::GetRetransTimer () const
+{
+ return m_retransTimer;
+}
+
+void RadvdInterface::SetRetransTimer (uint32_t retransTimer)
+{
+ m_retransTimer = retransTimer;
+}
+
+uint8_t RadvdInterface::GetCurHopLimit () const
+{
+ return m_curHopLimit;
+}
+
+void RadvdInterface::SetCurHopLimit (uint8_t curHopLimit)
+{
+ m_curHopLimit = curHopLimit;
+}
+
+uint8_t RadvdInterface::GetDefaultPreference () const
+{
+ return m_defaultPreference;
+}
+
+void RadvdInterface::SetDefaultPreference (uint8_t defaultPreference)
+{
+ m_defaultPreference = defaultPreference;
+}
+
+bool RadvdInterface::IsSourceLLAddress () const
+{
+ return m_sourceLLAddress;
+}
+
+void RadvdInterface::SetSourceLLAddress (bool sourceLLAddress)
+{
+ m_sourceLLAddress = sourceLLAddress;
+}
+
+bool RadvdInterface::IsHomeAgentFlag () const
+{
+ return m_homeAgentFlag;
+}
+
+void RadvdInterface::SetHomeAgentFlag (bool homeAgentFlag)
+{
+ m_homeAgentFlag = homeAgentFlag;
+}
+
+bool RadvdInterface::IsHomeAgentInfo () const
+{
+ return m_homeAgentInfo;
+}
+
+void RadvdInterface::SetHomeAgentInfo (bool homeAgentInfo)
+{
+ m_homeAgentInfo = homeAgentInfo;
+}
+
+uint32_t RadvdInterface::GetHomeAgentLifeTime () const
+{
+ return m_homeAgentLifeTime;
+}
+
+void RadvdInterface::SetHomeAgentLifeTime (uint32_t homeAgentLifeTime)
+{
+ m_homeAgentLifeTime = homeAgentLifeTime;
+}
+
+uint32_t RadvdInterface::GetHomeAgentPreference () const
+{
+ return m_homeAgentPreference;
+}
+
+void RadvdInterface::SetHomeAgentPreference (uint32_t homeAgentPreference)
+{
+ m_homeAgentPreference = homeAgentPreference;
+}
+
+bool RadvdInterface::IsMobRtrSupportFlag () const
+{
+ return m_mobRtrSupportFlag;
+}
+
+void RadvdInterface::SetMobRtrSupportFlag (bool mobRtrSupportFlag)
+{
+ m_mobRtrSupportFlag = mobRtrSupportFlag;
+}
+
+bool RadvdInterface::IsIntervalOpt () const
+{
+ return m_intervalOpt;
+}
+
+void RadvdInterface::SetIntervalOpt (bool intervalOpt)
+{
+ m_intervalOpt = intervalOpt;
+}
+} /* namespace ns3 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/radvd/radvd-interface.h Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,420 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#ifndef RADVD_INTERFACE_H
+#define RADVD_INTERFACE_H
+
+#include <list>
+
+#include "radvd-prefix.h"
+
+namespace ns3
+{
+
+/**
+ * \class RadvdInterface
+ * \brief Radvd interface configuration.
+ */
+class RadvdInterface : public RefCountBase
+{
+ public:
+ /**
+ * \brief Constructor.
+ * \param interface interface index
+ */
+ RadvdInterface (uint32_t interface);
+
+ /**
+ * \brief Constructor.
+ * \param interface interface index
+ * \param maxRtrAdvInterval maximum RA interval (ms)
+ * \param minRtrAdvInterval minimum RA interval (ms)
+ */
+ RadvdInterface (uint32_t interface, uint32_t maxRtrAdvInterval, uint32_t minRtrAdvInterval);
+
+ /**
+ * \brief Destructor.
+ */
+ ~RadvdInterface ();
+
+ /**
+ * \brief Get interface index for this configuration.
+ * \return interface index
+ */
+ uint32_t GetInterface () const;
+
+ /**
+ * \brief Get list of prefixes advertised for this interface.
+ * \return list of IPv6 prefixes
+ */
+ std::list <Ptr<RadvdPrefix> > GetPrefixes () const;
+
+ /**
+ * \brief Add a prefix to advertise on interface.
+ * \param routerPrefix prefix to advertise
+ */
+ void AddPrefix (Ptr<RadvdPrefix> routerPrefix);
+
+ /**
+ * \brief Is send advert enabled (periodic RA and reply to RS) ?
+ * \return send advert flag
+ */
+ bool IsSendAdvert () const;
+
+ /**
+ * \brief Set send advert flag.
+ * \return sendAdvert value
+ */
+ void SetSendAdvert (bool sendAdvert);
+
+ /**
+ * \brief Get maximum RA interval.
+ * \return RA interval (ms)
+ */
+ uint32_t GetMaxRtrAdvInterval () const;
+
+ /**
+ * \brief Get maximum RA interval.
+ * \param maxRtrAdvInterval RA interval (ms)
+ */
+ void SetMaxRtrAdvInterval (uint32_t maxRtrAdvInterval);
+
+ /**
+ * \brief Get minimum RA interval
+ * \return RA interval (ms)
+ */
+ uint32_t GetMinRtrAdvInterval () const;
+
+ /**
+ * \brief Get minimum RA interval
+ * \param minRtrAdvInterval RA interval (ms).
+ */
+ void SetMinRtrAdvInterval (uint32_t minRtrAdvInterval);
+
+ /**
+ * \brief Get minimum delay between RAs.
+ * \return minimum delay (ms)
+ */
+ uint32_t GetMinDelayBetweenRAs () const;
+
+ /**
+ * \brief Set minimum delay between RAs.
+ * \param minDelayBetweenRAs minimum delay (ms)
+ */
+ void SetMinDelayBetweenRAs (uint32_t minDelayBetweenRAs);
+
+ /**
+ * \brief Is managed flag enabled ?
+ * \return managed flag
+ */
+ bool IsManagedFlag () const;
+
+ /**
+ * \brief Set managed flag
+ * \param managedFlag value
+ */
+ void SetManagedFlag (bool managedFlag);
+
+ /**
+ * \brief Is "other config" flag enabled ?
+ * \return other config flag
+ */
+ bool IsOtherConfigFlag () const;
+
+ /**
+ * \brief Set "other config" flag
+ * \param otherConfigFlag value
+ */
+ void SetOtherConfigFlag (bool otherConfigFlag);
+
+ /**
+ * \brief Get link MTU.
+ * \return link MTU
+ */
+ uint32_t GetLinkMtu () const;
+
+ /**
+ * \brief Set link MTU.
+ * \param linkMtu link MTU
+ */
+ void SetLinkMtu (uint32_t linkMtu);
+
+ /**
+ * \brief Get reachable time.
+ * \return reachable time
+ */
+ uint32_t GetReachableTime () const;
+
+ /**
+ * \brief Set reachable time.
+ * \param reachableTime reachable time
+ */
+ void SetReachableTime (uint32_t reachableTime);
+
+ /**
+ * \brief Get default lifetime.
+ * \return default lifetime
+ */
+ uint32_t GetDefaultLifeTime () const;
+
+ /**
+ * \brief Set default lifetime.
+ * \param defaultLifeTime default lifetime
+ */
+ void SetDefaultLifeTime (uint32_t defaultLifeTime);
+
+ /**
+ * \brief Get retransmission timer.
+ * \return retransmission timer
+ */
+ uint32_t GetRetransTimer () const;
+
+ /**
+ * \brief Set retransmission timer.
+ * \param retransTimer retransmission timer
+ */
+ void SetRetransTimer (uint32_t retransTimer);
+
+ /**
+ * \brief Get current hop limit.
+ * \return current hop limit for the link
+ */
+ uint8_t GetCurHopLimit () const;
+
+ /**
+ * \brief Set current hop limit.
+ * \param curHopLimit current hop limit for the link
+ */
+ void SetCurHopLimit (uint8_t curHopLimit);
+
+ /**
+ * \brief Get default preference.
+ * \return default preference
+ */
+ uint8_t GetDefaultPreference () const;
+
+ /**
+ * \brief Set default preference.
+ * \param defaultPreference default preference
+ */
+ void SetDefaultPreference (uint8_t defaultPreference);
+
+ /**
+ * \brief Is source LLA option should be included in RA ?
+ * \return true if source address is added in RA, false otherwise
+ */
+ bool IsSourceLLAddress () const;
+
+ /**
+ * \brief Set flag to add or not LLA to RA.
+ * \param sourceLLAddress value
+ */
+ void SetSourceLLAddress (bool sourceLLAddress);
+
+ /**
+ * \brief Is "home agent" flag enabled ?
+ * \return "home agent" flag
+ */
+ bool IsHomeAgentFlag () const;
+
+ /**
+ * \brief Set "home agent" flag.
+ * \param homeAgentFlag value
+ */
+ void SetHomeAgentFlag (bool homeAgentFlag);
+
+ /**
+ * \brief Is Home Agent Information option should be included in RA ?
+ * \return true if HA information option is added in RA, false otherwise
+ */
+ bool IsHomeAgentInfo () const;
+
+ /**
+ * \brief Set flag to add or not HA information option to RA.
+ * \param homeAgentFlag value
+ */
+ void SetHomeAgentInfo (bool homeAgentFlag);
+
+ /**
+ * \brief Get home agent lifetime.
+ * \return home agent lifetime
+ */
+ uint32_t GetHomeAgentLifeTime () const;
+
+ /**
+ * \brief Set home agent lifetime.
+ * \param homeAgentLifeTime home agent lifetime
+ */
+ void SetHomeAgentLifeTime (uint32_t homeAgentLifeTime);
+
+ /**
+ * \brief Get home agent preference.
+ * \return home agent preference
+ */
+ uint32_t GetHomeAgentPreference () const;
+
+ /**
+ * \brief Set home agent preference.
+ * \param homeAgentPreference home agent preference
+ */
+ void SetHomeAgentPreference (uint32_t homeAgentPreference);
+
+ /**
+ * \brief Is "mobile router support" flag enabled ?
+ * \return "mobile router support" flag
+ */
+ bool IsMobRtrSupportFlag () const;
+
+ /**
+ * \brief Set "mobile router support" flag.
+ * \param mobRtrSupportFlag value
+ */
+ void SetMobRtrSupportFlag (bool mobRtrSupportFlag);
+
+ /**
+ * \brief Is advertisement interval option should be included in RA ?
+ * \return true if advertisement interval option is added in RA, false otherwise
+ */
+ bool IsIntervalOpt () const;
+
+ /**
+ * \brief Set flag to add or not advertisement interval to RA.
+ * \param intervalOpt value
+ */
+ void SetIntervalOpt (bool intervalOpt);
+
+ private:
+ typedef std::list<Ptr<RadvdPrefix> > RadvdPrefixList;
+ typedef std::list<Ptr<RadvdPrefix> >::iterator RadvdPrefixListI;
+
+ /**
+ * \brief Interface to advertise RA.
+ */
+ uint32_t m_interface;
+
+ /**
+ * \brief List of prefixes to advertise.
+ */
+ RadvdPrefixList m_prefixes;
+
+ /**
+ * \brief Flag whether or not router sends periodic RA and respond to RS.
+ */
+ bool m_sendAdvert;
+
+ /**
+ * \brief Maximum RA interval in milliseconds.
+ */
+ uint32_t m_maxRtrAdvInterval;
+
+ /**
+ * \brief Minimum RA interval in milliseconds.
+ */
+ uint32_t m_minRtrAdvInterval;
+
+ /**
+ * \brief Minimum delay between RA in milliseconds.
+ */
+ uint32_t m_minDelayBetweenRAs;
+
+ /**
+ * \brief Managed flag. If true host use the stateful protocol for address autoconfiguration.
+ */
+ bool m_managedFlag;
+
+ /**
+ * \brief Other configuration flag. If true host use stateful protocol for other (non-address) information.
+ */
+ bool m_otherConfigFlag;
+
+ /**
+ * \brief Link MTU to use.
+ */
+ uint32_t m_linkMtu;
+
+ /**
+ * \brief Reachable time in milliseconds.
+ */
+ uint32_t m_reachableTime;
+
+ /**
+ * \brief Retransmission timer in milliseconds.
+ */
+ uint32_t m_retransTimer;
+
+ /**
+ * \brief Current hop limit (TTL).
+ */
+ uint32_t m_curHopLimit;
+
+ /**
+ * \brief Default life time in seconds.
+ */
+ uint32_t m_defaultLifeTime;
+
+ /**
+ * \brief Preference associated with default router.
+ * 0 = low
+ * 1 = medium
+ * 2 = high
+ */
+ uint8_t m_defaultPreference;
+
+ /**
+ * \brief Flag to add link-layer address in RA.
+ */
+ bool m_sourceLLAddress;
+
+ /**
+ * \brief Flag to add HA (home agent) flag in RA.
+ */
+ bool m_homeAgentFlag;
+
+ /**
+ * \brief Flag to add Home Agent Information option (Mobile IPv6).
+ * Currently not implemented.
+ */
+ bool m_homeAgentInfo;
+
+ /**
+ * \brief Home agent lifetime in seconds. Ignored if home agent info is not set.
+ */
+ uint32_t m_homeAgentLifeTime;
+
+ /**
+ * \brief Home agent preference. Ignored if home agent info is not set.
+ */
+ uint32_t m_homeAgentPreference;
+
+ /**
+ * \brief Flag for HA to signals it supports Mobile Router registrations (NEMO Basic).
+ */
+ bool m_mobRtrSupportFlag;
+
+ /**
+ * \brief Flag to add Advertisement Interval option in RA.
+ */
+ bool m_intervalOpt;
+};
+
+} /* namespace ns3 */
+
+#endif /* RADVD_INTERFACE_H */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/radvd/radvd-prefix.cc Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,112 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#include "radvd-prefix.h"
+
+namespace ns3
+{
+
+RadvdPrefix::RadvdPrefix (Ipv6Address network, uint8_t prefixLength, uint32_t preferredLifeTime, uint32_t validLifeTime, bool onLinkFlag, bool autonomousFlag, bool routerAddrFlag)
+ : m_network (network),
+ m_prefixLength (prefixLength),
+ m_preferredLifeTime (preferredLifeTime),
+ m_validLifeTime (validLifeTime),
+ m_onLinkFlag (onLinkFlag),
+ m_autonomousFlag (autonomousFlag),
+ m_routerAddrFlag (routerAddrFlag)
+{
+}
+
+RadvdPrefix::~RadvdPrefix ()
+{
+}
+
+Ipv6Address RadvdPrefix::GetNetwork () const
+{
+ return m_network;
+}
+
+void RadvdPrefix::SetNetwork (Ipv6Address network)
+{
+ m_network = network;
+}
+
+uint8_t RadvdPrefix::GetPrefixLength () const
+{
+ return m_prefixLength;
+}
+
+void RadvdPrefix::SetPrefixLength (uint8_t prefixLength)
+{
+ m_prefixLength = prefixLength;
+}
+
+uint32_t RadvdPrefix::GetValidLifeTime () const
+{
+ return m_validLifeTime;
+}
+
+void RadvdPrefix::SetValidLifeTime (uint32_t validLifeTime)
+{
+ m_validLifeTime = validLifeTime;
+}
+
+uint32_t RadvdPrefix::GetPreferredLifeTime () const
+{
+ return m_preferredLifeTime;
+}
+
+void RadvdPrefix::SetPreferredLifeTime (uint32_t preferredLifeTime)
+{
+ m_preferredLifeTime = preferredLifeTime;
+}
+
+bool RadvdPrefix::IsOnLinkFlag () const
+{
+ return m_onLinkFlag;
+}
+
+void RadvdPrefix::SetOnLinkFlag (bool onLinkFlag)
+{
+ m_onLinkFlag = onLinkFlag;
+}
+
+bool RadvdPrefix::IsAutonomousFlag () const
+{
+ return m_autonomousFlag;
+}
+
+void RadvdPrefix::SetAutonomousFlag (bool autonomousFlag)
+{
+ m_autonomousFlag = autonomousFlag;
+}
+
+bool RadvdPrefix::IsRouterAddrFlag () const
+{
+ return m_routerAddrFlag;
+}
+
+void RadvdPrefix::SetRouterAddrFlag (bool routerAddrFlag)
+{
+ m_routerAddrFlag = routerAddrFlag;
+}
+
+} /* namespace ns3 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/radvd/radvd-prefix.h Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,180 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#ifndef RADVD_PREFIX_H
+#define RADVD_PREFIX_H
+
+#include <stdint.h>
+
+#include "ns3/ipv6-address.h"
+
+namespace ns3
+{
+
+/**
+ * \class RadvdPrefix
+ * \brief Router prefix for radvd application.
+ */
+class RadvdPrefix : public RefCountBase
+{
+ public:
+ /**
+ * \brief Constructor.
+ * \param network network prefix advertised
+ * \param prefixLength prefix length ( 0 < x <= 128)
+ * \param preferredLifeTime preferred life time in seconds (default 7 days)
+ * \param validLifeTime valid life time in seconds (default 30 days)
+ * \param onLinkFlag on link flag
+ * \param autonomousFlag autonomous link flag
+ * \param routerAddrFlag router address flag (for Mobile IPv6)
+ */
+ RadvdPrefix (Ipv6Address network, uint8_t prefixLength, uint32_t preferredLifeTime = 604800, uint32_t validLifeTime = 2592000, bool onLinkFlag = true, bool autonomousFlag = true, bool routerAddrFlag = false);
+
+ /**
+ * \brief Destructor.
+ */
+ ~RadvdPrefix ();
+
+ /**
+ * \brief Get network prefix.
+ * \return network prefix
+ */
+ Ipv6Address GetNetwork () const;
+
+ /**
+ * \brief Set network prefix.
+ * \param network network prefix
+ */
+ void SetNetwork (Ipv6Address network);
+
+ /**
+ * \brief Get prefix length.
+ * \return prefix length
+ */
+ uint8_t GetPrefixLength () const;
+
+ /**
+ * \brief Set prefix length.
+ * \param prefixLength prefix length
+ */
+ void SetPrefixLength (uint8_t prefixLength);
+
+ /**
+ * \brief Get preferred lifetime.
+ * \return lifetime
+ */
+ uint32_t GetPreferredLifeTime () const;
+
+ /**
+ * \brief Set preferred lifetime.
+ * \param preferredLifeTime lifetime
+ */
+ void SetPreferredLifeTime (uint32_t preferredLifeTime);
+
+ /**
+ * \brief Get valid lifetime.
+ * \return lifetime
+ */
+ uint32_t GetValidLifeTime () const;
+
+ /**
+ * \brief Set valid lifetime.
+ * \param validLifeTime lifetime
+ */
+ void SetValidLifeTime (uint32_t validLifeTime);
+
+ /**
+ * \brief Is on-link flag ?
+ * \return true if on-link is activated, false otherwise
+ */
+ bool IsOnLinkFlag () const;
+
+ /**
+ * \brief Set on-link flag.
+ * \param onLinkFlag value
+ */
+ void SetOnLinkFlag (bool onLinkFlag);
+
+ /**
+ * \brief Is autonomous flag ?
+ * \return true if autonomous is activated, false otherwise
+ */
+ bool IsAutonomousFlag () const;
+
+ /**
+ * \brief Set autonomous flag.
+ * \param autonomousFlag value
+ */
+ void SetAutonomousFlag (bool autonomousFlag);
+
+ /**
+ * \brief Is router address flag ?
+ * \return true if router address is activated, false otherwise
+ */
+ bool IsRouterAddrFlag () const;
+
+ /**
+ * \brief Set router address flag.
+ * \param routerAddrFlag value
+ */
+ void SetRouterAddrFlag (bool routerAddrFlag);
+
+ private:
+ /**
+ * \brief Network prefix.
+ */
+ Ipv6Address m_network;
+
+ /**
+ * \brief Prefix length.
+ */
+ uint8_t m_prefixLength;
+
+ /**
+ * \brief Preferred time.
+ */
+ uint32_t m_preferredLifeTime;
+
+ /**
+ * \brief Valid time.
+ */
+ uint32_t m_validLifeTime;
+
+ /**
+ * \brief On link flag, indicates that this prefix can be used for on-link determination.
+ */
+ bool m_onLinkFlag;
+
+ /**
+ * \brief Autonomous flag, it is used for autonomous address configuration (RFC 2462).
+ */
+ bool m_autonomousFlag;
+
+ /**
+ * \brief Router address flag, indicates that router address is sent instead
+ * of network prefix as is required by Mobile IPv6.
+ */
+ bool m_routerAddrFlag;
+};
+
+} /* namespace ns3 */
+
+#endif /* RADVD_PREFIX_H */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/radvd/radvd.cc Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,273 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 Telecom Bretagne
+ * Copyright (c) 2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ * Mehdi Benamor <benamor.mehdi@ensi.rnu.tn>
+ */
+
+#include "ns3/log.h"
+#include "ns3/ipv6-address.h"
+#include "ns3/nstime.h"
+#include "ns3/simulator.h"
+#include "ns3/packet.h"
+#include "ns3/net-device.h"
+#include "ns3/uinteger.h"
+#include "ns3/random-variable.h"
+#include "ns3/inet6-socket-address.h"
+#include "ns3/ipv6.h"
+#include "ns3/ipv6-raw-socket-factory.h"
+#include "ns3/ipv6-header.h"
+#include "ns3/icmpv6-header.h"
+
+#include "radvd.h"
+
+namespace ns3
+{
+
+NS_LOG_COMPONENT_DEFINE ("RadvdApplication");
+
+NS_OBJECT_ENSURE_REGISTERED (Radvd);
+
+TypeId Radvd::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Radvd")
+ .SetParent<Application> ()
+ .AddConstructor<Radvd> ()
+ ;
+ return tid;
+}
+
+Radvd::Radvd ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+Radvd::~Radvd ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ for (RadvdInterfaceListI it = m_configurations.begin () ; it != m_configurations.end () ; ++it)
+ {
+ *it = 0;
+ }
+ m_configurations.clear ();
+ m_socket = 0;
+}
+
+void Radvd::DoDispose ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ Application::DoDispose ();
+}
+
+void Radvd::StartApplication ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ if (!m_socket)
+ {
+ TypeId tid = TypeId::LookupByName ("ns3::Ipv6RawSocketFactory");
+ m_socket = Socket::CreateSocket (GetNode (), tid);
+
+ NS_ASSERT (m_socket);
+
+/* m_socket->Bind (Inet6SocketAddress (m_localAddress, 0)); */
+/* m_socket->Connect (Inet6SocketAddress (Ipv6Address::GetAllNodesMulticast (), 0)); */
+ m_socket->SetAttribute ("Protocol", UintegerValue (58)); /* ICMPv6 */
+ m_socket->SetRecvCallback (MakeCallback (&Radvd::HandleRead, this));
+ }
+
+ for (RadvdInterfaceListCI it = m_configurations.begin () ; it != m_configurations.end () ; it++)
+ {
+ m_eventIds[(*it)->GetInterface ()] = EventId ();
+ ScheduleTransmit (Seconds (0.), (*it), m_eventIds[(*it)->GetInterface ()]);
+ }
+}
+
+void Radvd::StopApplication ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ if (m_socket)
+ {
+ m_socket->SetRecvCallback (MakeNullCallback<void, Ptr<Socket> > ());
+ }
+
+ for (EventIdMapI it = m_eventIds.begin () ; it != m_eventIds.end () ; ++it)
+ {
+ Simulator::Cancel ((*it).second);
+ }
+ m_eventIds.clear ();
+}
+
+void Radvd::AddConfiguration (Ptr<RadvdInterface> routerInterface)
+{
+ m_configurations.push_back (routerInterface);
+}
+
+void Radvd::ScheduleTransmit (Time dt, Ptr<RadvdInterface> config, EventId& eventId)
+{
+ NS_LOG_FUNCTION (this << dt);
+ eventId = Simulator::Schedule (dt, &Radvd::Send, this, config, Ipv6Address::GetAllNodesMulticast ());
+}
+
+void Radvd::Send (Ptr<RadvdInterface> config, Ipv6Address dst)
+{
+ NS_LOG_FUNCTION (this << dst);
+ NS_ASSERT (m_eventIds[config->GetInterface ()].IsExpired ());
+ Icmpv6RA raHdr;
+ Icmpv6OptionLinkLayerAddress llaHdr;
+ Icmpv6OptionMtu mtuHdr;
+ Icmpv6OptionPrefixInformation prefixHdr;
+
+ if (m_eventIds.size () == 0)
+ {
+ return;
+ }
+
+ std::list<Ptr<RadvdPrefix> > prefixes = config->GetPrefixes ();
+ Ptr<Packet> p = Create<Packet> ();
+ Ptr<Ipv6> ipv6 = GetNode ()->GetObject<Ipv6> ();
+
+ /* set RA header information */
+ raHdr.SetFlagM (config->IsManagedFlag ());
+ raHdr.SetFlagO (config->IsOtherConfigFlag ());
+ raHdr.SetFlagH (config->IsHomeAgentFlag ());
+ raHdr.SetCurHopLimit (config->GetCurHopLimit ());
+ raHdr.SetLifeTime (config->GetDefaultLifeTime ());
+ raHdr.SetReachableTime (config->GetReachableTime ());
+ raHdr.SetRetransmissionTime (config->GetRetransTimer ());
+
+ if (config->IsSourceLLAddress ())
+ {
+ /* Get L2 address from NetDevice */
+ Address addr = ipv6->GetNetDevice (config->GetInterface ())->GetAddress ();
+ llaHdr = Icmpv6OptionLinkLayerAddress (true, addr);
+ p->AddHeader (llaHdr);
+ }
+
+ if (config->GetLinkMtu ())
+ {
+ NS_ASSERT (config->GetLinkMtu () >= 1280);
+ mtuHdr = Icmpv6OptionMtu (config->GetLinkMtu ());
+ p->AddHeader (mtuHdr);
+ }
+
+ /* add list of prefixes */
+ for (std::list<Ptr<RadvdPrefix> >::const_iterator jt = prefixes.begin () ; jt != prefixes.end () ; jt++)
+ {
+ uint8_t flags = 0;
+ prefixHdr = Icmpv6OptionPrefixInformation ();
+ prefixHdr.SetPrefix ((*jt)->GetNetwork ());
+ prefixHdr.SetPrefixLength ((*jt)->GetPrefixLength ());
+ prefixHdr.SetValidTime ((*jt)->GetValidLifeTime ());
+ prefixHdr.SetPreferredTime ((*jt)->GetPreferredLifeTime ());
+
+ if ((*jt)->IsOnLinkFlag ())
+ {
+ flags += 1 << 7;
+ }
+
+ if ((*jt)->IsAutonomousFlag ())
+ {
+ flags += 1 << 6;
+ }
+
+ if ((*jt)->IsRouterAddrFlag ())
+ {
+ flags += 1 << 5;
+ }
+
+ prefixHdr.SetFlags (flags);
+
+ p->AddHeader (prefixHdr);
+ }
+
+ Ipv6Address src = ipv6->GetAddress (config->GetInterface (), 0).GetAddress ();
+ m_socket->Bind (Inet6SocketAddress (src, 0));
+ m_socket->Connect (Inet6SocketAddress (dst, 0));
+
+ /* as we know interface index that will be used to send RA and
+ * we always send RA with router's link-local address, we can
+ * calculate checksum here.
+ */
+ raHdr.CalculatePseudoHeaderChecksum (src, dst, p->GetSize () + raHdr.GetSerializedSize (), 58 /* ICMPv6 */);
+ p->AddHeader (raHdr);
+
+ /* send RA */
+ NS_LOG_LOGIC ("Send RA");
+ m_socket->Send (p, 0);
+
+ UniformVariable rnd;
+ uint64_t delay = static_cast<uint64_t> (rnd.GetValue (config->GetMinRtrAdvInterval (), config->GetMaxRtrAdvInterval ()) + 0.5);
+ Time t = MilliSeconds (delay);
+ ScheduleTransmit (t, config, m_eventIds[config->GetInterface ()]);
+}
+
+void Radvd::HandleRead (Ptr<Socket> socket)
+{
+ NS_LOG_FUNCTION (this << socket);
+ Ptr<Packet> packet = 0;
+ Address from;
+
+ while (packet = socket->RecvFrom (from))
+ {
+ if (Inet6SocketAddress::IsMatchingType (from))
+ {
+ Ipv6Header hdr;
+ Icmpv6RS rsHdr;
+ Inet6SocketAddress address = Inet6SocketAddress::ConvertFrom (from);
+ uint64_t delay = 0;
+ UniformVariable rnd;
+ Time t;
+
+ packet->RemoveHeader (hdr);
+
+ switch (*packet->PeekData ())
+ {
+ case Icmpv6Header::ICMPV6_ND_ROUTER_SOLICITATION:
+ /* send RA in response of a RS */
+ packet->RemoveHeader (rsHdr);
+ NS_LOG_INFO ("Received ICMPv6 Router Solicitation from " << hdr.GetSourceAddress () << " code = " << (uint32_t)rsHdr.GetCode ());
+
+ delay = static_cast<uint64_t> (rnd.GetValue (0, MAX_RA_DELAY_TIME) + 0.5);
+ t = Simulator::Now () + MilliSeconds (delay);
+
+#if 0
+ NS_LOG_INFO ("schedule new RA : " << t.GetTimeStep () << " next scheduled RA" << (int64_t)m_sendEvent.GetTs ());
+
+ if (t.GetTimeStep () < static_cast<int64_t> (m_sendEvent.GetTs ()))
+ {
+ /* send multicast RA */
+ /* maybe replace this by a unicast RA (it is a SHOULD in the RFC) */
+ NS_LOG_INFO ("Respond to RS");
+ /* XXX advertise just the prefix for the interface not all */
+ t = MilliSeconds (delay);
+ /* XXX schedule packet send */
+ /* ScheduleTransmit (t); */
+ }
+#endif
+ break;
+ default:
+ break;
+ }
+ }
+ }
+}
+
+} /* namespace ns3 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/radvd/radvd.h Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,135 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 Telecom Bretagne
+ * Copyright (c) 2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ * Mehdi Benamor <benamor.mehdi@ensi.rnu.tn>
+ */
+
+#ifndef RADVD_H
+#define RADVD_H
+
+#include <map>
+
+#include "ns3/application.h"
+#include "ns3/socket.h"
+
+#include "radvd-interface.h"
+
+namespace ns3
+{
+
+/**
+ * \class Radvd
+ * \brief Router advertisement daemon.
+ */
+class Radvd : public Application
+{
+ public:
+ /**
+ * \brief Get the type ID.
+ * \return type ID
+ */
+ static TypeId GetTypeId (void);
+
+ /**
+ * \brief Constructor.
+ */
+ Radvd ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Radvd ();
+
+ /**
+ * \brief Default value for maximum delay of RA (ms)
+ */
+ static const uint32_t MAX_RA_DELAY_TIME = 500;
+
+ /**
+ * \brief Add configuration for an interface;
+ * \param routerInterface configuration
+ */
+ void AddConfiguration (Ptr<RadvdInterface> routerInterface);
+
+ protected:
+ /**
+ * \brief Dispose the instance.
+ */
+ virtual void DoDispose ();
+
+ private:
+ typedef std::list<Ptr<RadvdInterface> > RadvdInterfaceList;
+ typedef std::list<Ptr<RadvdInterface> >::iterator RadvdInterfaceListI;
+ typedef std::list<Ptr<RadvdInterface> >::const_iterator RadvdInterfaceListCI;
+
+ typedef std::map<uint32_t, EventId> EventIdMap;
+ typedef std::map<uint32_t, EventId>::iterator EventIdMapI;
+ typedef std::map<uint32_t, EventId>::const_iterator EventIdMapCI;
+
+ /**
+ * \brief Start the application.
+ */
+ virtual void StartApplication ();
+
+ /**
+ * \brief Stop the application.
+ */
+ virtual void StopApplication ();
+
+ /**
+ * \brief Schedule sending a packet.
+ * \param dt interval between packet
+ * \param config interface configuration
+ * \param eventId event ID associated
+ */
+ void ScheduleTransmit (Time dt, Ptr<RadvdInterface> config, EventId& eventId);
+
+ /**
+ * \brief Send a packet.
+ * \param config interface configuration
+ * \param dst destination address (default ff02::1)
+ */
+ void Send (Ptr<RadvdInterface> config, Ipv6Address dst = Ipv6Address::GetAllNodesMulticast ());
+
+ /**
+ * \brief Handle received packet, especially router solicitation
+ * \param socket socket to read data from
+ */
+ void HandleRead (Ptr<Socket> socket);
+
+ /**
+ * \brief Raw socket to send RA.
+ */
+ Ptr<Socket> m_socket;
+
+ /**
+ * \brief List of configuration for interface.
+ */
+ RadvdInterfaceList m_configurations;
+
+ /**
+ * \brief Event ID map.
+ */
+ EventIdMap m_eventIds;
+};
+
+} /* namespace ns3 */
+
+#endif /* RADVD_H */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/radvd/wscript Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,17 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+def build(bld):
+ module = bld.create_ns3_module('radvd', ['internet-stack'])
+ module.source = [
+ 'radvd.cc',
+ 'radvd-interface.cc',
+ 'radvd-prefix.cc',
+ ]
+ headers = bld.new_task_gen('ns3header')
+ headers.module = 'radvd'
+ headers.source = [
+ 'radvd.h',
+ 'radvd-interface.h',
+ 'radvd-prefix.h',
+ ]
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/sgi-hashmap.h Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,38 @@
+/* This code snippet was ripped out of the gcc
+ * documentation and slightly modified to work
+ * with gcc 4.x
+ */
+#ifndef SGI_HASHMAP_H
+#define SGI_HASHMAP_H
+
+/* To use gcc extensions.
+ */
+#ifdef __GNUC__
+ #if __GNUC__ < 3
+ #include <hash_map.h>
+namespace sgi { using ::hash_map; }; // inherit globals
+ #else
+ #if __GNUC__ < 4
+ #include <ext/hash_map>
+ #if __GNUC_MINOR__ == 0
+namespace sgi = std; // GCC 3.0
+ #else
+namespace sgi = ::__gnu_cxx; // GCC 3.1 and later
+ #endif
+ #else // gcc 4.x and later
+ #if __GNUC_MINOR__ < 3
+ #include <ext/hash_map>
+namespace sgi = ::__gnu_cxx;
+ #else
+#undef __DEPRECATED
+ #include <backward/hash_map>
+namespace sgi = ::__gnu_cxx;
+ #endif
+ #endif
+ #endif
+#else // ... there are other compilers, right?
+namespace sgi = std;
+#endif
+
+
+#endif /* SGI_HASHMAP_H */
--- a/src/common/wscript Tue Aug 25 20:12:53 2009 +0400
+++ b/src/common/wscript Wed Aug 26 15:29:03 2009 +0400
@@ -37,4 +37,5 @@
'tag-buffer.h',
'packet-tag-list.h',
'ascii-writer.h',
+ 'sgi-hashmap.h',
]
--- a/src/core/random-variable.cc Tue Aug 25 20:12:53 2009 +0400
+++ b/src/core/random-variable.cc Wed Aug 26 15:29:03 2009 +0400
@@ -778,23 +778,19 @@
double m_bound; // Bound on value's difference from the mean (absolute value)
bool m_nextValid; // True if next valid
double m_next; // The algorithm produces two values at a time
- static bool m_static_nextValid;
- static double m_static_next;
};
-bool NormalVariableImpl::m_static_nextValid = false;
-double NormalVariableImpl::m_static_next;
const double NormalVariableImpl::INFINITE_VALUE = 1e307;
NormalVariableImpl::NormalVariableImpl()
: m_mean(0.0), m_variance(1.0), m_bound(INFINITE_VALUE), m_nextValid(false){}
-NormalVariableImpl::NormalVariableImpl(double m, double v, double b/*=INFINITE_VALUE*/)
+NormalVariableImpl::NormalVariableImpl(double m, double v, double b)
: m_mean(m), m_variance(v), m_bound(b), m_nextValid(false) { }
NormalVariableImpl::NormalVariableImpl(const NormalVariableImpl& c)
: RandomVariableBase(c), m_mean(c.m_mean), m_variance(c.m_variance),
- m_bound(c.m_bound) { }
+ m_bound(c.m_bound), m_nextValid(false) { }
double NormalVariableImpl::GetValue()
{
--- a/src/devices/wifi/wifi-mac-header.cc Tue Aug 25 20:12:53 2009 +0400
+++ b/src/devices/wifi/wifi-mac-header.cc Wed Aug 26 15:29:03 2009 +0400
@@ -896,9 +896,9 @@
void
WifiMacHeader::PrintFrameControl (std::ostream &os) const
{
- os << "ToDS=" << m_ctrlToDs << ", FromDS=" << m_ctrlFromDs
- << ", MoreFrag=" << m_ctrlMoreFrag << ", Retry=" << m_ctrlRetry
- << ", MoreData=" << m_ctrlMoreData
+ os << "ToDS=" << std::hex << (int) m_ctrlToDs << ", FromDS=" << std::hex << (int) m_ctrlFromDs
+ << ", MoreFrag=" << std::hex << (int) m_ctrlMoreFrag << ", Retry=" << std::hex << (int) m_ctrlRetry
+ << ", MoreData=" << std::hex << (int) m_ctrlMoreData << std::dec
;
}
@@ -935,7 +935,7 @@
PrintFrameControl (os);
os << " Duration/ID=" << m_duration << "us"
<< ", DA=" << m_addr1 << ", SA=" << m_addr2
- << ", BSSID=" << m_addr3 << ", FragNumber=" << m_seqFrag
+ << ", BSSID=" << m_addr3 << ", FragNumber=" << std::hex << (int) m_seqFrag << std::dec
<< ", SeqNumber=" << m_seqSeq;
break;
case WIFI_MAC_MGT_ACTION:
@@ -943,11 +943,11 @@
PrintFrameControl (os);
os << " Duration/ID=" << m_duration << "us"
<< "DA=" << m_addr1 << ", SA=" << m_addr2 << ", BSSID=" << m_addr3
- << ", FragNumber=" << m_seqFrag << ", SeqNumber=" << m_seqSeq;
+ << ", FragNumber=" << std::hex << (int) m_seqFrag << std::dec << ", SeqNumber=" << m_seqSeq;
case WIFI_MAC_MGT_MULTIHOP_ACTION:
os << " Duration/ID=" << m_duration << "us"
<< "RA=" << m_addr1 << ", TA=" << m_addr2 << ", DA=" << m_addr3
- << ", FragNumber=" << m_seqFrag << ", SeqNumber=" << m_seqSeq;
+ << ", FragNumber=" << std::hex << (int) m_seqFrag << std::dec << ", SeqNumber=" << m_seqSeq;
case WIFI_MAC_DATA:
PrintFrameControl (os);
os << " Duration/ID=" << m_duration << "us";
@@ -971,7 +971,7 @@
{
NS_FATAL_ERROR ("Impossible ToDs and FromDs flags combination");
}
- os << ", FragNumber=" << m_seqFrag
+ os << ", FragNumber=" << std::hex << (int) m_seqFrag << std::dec
<< ", SeqNumber=" << m_seqSeq;
break;
case WIFI_MAC_DATA_CFACK:
--- a/src/devices/wifi/wifi-remote-station-manager.cc Tue Aug 25 20:12:53 2009 +0400
+++ b/src/devices/wifi/wifi-remote-station-manager.cc Wed Aug 26 15:29:03 2009 +0400
@@ -159,6 +159,18 @@
WifiModeValue (),
MakeWifiModeAccessor (&WifiRemoteStationManager::m_nonUnicastMode),
MakeWifiModeChecker ())
+ .AddTraceSource ("MacTxRtsFailed",
+ "The transmission of a RTS by the MAC layer has failed",
+ MakeTraceSourceAccessor (&WifiRemoteStationManager::m_macTxRtsFailed))
+ .AddTraceSource ("MacTxDataFailed",
+ "The transmission of a data packet by the MAC layer has failed",
+ MakeTraceSourceAccessor (&WifiRemoteStationManager::m_macTxDataFailed))
+ .AddTraceSource ("MacTxFinalRtsFailed",
+ "The transmission of a RTS has exceeded the maximum number of attempts",
+ MakeTraceSourceAccessor (&WifiRemoteStationManager::m_macTxFinalRtsFailed))
+ .AddTraceSource ("MacTxFinalDataFailed",
+ "The transmission of a data packet has exceeded the maximum number of attempts",
+ MakeTraceSourceAccessor (&WifiRemoteStationManager::m_macTxFinalDataFailed))
;
return tid;
}
@@ -175,7 +187,7 @@
{
for (Stations::const_iterator i = m_stations.begin (); i != m_stations.end (); i++)
{
- delete (*i).second;
+ delete (*i);
}
m_stations.clear ();
delete m_nonUnicast;
@@ -237,14 +249,15 @@
}
for (Stations::const_iterator i = m_stations.begin (); i != m_stations.end (); i++)
{
- if ((*i).first == address)
+ if ((*i)->GetAddress () == address)
{
- return (*i).second;
+ return (*i);
}
}
WifiRemoteStation *station = CreateStation ();
+ station->SetAddress(address);
station->Reset ();
- m_stations.push_back (std::make_pair (address, station));
+ m_stations.push_back (station);
return station;
}
@@ -264,7 +277,7 @@
{
for (Stations::const_iterator i = m_stations.begin (); i != m_stations.end (); i++)
{
- delete i->second;
+ delete (*i);
}
m_stations.clear ();
m_basicModes.clear ();
@@ -318,6 +331,33 @@
return m_nonUnicastMode;
}
+
+void
+WifiRemoteStationManager::NotifyTxRtsFailed (Mac48Address address)
+{
+ m_macTxRtsFailed (address);
+}
+
+void
+WifiRemoteStationManager::NotifyTxDataFailed (Mac48Address address)
+{
+ m_macTxDataFailed (address);
+}
+
+void
+WifiRemoteStationManager::NotifyTxFinalRtsFailed (Mac48Address address)
+{
+ m_macTxFinalRtsFailed (address);
+}
+
+void
+WifiRemoteStationManager::NotifyTxFinalDataFailed (Mac48Address address)
+{
+ m_macTxFinalDataFailed (address);
+}
+
+
+
} // namespace ns3
/***************************************************************
@@ -564,6 +604,16 @@
{
return m_avgSlrc;
}
+void
+WifiRemoteStation::SetAddress(Mac48Address address)
+{
+ m_address = address;
+}
+Mac48Address
+WifiRemoteStation::GetAddress()
+{
+ return m_address;
+}
uint32_t
WifiRemoteStation::GetNSupportedModes (void) const
{
@@ -698,6 +748,7 @@
WifiRemoteStation::ReportRtsFailed (void)
{
m_ssrc++;
+ GetManager ()->NotifyTxRtsFailed (m_address);
DoReportRtsFailed ();
}
@@ -705,6 +756,7 @@
WifiRemoteStation::ReportDataFailed (void)
{
m_slrc++;
+ GetManager ()->NotifyTxDataFailed (m_address);
DoReportDataFailed ();
}
@@ -727,6 +779,7 @@
WifiRemoteStation::ReportFinalRtsFailed (void)
{
m_ssrc = 0;
+ GetManager ()->NotifyTxFinalRtsFailed (m_address);
DoReportFinalRtsFailed ();
}
@@ -734,6 +787,7 @@
WifiRemoteStation::ReportFinalDataFailed (void)
{
m_slrc = 0;
+ GetManager ()->NotifyTxFinalDataFailed (m_address);
DoReportFinalDataFailed ();
}
--- a/src/devices/wifi/wifi-remote-station-manager.h Tue Aug 25 20:12:53 2009 +0400
+++ b/src/devices/wifi/wifi-remote-station-manager.h Wed Aug 26 15:29:03 2009 +0400
@@ -88,7 +88,7 @@
friend class WifiRemoteStation;
virtual void DoDispose (void);
private:
- typedef std::vector <std::pair<Mac48Address, WifiRemoteStation *> > Stations;
+ typedef std::vector <WifiRemoteStation *> Stations;
virtual class WifiRemoteStation *CreateStation (void) = 0;
Stations m_stations;
WifiMode m_defaultTxMode;
@@ -100,6 +100,63 @@
uint32_t m_rtsCtsThreshold;
uint32_t m_fragmentationThreshold;
WifiMode m_nonUnicastMode;
+
+
+ /**
+ * Public method used to fire a MacTxRtsFailed trace.
+ * Implemented for encapsulation purposes.
+ */
+ void NotifyTxRtsFailed (Mac48Address address);
+
+ /**
+ * Public method used to fire a MacTxDataFailed trace.
+ * Implemented for encapsulation purposes.
+ */
+ void NotifyTxDataFailed (Mac48Address address);
+
+ /**
+ * Public method used to fire a MacTxFinalRtsFailed trace.
+ * Implemented for encapsulation purposes.
+ */
+ void NotifyTxFinalRtsFailed (Mac48Address address);
+
+ /**
+ * Public method used to fire a MacTxFinalDataFailed trace.
+ * Implemented for encapsulation purposes.
+ */
+ void NotifyTxFinalDataFailed (Mac48Address address);
+
+
+ /**
+ * The trace source fired when the transmission of a RTS has failed
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Mac48Address> m_macTxRtsFailed;
+
+ /**
+ * The trace source fired when the transmission of a data packet has failed
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Mac48Address> m_macTxDataFailed;
+
+ /**
+ * The trace source fired when the transmission of a RTS has
+ * exceeded the maximum number of attempts
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Mac48Address> m_macTxFinalRtsFailed;
+
+ /**
+ * The trace source fired when the transmission of a data packet has
+ * exceeded the maximum number of attempts
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Mac48Address> m_macTxFinalDataFailed;
+
};
} // namespace ns3
@@ -264,6 +321,18 @@
* \return exponentially weighted average SLRC, this is used by Airtime link metric of 802.11s
*/
double GetAvgSlrc () const;
+ /**
+ * set the address of the remote stationt represented by this instance of WifiRemoteStation
+ *
+ * @param address the MAC address of the remote station
+ */
+ void SetAddress(Mac48Address address);
+ /**
+ * get the address of the remote stationt represented by this instance of WifiRemoteStation
+ *
+ * @return the MAC address of the remote station
+ */
+ Mac48Address GetAddress();
private:
virtual Ptr<WifiRemoteStationManager> GetManager (void) const = 0;
virtual WifiMode DoGetDataMode (uint32_t size) = 0;
@@ -294,6 +363,7 @@
TracedValue<uint32_t> m_slrc;
double m_avgSlrcCoefficient;
double m_avgSlrc;
+ Mac48Address m_address;
};
} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/athstats-helper.cc Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,309 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#include "ns3/log.h"
+#include "ns3/assert.h"
+#include "ns3/abort.h"
+#include "ns3/simulator.h"
+#include "ns3/nstime.h"
+#include "ns3/config.h"
+#include "athstats-helper.h"
+#include <iomanip>
+#include <iostream>
+#include <fstream>
+
+
+NS_LOG_COMPONENT_DEFINE("Athstats");
+
+namespace ns3 {
+
+
+AthstatsHelper::AthstatsHelper ()
+ : m_interval (Seconds (1.0))
+{
+}
+
+void
+AthstatsHelper::EnableAthstats (std::string filename, uint32_t nodeid, uint32_t deviceid)
+{
+ Ptr<AthstatsWifiTraceSink> athstats = CreateObject<AthstatsWifiTraceSink> ();
+ std::ostringstream oss;
+ oss << filename
+ << "_" << std::setfill ('0') << std::setw (3) << std::right << nodeid
+ << "_" << std::setfill ('0') << std::setw (3) << std::right << deviceid;
+ athstats->Open (oss.str ());
+
+ oss.str ("");
+ oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid;
+ std::string devicepath = oss.str ();
+
+ Config::Connect (devicepath + "/Mac/MacTx", MakeCallback (&AthstatsWifiTraceSink::DevTxTrace, athstats));
+ Config::Connect (devicepath + "/Mac/MacRx", MakeCallback (&AthstatsWifiTraceSink::DevRxTrace, athstats));
+
+ Config::Connect (devicepath + "/RemoteStationManager/TxRtsFailed", MakeCallback (&AthstatsWifiTraceSink::TxRtsFailedTrace, athstats));
+ Config::Connect (devicepath + "/RemoteStationManager/MacTxDataFailed", MakeCallback (&AthstatsWifiTraceSink::TxDataFailedTrace, athstats));
+ Config::Connect (devicepath + "/RemoteStationManager/MacTxFinalRtsFailed", MakeCallback (&AthstatsWifiTraceSink::TxFinalRtsFailedTrace, athstats));
+ Config::Connect (devicepath + "/RemoteStationManager/MacTxFinalDataFailed", MakeCallback (&AthstatsWifiTraceSink::TxFinalDataFailedTrace, athstats));
+
+ Config::Connect (devicepath + "/Phy/State/RxOk", MakeCallback (&AthstatsWifiTraceSink::PhyRxOkTrace, athstats));
+ Config::Connect (devicepath + "/Phy/State/RxError", MakeCallback (&AthstatsWifiTraceSink::PhyRxErrorTrace, athstats));
+ Config::Connect (devicepath + "/Phy/State/Tx", MakeCallback (&AthstatsWifiTraceSink::PhyTxTrace, athstats));
+ Config::Connect (devicepath + "/Phy/State/State", MakeCallback (&AthstatsWifiTraceSink::PhyStateTrace, athstats));
+}
+
+void
+AthstatsHelper::EnableAthstats (std::string filename, Ptr<NetDevice> nd)
+{
+ EnableAthstats (filename, nd->GetNode ()->GetId (), nd->GetIfIndex ());
+}
+
+
+void
+AthstatsHelper::EnableAthstats (std::string filename, NetDeviceContainer d)
+{
+ for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i)
+ {
+ Ptr<NetDevice> dev = *i;
+ EnableAthstats (filename, dev->GetNode ()->GetId (), dev->GetIfIndex ());
+ }
+}
+
+
+void
+AthstatsHelper::EnableAthstats (std::string filename, NodeContainer n)
+{
+ NetDeviceContainer devs;
+ for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
+ {
+ Ptr<Node> node = *i;
+ for (uint32_t j = 0; j < node->GetNDevices (); ++j)
+ {
+ devs.Add (node->GetDevice (j));
+ }
+ }
+ EnableAthstats (filename, devs);
+}
+
+
+
+
+
+NS_OBJECT_ENSURE_REGISTERED (AthstatsWifiTraceSink);
+
+TypeId
+AthstatsWifiTraceSink::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::AthstatsWifiTraceSink")
+ .SetParent<Object> ()
+ .AddConstructor<AthstatsWifiTraceSink> ()
+ .AddAttribute ("Interval",
+ "Time interval between reports",
+ TimeValue (Seconds(1.0)),
+ MakeTimeAccessor (&AthstatsWifiTraceSink::m_interval),
+ MakeTimeChecker ())
+ ;
+ return tid;
+}
+
+AthstatsWifiTraceSink::AthstatsWifiTraceSink ()
+ : m_txCount (0),
+ m_rxCount (0),
+ m_shortRetryCount (0),
+ m_longRetryCount (0),
+ m_exceededRetryCount (0),
+ m_phyRxOkCount (0),
+ m_phyRxErrorCount (0),
+ m_phyTxCount (0),
+ m_writer (0)
+{
+ Simulator::ScheduleNow (&AthstatsWifiTraceSink::WriteStats, this);
+}
+
+AthstatsWifiTraceSink::~AthstatsWifiTraceSink ()
+{
+ NS_LOG_FUNCTION (this);
+
+ if (m_writer != 0)
+ {
+ NS_LOG_LOGIC ("m_writer nonzero " << m_writer);
+ if (m_writer->is_open ())
+ {
+ NS_LOG_LOGIC ("m_writer open. Closing " << m_writer);
+ m_writer->close ();
+ }
+
+ NS_LOG_LOGIC ("Deleting writer " << m_writer);
+ delete m_writer;
+
+ NS_LOG_LOGIC ("m_writer = 0");
+ m_writer = 0;
+ }
+ else
+ {
+ NS_LOG_LOGIC ("m_writer == 0");
+ }
+}
+
+void
+AthstatsWifiTraceSink::ResetCounters ()
+{
+ m_txCount = 0;
+ m_rxCount = 0;
+ m_shortRetryCount = 0;
+ m_longRetryCount = 0;
+ m_exceededRetryCount = 0;
+ m_phyRxOkCount = 0;
+ m_phyRxErrorCount = 0;
+ m_phyTxCount = 0;
+}
+
+void
+AthstatsWifiTraceSink::DevTxTrace (std::string context, Ptr<const Packet> p)
+{
+ NS_LOG_FUNCTION (this << context <<p);
+ ++m_txCount;
+}
+
+void
+AthstatsWifiTraceSink::DevRxTrace (std::string context, Ptr<const Packet> p)
+{
+ NS_LOG_FUNCTION (this << context <<p);
+ ++m_rxCount;
+}
+
+
+void
+AthstatsWifiTraceSink::TxRtsFailedTrace (std::string context, Mac48Address address)
+{
+ NS_LOG_FUNCTION (this << context << address);
+ ++m_shortRetryCount;
+}
+
+void
+AthstatsWifiTraceSink::TxDataFailedTrace (std::string context, Mac48Address address)
+{
+ NS_LOG_FUNCTION (this << context << address);
+ ++m_longRetryCount;
+}
+
+void
+AthstatsWifiTraceSink::TxFinalRtsFailedTrace (std::string context, Mac48Address address)
+{
+ NS_LOG_FUNCTION (this << context << address);
+ ++m_exceededRetryCount;
+}
+
+void
+AthstatsWifiTraceSink::TxFinalDataFailedTrace (std::string context, Mac48Address address)
+{
+ NS_LOG_FUNCTION (this << context << address);
+ ++m_exceededRetryCount;
+}
+
+
+
+void
+AthstatsWifiTraceSink::PhyRxOkTrace (std::string context, Ptr<const Packet> packet, double snr, WifiMode mode, enum WifiPreamble preamble)
+{
+ NS_LOG_FUNCTION (this << context <<packet<< " mode=" << mode << " snr=" << snr );
+ ++m_phyRxOkCount;
+}
+
+void
+AthstatsWifiTraceSink::PhyRxErrorTrace (std::string context, Ptr<const Packet> packet, double snr)
+{
+ NS_LOG_FUNCTION (this << context <<packet <<" snr=" << snr );
+ ++m_phyRxErrorCount;
+}
+
+void
+AthstatsWifiTraceSink::PhyTxTrace (std::string context, Ptr<const Packet> packet, WifiMode mode, WifiPreamble preamble, uint8_t txPower)
+{
+ NS_LOG_FUNCTION (this << context << packet << "PHYTX mode=" << mode );
+ ++m_phyTxCount;
+}
+
+
+void
+AthstatsWifiTraceSink::PhyStateTrace (std::string context, Time start, Time duration, enum WifiPhy::State state)
+{
+ NS_LOG_FUNCTION (this << context << start << duration << state);
+
+}
+
+
+
+void
+AthstatsWifiTraceSink::Open (std::string const &name)
+{
+ NS_LOG_FUNCTION (this << name);
+ NS_ABORT_MSG_UNLESS (m_writer == 0, "AthstatsWifiTraceSink::Open (): m_writer already allocated (std::ofstream leak detected)");
+
+ m_writer = new std::ofstream ();
+ NS_ABORT_MSG_UNLESS (m_writer, "AthstatsWifiTraceSink::Open (): Cannot allocate m_writer");
+
+ NS_LOG_LOGIC ("Created writer " << m_writer);
+
+ m_writer->open (name.c_str (), std::ios_base::binary | std::ios_base::out);
+ NS_ABORT_MSG_IF (m_writer->fail (), "AthstatsWifiTraceSink::Open (): m_writer->open (" << name.c_str () << ") failed");
+
+ NS_ASSERT_MSG (m_writer->is_open (), "AthstatsWifiTraceSink::Open (): m_writer not open");
+
+ NS_LOG_LOGIC ("Writer opened successfully");
+}
+
+
+void
+AthstatsWifiTraceSink::WriteStats ()
+{
+ NS_ABORT_MSG_UNLESS (this, "function called with null this pointer, now=" << Now () );
+ // the comments below refer to how each value maps to madwifi's athstats
+ // I know C strings are ugly but that's the quickest way to use exactly the same format as in madwifi
+ char str[200];
+ snprintf (str, 200, "%8u %8u %7u %7u %7u %6u %6u %6u %7u %4u %3uM\n",
+ m_txCount, // /proc/net/dev transmitted packets to which we should subract mgmt frames
+ m_rxCount, // /proc/net/dev received packets but subracts mgmt frames from it
+ 0, // ast_tx_altrate,
+ m_shortRetryCount, // ast_tx_shortretry,
+ m_longRetryCount, // ast_tx_longretry,
+ m_exceededRetryCount, // ast_tx_xretries,
+ m_phyRxErrorCount, // ast_rx_crcerr,
+ 0, // ast_rx_badcrypt,
+ 0, // ast_rx_phyerr,
+ 0, // ast_rx_rssi,
+ 0 // rate
+ );
+
+ if (m_writer)
+ {
+
+ *m_writer << str;
+
+ ResetCounters ();
+ Simulator::Schedule (m_interval, &AthstatsWifiTraceSink::WriteStats, this);
+ }
+}
+
+
+
+
+} // namespace ns3
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/athstats-helper.h Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,226 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 CTTC
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#ifndef ATHSTATS_HELPER_H
+#define ATHSTATS_HELPER_H
+
+#include<string>
+#include "ns3/object.h"
+#include "ns3/attribute.h"
+#include "ns3/object-factory.h"
+#include "ns3/node-container.h"
+#include "ns3/net-device-container.h"
+#include "ns3/nstime.h"
+#include "ns3/wifi-phy.h"
+#include "ns3/double.h"
+#include "ns3/mac48-address.h"
+
+namespace ns3 {
+
+
+class NetDevice;
+
+/**
+ * @brief create AthstatsWifiTraceSink instances and connect them to wifi devices
+ *
+ *
+ */
+class AthstatsHelper
+{
+public:
+ AthstatsHelper ();
+ void EnableAthstats (std::string filename, uint32_t nodeid, uint32_t deviceid);
+ void EnableAthstats (std::string filename, Ptr<NetDevice> nd);
+ void EnableAthstats (std::string filename, NetDeviceContainer d);
+ void EnableAthstats (std::string filename, NodeContainer n);
+
+private:
+ Time m_interval;
+};
+
+
+
+
+/**
+ * @brief trace sink for wifi device that mimics madwifi's athstats tool.
+ *
+ * The AthstatsWifiTraceSink class is a trace sink to be connected to several of the traces
+ * available within a wifi device. The purpose of AthstatsWifiTraceSink is to
+ * mimic the behavior of the athstats tool distributed wih the madwifi
+ * driver. In particular, the reproduced behavior is that obtained
+ * when executing athstats without parameters: a report written in
+ * text format is produced every fixed interval, based on the events
+ * observed by the wifi device.
+ *
+ * Differences with the "real" athstats:
+ *
+ * - AthstatsWifiTraceSink is expected to write its output to a file
+ * (not to stdout).
+ *
+ * - only a subset of the metrics supported by athstats is supported
+ * by AthstatsWifiTraceSink
+ *
+ * - AthstatsWifiTraceSink does never produce a cumulative report.
+ */
+class AthstatsWifiTraceSink : public Object
+{
+public:
+ static TypeId GetTypeId (void);
+ AthstatsWifiTraceSink ();
+ virtual ~AthstatsWifiTraceSink ();
+
+
+ /**
+ * function to be called when the net device transmittes a packet
+ *
+ * @param context
+ * @param p the packet being transmitted
+ */
+ void DevTxTrace (std::string context, Ptr<const Packet> p);
+
+ /**
+ * function to be called when the net device receives a packet
+ *
+ * @param context
+ * @param p the packet being received
+ */
+ void DevRxTrace (std::string context, Ptr<const Packet> p);
+
+ /**
+ * Function to be called when a RTS frame transmission by the considered
+ * device has failed
+ *
+ * @param context
+ * @param address the MAC address of the remote station
+ */
+ void TxRtsFailedTrace (std::string context, Mac48Address address);
+
+ /**
+ * Function to be called when a data frame transmission by the considered
+ * device has failed
+ *
+ * @param context
+ * @param address the MAC address of the remote station
+ */
+ void TxDataFailedTrace (std::string context, Mac48Address address);
+
+ /**
+ * Function to be called when the transmission of a RTS frame has
+ * exceeded the retry limit
+ *
+ * @param context
+ * @param address the MAC address of the remote station
+ */
+ void TxFinalRtsFailedTrace (std::string context, Mac48Address address);
+
+ /**
+ * Function to be called when the transmission of a data frame has
+ * exceeded the retry limit
+ *
+ * @param context
+ * @param address the MAC address of the remote station
+ */
+ void TxFinalDataFailedTrace (std::string context, Mac48Address address);
+
+
+ /**
+ * Function to be called when the PHY layer of the considered
+ * device receives a frame
+ *
+ * @param context
+ * @param packet
+ * @param snr
+ * @param mode
+ * @param preamble
+ */
+ void PhyRxOkTrace (std::string context, Ptr<const Packet> packet, double snr, WifiMode mode, enum WifiPreamble preamble);
+
+ /**
+ * Function to be called when a frame reception by the PHY
+ * layer of the considered device resulted in an error due to a failure in the CRC check of
+ * the frame
+ *
+ * @param context
+ * @param packet
+ * @param snr
+ */
+ void PhyRxErrorTrace (std::string context, Ptr<const Packet> packet, double snr);
+
+ /**
+ * Function to be called when a frame is being transmitted by the
+ * PHY layer of the considered device
+ *
+ * @param context
+ * @param packet
+ * @param mode
+ * @param preamble
+ * @param txPower
+ */
+ void PhyTxTrace (std::string context, Ptr<const Packet> packet, WifiMode mode, WifiPreamble preamble, uint8_t txPower);
+
+ /**
+ * Function to be called when the PHY layer of the considered device
+ * changes state
+ *
+ * @param context
+ * @param start
+ * @param duration
+ * @param state
+ */
+ void PhyStateTrace (std::string context, Time start, Time duration, enum WifiPhy::State state);
+
+ /**
+ * Open a file for output
+ *
+ * @param name the name of the file to be opened.
+ */
+ void Open (std::string const& name);
+
+private:
+
+ void WriteStats ();
+ void ResetCounters ();
+
+
+ uint32_t m_txCount;
+ uint32_t m_rxCount;
+ uint32_t m_shortRetryCount;
+ uint32_t m_longRetryCount;
+ uint32_t m_exceededRetryCount;
+ uint32_t m_phyRxOkCount;
+ uint32_t m_phyRxErrorCount;
+ uint32_t m_phyTxCount;
+
+ std::ofstream *m_writer;
+
+ Time m_interval;
+
+
+}; // class AthstatsWifiTraceSink
+
+
+
+
+} // namespace ns3
+
+
+
+
+#endif /* ATHSTATS_HELPER_H */
--- a/src/helper/internet-stack-helper.cc Tue Aug 25 20:12:53 2009 +0400
+++ b/src/helper/internet-stack-helper.cc Wed Aug 26 15:29:03 2009 +0400
@@ -153,6 +153,7 @@
#include "ns3/object.h"
#include "ns3/names.h"
#include "ns3/ipv4.h"
+#include "ns3/ipv6.h"
#include "ns3/packet-socket-factory.h"
#include "ns3/config.h"
#include "ns3/simulator.h"
@@ -167,6 +168,8 @@
#include "ipv4-list-routing-helper.h"
#include "ipv4-static-routing-helper.h"
#include "ipv4-global-routing-helper.h"
+#include "ipv6-list-routing-helper.h"
+#include "ipv6-static-routing-helper.h"
#include <limits>
namespace ns3 {
@@ -176,19 +179,28 @@
bool InternetStackHelper::m_isInitialized = false;
InternetStackHelper::InternetStackHelper ()
+ : m_ipv4Enabled (true),
+ m_ipv6Enabled (true)
{
SetTcp ("ns3::TcpL4Protocol");
static Ipv4StaticRoutingHelper staticRouting;
static Ipv4GlobalRoutingHelper globalRouting;
static Ipv4ListRoutingHelper listRouting;
+ static Ipv6ListRoutingHelper listRoutingv6;
+ static Ipv6StaticRoutingHelper staticRoutingv6;
if (m_isInitialized == false)
{
// Only add these once
listRouting.Add (staticRouting, 0);
listRouting.Add (globalRouting, -10);
+
+ /* IPv6 */
+ listRoutingv6.Add (staticRoutingv6, 0);
+ /* TODO add IPv6 global routing */
m_isInitialized = true;
}
SetRoutingHelper (listRouting);
+ SetRoutingHelper (listRoutingv6);
}
void
@@ -198,9 +210,26 @@
}
void
+InternetStackHelper::SetRoutingHelper (const Ipv6RoutingHelper &routing)
+{
+ m_routingv6 = &routing;
+}
+
+void
+InternetStackHelper::SetIpv4StackInstall (bool enable)
+{
+ m_ipv4Enabled = enable;
+}
+
+void InternetStackHelper::SetIpv6StackInstall (bool enable)
+{
+ m_ipv6Enabled = enable;
+}
+
+void
InternetStackHelper::Cleanup (void)
{
- uint32_t illegal = std::numeric_limits<uint32_t>::max();
+ uint32_t illegal = std::numeric_limits<uint32_t>::max ();
for (std::vector<Trace>::iterator i = m_traces.begin ();
i != m_traces.end (); i++)
@@ -244,7 +273,7 @@
InternetStackHelper::CreateAndAggregateObjectFromTypeId (Ptr<Node> node, const std::string typeId)
{
ObjectFactory factory;
- factory.SetTypeId(typeId);
+ factory.SetTypeId (typeId);
Ptr<Object> protocol = factory.Create <Object> ();
node->AggregateObject (protocol);
}
@@ -252,24 +281,45 @@
void
InternetStackHelper::Install (Ptr<Node> node) const
{
- if (node->GetObject<Ipv4> () != 0)
+ if (m_ipv4Enabled)
{
- NS_FATAL_ERROR ("InternetStackHelper::Install(): Aggregating "
- "an InternetStack to a node with an existing Ipv4 object");
- return;
+ if (node->GetObject<Ipv4> () != 0)
+ {
+ NS_FATAL_ERROR ("InternetStackHelper::Install (): Aggregating "
+ "an InternetStack to a node with an existing Ipv4 object");
+ return;
+ }
+
+ CreateAndAggregateObjectFromTypeId (node, "ns3::ArpL3Protocol");
+ CreateAndAggregateObjectFromTypeId (node, "ns3::Ipv4L3Protocol");
+ CreateAndAggregateObjectFromTypeId (node, "ns3::Icmpv4L4Protocol");
+ CreateAndAggregateObjectFromTypeId (node, "ns3::UdpL4Protocol");
+ node->AggregateObject (m_tcpFactory.Create<Object> ());
+ Ptr<PacketSocketFactory> factory = CreateObject<PacketSocketFactory> ();
+ node->AggregateObject (factory);
+ // Set routing
+ Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+ Ptr<Ipv4RoutingProtocol> ipv4Routing = m_routing->Create (node);
+ ipv4->SetRoutingProtocol (ipv4Routing);
}
- CreateAndAggregateObjectFromTypeId (node, "ns3::ArpL3Protocol");
- CreateAndAggregateObjectFromTypeId (node, "ns3::Ipv4L3Protocol");
- CreateAndAggregateObjectFromTypeId (node, "ns3::Icmpv4L4Protocol");
- CreateAndAggregateObjectFromTypeId (node, "ns3::UdpL4Protocol");
- node->AggregateObject (m_tcpFactory.Create<Object> ());
- Ptr<PacketSocketFactory> factory = CreateObject<PacketSocketFactory> ();
- node->AggregateObject (factory);
- // Set routing
- Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
- Ptr<Ipv4RoutingProtocol> ipv4Routing = m_routing->Create (node);
- ipv4->SetRoutingProtocol (ipv4Routing);
+ if (m_ipv6Enabled)
+ {
+ /* IPv6 stack */
+ if (node->GetObject<Ipv6> () != 0)
+ {
+ NS_FATAL_ERROR ("InternetStackHelper::Install (): Aggregating "
+ "an InternetStack to a node with an existing Ipv6 object");
+ return;
+ }
+
+ CreateAndAggregateObjectFromTypeId (node, "ns3::Ipv6L3Protocol");
+ CreateAndAggregateObjectFromTypeId (node, "ns3::Icmpv6L4Protocol");
+ /* TODO add UdpL4Protocol / TcpL4Protocol for IPv6 */
+ Ptr<Ipv6> ipv6 = node->GetObject<Ipv6> ();
+ Ptr<Ipv6RoutingProtocol> ipv6Routing = m_routingv6->Create (node);
+ ipv6->SetRoutingProtocol (ipv6Routing);
+ }
}
void
@@ -293,6 +343,9 @@
oss << "/NodeList/" << node->GetId () << "/$ns3::ArpL3Protocol/Drop";
Config::Connect (oss.str (), MakeBoundCallback (&InternetStackHelper::AsciiDropEvent, writer));
oss.str ("");
+ oss << "/NodeList/" << node->GetId () << "/$ns3::Ipv6L3Protocol/Drop";
+ Config::Connect (oss.str (), MakeBoundCallback (&InternetStackHelper::AsciiDropEvent, writer));
+ oss.str ("");
}
}
@@ -312,6 +365,12 @@
MakeCallback (&InternetStackHelper::LogTxIp));
Config::Connect ("/NodeList/*/$ns3::Ipv4L3Protocol/Rx",
MakeCallback (&InternetStackHelper::LogRxIp));
+
+ /* IPv6 */
+ Config::Connect ("/NodeList/*/$ns3::Ipv6L3Protocol/Tx",
+ MakeCallback (&InternetStackHelper::LogTxIp));
+ Config::Connect ("/NodeList/*/$ns3::Ipv6L3Protocol/Rx",
+ MakeCallback (&InternetStackHelper::LogRxIp));
}
uint32_t
--- a/src/helper/internet-stack-helper.h Tue Aug 25 20:12:53 2009 +0400
+++ b/src/helper/internet-stack-helper.h Wed Aug 26 15:29:03 2009 +0400
@@ -31,6 +31,7 @@
class Node;
class Ipv4RoutingHelper;
+class Ipv6RoutingHelper;
/**
* \brief aggregate IP/TCP/UDP functionality to existing Nodes.
@@ -59,9 +60,15 @@
* ns3::Ipv4::SetRoutingProtocol.
*/
void SetRoutingHelper (const Ipv4RoutingHelper &routing);
+
+ /**
+ * \brief Set IPv6 routing helper.
+ * \param routing IPv6 routing helper
+ */
+ void SetRoutingHelper (const Ipv6RoutingHelper &routing);
/**
- * Aggregate implementations of the ns3::Ipv4, ns3::Udp, and ns3::Tcp classes
+ * Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes
* onto the provided node. This method will assert if called on a node that
* already has an Ipv4 object aggregated to it.
*
@@ -70,7 +77,7 @@
void Install (std::string nodeName) const;
/**
- * Aggregate implementations of the ns3::Ipv4, ns3::Udp, and ns3::Tcp classes
+ * Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes
* onto the provided node. This method will assert if called on a node that
* already has an Ipv4 object aggregated to it.
*
@@ -80,7 +87,7 @@
/**
* For each node in the input container, aggregate implementations of the
- * ns3::Ipv4, ns3::Udp, and, ns3::Tcp classes. The program will assert
+ * ns3::Ipv4, ns3::Ipv6, ns3::Udp, and, ns3::Tcp classes. The program will assert
* if this method is called on a container with a node that already has
* an Ipv4 object aggregated to it.
*
@@ -90,11 +97,11 @@
void Install (NodeContainer c) const;
/**
- * Aggregate ip, udp, and tcp stacks to all nodes in the simulation
+ * Aggregate IPv4, IPv6, UDP, and TCP stacks to all nodes in the simulation
*/
void InstallAll (void) const;
- /**
+ /**
* \brief set the Tcp stack which will not need any other parameter.
*
* This function sets up the tcp stack to the given TypeId. It should not be
@@ -128,6 +135,7 @@
* Enable ascii output on these drop traces, for each node in the NodeContainer..
* /NodeList/[i]/$ns3ArpL3Protocol/Drop
* /NodeList/[i]/$ns3Ipv4L3Protocol/Drop
+ * /NodeList/[i]/$ns3Ipv6L3Protocol/Drop
*/
static void EnableAscii (std::ostream &os, NodeContainer n);
@@ -137,12 +145,14 @@
* Enable ascii output on these drop traces, for all nodes.
* /NodeList/[i]/$ns3ArpL3Protocol/Drop
* /NodeList/[i]/$ns3Ipv4L3Protocol/Drop
+ * /NodeList/[i]/$ns3Ipv6L3Protocol/Drop
*/
static void EnableAsciiAll (std::ostream &os);
/**
* Enable pcap output on each protocol instance which is of the
- * ns3::Ipv4L3Protocol type. Both Tx and Rx events will be logged.
+ * ns3::Ipv4L3Protocol or ns3::Ipv6L3Protocol type. Both Tx and
+ * Rx events will be logged.
*
* \param filename filename prefix to use for pcap files.
*
@@ -155,9 +165,27 @@
*/
static void EnablePcapAll (std::string filename);
+ /**
+ * \brief Enable/disable IPv4 stack install.
+ * \param enable enable state
+ */
+ void SetIpv4StackInstall (bool enable);
+
+ /**
+ * \brief Enable/disable IPv6 stack install.
+ * \param enable enable state
+ */
+ void SetIpv6StackInstall (bool enable);
+
private:
ObjectFactory m_tcpFactory;
const Ipv4RoutingHelper *m_routing;
+
+ /**
+ * \brief IPv6 routing helper.
+ */
+ const Ipv6RoutingHelper *m_routingv6;
+
static void CreateAndAggregateObjectFromTypeId (Ptr<Node> node, const std::string typeId);
static void Cleanup (void);
static void LogRxIp (std::string context, Ptr<const Packet> packet, uint32_t deviceId);
@@ -173,6 +201,16 @@
static uint32_t GetNodeIndex (std::string context);
static std::vector<Trace> m_traces;
static bool m_isInitialized;
+
+ /**
+ * \brief IPv4 install state (enabled/disabled) ?
+ */
+ bool m_ipv4Enabled;
+
+ /**
+ * \brief IPv6 install state (enabled/disabled) ?
+ */
+ bool m_ipv6Enabled;
};
} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/ipv6-address-helper.cc Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,167 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#include "ns3/assert.h"
+#include "ns3/log.h"
+#include "ns3/ptr.h"
+#include "ns3/node.h"
+#include "ns3/net-device.h"
+#include "ns3/mac48-address.h"
+#include "ns3/ipv6.h"
+
+#include "ipv6-address-helper.h"
+
+namespace ns3
+{
+
+NS_LOG_COMPONENT_DEFINE ("Ipv6AddressHelper");
+
+Ipv6AddressHelper::Ipv6AddressHelper ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_network = Ipv6Address ("2001::");
+ m_prefix = Ipv6Prefix (64);
+}
+
+Ipv6Address Ipv6AddressHelper::NewAddress (Address addr)
+{
+ NS_LOG_FUNCTION (this << addr);
+
+ switch (addr.GetLength ())
+ {
+ case 6:
+ return Ipv6Address::MakeAutoconfiguredAddress (Mac48Address::ConvertFrom (addr), m_network);
+ default:
+ return Ipv6Address ("::");
+ }
+ /* never reached */
+ return Ipv6Address ("::");
+}
+
+void Ipv6AddressHelper::NewNetwork (Ipv6Address network, Ipv6Prefix prefix)
+{
+ NS_LOG_FUNCTION (this << network << prefix);
+
+ m_network = network;
+ m_prefix = prefix;
+}
+
+Ipv6InterfaceContainer Ipv6AddressHelper::Assign (const NetDeviceContainer &c)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ Ipv6InterfaceContainer retval;
+
+ for (uint32_t i = 0; i < c.GetN (); ++i)
+ {
+ Ptr<NetDevice> device = c.Get (i);
+
+ Ptr<Node> node = device->GetNode ();
+ NS_ASSERT_MSG (node, "Ipv6AddressHelper::Allocate (): Bad node");
+
+ Ptr<Ipv6> ipv6 = node->GetObject<Ipv6> ();
+ NS_ASSERT_MSG (ipv6, "Ipv6AddressHelper::Allocate (): Bad ipv6");
+ int32_t ifIndex = 0;
+
+ ifIndex = ipv6->GetInterfaceForDevice (device);
+ if (ifIndex == -1)
+ {
+ ifIndex = ipv6->AddInterface (device);
+ }
+ NS_ASSERT_MSG (ifIndex >= 0, "Ipv6AddressHelper::Allocate (): "
+ "Interface index not found");
+
+ Ipv6InterfaceAddress ipv6Addr = Ipv6InterfaceAddress (NewAddress (device->GetAddress ()), m_prefix);
+ ipv6->SetMetric (ifIndex, 1);
+ ipv6->SetUp (ifIndex);
+ ipv6->AddAddress (ifIndex, ipv6Addr);
+
+ retval.Add (ipv6, ifIndex);
+ }
+ return retval;
+}
+
+Ipv6InterfaceContainer Ipv6AddressHelper::Assign (const NetDeviceContainer &c, std::vector<bool> withConfiguration)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ Ipv6InterfaceContainer retval;
+ for (uint32_t i = 0; i < c.GetN (); ++i)
+ {
+ Ptr<NetDevice> device = c.Get (i);
+
+ Ptr<Node> node = device->GetNode ();
+ NS_ASSERT_MSG (node, "Ipv6AddressHelper::Allocate (): Bad node");
+
+ Ptr<Ipv6> ipv6 = node->GetObject<Ipv6> ();
+ NS_ASSERT_MSG (ipv6, "Ipv6AddressHelper::Allocate (): Bad ipv6");
+
+ int32_t ifIndex = ipv6->GetInterfaceForDevice (device);
+ if (ifIndex == -1)
+ {
+ ifIndex = ipv6->AddInterface (device);
+ }
+ NS_ASSERT_MSG (ifIndex >= 0, "Ipv6AddressHelper::Allocate (): "
+ "Interface index not found");
+
+ ipv6->SetMetric (ifIndex, 1);
+ ipv6->SetUp (ifIndex);
+
+ if (withConfiguration.at (i))
+ {
+ Ipv6InterfaceAddress ipv6Addr = Ipv6InterfaceAddress (NewAddress (device->GetAddress ()), m_prefix);
+ ipv6->AddAddress (ifIndex, ipv6Addr);
+ }
+
+ retval.Add (ipv6, ifIndex);
+ }
+ return retval;
+}
+
+Ipv6InterfaceContainer Ipv6AddressHelper::AssignWithoutAddress (const NetDeviceContainer &c)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ Ipv6InterfaceContainer retval;
+ for (uint32_t i = 0; i < c.GetN (); ++i)
+ {
+ Ptr<NetDevice> device = c.Get (i);
+
+ Ptr<Node> node = device->GetNode ();
+ NS_ASSERT_MSG (node, "Ipv6AddressHelper::Allocate (): Bad node");
+
+ Ptr<Ipv6> ipv6 = node->GetObject<Ipv6> ();
+ NS_ASSERT_MSG (ipv6, "Ipv6AddressHelper::Allocate (): Bad ipv6");
+
+ int32_t ifIndex = ipv6->GetInterfaceForDevice (device);
+ if (ifIndex == -1)
+ {
+ ifIndex = ipv6->AddInterface (device);
+ }
+ NS_ASSERT_MSG (ifIndex >= 0, "Ipv6AddressHelper::Allocate (): "
+ "Interface index not found");
+
+ ipv6->SetMetric (ifIndex, 1);
+ ipv6->SetUp (ifIndex);
+
+ retval.Add (ipv6, ifIndex);
+ }
+ return retval;
+}
+
+} /* namespace ns3 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/ipv6-address-helper.h Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,96 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#ifndef IPV6_ADDRESS_STATIC_HELPER_H
+#define IPV6_ADDRESS_STATIC_HELPER_H
+
+#include <vector>
+
+#include "ns3/ipv6-address.h"
+#include "net-device-container.h"
+#include "ipv6-interface-container.h"
+
+namespace ns3
+{
+
+/**
+ * \class Ipv6AddressHelper
+ * \brief Helper class to assign IPv6 address statically.
+ */
+class Ipv6AddressHelper
+{
+ public:
+ /**
+ * \brief Constructor.
+ */
+ Ipv6AddressHelper ();
+
+ /**
+ * \brief Allocate a new network.
+ * \param network The IPv6 network
+ * \param prefix The prefix
+ */
+ void NewNetwork (Ipv6Address network, Ipv6Prefix prefix);
+
+ /**
+ * \brief Allocate a new address.
+ * \param addr L2 address (currenty only ethernet address is supported)
+ * \return newly created Ipv6Address
+ */
+ Ipv6Address NewAddress (Address addr);
+
+ /**
+ * \brief Allocate an Ipv6InterfaceContainer.
+ * \param c netdevice container
+ * \return newly created Ipv6InterfaceContainer
+ */
+ Ipv6InterfaceContainer Assign (const NetDeviceContainer &c);
+
+ /**
+ * \brief Allocate an Ipv6InterfaceContainer.
+ * \param c netdevice container
+ * \param withConfiguration true : interface statically configured, false : no static configuration
+ * \return newly created Ipv6InterfaceContainer
+ */
+ Ipv6InterfaceContainer Assign (const NetDeviceContainer &c, std::vector<bool> withConfiguration);
+
+ /**
+ * \brief Allocate an Ipv6InterfaceContainer without static IPv6 configuration.
+ * \param c netdevice container
+ * \return newly created Ipv6InterfaceContainer
+ */
+ Ipv6InterfaceContainer AssignWithoutAddress (const NetDeviceContainer &c);
+
+ private:
+ /**
+ * \brief The IPv6 network.
+ */
+ Ipv6Address m_network;
+
+ /**
+ * \brief IPv6 The prefix (mask).
+ */
+ Ipv6Prefix m_prefix;
+};
+
+} /* namespace ns3 */
+
+#endif /* IPV6_ADDRESS_STATIC_HELPER_H */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/ipv6-interface-container.cc Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,109 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#include "ns3/node-list.h"
+#include "ns3/names.h"
+
+#include "ipv6-interface-container.h"
+#include "ipv6-static-routing-helper.h"
+
+namespace ns3
+{
+
+Ipv6InterfaceContainer::Ipv6InterfaceContainer ()
+{
+}
+
+uint32_t Ipv6InterfaceContainer::GetN () const
+{
+ return m_interfaces.size ();
+}
+
+uint32_t Ipv6InterfaceContainer::GetInterfaceIndex (uint32_t i) const
+{
+ return m_interfaces[i].second;
+}
+
+Ipv6Address Ipv6InterfaceContainer::GetAddress (uint32_t i, uint32_t j) const
+{
+ Ptr<Ipv6> ipv6 = m_interfaces[i].first;
+ uint32_t interface = m_interfaces[i].second;
+ return ipv6->GetAddress (interface, j).GetAddress ();
+}
+
+void Ipv6InterfaceContainer::Add (Ptr<Ipv6> ipv6, uint32_t interface)
+{
+ m_interfaces.push_back (std::make_pair (ipv6, interface));
+}
+
+void Ipv6InterfaceContainer::Add (std::string ipv6Name, uint32_t interface)
+{
+ Ptr<Ipv6> ipv6 = Names::Find<Ipv6> (ipv6Name);
+ m_interfaces.push_back (std::make_pair (ipv6, interface));
+}
+
+void Ipv6InterfaceContainer::Add (Ipv6InterfaceContainer& c)
+{
+ for (InterfaceVector::const_iterator it = c.m_interfaces.begin () ; it != c.m_interfaces.end () ; it++)
+ {
+ m_interfaces.push_back (*it);
+ }
+}
+
+void Ipv6InterfaceContainer::SetRouter (uint32_t i, bool router)
+{
+ Ptr<Ipv6> ipv6 = m_interfaces[i].first;
+ ipv6->SetForwarding (m_interfaces[i].second, router);
+
+ if (router)
+ {
+ uint32_t other;
+ /* assume first global address is index 1 (0 is link-local) */
+ Ipv6Address routerAddress = ipv6->GetAddress (m_interfaces[i].second, 1).GetAddress ();
+
+ for (other = 0 ; other < m_interfaces.size () ; other++)
+ {
+ if (other != i)
+ {
+ Ptr<Ipv6StaticRouting> routing = 0;
+ Ipv6StaticRoutingHelper routingHelper;
+
+ ipv6 = m_interfaces[other].first;
+ routing = routingHelper.GetStaticRouting (ipv6);
+ routing->SetDefaultRoute (routerAddress, m_interfaces[other].second);
+ }
+ }
+ }
+}
+
+void Ipv6InterfaceContainer::SetDefaultRoute (uint32_t i, uint32_t router)
+{
+ Ptr<Ipv6> ipv6 = m_interfaces[i].first;
+ Ptr<Ipv6> ipv6Router = m_interfaces[router].first;
+ Ipv6Address routerAddress = ipv6Router->GetAddress (m_interfaces[router].second, 1).GetAddress ();
+ Ptr<Ipv6StaticRouting> routing = 0;
+ Ipv6StaticRoutingHelper routingHelper;
+
+ routing = routingHelper.GetStaticRouting (ipv6);
+ routing->SetDefaultRoute (routerAddress, m_interfaces[i].second);
+}
+
+} /* namespace ns3 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/ipv6-interface-container.h Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,111 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#ifndef IPV6_INTERFACE_CONTAINER_H
+#define IPV6_INTERFACE_CONTAINER_H
+
+#include <stdint.h>
+#include <vector>
+#include "ns3/ipv6.h"
+#include "ns3/ipv6-address.h"
+
+namespace ns3
+{
+
+/**
+ * \class Ipv6InterfaceContainer
+ * \brief keep track of a set of IPv6 interfaces.
+ */
+class Ipv6InterfaceContainer
+{
+ public:
+ /**
+ * \brief Constructor.
+ */
+ Ipv6InterfaceContainer ();
+
+ /**
+ * \brief Get the number of interfaces.
+ * \return the number of interfaces stored in this Ipv6InterfaceContainer.
+ */
+ uint32_t GetN (void) const;
+
+ /**
+ * \brief Get the interface index for the specified node index.
+ * \param i index of the node
+ * \return interface index
+ */
+ uint32_t GetInterfaceIndex (uint32_t i) const;
+
+ /**
+ * \brief Get the address for the specified index.
+ * \param i interface index
+ * \param j address index, generally index 0 is the link-local address
+ * \return IPv6 address
+ */
+ Ipv6Address GetAddress (uint32_t i, uint32_t j) const;
+
+ /**
+ * \brief Add a couple IPv6/interface.
+ * \param ipv6 IPv6 address
+ * \param interface interface index
+ */
+ void Add (Ptr<Ipv6> ipv6, uint32_t interface);
+
+ /**
+ * \brief Fusion with another Ipv6InterfaceContainer.
+ * \param c container
+ */
+ void Add (Ipv6InterfaceContainer& c);
+
+ /**
+ * \brief Add a couple of name/interface.
+ * \param ipv6Name name of a node
+ * \param interface interface index to add
+ */
+ void Add (std::string ipv6Name, uint32_t interface);
+
+ /**
+ * \brief Set the state of the stack (act as a router or not) for the specified index.
+ * \param i index
+ * \param router true : is a router, false : is an host
+ */
+ void SetRouter (uint32_t i, bool router);
+
+ /**
+ * \brief Set the default route for the specified index.
+ * \param i index
+ * \param router the default router
+ */
+ void SetDefaultRoute (uint32_t i, uint32_t router);
+
+ private:
+ typedef std::vector<std::pair<Ptr<Ipv6>, uint32_t> > InterfaceVector;
+
+ /**
+ * \brief List of IPv6 stack and interfaces index.
+ */
+ InterfaceVector m_interfaces;
+};
+
+} /* namespace ns3 */
+
+#endif /* IPV6_INTERFACE_CONTAINER_H */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/ipv6-list-routing-helper.cc Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,46 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "ipv6-list-routing-helper.h"
+#include "ns3/ipv6-list-routing.h"
+#include "ns3/node.h"
+
+namespace ns3 {
+
+Ipv6ListRoutingHelper::Ipv6ListRoutingHelper ()
+{}
+void
+Ipv6ListRoutingHelper::Add (const Ipv6RoutingHelper &routing, int16_t priority)
+{
+ m_list.push_back (std::make_pair (&routing,priority));
+}
+Ptr<Ipv6RoutingProtocol>
+Ipv6ListRoutingHelper::Create (Ptr<Node> node) const
+{
+ Ptr<Ipv6ListRouting> list = CreateObject<Ipv6ListRouting> ();
+ for (std::list<std::pair<const Ipv6RoutingHelper *,int16_t> >::const_iterator i = m_list.begin ();
+ i != m_list.end (); ++i)
+ {
+ Ptr<Ipv6RoutingProtocol> prot = i->first->Create (node);
+ list->AddRoutingProtocol (prot,i->second);
+ }
+ return list;
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/ipv6-list-routing-helper.h Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,64 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef IPV6_LIST_ROUTING_HELPER_H
+#define IPV6_LIST_ROUTING_HELPER_H
+
+#include "ipv6-routing-helper.h"
+#include <stdint.h>
+#include <list>
+
+namespace ns3 {
+
+/**
+ * \brief Helper class that adds ns3::Ipv6ListRouting objects
+ *
+ * This class is expected to be used in conjunction with
+ * ns3::InternetStackHelper::SetRoutingHelper
+ */
+class Ipv6ListRoutingHelper : public Ipv6RoutingHelper
+{
+public:
+ Ipv6ListRoutingHelper ();
+ /**
+ * \param routing a routing helper
+ * \param priority the priority of the associated helper
+ *
+ * Store in the internal list a reference to the input routing helper
+ * and associated priority. These helpers will be used later by
+ * the ns3::Ipv6ListRoutingHelper::Create method to create
+ * an ns3::Ipv6ListRouting object and add in it routing protocols
+ * created with the helpers.
+ */
+ void Add (const Ipv6RoutingHelper &routing, int16_t priority);
+ /**
+ * \param node the node on which the routing protocol will run
+ * \returns a newly-created routing protocol
+ *
+ * This method will be called by ns3::InternetStackHelper::Install
+ */
+ virtual Ptr<Ipv6RoutingProtocol> Create (Ptr<Node> node) const;
+private:
+ std::list<std::pair<const Ipv6RoutingHelper *,int16_t> > m_list;
+};
+
+} // namespace ns3
+
+#endif /* IPV6_LIST_ROUTING_HELPER_H */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/ipv6-routing-helper.cc Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,28 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#include "ipv6-routing-helper.h"
+
+namespace ns3 {
+
+Ipv6RoutingHelper::~Ipv6RoutingHelper ()
+{}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/ipv6-routing-helper.h Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,54 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef IPV6_ROUTING_HELPER_H
+#define IPV6_ROUTING_HELPER_H
+
+#include "ns3/ptr.h"
+
+namespace ns3 {
+
+class Ipv6RoutingProtocol;
+class Node;
+
+/**
+ * \brief a factory to create ns3::Ipv6RoutingProtocol objects
+ *
+ * For each new routing protocol created as a subclass of
+ * ns3::Ipv6RoutingProtocol, you need to create a subclass of
+ * ns3::Ipv6RoutingHelper which can be used by
+ * ns3::InternetStackHelper::SetRoutingHelper and
+ * ns3::InternetStackHelper::Install.
+ */
+class Ipv6RoutingHelper
+{
+public:
+ virtual ~Ipv6RoutingHelper ();
+ /**
+ * \param node the node within which the new routing protocol will run
+ * \returns a newly-created routing protocol
+ */
+ virtual Ptr<Ipv6RoutingProtocol> Create (Ptr<Node> node) const = 0;
+};
+
+} // namespace ns3
+
+
+#endif /* IPV6_ROUTING_HELPER_H */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/ipv6-static-routing-helper.cc Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,200 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <vector>
+#include "ns3/log.h"
+#include "ns3/ptr.h"
+#include "ns3/names.h"
+#include "ns3/node.h"
+#include "ns3/ipv6.h"
+#include "ns3/ipv6-route.h"
+#include "ns3/ipv6-list-routing.h"
+#include "ns3/assert.h"
+#include "ns3/ipv6-address.h"
+#include "ns3/ipv6-routing-protocol.h"
+#include "ipv6-static-routing-helper.h"
+
+NS_LOG_COMPONENT_DEFINE ("Ipv6StaticRoutingHelper");
+
+namespace ns3 {
+
+Ipv6StaticRoutingHelper::Ipv6StaticRoutingHelper ()
+{}
+Ptr<Ipv6RoutingProtocol>
+Ipv6StaticRoutingHelper::Create (Ptr<Node> node) const
+{
+ return CreateObject<Ipv6StaticRouting> ();
+}
+
+Ptr<Ipv6StaticRouting>
+Ipv6StaticRoutingHelper::GetStaticRouting (Ptr<Ipv6> ipv6) const
+{
+ NS_LOG_FUNCTION (this);
+ Ptr<Ipv6RoutingProtocol> ipv6rp = ipv6->GetRoutingProtocol ();
+ NS_ASSERT_MSG (ipv6rp, "No routing protocol associated with Ipv6");
+ if (DynamicCast<Ipv6StaticRouting> (ipv6rp))
+ {
+ NS_LOG_LOGIC ("Static routing found as the main IPv4 routing protocol.");
+ return DynamicCast<Ipv6StaticRouting> (ipv6rp);
+ }
+ if (DynamicCast<Ipv6ListRouting> (ipv6rp))
+ {
+ Ptr<Ipv6ListRouting> lrp = DynamicCast<Ipv6ListRouting> (ipv6rp);
+ int16_t priority;
+ for (uint32_t i = 0; i < lrp->GetNRoutingProtocols (); i++)
+ {
+ NS_LOG_LOGIC ("Searching for static routing in list");
+ Ptr<Ipv6RoutingProtocol> temp = lrp->GetRoutingProtocol (i, priority);
+ if (DynamicCast<Ipv6StaticRouting> (temp))
+ {
+ NS_LOG_LOGIC ("Found static routing in list");
+ return DynamicCast<Ipv6StaticRouting> (temp);
+ }
+ }
+ }
+ NS_LOG_LOGIC ("Static routing not found");
+ return 0;
+}
+
+void
+Ipv6StaticRoutingHelper::AddMulticastRoute (
+ Ptr<Node> n,
+ Ipv6Address source,
+ Ipv6Address group,
+ Ptr<NetDevice> input,
+ NetDeviceContainer output)
+{
+ Ptr<Ipv6> ipv6 = n->GetObject<Ipv6> ();
+
+ // We need to convert the NetDeviceContainer to an array of interface
+ // numbers
+ std::vector<uint32_t> outputInterfaces;
+ for (NetDeviceContainer::Iterator i = output.Begin (); i != output.End (); ++i)
+ {
+ Ptr<NetDevice> nd = *i;
+ int32_t interface = ipv6->GetInterfaceForDevice (nd);
+ NS_ASSERT_MSG (interface >= 0,
+ "Ipv6StaticRoutingHelper::AddMulticastRoute (): "
+ "Expected an interface associated with the device nd");
+ outputInterfaces.push_back (interface);
+ }
+
+ int32_t inputInterface = ipv6->GetInterfaceForDevice (input);
+ NS_ASSERT_MSG (inputInterface >= 0,
+ "Ipv6StaticRoutingHelper::AddMulticastRoute (): "
+ "Expected an interface associated with the device input");
+ Ipv6StaticRoutingHelper helper;
+ Ptr<Ipv6StaticRouting> ipv6StaticRouting = helper.GetStaticRouting (ipv6);
+ if (!ipv6StaticRouting)
+ {
+ NS_ASSERT_MSG (ipv6StaticRouting,
+ "Ipv6StaticRoutingHelper::SetDefaultMulticastRoute (): "
+ "Expected an Ipv6StaticRouting associated with this node");
+ }
+ ipv6StaticRouting->AddMulticastRoute (source, group, inputInterface, outputInterfaces);
+}
+
+void
+Ipv6StaticRoutingHelper::AddMulticastRoute (
+ Ptr<Node> n,
+ Ipv6Address source,
+ Ipv6Address group,
+ std::string inputName,
+ NetDeviceContainer output)
+{
+ Ptr<NetDevice> input = Names::Find<NetDevice> (inputName);
+ AddMulticastRoute (n, source, group, input, output);
+}
+
+void
+Ipv6StaticRoutingHelper::AddMulticastRoute (
+ std::string nName,
+ Ipv6Address source,
+ Ipv6Address group,
+ Ptr<NetDevice> input,
+ NetDeviceContainer output)
+{
+ Ptr<Node> n = Names::Find<Node> (nName);
+ AddMulticastRoute (n, source, group, input, output);
+}
+
+void
+Ipv6StaticRoutingHelper::AddMulticastRoute (
+ std::string nName,
+ Ipv6Address source,
+ Ipv6Address group,
+ std::string inputName,
+ NetDeviceContainer output)
+{
+ Ptr<NetDevice> input = Names::Find<NetDevice> (inputName);
+ Ptr<Node> n = Names::Find<Node> (nName);
+ AddMulticastRoute (n, source, group, input, output);
+}
+
+#if 0
+void
+Ipv6StaticRoutingHelper::SetDefaultMulticastRoute (
+ Ptr<Node> n,
+ Ptr<NetDevice> nd)
+{
+ Ptr<Ipv6> ipv6 = n->GetObject<Ipv6> ();
+ int32_t interfaceSrc = ipv6->GetInterfaceForDevice (nd);
+ NS_ASSERT_MSG (interfaceSrc >= 0,
+ "Ipv6StaticRoutingHelper::SetDefaultMulticastRoute (): "
+ "Expected an interface associated with the device");
+ Ipv6StaticRoutingHelper helper;
+ Ptr<Ipv6StaticRouting> ipv6StaticRouting = helper.GetStaticRouting (ipv6);
+ if (!ipv6StaticRouting)
+ {
+ NS_ASSERT_MSG (ipv6StaticRouting,
+ "Ipv6StaticRoutingHelper::SetDefaultMulticastRoute (): "
+ "Expected an Ipv6StaticRouting associated with this node");
+ }
+ ipv6StaticRouting->SetDefaultMulticastRoute (interfaceSrc);
+}
+
+void
+Ipv6StaticRoutingHelper::SetDefaultMulticastRoute (
+ Ptr<Node> n,
+ std::string ndName)
+{
+ Ptr<NetDevice> nd = Names::Find<NetDevice> (ndName);
+ SetDefaultMulticastRoute (n, nd);
+}
+
+void
+Ipv6StaticRoutingHelper::SetDefaultMulticastRoute (
+ std::string nName,
+ Ptr<NetDevice> nd)
+{
+ Ptr<Node> n = Names::Find<Node> (nName);
+ SetDefaultMulticastRoute (n, nd);
+}
+
+void
+Ipv6StaticRoutingHelper::SetDefaultMulticastRoute (
+ std::string nName,
+ std::string ndName)
+{
+ Ptr<Node> n = Names::Find<Node> (nName);
+ Ptr<NetDevice> nd = Names::Find<NetDevice> (ndName);
+ SetDefaultMulticastRoute (n, nd);
+}
+#endif
+
+}; // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/ipv6-static-routing-helper.h Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,79 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef IPV6_STATIC_ROUTING_HELPER_H
+#define IPV6_STATIC_ROUTING_HELPER_H
+
+#include "ns3/ipv6.h"
+#include "ns3/ipv6-static-routing.h"
+#include "ns3/ptr.h"
+#include "ns3/ipv6-address.h"
+#include "ns3/node.h"
+#include "ns3/net-device.h"
+#include "ipv6-routing-helper.h"
+#include "node-container.h"
+#include "net-device-container.h"
+
+namespace ns3 {
+
+/**
+ * \brief Helper class that adds ns3::Ipv6StaticRouting objects
+ *
+ * This class is expected to be used in conjunction with
+ * ns3::InternetStackHelper::SetRoutingHelper
+ */
+class Ipv6StaticRoutingHelper : public Ipv6RoutingHelper
+{
+public:
+ Ipv6StaticRoutingHelper ();
+
+ /**
+ * \param node the node on which the routing protocol will run
+ * \returns a newly-created routing protocol
+ *
+ * This method will be called by ns3::InternetStackHelper::Install
+ */
+ virtual Ptr<Ipv6RoutingProtocol> Create (Ptr<Node> node) const;
+
+ Ptr<Ipv6StaticRouting> GetStaticRouting (Ptr<Ipv6> ipv6) const;
+
+ void AddMulticastRoute (Ptr<Node> n, Ipv6Address source, Ipv6Address group,
+ Ptr<NetDevice> input, NetDeviceContainer output);
+ void AddMulticastRoute (std::string n, Ipv6Address source, Ipv6Address group,
+ Ptr<NetDevice> input, NetDeviceContainer output);
+ void AddMulticastRoute (Ptr<Node> n, Ipv6Address source, Ipv6Address group,
+ std::string inputName, NetDeviceContainer output);
+ void AddMulticastRoute (std::string nName, Ipv6Address source, Ipv6Address group,
+ std::string inputName, NetDeviceContainer output);
+
+#if 0
+ /**
+ * \brief Add a default route to the static routing protocol to forward
+ * packets out a particular interface
+ */
+ void SetDefaultMulticastRoute (Ptr<Node> n, Ptr<NetDevice> nd);
+ void SetDefaultMulticastRoute (Ptr<Node> n, std::string ndName);
+ void SetDefaultMulticastRoute (std::string nName, Ptr<NetDevice> nd);
+ void SetDefaultMulticastRoute (std::string nName, std::string ndName);
+#endif
+};
+
+} // namespace ns3
+
+#endif /* IPV6_STATIC_ROUTING_HELPER_H */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/ping6-helper.cc Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,72 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#include "ns3/ping6.h"
+#include "ns3/uinteger.h"
+
+#include "ping6-helper.h"
+
+namespace ns3
+{
+
+Ping6Helper::Ping6Helper ()
+ : m_ifIndex (0)
+{
+ m_factory.SetTypeId (Ping6::GetTypeId ());
+}
+
+void Ping6Helper::SetLocal (Ipv6Address ip)
+{
+ m_localIp = ip;
+}
+
+void Ping6Helper::SetRemote (Ipv6Address ip)
+{
+ m_remoteIp = ip;
+}
+
+void Ping6Helper::SetAttribute (std::string name, const AttributeValue& value)
+{
+ m_factory.Set (name, value);
+}
+
+ApplicationContainer Ping6Helper::Install (NodeContainer c)
+{
+ ApplicationContainer apps;
+ for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
+ {
+ Ptr<Node> node = *i;
+ Ptr<Ping6> client = m_factory.Create<Ping6> ();
+ client->SetLocal (m_localIp);
+ client->SetRemote (m_remoteIp);
+ client->SetIfIndex (m_ifIndex);
+ node->AddApplication (client);
+ apps.Add (client);
+ }
+ return apps;
+}
+
+void Ping6Helper::SetIfIndex (uint32_t ifIndex)
+{
+ m_ifIndex = ifIndex;
+}
+
+} /* namespace ns3 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/ping6-helper.h Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,103 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#ifndef PING6_HELPER_H
+#define PING6_HELPER_H
+
+#include <stdint.h>
+#include "application-container.h"
+#include "node-container.h"
+#include "ns3/object-factory.h"
+#include "ns3/ipv6-address.h"
+
+namespace ns3 {
+
+/**
+ * \class Ping6Helper
+ * \brief Ping6 application helper.
+ */
+class Ping6Helper
+{
+ public:
+ /**
+ * \brief Constructor.
+ */
+ Ping6Helper ();
+
+ /**
+ * \brief Set the local IPv6 address.
+ * \param ip local IPv6 address
+ */
+ void SetLocal (Ipv6Address ip);
+
+ /**
+ * \brief Set the remote IPv6 address.
+ * \param ip remote IPv6 address
+ */
+ void SetRemote (Ipv6Address ip);
+
+ /**
+ * \brief Set some attributes.
+ * \param name attribute name
+ * \param value attribute value
+ */
+ void SetAttribute (std::string name, const AttributeValue& value);
+
+ /**
+ * \brief Install the application in Nodes.
+ * \param c list of Nodes
+ * \return application container
+ */
+ ApplicationContainer Install (NodeContainer c);
+
+ /**
+ * \brief Set the out interface index.
+ * This is to send to link-local (unicast or multicast) address
+ * when a node has multiple interfaces.
+ * \param ifIndex interface index
+ */
+ void SetIfIndex (uint32_t ifIndex);
+
+ private:
+ /**
+ * \brief An object factory.
+ */
+ ObjectFactory m_factory;
+
+ /**
+ * \brief The local IPv6 address.
+ */
+ Ipv6Address m_localIp;
+
+ /**
+ * \brief The remote IPv6 address.
+ */
+ Ipv6Address m_remoteIp;
+
+ /**
+ * \brief Out interface index.
+ */
+ uint32_t m_ifIndex;
+};
+
+} /* namespace ns3 */
+
+#endif /* PING6_HELPER_H */
+
--- a/src/helper/wscript Tue Aug 25 20:12:53 2009 +0400
+++ b/src/helper/wscript Wed Aug 26 15:29:03 2009 +0400
@@ -29,6 +29,13 @@
'ipv4-list-routing-helper.cc',
'ipv4-routing-helper.cc',
'mesh-helper.cc',
+ 'athstats-helper.cc',
+ 'ipv6-address-helper.cc',
+ 'ipv6-interface-container.cc',
+ 'ipv6-static-routing-helper.cc',
+ 'ipv6-list-routing-helper.cc',
+ 'ipv6-routing-helper.cc',
+ 'ping6-helper.cc',
]
headers = bld.new_task_gen('ns3header')
@@ -60,6 +67,13 @@
'ipv4-list-routing-helper.h',
'ipv4-routing-helper.h',
'mesh-helper.h',
+ 'athstats-helper.h',
+ 'ipv6-address-helper.h',
+ 'ipv6-interface-container.h',
+ 'ipv6-static-routing-helper.h',
+ 'ipv6-list-routing-helper.h',
+ 'ipv6-routing-helper.h',
+ 'ping6-helper.h',
]
env = bld.env_of_name('default')
--- a/src/internet-stack/arp-cache.h Tue Aug 25 20:12:53 2009 +0400
+++ b/src/internet-stack/arp-cache.h Wed Aug 26 15:29:03 2009 +0400
@@ -32,7 +32,7 @@
#include "ns3/ptr.h"
#include "ns3/object.h"
#include "ns3/traced-callback.h"
-#include "sgi-hashmap.h"
+#include "ns3/sgi-hashmap.h"
namespace ns3 {
--- a/src/internet-stack/arp-l3-protocol.h Tue Aug 25 20:12:53 2009 +0400
+++ b/src/internet-stack/arp-l3-protocol.h Wed Aug 26 15:29:03 2009 +0400
@@ -26,14 +26,13 @@
#include "ns3/ptr.h"
#include "ns3/traced-callback.h"
-#include "ipv4-interface.h"
-
namespace ns3 {
class ArpCache;
class NetDevice;
class Node;
class Packet;
+class Ipv4Interface;
/**
* \ingroup internetStack
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/icmpv6-header.cc Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,1773 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ * Mehdi Benamor <benamor.mehdi@ensi.rnu.tn>
+ * David Gross <gdavid.devel@gmail.com>
+ */
+
+#include "ns3/assert.h"
+#include "ns3/address-utils.h"
+#include "icmpv6-header.h"
+#include "ns3/log.h"
+
+namespace ns3
+{
+
+NS_OBJECT_ENSURE_REGISTERED (Icmpv6Header);
+
+NS_LOG_COMPONENT_DEFINE ("Icmpv6Header");
+
+TypeId Icmpv6Header::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Icmpv6Header")
+ .SetParent<Header> ()
+ .AddConstructor<Icmpv6Header> ()
+ ;
+ return tid;
+}
+
+TypeId Icmpv6Header::GetInstanceTypeId () const
+{
+ return GetTypeId ();
+}
+
+Icmpv6Header::Icmpv6Header ()
+ : m_calcChecksum (true),
+ m_checksum (0),
+ m_type (0),
+ m_code (0)
+{
+}
+
+Icmpv6Header::~Icmpv6Header ()
+{
+}
+
+uint8_t Icmpv6Header::GetType () const
+{
+ return m_type;
+}
+
+void Icmpv6Header::SetType (uint8_t type)
+{
+ m_type = type;
+}
+
+uint8_t Icmpv6Header::GetCode () const
+{
+ return m_code;
+}
+
+void Icmpv6Header::SetCode (uint8_t code)
+{
+ m_code = code;
+}
+
+uint16_t Icmpv6Header::GetChecksum () const
+{
+ return m_checksum;
+}
+
+void Icmpv6Header::SetChecksum (uint16_t checksum)
+{
+ m_checksum = checksum;
+}
+
+void Icmpv6Header::Print (std::ostream& os) const
+{
+ os << "( type = " << (uint32_t)m_type << " code = " << (uint32_t)m_code << " checksum = " << (uint32_t)m_checksum << ")";
+}
+
+uint32_t Icmpv6Header::GetSerializedSize () const
+{
+ return 4;
+}
+
+uint32_t Icmpv6Header::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+
+ m_type = i.ReadU8 ();
+ m_code = i.ReadU8 ();
+ m_checksum = i.ReadNtohU16 ();
+#if 0
+ i.ReadU32 (); /* padding */
+#endif
+ return GetSerializedSize ();
+}
+
+void Icmpv6Header::Serialize (Buffer::Iterator start) const
+{
+ Buffer::Iterator i = start;
+
+ i.WriteU8 (m_type);
+ i.WriteU8 (m_code);
+ i.WriteU16 (0);
+#if 0
+ i.WriteU32 (0); /* padding */
+#endif
+
+ if (m_calcChecksum)
+ {
+ i = start;
+ uint16_t checksum = i.CalculateIpChecksum (i.GetSize (), m_checksum);
+ i = start;
+ i.Next (2);
+ i.WriteU16 (checksum);
+ }
+}
+
+void Icmpv6Header::CalculatePseudoHeaderChecksum (Ipv6Address src, Ipv6Address dst, uint16_t length, uint8_t protocol)
+{
+ Buffer buf = Buffer (40);
+ uint8_t tmp[16];
+ Buffer::Iterator it;
+
+ buf.AddAtStart (40);
+ it = buf.Begin ();
+
+ src.Serialize (tmp);
+ it.Write (tmp, 16); /* source IPv6 address */
+ dst.Serialize (tmp);
+ it.Write (tmp, 16); /* destination IPv6 address */
+ it.WriteU16 (0); /* length */
+ it.WriteU8 (length >> 8); /* length */
+ it.WriteU8 (length & 0xff); /* length */
+ it.WriteU16 (0); /* zero */
+ it.WriteU8 (0); /* zero */
+ it.WriteU8 (protocol); /* next header */
+
+ it = buf.Begin ();
+ m_checksum = ~(it.CalculateIpChecksum (40));
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Icmpv6NS);
+
+Icmpv6NS::Icmpv6NS ()
+{
+ SetType (ICMPV6_ND_NEIGHBOR_SOLICITATION);
+ SetCode (0);
+ SetReserved (0);
+ m_checksum = 0;
+}
+
+TypeId Icmpv6NS::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Icmpv6NS")
+ .SetParent<Icmpv6Header> ()
+ .AddConstructor<Icmpv6NS> ()
+ ;
+ return tid;
+}
+
+TypeId Icmpv6NS::GetInstanceTypeId () const
+{
+ return GetTypeId ();
+}
+
+Icmpv6NS::Icmpv6NS (Ipv6Address target)
+{
+ SetType (ICMPV6_ND_NEIGHBOR_SOLICITATION);
+ SetCode (0);
+ SetReserved (0);
+ SetIpv6Target (target);
+ m_checksum = 0;
+
+ /* test */
+ /*
+ m_reserved = 0xdeadbeef;
+ */
+}
+
+Icmpv6NS::~Icmpv6NS ()
+{
+}
+
+uint32_t Icmpv6NS::GetReserved () const
+{
+ return m_reserved;
+}
+
+void Icmpv6NS::SetReserved (uint32_t reserved)
+{
+ m_reserved = reserved;
+}
+
+Ipv6Address Icmpv6NS::GetIpv6Target () const
+{
+ return m_target;
+}
+
+void Icmpv6NS::SetIpv6Target (Ipv6Address target)
+{
+ m_target = target;
+}
+
+void Icmpv6NS::Print (std::ostream& os) const
+{
+ os << "( type = " << (uint32_t)GetType () << " (NS) code = " << (uint32_t)GetCode () << " checksum = " << (uint32_t)GetChecksum () << ")";
+}
+
+uint32_t Icmpv6NS::GetSerializedSize () const
+{
+ return 24;
+}
+
+void Icmpv6NS::Serialize (Buffer::Iterator start) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ uint8_t buff_target[16];
+ uint16_t checksum = 0;
+ Buffer::Iterator i = start;
+
+ i.WriteU8 (GetType ());
+ i.WriteU8 (GetCode ());
+ i.WriteU16 (0);
+ i.WriteHtonU32 (m_reserved);
+ m_target.Serialize (buff_target);
+ i.Write (buff_target, 16);
+
+ if (m_calcChecksum)
+ {
+ i = start;
+ checksum = i.CalculateIpChecksum (i.GetSize (), m_checksum);
+ i = start;
+ i.Next (2);
+ i.WriteU16 (checksum);
+ }
+}
+
+uint32_t Icmpv6NS::Deserialize (Buffer::Iterator start)
+{
+ uint8_t buf[16];
+ Buffer::Iterator i = start;
+
+ SetType (i.ReadU8 ());
+ SetCode (i.ReadU8 ());
+ m_checksum = i.ReadU16 ();
+ m_reserved = i.ReadNtohU32 ();
+ i.Read (buf, 16);
+ m_target.Set (buf);
+
+ return GetSerializedSize ();
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Icmpv6NA);
+
+TypeId Icmpv6NA::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Icmpv6NA")
+ .SetParent<Icmpv6Header> ()
+ .AddConstructor<Icmpv6NA> ()
+ ;
+ return tid;
+}
+
+TypeId Icmpv6NA::GetInstanceTypeId () const
+{
+ return GetTypeId ();
+}
+
+Icmpv6NA::Icmpv6NA ()
+{
+ SetType (ICMPV6_ND_NEIGHBOR_ADVERTISEMENT);
+ SetCode (0);
+ SetReserved (0);
+ SetFlagR (0);
+ SetFlagS (0);
+ SetFlagO (0);
+ m_checksum = 0;
+}
+
+Icmpv6NA::~Icmpv6NA ()
+{
+}
+
+uint32_t Icmpv6NA::GetReserved () const
+{
+ return m_reserved;
+}
+
+void Icmpv6NA::SetReserved (uint32_t reserved)
+{
+ m_reserved = reserved;
+}
+
+Ipv6Address Icmpv6NA::GetIpv6Target () const
+{
+ return m_target;
+}
+
+bool Icmpv6NA::GetFlagR () const
+{
+ return m_flagR;
+}
+
+void Icmpv6NA::SetFlagR (bool r)
+{
+ m_flagR = r;
+}
+
+bool Icmpv6NA::GetFlagS () const
+{
+ return m_flagS;
+}
+
+void Icmpv6NA::SetFlagS (bool s)
+{
+ m_flagS = s;
+}
+
+bool Icmpv6NA::GetFlagO () const
+{
+ return m_flagO;
+}
+
+void Icmpv6NA::SetFlagO (bool o)
+{
+ m_flagO = o;
+}
+
+void Icmpv6NA::SetIpv6Target (Ipv6Address target)
+{
+ m_target = target;
+}
+
+void Icmpv6NA::Print (std::ostream& os) const
+{
+ os << "( type = " << (uint32_t)GetType () << " (NA) code = " << (uint32_t)GetCode () << " checksum = " << (uint32_t)GetChecksum () << ")";
+}
+
+uint32_t Icmpv6NA::GetSerializedSize () const
+{
+ return 24;
+}
+
+void Icmpv6NA::Serialize (Buffer::Iterator start) const
+{
+ uint8_t buff_target[16];
+ uint16_t checksum = 0;
+ Buffer::Iterator i = start;
+ uint32_t reserved = m_reserved;
+
+ i.WriteU8 (GetType ());
+ i.WriteU8 (GetCode ());
+ i.WriteU16 (0);
+
+ if (m_flagR)
+ {
+ reserved |= (uint32_t)(1 << 31);
+ }
+
+ if (m_flagS)
+ {
+ reserved |= (uint32_t)(1<< 30);
+ }
+
+ if (m_flagO)
+ {
+ reserved |= (uint32_t)(1<< 29);
+ }
+
+ i.WriteHtonU32 (reserved);
+ m_target.Serialize (buff_target);
+ i.Write (buff_target, 16);
+
+ if (m_calcChecksum)
+ {
+ i = start;
+ checksum = i.CalculateIpChecksum (i.GetSize (), GetChecksum ());
+ i = start;
+ i.Next (2);
+ i.WriteU16 (checksum);
+ }
+}
+
+uint32_t Icmpv6NA::Deserialize (Buffer::Iterator start)
+{
+ uint8_t buf[16];
+ Buffer::Iterator i = start;
+
+ SetType (i.ReadU8 ());
+ SetCode (i.ReadU8 ());
+ m_checksum = i.ReadU16 ();
+ m_reserved = i.ReadNtohU32 ();
+
+ m_flagR = false;
+ m_flagS = false;
+ m_flagO = false;
+
+ if (m_reserved & (1 << 31))
+ {
+ m_flagR = true;
+ }
+
+ if (m_reserved & (1 << 30))
+ {
+ m_flagS = true;
+ }
+
+ if (m_reserved & (1 << 29))
+ {
+ m_flagO = true;
+ }
+
+ i.Read (buf, 16);
+ m_target.Set (buf);
+
+ return GetSerializedSize ();
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Icmpv6RA);
+
+TypeId Icmpv6RA::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Icmpv6RA")
+ .SetParent<Icmpv6Header> ()
+ .AddConstructor<Icmpv6RA> ()
+ ;
+ return tid;
+}
+
+TypeId Icmpv6RA::GetInstanceTypeId () const
+{
+ return GetTypeId ();
+}
+
+Icmpv6RA::Icmpv6RA ()
+{
+ SetType (ICMPV6_ND_ROUTER_ADVERTISEMENT);
+ SetCode (0);
+ SetFlags (0);
+ SetFlagM (0);
+ SetFlagO (0);
+ SetFlagH (0);
+ SetCurHopLimit (0);
+ SetLifeTime (0);
+ SetRetransmissionTime (0);
+ SetReachableTime (0);
+}
+
+Icmpv6RA::~Icmpv6RA ()
+{
+}
+
+void Icmpv6RA::SetCurHopLimit (uint8_t m)
+{
+ m_curHopLimit = m;
+}
+
+uint8_t Icmpv6RA::GetCurHopLimit () const
+{
+ return m_curHopLimit;
+}
+
+uint16_t Icmpv6RA::GetLifeTime () const
+{
+ return m_LifeTime;
+}
+
+uint32_t Icmpv6RA::GetReachableTime () const
+{
+ return m_ReachableTime;
+}
+
+uint32_t Icmpv6RA::GetRetransmissionTime () const
+{
+ return m_RetransmissionTimer;
+}
+
+void Icmpv6RA::SetLifeTime (uint16_t l)
+{
+ m_LifeTime = l;
+}
+
+void Icmpv6RA::SetReachableTime (uint32_t r)
+{
+ m_ReachableTime = r;
+}
+
+void Icmpv6RA::SetRetransmissionTime (uint32_t r)
+{
+ m_RetransmissionTimer = r;
+}
+
+bool Icmpv6RA::GetFlagM () const
+{
+ return m_flagM;
+}
+
+void Icmpv6RA::SetFlagM (bool m)
+{
+ m_flagM = m;
+}
+
+bool Icmpv6RA::GetFlagO () const
+{
+ return m_flagO;
+}
+
+void Icmpv6RA::SetFlagO (bool o)
+{
+ m_flagO = o;
+}
+
+bool Icmpv6RA::GetFlagH () const
+{
+ return m_flagH;
+}
+
+void Icmpv6RA::SetFlagH (bool h)
+{
+ m_flagH = h;
+}
+
+uint8_t Icmpv6RA::GetFlags () const
+{
+ return m_flags;
+}
+
+void Icmpv6RA::SetFlags (uint8_t f)
+{
+ m_flags = f;
+}
+
+void Icmpv6RA::Print (std::ostream& os) const
+{
+ os << "( type = " << (uint32_t)GetType () << " (RA) code = " << (uint32_t)GetCode () << " checksum = " << (uint32_t)GetChecksum () << ")";
+}
+
+uint32_t Icmpv6RA::GetSerializedSize () const
+{
+ return 16;
+}
+
+void Icmpv6RA::Serialize (Buffer::Iterator start) const
+{
+ uint16_t checksum = 0;
+ Buffer::Iterator i = start;
+ uint8_t flags = 0;
+
+ i.WriteU8 (GetType ());
+ i.WriteU8 (GetCode ());
+ i.WriteHtonU16 (0);
+ i.WriteU8 (m_curHopLimit);
+
+ if (m_flagM)
+ {
+ flags |= (uint8_t)(1<< 7);
+ }
+
+ if (m_flagO)
+ {
+ flags |= (uint8_t)(1<< 6);
+ }
+
+ if (m_flagH)
+ {
+ flags |= (uint8_t)(1<< 5);
+ }
+ i.WriteU8 (flags);
+ i.WriteHtonU16 (GetLifeTime ());
+ i.WriteHtonU32 (GetReachableTime ());
+ i.WriteHtonU32 (GetRetransmissionTime ());
+
+ i = start;
+ checksum = i.CalculateIpChecksum (i.GetSize (), GetChecksum ());
+
+ i = start;
+ i.Next (2);
+ i.WriteU16 (checksum);
+}
+
+uint32_t Icmpv6RA::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+
+ SetType (i.ReadU8 ());
+ SetCode (i.ReadU8 ());
+ m_checksum = i.ReadU16 ();
+ SetCurHopLimit (i.ReadU8 ());
+ m_flags = i.ReadU8 ();
+ m_flagM = false;
+ m_flagO = false;
+ m_flagH = false;
+
+ if (m_flags & (1 << 7))
+ {
+ m_flagM = true;
+ }
+
+ if (m_flags & (1 << 6))
+ {
+ m_flagO = true;
+ }
+
+ if (m_flags & (1 << 5))
+ {
+ m_flagH = true;
+ }
+ SetLifeTime (i.ReadNtohU16 ());
+ SetReachableTime (i.ReadNtohU32 ());
+ SetRetransmissionTime (i.ReadNtohU32 ());
+
+ return GetSerializedSize ();
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Icmpv6RS);
+
+TypeId Icmpv6RS::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Icmpv6RS")
+ .SetParent<Icmpv6Header> ()
+ .AddConstructor<Icmpv6RS> ()
+ ;
+ return tid;
+}
+
+TypeId Icmpv6RS::GetInstanceTypeId () const
+{
+ return GetTypeId ();
+}
+
+Icmpv6RS::Icmpv6RS ()
+{
+ SetType (ICMPV6_ND_ROUTER_SOLICITATION);
+ SetCode (0);
+ SetReserved (0);
+}
+
+Icmpv6RS::~Icmpv6RS ()
+{
+}
+
+uint32_t Icmpv6RS::GetReserved () const
+{
+ return m_reserved;
+}
+
+void Icmpv6RS::SetReserved (uint32_t reserved)
+{
+ m_reserved = reserved;
+}
+
+void Icmpv6RS::Print (std::ostream& os)
+{
+ os << "( type = " << (uint32_t)GetType () << " (RS) code = " << (uint32_t)GetCode () << " checksum = " << (uint32_t)GetChecksum () << ")";
+}
+
+uint32_t Icmpv6RS::GetSerializedSize () const
+{
+ return 8;
+}
+
+void Icmpv6RS::Serialize (Buffer::Iterator start) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ uint16_t checksum = 0;
+ Buffer::Iterator i = start;
+
+ i.WriteU8 (GetType ());
+ i.WriteU8 (GetCode ());
+ i.WriteU16 (0);
+ i.WriteHtonU32 (m_reserved);
+
+ if (m_calcChecksum)
+ {
+ i = start;
+ checksum = i.CalculateIpChecksum (i.GetSize (), GetChecksum ());
+
+ i = start;
+ i.Next (2);
+ i.WriteU16 (checksum);
+ }
+}
+
+uint32_t Icmpv6RS::Deserialize (Buffer::Iterator start)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ Buffer::Iterator i = start;
+
+ SetType (i.ReadU8 ());
+ SetCode (i.ReadU8 ());
+ m_checksum = i.ReadU16 ();
+ m_reserved = i.ReadNtohU32 ();
+
+ return GetSerializedSize ();
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Icmpv6Redirection);
+
+TypeId Icmpv6Redirection::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Icmpv6Redirection")
+ .SetParent<Icmpv6Header> ()
+ .AddConstructor<Icmpv6Redirection> ()
+ ;
+ return tid;
+}
+
+TypeId Icmpv6Redirection::GetInstanceTypeId () const
+{
+ return GetTypeId ();
+}
+
+Icmpv6Redirection::Icmpv6Redirection ()
+ : m_target (Ipv6Address ("")),
+ m_destination (Ipv6Address ("")),
+ m_reserved (0)
+{
+ SetType (ICMPV6_ND_REDIRECTION);
+ SetCode (0);
+ m_checksum = 0;
+}
+
+Icmpv6Redirection::~Icmpv6Redirection ()
+{
+}
+
+void Icmpv6Redirection::SetReserved (uint32_t reserved)
+{
+ m_reserved = reserved;
+}
+
+uint32_t Icmpv6Redirection::GetReserved () const
+{
+ return m_reserved;
+}
+
+Ipv6Address Icmpv6Redirection::GetTarget () const
+{
+ return m_target;
+}
+
+void Icmpv6Redirection::SetTarget (Ipv6Address target)
+{
+ m_target = target;
+}
+
+Ipv6Address Icmpv6Redirection::GetDestination () const
+{
+ return m_destination;
+}
+
+void Icmpv6Redirection::SetDestination (Ipv6Address destination)
+{
+ m_destination = destination;
+}
+
+void Icmpv6Redirection::Print (std::ostream& os)
+{
+ os << "( type = " << (uint32_t)GetType () << " (Redirection) code = " << (uint32_t)GetCode () << " checksum = " << (uint32_t)GetChecksum () << " target = " << m_target << " destination = " << m_destination << ")";
+}
+
+uint32_t Icmpv6Redirection::GetSerializedSize () const
+{
+ return 40;
+}
+
+void Icmpv6Redirection::Serialize (Buffer::Iterator start) const
+{
+ uint8_t buff[16];
+ uint16_t checksum = 0;
+ Buffer::Iterator i = start;
+
+ i.WriteU8 (GetType ());
+ i.WriteU8 (GetCode ());
+ i.WriteU16 (checksum);
+ i.WriteU32 (m_reserved);
+
+ m_target.Serialize (buff);
+ i.Write (buff, 16);
+
+ m_destination.Serialize (buff);
+ i.Write (buff, 16);
+
+ if (m_calcChecksum)
+ {
+ i = start;
+ checksum = i.CalculateIpChecksum (i.GetSize (), GetChecksum ());
+
+ i = start;
+ i.Next (2);
+ i.WriteU16 (checksum);
+ }
+}
+
+uint32_t Icmpv6Redirection::Deserialize (Buffer::Iterator start)
+{
+ uint8_t buff[16];
+ Buffer::Iterator i = start;
+
+ SetType (i.ReadU8 ());
+ SetCode (i.ReadU8 ());
+ m_checksum = i.ReadU16 ();
+ SetReserved (i.ReadU32 ());
+
+ i.Read (buff, 16);
+ m_target.Set (buff);
+
+ i.Read (buff, 16);
+ m_destination.Set (buff);
+
+ return GetSerializedSize ();
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Icmpv6Echo);
+
+TypeId Icmpv6Echo::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Icmpv6Echo")
+ .SetParent<Icmpv6Header> ()
+ .AddConstructor<Icmpv6Echo> ()
+ ;
+ return tid;
+}
+
+TypeId Icmpv6Echo::GetInstanceTypeId () const
+{
+ return GetTypeId ();
+}
+
+Icmpv6Echo::Icmpv6Echo ()
+{
+ SetType (Icmpv6Header::ICMPV6_ECHO_REQUEST);
+ SetCode (0);
+ m_checksum = 0;
+ SetId (0);
+ SetSeq (0);
+}
+
+Icmpv6Echo::Icmpv6Echo (bool request)
+{
+ SetType (request ? Icmpv6Header::ICMPV6_ECHO_REQUEST : Icmpv6Header::ICMPV6_ECHO_REPLY);
+ SetCode (0);
+ m_checksum = 0;
+ SetId (0);
+ SetSeq (0);
+}
+
+Icmpv6Echo::~Icmpv6Echo ()
+{
+}
+
+uint16_t Icmpv6Echo::GetId () const
+{
+ return m_id;
+}
+
+void Icmpv6Echo::SetId (uint16_t id)
+{
+ m_id = id;
+}
+
+uint16_t Icmpv6Echo::GetSeq () const
+{
+ return m_seq;
+}
+
+void Icmpv6Echo::SetSeq (uint16_t seq)
+{
+ m_seq = seq;
+}
+
+void Icmpv6Echo::Print (std::ostream& os) const
+{
+ os << "( type = " << (GetType () == 128 ? "128 (Request)" : "129 (Reply)") <<
+ " code = " << (uint32_t)GetCode () <<
+ " checksum = " << (uint32_t)GetChecksum () << ")";
+}
+
+uint32_t Icmpv6Echo::GetSerializedSize () const
+{
+ return 8;
+}
+
+void Icmpv6Echo::Serialize (Buffer::Iterator start) const
+{
+ uint16_t checksum = 0;
+ Buffer::Iterator i = start;
+
+ i.WriteU8 (GetType ());
+ i.WriteU8 (GetCode ());
+ i.WriteHtonU16 (0);
+
+ i.WriteHtonU16 (m_id);
+ i.WriteHtonU16 (m_seq);
+
+ if (m_calcChecksum)
+ {
+ i = start;
+ checksum = i.CalculateIpChecksum (i.GetSize (), GetChecksum ());
+ i = start;
+ i.Next (2);
+ i.WriteU16 (checksum);
+ }
+}
+
+uint32_t Icmpv6Echo::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+
+ SetType (i.ReadU8 ());
+ SetCode (i.ReadU8 ());
+ m_checksum = i.ReadU16 ();
+
+ m_id = i.ReadNtohU16 ();
+ m_seq = i.ReadNtohU16 ();
+ return GetSerializedSize ();
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Icmpv6DestinationUnreachable);
+
+TypeId Icmpv6DestinationUnreachable::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Icmpv6DestinationUnreachable")
+ .SetParent<Icmpv6Header> ()
+ .AddConstructor<Icmpv6DestinationUnreachable> ()
+ ;
+ return tid;
+}
+
+TypeId Icmpv6DestinationUnreachable::GetInstanceTypeId () const
+{
+ return GetTypeId ();
+}
+
+Icmpv6DestinationUnreachable::Icmpv6DestinationUnreachable ()
+ : m_packet (0)
+{
+ SetType (ICMPV6_ERROR_DESTINATION_UNREACHABLE);
+}
+
+Icmpv6DestinationUnreachable::~Icmpv6DestinationUnreachable ()
+{
+}
+
+Ptr<Packet> Icmpv6DestinationUnreachable::GetPacket () const
+{
+ return m_packet;
+}
+
+void Icmpv6DestinationUnreachable::SetPacket (Ptr<Packet> p)
+{
+ NS_ASSERT (p->GetSize () <= 1280);
+ m_packet = p;
+}
+
+void Icmpv6DestinationUnreachable::Print (std::ostream& os)
+{
+ os << "( type = " << (uint32_t)GetType () << " (Destination Unreachable) code = " << (uint32_t)GetCode () << " checksum = " << (uint32_t)GetChecksum () << ")";
+}
+
+uint32_t Icmpv6DestinationUnreachable::GetSerializedSize () const
+{
+ return 8 + m_packet->GetSize ();
+}
+
+void Icmpv6DestinationUnreachable::Serialize (Buffer::Iterator start) const
+{
+ const uint8_t *packet = m_packet->PeekData ();
+ uint16_t checksum = 0;
+ Buffer::Iterator i = start;
+
+ i.WriteU8 (GetType ());
+ i.WriteU8 (GetCode ());
+ i.WriteHtonU16 (0);
+ i.WriteHtonU32 (0);
+
+ i.Write (packet, m_packet->GetSize ());
+
+ i = start;
+ checksum = i.CalculateIpChecksum (i.GetSize (), GetChecksum ());
+
+ i = start;
+ i.Next (2);
+ i.WriteU16 (checksum);
+}
+
+uint32_t Icmpv6DestinationUnreachable::Deserialize (Buffer::Iterator start)
+{
+ uint16_t length = start.GetSize () - 8;
+ uint8_t data[length];
+ Buffer::Iterator i = start;
+
+ SetType (i.ReadU8 ());
+ SetCode (i.ReadU8 ());
+ m_checksum = i.ReadU16 ();
+ i.ReadNtohU32 ();
+ i.Read (data, length);
+ m_packet = Create<Packet> (data, length);
+
+ return GetSerializedSize ();
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Icmpv6TooBig);
+
+TypeId Icmpv6TooBig::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Icmpv6TooBig")
+ .SetParent<Icmpv6Header> ()
+ .AddConstructor<Icmpv6TooBig> ()
+ ;
+ return tid;
+}
+
+TypeId Icmpv6TooBig::GetInstanceTypeId () const
+{
+ return GetTypeId ();
+}
+
+Icmpv6TooBig::Icmpv6TooBig ()
+ : m_packet (0),
+ m_mtu (0)
+{
+ SetType (ICMPV6_ERROR_PACKET_TOO_BIG);
+}
+
+Icmpv6TooBig::~Icmpv6TooBig ()
+{
+}
+
+Ptr<Packet> Icmpv6TooBig::GetPacket () const
+{
+ return m_packet;
+}
+
+void Icmpv6TooBig::SetPacket (Ptr<Packet> p)
+{
+ NS_ASSERT (p->GetSize () <= 1280);
+ m_packet = p;
+}
+
+uint32_t Icmpv6TooBig::GetMtu () const
+{
+ return m_mtu;
+}
+
+void Icmpv6TooBig::SetMtu (uint32_t mtu)
+{
+ m_mtu = mtu;
+}
+
+void Icmpv6TooBig::Print (std::ostream& os)
+{
+ os << "( type = " << (uint32_t)GetType () << " (Too Big) code = " << (uint32_t)GetCode () << " checksum = " << (uint32_t)GetChecksum () << " mtu = " << (uint32_t)GetMtu () << ")";
+}
+
+uint32_t Icmpv6TooBig::GetSerializedSize () const
+{
+ return 8 + m_packet->GetSize ();
+}
+
+void Icmpv6TooBig::Serialize (Buffer::Iterator start) const
+{
+ const uint8_t *packet = m_packet->PeekData ();
+ uint16_t checksum = 0;
+ Buffer::Iterator i = start;
+
+ i.WriteU8 (GetType ());
+ i.WriteU8 (GetCode ());
+ i.WriteHtonU16 (0);
+ i.WriteHtonU32 (GetMtu ());
+
+ i.Write (packet, m_packet->GetSize ());
+
+ i = start;
+ checksum = i.CalculateIpChecksum (i.GetSize (), GetChecksum ());
+
+ i = start;
+ i.Next (2);
+ i.WriteU16 (checksum);
+}
+
+uint32_t Icmpv6TooBig::Deserialize (Buffer::Iterator start)
+{
+ uint16_t length = start.GetSize () - 8;
+ uint8_t data[length];
+ Buffer::Iterator i = start;
+
+ SetType (i.ReadU8 ());
+ SetCode (i.ReadU8 ());
+ m_checksum = i.ReadU16 ();
+ SetMtu (i.ReadNtohU32 ());
+ i.Read (data, length);
+ m_packet = Create<Packet> (data, length);
+
+ return GetSerializedSize ();
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Icmpv6TimeExceeded);
+
+TypeId Icmpv6TimeExceeded::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Icmpv6TimeExceeded")
+ .SetParent<Icmpv6Header> ()
+ .AddConstructor<Icmpv6TimeExceeded> ()
+ ;
+ return tid;
+}
+
+TypeId Icmpv6TimeExceeded::GetInstanceTypeId () const
+{
+ return GetTypeId ();
+}
+
+Icmpv6TimeExceeded::Icmpv6TimeExceeded ()
+ : m_packet (0)
+{
+ SetType (ICMPV6_ERROR_TIME_EXCEEDED);
+}
+
+Icmpv6TimeExceeded::~Icmpv6TimeExceeded ()
+{
+}
+
+Ptr<Packet> Icmpv6TimeExceeded::GetPacket () const
+{
+ return m_packet;
+}
+
+void Icmpv6TimeExceeded::SetPacket (Ptr<Packet> p)
+{
+ NS_ASSERT (p->GetSize () <= 1280);
+ m_packet = p;
+}
+
+void Icmpv6TimeExceeded::Print (std::ostream& os)
+{
+ os << "( type = " << (uint32_t)GetType () << " (Destination Unreachable) code = " << (uint32_t)GetCode () << " checksum = " << (uint32_t)GetChecksum () << ")";
+}
+
+uint32_t Icmpv6TimeExceeded::GetSerializedSize () const
+{
+ return 8 + m_packet->GetSize ();
+}
+
+void Icmpv6TimeExceeded::Serialize (Buffer::Iterator start) const
+{
+ const uint8_t *packet = m_packet->PeekData ();
+ uint16_t checksum = 0;
+ Buffer::Iterator i = start;
+
+ i.WriteU8 (GetType ());
+ i.WriteU8 (GetCode ());
+ i.WriteHtonU16 (0);
+ i.WriteHtonU32 (0);
+
+ i.Write (packet, m_packet->GetSize ());
+
+ i = start;
+ checksum = i.CalculateIpChecksum (i.GetSize (), GetChecksum ());
+
+ i = start;
+ i.Next (2);
+ i.WriteU16 (checksum);
+}
+
+uint32_t Icmpv6TimeExceeded::Deserialize (Buffer::Iterator start)
+{
+ uint16_t length = start.GetSize () - 8;
+ uint8_t data[length];
+ Buffer::Iterator i = start;
+
+ SetType (i.ReadU8 ());
+ SetCode (i.ReadU8 ());
+ m_checksum = i.ReadU16 ();
+ i.ReadNtohU32 ();
+ i.Read (data, length);
+ m_packet = Create<Packet> (data, length);
+
+ return GetSerializedSize ();
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Icmpv6ParameterError);
+
+TypeId Icmpv6ParameterError::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Icmpv6ParameterError")
+ .SetParent<Icmpv6Header> ()
+ .AddConstructor<Icmpv6ParameterError> ()
+ ;
+ return tid;
+}
+
+TypeId Icmpv6ParameterError::GetInstanceTypeId () const
+{
+ return GetTypeId ();
+}
+
+Icmpv6ParameterError::Icmpv6ParameterError ()
+ : m_packet (0),
+ m_ptr (0)
+{
+ SetType (ICMPV6_ERROR_PARAMETER_ERROR);
+}
+
+Icmpv6ParameterError::~Icmpv6ParameterError ()
+{
+}
+
+Ptr<Packet> Icmpv6ParameterError::GetPacket () const
+{
+ return m_packet;
+}
+
+void Icmpv6ParameterError::SetPacket (Ptr<Packet> p)
+{
+ NS_ASSERT (p->GetSize () <= 1280);
+ m_packet = p;
+}
+
+uint32_t Icmpv6ParameterError::GetPtr () const
+{
+ return m_ptr;
+}
+
+void Icmpv6ParameterError::SetPtr (uint32_t ptr)
+{
+ m_ptr = ptr;
+}
+
+void Icmpv6ParameterError::Print (std::ostream& os)
+{
+ os << "( type = " << (uint32_t)GetType () << " (Destination Unreachable) code = " << (uint32_t)GetCode () << " checksum = " << (uint32_t)GetChecksum () << " ptr = " << (uint32_t)GetPtr () << ")";
+}
+
+uint32_t Icmpv6ParameterError::GetSerializedSize () const
+{
+ return 8 + m_packet->GetSize ();
+}
+
+void Icmpv6ParameterError::Serialize (Buffer::Iterator start) const
+{
+ const uint8_t *packet = m_packet->PeekData ();
+ uint16_t checksum = 0;
+ Buffer::Iterator i = start;
+
+ i.WriteU8 (GetType ());
+ i.WriteU8 (GetCode ());
+ i.WriteHtonU16 (0);
+ i.WriteHtonU32 (GetPtr ());
+
+ i.Write (packet, m_packet->GetSize ());
+
+ i = start;
+ checksum = i.CalculateIpChecksum (i.GetSize (), GetChecksum ());
+
+ i = start;
+ i.Next (2);
+ i.WriteU16 (checksum);
+}
+
+uint32_t Icmpv6ParameterError::Deserialize (Buffer::Iterator start)
+{
+ uint16_t length = start.GetSize () - 8;
+ uint8_t data[length];
+ Buffer::Iterator i = start;
+
+ SetType (i.ReadU8 ());
+ SetCode (i.ReadU8 ());
+ m_checksum = i.ReadU16 ();
+ SetPtr (i.ReadNtohU32 ());
+ i.Read (data, length);
+ m_packet = Create<Packet> (data, length);
+
+ return GetSerializedSize ();
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Icmpv6OptionHeader);
+
+TypeId Icmpv6OptionHeader::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Icmpv6OptionHeader")
+ .SetParent<Header> ()
+ .AddConstructor<Icmpv6OptionHeader> ()
+ ;
+ return tid;
+}
+
+TypeId Icmpv6OptionHeader::GetInstanceTypeId () const
+{
+ return GetTypeId ();
+}
+
+
+Icmpv6OptionHeader::Icmpv6OptionHeader ()
+{
+ /* TODO */
+ m_type = 0;
+ m_len = 0;
+}
+
+Icmpv6OptionHeader::~Icmpv6OptionHeader ()
+{
+}
+
+uint8_t Icmpv6OptionHeader::GetType () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_type;
+}
+
+void Icmpv6OptionHeader::SetType (uint8_t type)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_type = type;
+}
+
+uint8_t Icmpv6OptionHeader::GetLength () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_len;
+}
+
+void Icmpv6OptionHeader::SetLength (uint8_t len)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_len = len;
+}
+
+void Icmpv6OptionHeader::Print (std::ostream& os) const
+{
+ os << "( type = " << (uint32_t)GetType () << " length = " << (uint32_t)GetLength () << ")";
+}
+
+uint32_t Icmpv6OptionHeader::GetSerializedSize () const
+{
+ return m_len*8;
+}
+
+uint32_t Icmpv6OptionHeader::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+ return GetSerializedSize ();
+}
+
+void Icmpv6OptionHeader::Serialize (Buffer::Iterator start) const
+{
+ Buffer::Iterator i = start;
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Icmpv6OptionMtu);
+
+TypeId Icmpv6OptionMtu::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Icmpv6OptionMtu")
+ .SetParent<Icmpv6OptionHeader> ()
+ .AddConstructor<Icmpv6OptionMtu> ()
+ ;
+ return tid;
+}
+
+TypeId Icmpv6OptionMtu::GetInstanceTypeId () const
+{
+ return GetTypeId ();
+}
+
+Icmpv6OptionMtu::Icmpv6OptionMtu ()
+{
+ SetType (Icmpv6Header::ICMPV6_OPT_MTU);
+ SetLength (1);
+ SetReserved (0);
+}
+
+Icmpv6OptionMtu::Icmpv6OptionMtu (uint32_t mtu)
+ : m_mtu (mtu)
+{
+ SetType (Icmpv6Header::ICMPV6_OPT_MTU);
+ SetLength (1);
+ SetReserved (0);
+}
+
+Icmpv6OptionMtu::~Icmpv6OptionMtu ()
+{
+}
+
+uint16_t Icmpv6OptionMtu::GetReserved () const
+{
+ return m_reserved;
+}
+
+void Icmpv6OptionMtu::SetReserved (uint16_t reserved)
+{
+ m_reserved = reserved;
+}
+
+uint32_t Icmpv6OptionMtu::GetMtu () const
+{
+ return m_mtu;
+}
+
+void Icmpv6OptionMtu::SetMtu (uint32_t mtu)
+{
+ m_mtu = mtu;
+}
+
+void Icmpv6OptionMtu::Print (std::ostream& os) const
+{
+ os << "( type = " << (uint32_t)GetType () << " length = " << (uint32_t)GetLength () << " MTU = " << m_mtu << ")";
+}
+
+uint32_t Icmpv6OptionMtu::GetSerializedSize () const
+{
+ return 8; /* m_len = 1 so the real size is multiple by 8 */
+}
+
+void Icmpv6OptionMtu::Serialize (Buffer::Iterator start) const
+{
+ Buffer::Iterator i = start;
+ i.WriteU8 (GetType ());
+ i.WriteU8 (GetLength ());
+ i.WriteHtonU16 (GetReserved ());
+ i.WriteHtonU32 (GetMtu ());
+}
+
+uint32_t Icmpv6OptionMtu::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+ SetType (i.ReadU8 ());
+ SetLength (i.ReadU8 ());
+ SetReserved (i.ReadNtohU16 ());
+ SetMtu (i.ReadNtohU32 ());
+ return GetSerializedSize ();
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Icmpv6OptionPrefixInformation);
+
+TypeId Icmpv6OptionPrefixInformation::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Icmpv6OptionPrefixInformation")
+ .SetParent<Icmpv6OptionHeader> ()
+ .AddConstructor<Icmpv6OptionPrefixInformation> ()
+ ;
+ return tid;
+}
+
+TypeId Icmpv6OptionPrefixInformation::GetInstanceTypeId () const
+{
+ return GetTypeId ();
+}
+
+Icmpv6OptionPrefixInformation::Icmpv6OptionPrefixInformation ()
+{
+ SetType (Icmpv6Header::ICMPV6_OPT_PREFIX);
+ SetLength (4);
+ SetPrefix (Ipv6Address ("::"));
+ SetPrefixLength (0);
+ SetValidTime (0);
+ SetPreferredTime (0);
+ SetFlags (0);
+ SetReserved (0);
+}
+
+Icmpv6OptionPrefixInformation::Icmpv6OptionPrefixInformation (Ipv6Address prefix, uint8_t prefixlen)
+{
+ SetType (Icmpv6Header::ICMPV6_OPT_PREFIX);
+ SetLength (4);
+ SetPrefix (prefix);
+ SetPrefixLength (prefixlen);
+ SetValidTime (0);
+ SetPreferredTime (0);
+ SetFlags (0);
+ SetReserved (0);
+}
+
+Icmpv6OptionPrefixInformation::~Icmpv6OptionPrefixInformation ()
+{
+}
+
+uint8_t Icmpv6OptionPrefixInformation::GetPrefixLength () const
+{
+ return m_prefixLength;
+}
+
+void Icmpv6OptionPrefixInformation::SetPrefixLength (uint8_t prefixLength)
+{
+ NS_ASSERT (prefixLength <= 128);
+ m_prefixLength = prefixLength;
+}
+
+uint8_t Icmpv6OptionPrefixInformation::GetFlags () const
+{
+ return m_flags;
+}
+
+void Icmpv6OptionPrefixInformation::SetFlags (uint8_t flags)
+{
+ m_flags = flags;
+}
+
+uint32_t Icmpv6OptionPrefixInformation::GetValidTime () const
+{
+ return m_validTime;
+}
+
+void Icmpv6OptionPrefixInformation::SetValidTime (uint32_t validTime)
+{
+ m_validTime = validTime;
+}
+
+uint32_t Icmpv6OptionPrefixInformation::GetPreferredTime () const
+{
+ return m_preferredTime;
+}
+
+void Icmpv6OptionPrefixInformation::SetPreferredTime (uint32_t preferredTime)
+{
+ m_preferredTime = preferredTime;
+}
+
+uint32_t Icmpv6OptionPrefixInformation::GetReserved () const
+{
+ return m_preferredTime;
+}
+
+void Icmpv6OptionPrefixInformation::SetReserved (uint32_t reserved)
+{
+ m_reserved = reserved;
+}
+
+Ipv6Address Icmpv6OptionPrefixInformation::GetPrefix () const
+{
+ return m_prefix;
+}
+
+void Icmpv6OptionPrefixInformation::SetPrefix (Ipv6Address prefix)
+{
+ m_prefix = prefix;
+}
+
+void Icmpv6OptionPrefixInformation::Print (std::ostream& os) const
+{
+ os << "( type = " << (uint32_t)GetType () << " length = " << (uint32_t)GetLength () << " prefix " << m_prefix << ")";
+}
+
+uint32_t Icmpv6OptionPrefixInformation::GetSerializedSize () const
+{
+ return 32;
+}
+
+void Icmpv6OptionPrefixInformation::Serialize (Buffer::Iterator start) const
+{
+ Buffer::Iterator i = start;
+ uint8_t buf[16];
+
+ memset (buf, 0x00, sizeof (buf));
+
+ i.WriteU8 (GetType ());
+ i.WriteU8 (GetLength ());
+ i.WriteU8 (m_prefixLength);
+ i.WriteU8 (m_flags);
+ i.WriteHtonU32 (m_validTime);
+ i.WriteHtonU32 (m_preferredTime);
+ i.WriteHtonU32 (m_reserved);
+ m_prefix.GetBytes (buf);
+ i.Write (buf, 16);
+}
+
+uint32_t Icmpv6OptionPrefixInformation::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+ uint8_t buf[16];
+
+ SetType (i.ReadU8 ());
+ SetLength (i.ReadU8 ());
+ SetPrefixLength (i.ReadU8 ());
+ SetFlags (i.ReadU8 ());
+ SetValidTime (i.ReadNtohU32 ());
+ SetPreferredTime (i.ReadNtohU32 ());
+ SetReserved (i.ReadNtohU32 ());
+ i.Read (buf, 16);
+
+ Ipv6Address prefix (buf);
+ SetPrefix (prefix);
+
+ return GetSerializedSize ();
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Icmpv6OptionLinkLayerAddress);
+
+TypeId Icmpv6OptionLinkLayerAddress::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Icmpv6OptionLinkLayerAddress")
+ .SetParent<Icmpv6OptionHeader> ()
+ .AddConstructor<Icmpv6OptionLinkLayerAddress> ()
+ ;
+ return tid;
+}
+
+TypeId Icmpv6OptionLinkLayerAddress::GetInstanceTypeId () const
+{
+ return GetTypeId ();
+}
+
+Icmpv6OptionLinkLayerAddress::Icmpv6OptionLinkLayerAddress (bool source)
+{
+ SetType (source ? Icmpv6Header::ICMPV6_OPT_LINK_LAYER_SOURCE : Icmpv6Header::ICMPV6_OPT_LINK_LAYER_TARGET);
+}
+
+Icmpv6OptionLinkLayerAddress::Icmpv6OptionLinkLayerAddress ()
+{
+ SetType (Icmpv6Header::ICMPV6_OPT_LINK_LAYER_SOURCE);
+}
+
+Icmpv6OptionLinkLayerAddress::Icmpv6OptionLinkLayerAddress (bool source, Address addr)
+{
+ SetType (source ? Icmpv6Header::ICMPV6_OPT_LINK_LAYER_SOURCE : Icmpv6Header::ICMPV6_OPT_LINK_LAYER_TARGET);
+ SetAddress (addr);
+ SetLength (GetSerializedSize () / 8);
+}
+
+Icmpv6OptionLinkLayerAddress::~Icmpv6OptionLinkLayerAddress ()
+{
+}
+
+Address Icmpv6OptionLinkLayerAddress::GetAddress () const
+{
+ return m_addr;
+}
+
+void Icmpv6OptionLinkLayerAddress::SetAddress (Address addr)
+{
+ m_addr = addr;
+}
+
+void Icmpv6OptionLinkLayerAddress::Print (std::ostream& os) const
+{
+ os << "( type = " << (uint32_t)GetType () << " length = " << (uint32_t)GetLength () << " L2 Address = " << m_addr << ")";
+}
+
+uint32_t Icmpv6OptionLinkLayerAddress::GetSerializedSize () const
+{
+ /* TODO add padding */
+ uint8_t nb = 2 + m_addr.GetLength ();
+ return nb;
+}
+
+void Icmpv6OptionLinkLayerAddress::Serialize (Buffer::Iterator start) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ Buffer::Iterator i = start;
+ uint8_t mac[32];
+
+ i.WriteU8 (GetType ());
+ i.WriteU8 (GetLength ());
+ m_addr.CopyTo (mac);
+ i.Write (mac, m_addr.GetLength ());
+
+ /* XXX if size of the option is not a multiple of 8, add padding */
+}
+
+uint32_t Icmpv6OptionLinkLayerAddress::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+ uint8_t mac[32];
+
+ SetType (i.ReadU8 ());
+ SetLength (i.ReadU8 ());
+ i.Read (mac, (GetLength () * 8) - 2);
+
+ m_addr.CopyFrom (mac, (GetLength () * 8)-2);
+
+ return GetSerializedSize ();
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Icmpv6OptionRedirected);
+
+TypeId Icmpv6OptionRedirected::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Icmpv6OptionRedirected")
+ .SetParent<Icmpv6OptionHeader> ()
+ .AddConstructor<Icmpv6OptionRedirected> ()
+ ;
+ return tid;
+}
+
+TypeId Icmpv6OptionRedirected::GetInstanceTypeId () const
+{
+ return GetTypeId ();
+}
+
+Icmpv6OptionRedirected::Icmpv6OptionRedirected ()
+ : m_packet (0)
+{
+ SetType (Icmpv6Header::ICMPV6_OPT_REDIRECTED);
+}
+
+Icmpv6OptionRedirected::~Icmpv6OptionRedirected ()
+{
+ m_packet = 0;
+}
+
+Ptr<Packet> Icmpv6OptionRedirected::GetPacket () const
+{
+ return m_packet;
+}
+
+void Icmpv6OptionRedirected::SetPacket (Ptr<Packet> packet)
+{
+ NS_ASSERT (packet->GetSize () <= 1280);
+ m_packet = packet;
+ SetLength (1 + (m_packet->GetSize () / 8));
+}
+
+void Icmpv6OptionRedirected::Print (std::ostream& os) const
+{
+ os << "( type = " << (uint32_t)GetType () << " length = " << (uint32_t)GetLength () << ")";
+}
+
+uint32_t Icmpv6OptionRedirected::GetSerializedSize () const
+{
+ return 8 + m_packet->GetSize ();
+}
+
+void Icmpv6OptionRedirected::Serialize (Buffer::Iterator start) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ Buffer::Iterator i = start;
+
+ i.WriteU8 (GetType ());
+ i.WriteU8 (GetLength ());
+ // Reserved
+ i.WriteU16 (0);
+ i.WriteU32 (0);
+
+ i.Write (m_packet->PeekData (), m_packet->GetSize ());
+}
+
+uint32_t Icmpv6OptionRedirected::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+
+ SetType (i.ReadU8 ());
+ uint8_t length = i.ReadU8 ();
+ SetLength (length);
+ i.ReadU16 ();
+ i.ReadU32 ();
+
+ uint32_t len2 = (GetLength () - 1) * 8;
+ uint8_t buff[len2];
+ i.Read (buff, len2);
+ m_packet = Create<Packet> (buff, len2);
+
+ return GetSerializedSize ();
+}
+
+} /* namespace ns3 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/icmpv6-header.h Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,1785 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ * Mehdi Benamor <benamor.mehdi@ensi.rnu.tn>
+ * David Gross <gdavid.devel@gmail.com>
+ */
+
+#ifndef ICMPV6_HEADER_H
+#define ICMPV6_HEADER_H
+
+#include "ns3/header.h"
+#include "ns3/ipv6-address.h"
+#include "ns3/packet.h"
+
+namespace ns3
+{
+
+/**
+ * \class Icmpv6Header
+ * \brief ICMPv6 header.
+ */
+class Icmpv6Header : public Header
+{
+ public:
+ /**
+ * \enum Type_e
+ * \brief ICMPv6 type code.
+ */
+ enum Type_e
+ {
+ ICMPV6_ERROR_DESTINATION_UNREACHABLE = 1,
+ ICMPV6_ERROR_PACKET_TOO_BIG,
+ ICMPV6_ERROR_TIME_EXCEEDED,
+ ICMPV6_ERROR_PARAMETER_ERROR,
+ ICMPV6_ECHO_REQUEST=128,
+ ICMPV6_ECHO_REPLY,
+ ICMPV6_SUBSCRIBE_REQUEST,
+ ICMPV6_SUBSCRIBE_REPORT,
+ ICMPV6_SUBSCRIVE_END,
+ ICMPV6_ND_ROUTER_SOLICITATION,
+ ICMPV6_ND_ROUTER_ADVERTISEMENT,
+ ICMPV6_ND_NEIGHBOR_SOLICITATION,
+ ICMPV6_ND_NEIGHBOR_ADVERTISEMENT,
+ ICMPV6_ND_REDIRECTION,
+ ICMPV6_ROUTER_RENUMBER,
+ ICMPV6_INFORMATION_REQUEST,
+ ICMPV6_INFORMATION_RESPONSE,
+ ICMPV6_INVERSE_ND_SOLICITATION,
+ ICMPV6_INVERSE_ND_ADVERSTISEMENT,
+ ICMPV6_MLDV2_SUBSCRIBE_REPORT,
+ ICMPV6_MOBILITY_HA_DISCOVER_REQUEST,
+ ICMPV6_MOBILITY_HA_DISCOVER_RESPONSE,
+ ICMPV6_MOBILITY_MOBILE_PREFIX_SOLICITATION,
+ ICMPV6_SECURE_ND_CERTIFICATE_PATH_SOLICITATION,
+ ICMPV6_SECURE_ND_CERTIFICATE_PATH_ADVERTISEMENT,
+ ICMPV6_EXPERIMENTAL_MOBILITY
+ };
+
+ /**
+ * \enum OptionType_e
+ * \brief ICMPv6 Option type code.
+ */
+ enum OptionType_e
+ {
+ ICMPV6_OPT_LINK_LAYER_SOURCE = 1,
+ ICMPV6_OPT_LINK_LAYER_TARGET,
+ ICMPV6_OPT_PREFIX,
+ ICMPV6_OPT_REDIRECTED,
+ ICMPV6_OPT_MTU
+ };
+
+ /**
+ * \enum ErrorDestinationUnreachable_e
+ * \brief ICMPv6 error code : Destination Unreachable
+ */
+ enum ErrorDestinationUnreachable_e
+ {
+ ICMPV6_NO_ROUTE = 0,
+ ICMPV6_ADM_PROHIBITED,
+ ICMPV6_NOT_NEIGHBOUR,
+ ICMPV6_ADDR_UNREACHABLE,
+ ICMPV6_PORT_UNREACHABLE
+ };
+
+ /**
+ * \enum ErrorTimeExceeded_e
+ * \brief ICMPv6 error code : Time Exceeded
+ */
+ enum ErrorTimeExceeded_e
+ {
+ ICMPV6_HOPLIMIT = 0,
+ ICMPV6_FRAGTIME
+ };
+
+ /**
+ * \enum ErrorParameterError_e
+ * \brief ICMPv6 error code : Parameter Error
+ */
+ enum ErrorParameterError_e
+ {
+ ICMPV6_MALFORMED_HEADER = 0,
+ ICMPV6_UNKNOWN_NEXT_HEADER,
+ ICMPV6_UNKNOWN_OPTION
+ };
+
+ /**
+ * \brief Get the UID of this class.
+ * \return UID
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Get the instance type ID.
+ * \return instance type ID
+ */
+ virtual TypeId GetInstanceTypeId () const;
+
+ /**
+ * \brief Constructor.
+ */
+ Icmpv6Header ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Icmpv6Header ();
+
+ /**
+ * \brief Get the type field.
+ * \return type of ICMPv6 message
+ */
+ uint8_t GetType () const;
+
+ /**
+ * \brief Set the type.
+ * \param type type to set
+ */
+ void SetType (uint8_t type);
+
+ /**
+ * \brief Get the code field.
+ * \return code of ICMPv6 message
+ */
+ uint8_t GetCode () const;
+
+ /**
+ * \brief Set the code field.
+ * \param code code to set
+ */
+ void SetCode (uint8_t code);
+
+ /**
+ * \brief Get the checksum.
+ * \return checksum
+ */
+ uint16_t GetChecksum () const;
+
+ /**
+ * \brief Set the checksum.
+ * \param checksum to set
+ */
+ void SetChecksum (uint16_t checksum);
+
+ /**
+ * \brief Print informations.
+ * \param os output stream
+ */
+ virtual void Print (std::ostream& os) const;
+
+ /**
+ * \brief Get the serialized size.
+ * \return serialized size
+ */
+ virtual uint32_t GetSerializedSize () const;
+
+ /**
+ * \brief Serialize the packet.
+ * \param start start offset
+ */
+ virtual void Serialize (Buffer::Iterator start) const;
+
+ /**
+ * \brief Deserialize the packet.
+ * \param start start offset
+ * \return length of packet
+ */
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+
+ /**
+ * \brief Calculate pseudo header checksum for IPv6.
+ * \param src source address
+ * \param dst destination address
+ * \param length length
+ * \param protocol the protocol number to use in the
+ * underlying IPv6 packet.
+ */
+ void CalculatePseudoHeaderChecksum (Ipv6Address src, Ipv6Address dst, uint16_t length, uint8_t protocol);
+
+ protected:
+ /**
+ * \brief Checksum enable or not.
+ */
+ bool m_calcChecksum;
+
+ /**
+ * \brief The checksum.
+ */
+ uint16_t m_checksum;
+
+ private:
+ /**
+ * \brief The type.
+ */
+ uint8_t m_type;
+
+ /**
+ * \brief The code.
+ */
+ uint8_t m_code;
+};
+
+/**
+ * \class Icmpv6OptionHeader
+ * \brief ICMPv6 option header.
+ */
+class Icmpv6OptionHeader : public Header
+{
+ public:
+ /**
+ * \brief Get the UID of this class.
+ * \return UID
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Get the instance type ID.
+ * \return instance type ID
+ */
+ virtual TypeId GetInstanceTypeId () const;
+
+ /**
+ * \brief Constructor.
+ */
+ Icmpv6OptionHeader ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Icmpv6OptionHeader ();
+
+ /**
+ * \brief Get the type of the option.
+ * \return type
+ */
+ uint8_t GetType () const;
+
+ /**
+ * \brief Set the type of the option.
+ * \param type the type to set
+ */
+ void SetType (uint8_t type);
+
+ /**
+ * \brief Get the length of the option in 8 bytes unit.
+ * \return length of the option
+ */
+ uint8_t GetLength () const;
+
+ /**
+ * \brief Set the length of the option.
+ * \param len length value to set
+ */
+ void SetLength (uint8_t len);
+
+ /**
+ * \brief Print informations.
+ * \param os output stream
+ */
+ virtual void Print (std::ostream& os) const;
+
+ /**
+ * \brief Get the serialized size.
+ * \return serialized size
+ */
+ virtual uint32_t GetSerializedSize () const;
+
+ /**
+ * \brief Serialize the packet.
+ * \param start start offset
+ */
+ virtual void Serialize (Buffer::Iterator start) const;
+
+ /**
+ * \brief Deserialize the packet.
+ * \param start start offset
+ * \return length of packet
+ */
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+
+ private:
+ /**
+ * \brief The type.
+ */
+ uint8_t m_type;
+
+ /**
+ * \brief The length.
+ */
+ uint8_t m_len;
+};
+
+/**
+ * \class Icmpv6NS
+ * \brief ICMPv6 Neighbor Solicitation header.
+ */
+class Icmpv6NS : public Icmpv6Header
+{
+ public:
+ /**
+ * \brief Constructor.
+ * \param target target IPv6 address
+ */
+ Icmpv6NS (Ipv6Address target);
+
+ /**
+ * \brief Constructor.
+ */
+ Icmpv6NS ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Icmpv6NS ();
+
+ /**
+ * \brief Get the UID of this class.
+ * \return UID
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Get the instance type ID.
+ * \return instance type ID
+ */
+ virtual TypeId GetInstanceTypeId () const;
+
+ /**
+ * \brief Get the reserved field.
+ * \return reserved value
+ */
+ uint32_t GetReserved () const;
+
+ /**
+ * \brief Set the reserved field.
+ * \param reserved the reserved value
+ */
+ void SetReserved (uint32_t reserved);
+
+ /**
+ * \brief Get the IPv6 target field.
+ * \return IPv6 address
+ */
+ Ipv6Address GetIpv6Target () const;
+
+ /**
+ * \brief Set the IPv6 target field.
+ * \param target IPv6 address
+ */
+ void SetIpv6Target (Ipv6Address target);
+
+ /**
+ * \brief Get the IPv6 target field.
+ * \return IPv6 address
+ */
+ virtual void Print (std::ostream& os) const;
+
+ /**
+ * \brief Get the serialized size.
+ * \return serialized size
+ */
+ virtual uint32_t GetSerializedSize () const;
+
+ /**
+ * \brief Serialize the packet.
+ * \param start start offset
+ */
+ virtual void Serialize (Buffer::Iterator start) const;
+
+ /**
+ * \brief Deserialize the packet.
+ * \param start start offset
+ * \return length of packet
+ */
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+
+ private:
+
+ /**
+ * \brief The reserved value.
+ */
+ uint32_t m_reserved;
+
+ /**
+ * \brief The IPv6 target address.
+ */
+ Ipv6Address m_target;
+};
+
+/**
+ * \class Icmpv6NA
+ * \brief ICMPv6 Neighbor Advertisement header.
+ */
+class Icmpv6NA : public Icmpv6Header
+{
+ public:
+ /**
+ * \brief Constructor.
+ */
+ Icmpv6NA ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Icmpv6NA ();
+
+ /**
+ * \brief Get the UID of this class.
+ * \return UID
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Get the instance type ID.
+ * \return instance type ID
+ */
+ virtual TypeId GetInstanceTypeId () const;
+
+ /**
+ * \brief Get the reserved field.
+ * \return reserved value
+ */
+ uint32_t GetReserved () const;
+
+ /**
+ * \brief Set the reserved field.
+ * \param reserved the reserved value
+ */
+ void SetReserved (uint32_t reserved);
+
+ /**
+ * \brief Get the IPv6 target field.
+ * \return IPv6 address
+ */
+ Ipv6Address GetIpv6Target () const;
+
+ /**
+ * \brief Set the IPv6 target field.
+ * \param target IPv6 address
+ */
+ void SetIpv6Target (Ipv6Address target);
+
+ /**
+ * \brief Get the R flag.
+ * \return R flag
+ */
+ bool GetFlagR () const;
+
+ /**
+ * \brief Set the R flag.
+ * \param r value
+ */
+ void SetFlagR (bool r);
+
+ /**
+ * \brief Get the S flag.
+ * \return S flag
+ */
+ bool GetFlagS () const;
+
+ /**
+ * \brief Set the S flag.
+ * \param s value
+ */
+ void SetFlagS (bool s);
+
+ /**
+ * \brief Get the O flag.
+ * \return O flag
+ */
+ bool GetFlagO () const;
+
+ /**
+ * \brief Set the O flag.
+ * \param o value
+ */
+ void SetFlagO (bool o);
+
+ /**
+ * \brief Print informations.
+ * \param os output stream
+ */
+ virtual void Print (std::ostream& os) const;
+
+ /**
+ * \brief Get the serialized size.
+ * \return serialized size
+ */
+ virtual uint32_t GetSerializedSize () const;
+
+ /**
+ * \brief Serialize the packet.
+ * \param start start offset
+ */
+ virtual void Serialize (Buffer::Iterator start) const;
+
+ /**
+ * \brief Deserialize the packet.
+ * \param start start offset
+ * \return length of packet
+ */
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+
+ private:
+ /**
+ * \brief The R flag.
+ */
+ bool m_flagR;
+
+ /**
+ * \brief The O flag.
+ */
+ bool m_flagS;
+
+ /**
+ * \brief The M flag.
+ */
+ bool m_flagO;
+
+ /**
+ * \brief The reserved value.
+ */
+ uint32_t m_reserved;
+
+ /**
+ * \brief The IPv6 target address.
+ */
+ Ipv6Address m_target;
+};
+
+/**
+ * \class Icmpv6RA
+ * \brief ICMPv6 Router Advertisement header.
+ */
+class Icmpv6RA : public Icmpv6Header
+{
+ public:
+ /**
+ * \brief Constructor.
+ */
+ Icmpv6RA ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Icmpv6RA ();
+
+ /**
+ * \brief Get the UID of this class.
+ * \return UID
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Get the instance type ID.
+ * \return instance type ID
+ */
+ virtual TypeId GetInstanceTypeId () const;
+
+ /**
+ * \brief Set the IPv6 maximum number of jumps.
+ * \param m maximum jumps
+ */
+ void SetCurHopLimit (uint8_t m);
+
+ /**
+ * \brief Get the IPv6 maximum number of jumps.
+ * \return maximum jumps
+ */
+ uint8_t GetCurHopLimit () const;
+
+ /**
+ * \brief Set the node Life time (Neighbor Discovery).
+ * \param l life time
+ */
+ void SetLifeTime (uint16_t l);
+
+ /**
+ * \brief Get the node Life time (Neighbor Discovery).
+ * \return life time
+ */
+ uint16_t GetLifeTime () const;
+
+ /**
+ * \brief Set the node Reachable time (Neighbor Discovery).
+ * \param r Reachable time
+ */
+ void SetReachableTime (uint32_t r);
+
+ /**
+ * \brief Get the node Reachable time (Neighbor Discovery).
+ * \return reachable time
+ */
+ uint32_t GetReachableTime () const;
+
+ /**
+ * \brief Set the node Retransmission time (Neighbor Discovery).
+ * \param r Retransmission time
+ */
+ void SetRetransmissionTime (uint32_t r);
+
+ /**
+ * \brief Get the node Retransmission time (Neighbor Discovery).
+ * \return retransmission time
+ */
+ uint32_t GetRetransmissionTime () const;
+
+ /**
+ * \brief Get the M flag.
+ * \return M flag
+ */
+ bool GetFlagM () const;
+
+ /**
+ * \brief Set the M flag.
+ * \param m value
+ */
+ void SetFlagM (bool m);
+
+ /**
+ * \brief Get the O flag.
+ * \return O flag
+ */
+ bool GetFlagO () const;
+
+ /**
+ * \brief Set the O flag.
+ * \param o value
+ */
+ void SetFlagO (bool o);
+
+ /**
+ * \brief Get the H flag.
+ * \return H flag
+ */
+ bool GetFlagH () const;
+
+ /**
+ * \brief Set the H flag.
+ * \param h value
+ */
+ void SetFlagH (bool h);
+
+ /**
+ * \brief Print informations.
+ * \param os output stream
+ */
+ virtual void Print (std::ostream& os) const;
+
+ /**
+ * \brief Getflags.
+ * \return the flags value
+ */
+ uint8_t GetFlags () const;
+
+ /**
+ * \brief Setflags.
+ * \param f the flags value
+ */
+ void SetFlags (uint8_t f);
+
+ /**
+ * \brief Get the serialized size.
+ * \return serialized size
+ */
+ virtual uint32_t GetSerializedSize () const;
+
+ /**
+ * \brief Serialize the packet.
+ * \param start start offset
+ */
+ virtual void Serialize (Buffer::Iterator start) const;
+
+ /**
+ * \brief Deserialize the packet.
+ * \param start start offset
+ * \return length of packet
+ */
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+
+ private:
+ /**
+ * \brief The M flag.
+ */
+ bool m_flagM;
+
+ /**
+ * \brief The O flag.
+ */
+ bool m_flagO;
+
+ /**
+ * \brief The H flag.
+ */
+ bool m_flagH;
+
+ /**
+ * \brief The flags field value.
+ */
+ uint8_t m_flags;
+
+ /**
+ * \brief The lifetime value.
+ */
+ uint16_t m_LifeTime;
+
+ /**
+ * \brief The reachable time value.
+ */
+ uint32_t m_ReachableTime;
+
+ /**
+ * \brief The retransmission timer.
+ */
+ uint32_t m_RetransmissionTimer;
+
+ /**
+ * \brief The max jumps.
+ */
+ uint8_t m_curHopLimit;
+};
+
+/**
+ * \class Icmpv6RS
+ * \brief ICMPv6 Router Solicitation header.
+ */
+class Icmpv6RS : public Icmpv6Header
+{
+ public:
+ /**
+ * \brief Constructor.
+ */
+ Icmpv6RS ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Icmpv6RS ();
+
+ /**
+ * \brief Get the UID of this class.
+ * \return UID
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Get the instance type ID.
+ * \return instance type ID
+ */
+ virtual TypeId GetInstanceTypeId () const;
+
+ /**
+ * \brief Get the reserved field.
+ * \return reserved value
+ */
+ uint32_t GetReserved () const;
+
+ /**
+ * \brief Set the reserved field.
+ * \param reserved the reserved value
+ */
+ void SetReserved (uint32_t reserved);
+
+ /**
+ * \brief Print informations.
+ * \param os output stream
+ */
+ virtual void Print (std::ostream& os);
+
+ /**
+ * \brief Get the serialized size.
+ * \return serialized size
+ */
+ virtual uint32_t GetSerializedSize () const;
+
+ /**
+ * \brief Serialize the packet.
+ * \param start start offset
+ */
+ virtual void Serialize (Buffer::Iterator start) const;
+
+ /**
+ * \brief Deserialize the packet.
+ * \param start start offset
+ * \return length of packet
+ */
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+
+ private:
+ /**
+ * \brief The reserved value.
+ */
+ uint32_t m_reserved;
+};
+
+/**
+ * \class Icmpv6Redirection
+ * \brief ICMPv6 Redirection header.
+ */
+class Icmpv6Redirection : public Icmpv6Header
+{
+ public:
+ /**
+ * \brief Constructor.
+ */
+ Icmpv6Redirection ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Icmpv6Redirection ();
+
+ /**
+ * \brief Get the UID of this class.
+ * \return UID
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Get the instance type ID.
+ * \return instance type ID
+ */
+ virtual TypeId GetInstanceTypeId () const;
+
+ /**
+ * \brief Get the IPv6 target address.
+ * \return the IPv6 target address
+ */
+ Ipv6Address GetTarget () const;
+
+ /**
+ * \brief Set the IPv6 target address.
+ * \param target IPv6 target address
+ */
+ void SetTarget (Ipv6Address target);
+
+ /**
+ * \brief Get the IPv6 destination address.
+ * \return the IPv6 destination address
+ */
+ Ipv6Address GetDestination () const;
+
+ /**
+ * \brief Set the IPv6 destination address.
+ * \param destination IPv6 destination address
+ */
+ void SetDestination (Ipv6Address destination);
+
+ /**
+ * \brief Print informations.
+ * \param os output stream
+ */
+ virtual void Print (std::ostream& os);
+
+ /**
+ * \brief Get the serialized size.
+ * \return serialized size
+ */
+ virtual uint32_t GetSerializedSize () const;
+
+ /**
+ * \brief Serialize the packet.
+ * \param start start offset
+ */
+ virtual void Serialize (Buffer::Iterator start) const;
+
+ /**
+ * \brief Deserialize the packet.
+ * \param start start offset
+ * \return length of packet
+ */
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+
+ /**
+ * \brief Get the reserved field.
+ * \return reserved value
+ */
+ uint32_t GetReserved () const;
+
+ /**
+ * \brief Set the reserved field.
+ * \param reserved the reserved value
+ */
+ void SetReserved (uint32_t reserved);
+
+ private:
+ /**
+ * \brief IPv6 target address.
+ */
+ Ipv6Address m_target;
+
+ /**
+ * \brief IPv6 destination address.
+ */
+ Ipv6Address m_destination;
+
+ /**
+ * \brief Reserved value.
+ */
+ uint32_t m_reserved;
+};
+
+/**
+ * \class Icmpv6Echo
+ * \brief ICMPv6 Echo message.
+ */
+class Icmpv6Echo : public Icmpv6Header
+{
+ public:
+ /**
+ * \brief Get the UID of this class.
+ * \return UID
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Get the instance type ID.
+ * \return instance type ID
+ */
+ virtual TypeId GetInstanceTypeId () const;
+
+ /**
+ * \brief Default constructor.
+ */
+ Icmpv6Echo ();
+
+ /**
+ * \brief Constructor.
+ * \param request request or reply message
+ */
+ Icmpv6Echo (bool request);
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Icmpv6Echo ();
+
+ /**
+ * \brief Get the ID of the packet.
+ * \return id
+ */
+ uint16_t GetId () const;
+
+ /**
+ * \brief Set the ID of the packet.
+ * \param id id to set
+ */
+ void SetId (uint16_t id);
+
+ /**
+ * \brief Get the sequence number.
+ * \return sequence number
+ */
+ uint16_t GetSeq () const;
+
+ /**
+ * \brief Set the sequence number.
+ * \param seq sequence to set
+ */
+ void SetSeq (uint16_t seq);
+
+ /**
+ * \brief Print informations.
+ * \param os output stream
+ */
+ virtual void Print (std::ostream& os) const;
+
+ /**
+ * \brief Get the serialized size.
+ * \return serialized size
+ */
+ virtual uint32_t GetSerializedSize () const;
+
+ /**
+ * \brief Serialize the packet.
+ * \param start start offset
+ */
+ virtual void Serialize (Buffer::Iterator start) const;
+
+ /**
+ * \brief Deserialize the packet.
+ * \param start start offset
+ * \return length of packet
+ */
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+
+ private:
+ /**
+ * \brief ID of the packet (to distinguish response between many ping program).
+ */
+ uint16_t m_id;
+
+ /**
+ * \brief Sequence number (to distinguish response).
+ */
+ uint16_t m_seq;
+};
+
+/**
+ * \class Icmpv6DestinationUnreachable
+ * \brief ICMPv6 Error Destination Unreachable header.
+ */
+class Icmpv6DestinationUnreachable : public Icmpv6Header
+{
+ public:
+ /**
+ * \brief Constructor.
+ */
+ Icmpv6DestinationUnreachable ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Icmpv6DestinationUnreachable ();
+
+ /**
+ * \brief Get the UID of this class.
+ * \return UID
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Get the instance type ID.
+ * \return instance type ID
+ */
+ virtual TypeId GetInstanceTypeId () const;
+
+ /**
+ * \brief Get the incorrect packet.
+ * \return the incorrect packet
+ */
+ Ptr<Packet> GetPacket () const;
+
+ /**
+ * \brief Set the incorrect packet.
+ * \param p the incorrect packet
+ */
+ void SetPacket (Ptr<Packet> p);
+
+ /**
+ * \brief Print informations.
+ * \param os output stream
+ */
+ virtual void Print (std::ostream& os);
+
+ /**
+ * \brief Get the serialized size.
+ * \return serialized size
+ */
+ virtual uint32_t GetSerializedSize () const;
+
+ /**
+ * \brief Serialize the packet.
+ * \param start start offset
+ */
+ virtual void Serialize (Buffer::Iterator start) const;
+
+ /**
+ * \brief Deserialize the packet.
+ * \param start start offset
+ * \return length of packet
+ */
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+
+ private:
+ /**
+ * \brief The incorrect Packet.
+ */
+ Ptr<Packet> m_packet;
+};
+
+/**
+ * \class Icmpv6TooBig
+ * \brief ICMPv6 Error Too Big header.
+ */
+class Icmpv6TooBig : public Icmpv6Header
+{
+ public:
+ /**
+ * \brief Constructor.
+ */
+ Icmpv6TooBig ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Icmpv6TooBig ();
+
+ /**
+ * \brief Get the UID of this class.
+ * \return UID
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Get the instance type ID.
+ * \return instance type ID
+ */
+ virtual TypeId GetInstanceTypeId () const;
+
+ /**
+ * \brief Get the incorrect packet.
+ * \return the incorrect packet
+ */
+ Ptr<Packet> GetPacket () const;
+
+ /**
+ * \brief Set the incorrect packet.
+ * \param p the incorrect packet
+ */
+ void SetPacket (Ptr<Packet> p);
+
+ /**
+ * \brief Get the MTU field.
+ * \return MTU value
+ */
+ uint32_t GetMtu () const;
+
+ /**
+ * \brief Set the MTU.
+ * \param mtu the MTU
+ */
+ void SetMtu (uint32_t mtu);
+
+ /**
+ * \brief Print informations.
+ * \param os output stream
+ */
+ virtual void Print (std::ostream& os);
+
+ /**
+ * \brief Get the serialized size.
+ * \return serialized size
+ */
+ virtual uint32_t GetSerializedSize () const;
+
+ /**
+ * \brief Serialize the packet.
+ * \param start start offset
+ */
+ virtual void Serialize (Buffer::Iterator start) const;
+
+ /**
+ * \brief Deserialize the packet.
+ * \param start start offset
+ * \return length of packet
+ */
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+
+ private:
+
+ /**
+ * \brief the incorrect packet.
+ */
+ Ptr<Packet> m_packet;
+
+ /**
+ * \brief The MTU value.
+ */
+ uint32_t m_mtu;
+};
+
+/**
+ * \class Icmpv6TimeExceeded
+ * \brief ICMPv6 Error Time Exceeded header.
+ */
+class Icmpv6TimeExceeded : public Icmpv6Header
+{
+ public:
+ /**
+ * \brief Constructor.
+ */
+ Icmpv6TimeExceeded ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Icmpv6TimeExceeded ();
+
+ /**
+ * \brief Get the UID of this class.
+ * \return UID
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Get the instance type ID.
+ * \return instance type ID
+ */
+ virtual TypeId GetInstanceTypeId () const;
+
+ /**
+ * \brief Get the incorrect packet.
+ * \return the incorrect packet
+ */
+ Ptr<Packet> GetPacket () const;
+
+ /**
+ * \brief Set the incorrect packet.
+ * \param p the incorrect packet
+ */
+ void SetPacket (Ptr<Packet> p);
+
+ /**
+ * \brief Print informations.
+ * \param os output stream
+ */
+ virtual void Print (std::ostream& os);
+
+ /**
+ * \brief Get the serialized size.
+ * \return serialized size
+ */
+ virtual uint32_t GetSerializedSize () const;
+
+ /**
+ * \brief Serialize the packet.
+ * \param start start offset
+ */
+ virtual void Serialize (Buffer::Iterator start) const;
+
+ /**
+ * \brief Deserialize the packet.
+ * \param start start offset
+ * \return length of packet
+ */
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+
+ private:
+
+ /**
+ * \brief The incorrect packet.
+ */
+ Ptr<Packet> m_packet;
+};
+
+/**
+ * \class Icmpv6ParameterError
+ * \brief ICMPv6 Error Parameter Error header.
+ */
+class Icmpv6ParameterError : public Icmpv6Header
+{
+ public:
+ /**
+ * \brief Constructor.
+ */
+ Icmpv6ParameterError ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Icmpv6ParameterError ();
+
+ /**
+ * \brief Get the UID of this class.
+ * \return UID
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Get the instance type ID.
+ * \return instance type ID
+ */
+ virtual TypeId GetInstanceTypeId () const;
+
+ /**
+ * \brief Get the incorrect packet.
+ * \return the incorrect packet
+ */
+ Ptr<Packet> GetPacket () const;
+
+ /**
+ * \brief Set the incorrect packet.
+ * \param p the incorrect packet
+ */
+ void SetPacket (Ptr<Packet> p);
+
+ /**
+ * \brief Get the pointer field.
+ * \return pointer value
+ */
+ uint32_t GetPtr () const;
+
+ /**
+ * \brief Set the pointer field.
+ * \param ptr byte where the error is located in the incorrect packet
+ */
+ void SetPtr (uint32_t ptr);
+
+ /**
+ * \brief Print informations.
+ * \param os output stream
+ */
+ virtual void Print (std::ostream& os);
+
+ /**
+ * \brief Get the serialized size.
+ * \return serialized size
+ */
+ virtual uint32_t GetSerializedSize () const;
+
+ /**
+ * \brief Serialize the packet.
+ * \param start start offset
+ */
+ virtual void Serialize (Buffer::Iterator start) const;
+
+ /**
+ * \brief Deserialize the packet.
+ * \param start start offset
+ * \return length of packet
+ */
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+
+ private:
+
+ /**
+ * \brief The incorrect packet.
+ */
+ Ptr<Packet> m_packet;
+
+ /**
+ * \brief The pointer field.
+ */
+ uint32_t m_ptr;
+};
+
+/**
+ * \class Icmpv6OptionMtu
+ * \brief ICMPv6 MTU option.
+ */
+class Icmpv6OptionMtu : public Icmpv6OptionHeader
+{
+ public:
+ /**
+ * \brief Constructor.
+ */
+ Icmpv6OptionMtu ();
+
+ /**
+ * \brief Constructor.
+ * \param mtu MTU used.
+ */
+ Icmpv6OptionMtu (uint32_t mtu);
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Icmpv6OptionMtu ();
+
+ /**
+ * \brief Get the UID of this class.
+ * \return UID
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Get the instance type ID.
+ * \return instance type ID
+ */
+ virtual TypeId GetInstanceTypeId () const;
+
+ /**
+ * \brief Get the reserved field.
+ * \return the reserved value
+ */
+ uint16_t GetReserved () const;
+
+ /**
+ * \brief Set the reserved field.
+ * \param reserved the reserved value
+ */
+ void SetReserved (uint16_t reserved);
+
+ /**
+ * \brief Get the MTU.
+ * \return the MTU value
+ */
+ uint32_t GetMtu () const;
+
+ /**
+ * \brief Set the MTU.
+ * \param mtu the MTU to set
+ */
+ void SetMtu (uint32_t mtu);
+
+ /**
+ * \brief Print informations.
+ * \param os output stream
+ */
+ virtual void Print (std::ostream& os) const;
+
+ /**
+ * \brief Get the serialized size.
+ * \return serialized size
+ */
+ virtual uint32_t GetSerializedSize () const;
+
+ /**
+ * \brief Serialize the packet.
+ * \param start start offset
+ */
+ virtual void Serialize (Buffer::Iterator start) const;
+
+ /**
+ * \brief Deserialize the packet.
+ * \param start start offset
+ * \return length of packet
+ */
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+
+ private:
+ /**
+ * \brief The reserved value
+ */
+ uint16_t m_reserved;
+
+ /**
+ * \brief The MTU value.
+ */
+ uint32_t m_mtu;
+};
+
+/**
+ * \class Icmpv6OptionPrefixInformation
+ * \brief ICMPv6 Option Prefix Information.
+ */
+class Icmpv6OptionPrefixInformation : public Icmpv6OptionHeader
+{
+ public:
+ /**
+ * \brief Constructor.
+ */
+ Icmpv6OptionPrefixInformation ();
+
+ /**
+ * \brief Constructor.
+ * \param network prefix
+ * \param prefixlen prefix length
+ */
+ Icmpv6OptionPrefixInformation (Ipv6Address network, uint8_t prefixlen);
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Icmpv6OptionPrefixInformation ();
+
+ /**
+ * \brief Get the UID of this class.
+ * \return UID
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Get the instance type ID.
+ * \return instance type ID
+ */
+ virtual TypeId GetInstanceTypeId () const;
+
+ /**
+ * \brief Get the prefix length.
+ * \return prefix length
+ */
+ uint8_t GetPrefixLength () const;
+
+ /**
+ * \brief Set the prefix length.
+ * \param prefixLength the prefix length
+ */
+ void SetPrefixLength (uint8_t prefixLength);
+
+ /**
+ * \brief Get the flags.
+ * \return the flags.
+ */
+ uint8_t GetFlags () const;
+
+ /**
+ * \brief Set the flags.
+ * \param flags the flags to set
+ */
+ void SetFlags (uint8_t flags);
+
+ /**
+ * \brief Get the valid time of the information.
+ * \return valid time
+ */
+ uint32_t GetValidTime () const;
+
+ /**
+ * \brief Set the valid time of the information.
+ * \param validTime valid time
+ */
+ void SetValidTime (uint32_t validTime);
+
+ /**
+ * \brief Get the preferred time of the information.
+ * \return preferred time
+ */
+ uint32_t GetPreferredTime () const;
+
+ /**
+ * \brief Set the preferred time of the information.
+ * \param preferredTime preferred time
+ */
+ void SetPreferredTime (uint32_t preferredTime);
+
+ /**
+ * \brief Get the reserved field.
+ * \return the reserved field (should be 0x00000000)
+ */
+ uint32_t GetReserved () const;
+
+ /**
+ * \brief Set the reserved field (normally it will be 0x00000000).
+ * \param reserved reserved value
+ */
+ void SetReserved (uint32_t reserved);
+
+ /**
+ * \brief Get the IPv6 prefix.
+ * \return IPv6 prefix
+ */
+ Ipv6Address GetPrefix () const;
+
+ /**
+ * \brief Set the IPv6 prefix.
+ * \param prefix the IPv6 prefix
+ */
+ void SetPrefix (Ipv6Address prefix);
+
+ /**
+ * \brief Print informations.
+ * \param os output stream
+ */
+ virtual void Print (std::ostream& os) const;
+
+ /**
+ * \brief Get the serialized size.
+ * \return serialized size
+ */
+ virtual uint32_t GetSerializedSize () const;
+
+ /**
+ * \brief Serialize the packet.
+ * \param start start offset
+ */
+ virtual void Serialize (Buffer::Iterator start) const;
+
+ /**
+ * \brief Deserialize the packet.
+ * \param start start offset
+ * \return length of packet
+ */
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+
+ private:
+ /**
+ * \brief The prefix value.
+ */
+ Ipv6Address m_prefix;
+
+ /**
+ * \brief The length of the prefix.
+ */
+ uint8_t m_prefixLength;
+
+ /**
+ * \brief The flags.
+ */
+ uint8_t m_flags;
+
+ /**
+ * \brief The valid time.
+ */
+ uint32_t m_validTime;
+
+ /**
+ * \brief The preferred time.
+ */
+ uint32_t m_preferredTime;
+
+ /**
+ * \brief The reserved field.
+ */
+ uint32_t m_reserved;
+};
+
+/**
+ * \class Icmpv6OptionLinkLayerAddress
+ * \brief ICMPv6 link-layer address option.
+ */
+class Icmpv6OptionLinkLayerAddress : public Icmpv6OptionHeader
+{
+ public:
+ /**
+ * \brief Constructor.
+ * \param source source hardware address or target hardware address for the option
+ */
+ Icmpv6OptionLinkLayerAddress (bool source);
+
+ /**
+ * \brief Get the UID of this class.
+ * \return UID
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Get the instance type ID.
+ * \return instance type ID
+ */
+ virtual TypeId GetInstanceTypeId (void) const;
+
+ /**
+ * \brief Constructor.
+ * \param source source hardware address or target hardware address for the option
+ * \param addr hardware address
+ */
+ Icmpv6OptionLinkLayerAddress (bool source, Address addr);
+
+ /**
+ * \brief Constructor.
+ */
+ Icmpv6OptionLinkLayerAddress ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Icmpv6OptionLinkLayerAddress ();
+
+ /**
+ * \brief Get the hardware address.
+ * \return the hardware address
+ */
+ Address GetAddress () const;
+
+ /**
+ * \brief Set the hardware address.
+ * \param addr the address to set
+ */
+ void SetAddress (Address addr);
+
+ /**
+ * \brief Print informations.
+ * \param os output stream
+ */
+ virtual void Print (std::ostream& os) const;
+
+ /**
+ * \brief Get the serialized size.
+ * \return serialized size
+ */
+ virtual uint32_t GetSerializedSize () const;
+
+ /**
+ * \brief Serialize the packet.
+ * \param start start offset
+ */
+ virtual void Serialize (Buffer::Iterator start) const;
+
+ /**
+ * \brief Deserialize the packet.
+ * \param start start offset
+ * \return length of packet
+ */
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+
+ private:
+ /**
+ * \brief The hardware address.
+ */
+ Address m_addr;
+};
+
+/**
+ * \class Icmpv6OptionRedirected
+ * \brief ICMPv6 redirected option.
+ */
+class Icmpv6OptionRedirected : public Icmpv6OptionHeader
+{
+ public:
+ /**
+ * \brief Get the UID of this class.
+ * \return UID
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Get the instance type ID.
+ * \return instance type ID
+ */
+ virtual TypeId GetInstanceTypeId () const;
+
+ /**
+ * \brief Constructor.
+ */
+ Icmpv6OptionRedirected ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Icmpv6OptionRedirected ();
+
+ /**
+ * \brief Get the redirected packet.
+ * \return the redirected packet
+ */
+ Ptr<Packet> GetPacket () const;
+
+ /**
+ * \brief Set the redirected packet.
+ * \param packet the redirected packet
+ */
+ void SetPacket (Ptr<Packet> packet);
+
+ /**
+ * \brief Print informations.
+ * \param os output stream
+ */
+ virtual void Print (std::ostream& os) const;
+
+ /**
+ * \brief Get the serialized size.
+ * \return serialized size
+ */
+ virtual uint32_t GetSerializedSize () const;
+
+ /**
+ * \brief Serialize the packet.
+ * \param start start offset
+ */
+ virtual void Serialize (Buffer::Iterator start) const;
+
+ /**
+ * \brief Deserialize the packet.
+ * \param start start offset
+ * \return length of packet
+ */
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+
+ private:
+ /**
+ * \brief The redirected packet.
+ */
+ Ptr<Packet> m_packet;
+};
+
+} /* namespace ns3 */
+
+#endif /* ICMPV6_HEADER_H */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/icmpv6-l4-protocol.cc Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,1205 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ * David Gross <gdavid.devel@gmail.com>
+ * Mehdi Benamor <benamor.mehdi@ensi.rnu.tn>
+ */
+
+#include "ns3/log.h"
+#include "ns3/assert.h"
+#include "ns3/packet.h"
+#include "ns3/node.h"
+#include "ns3/ipv6-routing-protocol.h"
+#include "ns3/ipv6-route.h"
+
+#include "ipv6-raw-socket-factory-impl.h"
+#include "icmpv6-l4-protocol.h"
+#include "icmpv6-header.h"
+#include "ipv6-l3-protocol.h"
+#include "ipv6-end-point.h"
+
+#include "ns3/ipv6-static-routing-helper.h"
+
+namespace ns3
+{
+
+NS_OBJECT_ENSURE_REGISTERED (Icmpv6L4Protocol);
+
+NS_LOG_COMPONENT_DEFINE ("Icmpv6L4Protocol");
+
+const uint8_t Icmpv6L4Protocol::PROT_NUMBER = 58;
+
+const uint8_t Icmpv6L4Protocol::MAX_INITIAL_RTR_ADVERT_INTERVAL = 16;
+const uint8_t Icmpv6L4Protocol::MAX_INITIAL_RTR_ADVERTISEMENTS = 3;
+const uint8_t Icmpv6L4Protocol::MAX_FINAL_RTR_ADVERTISEMENTS = 3;
+const uint8_t Icmpv6L4Protocol::MIN_DELAY_BETWEEN_RAS = 3;
+const uint32_t Icmpv6L4Protocol::MAX_RA_DELAY_TIME = 500; /* millisecond */
+
+const uint8_t Icmpv6L4Protocol::MAX_RTR_SOLICITATION_DELAY = 1;
+const uint8_t Icmpv6L4Protocol::RTR_SOLICITATION_INTERVAL = 4;
+const uint8_t Icmpv6L4Protocol::MAX_RTR_SOLICITATIONS = 3;
+
+const uint8_t Icmpv6L4Protocol::MAX_MULTICAST_SOLICIT = 3;
+const uint8_t Icmpv6L4Protocol::MAX_UNICAST_SOLICIT = 3;
+const uint8_t Icmpv6L4Protocol::MAX_ANYCAST_DELAY_TIME = 1;
+const uint8_t Icmpv6L4Protocol::MAX_NEIGHBOR_ADVERTISEMENT = 3;
+const uint32_t Icmpv6L4Protocol::REACHABLE_TIME = 30000;
+const uint32_t Icmpv6L4Protocol::RETRANS_TIMER = 1000;
+const uint8_t Icmpv6L4Protocol::DELAY_FIRST_PROBE_TIME = 5;
+const double Icmpv6L4Protocol::MIN_RANDOM_FACTOR = 0.5;
+const double Icmpv6L4Protocol::MAX_RANDOM_FACTOR = 1.5;
+
+TypeId Icmpv6L4Protocol::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Icmpv6L4Protocol")
+ .SetParent<Ipv6L4Protocol> ()
+ .AddConstructor<Icmpv6L4Protocol> ()
+ ;
+ return tid;
+}
+
+Icmpv6L4Protocol::Icmpv6L4Protocol ()
+ : m_node (0)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+Icmpv6L4Protocol::~Icmpv6L4Protocol ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+void Icmpv6L4Protocol::DoDispose ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ for (CacheList::const_iterator it = m_cacheList.begin () ; it != m_cacheList.end () ; it++)
+ {
+ Ptr<NdiscCache> cache = *it;
+ cache->Dispose ();
+ cache = 0;
+ }
+ m_cacheList.clear ();
+
+ m_node = 0;
+ Ipv6L4Protocol::DoDispose ();
+}
+
+void Icmpv6L4Protocol::NotifyNewAggregate ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ if (m_node == 0)
+ {
+ Ptr<Node> node = this->GetObject<Node> ();
+ if (node != 0)
+ {
+ Ptr<Ipv6L3Protocol> ipv6 = this->GetObject<Ipv6L3Protocol> ();
+ if (ipv6 != 0)
+ {
+ this->SetNode (node);
+ ipv6->Insert (this);
+ Ptr<Ipv6RawSocketFactoryImpl> rawFactory = CreateObject<Ipv6RawSocketFactoryImpl> ();
+ ipv6->AggregateObject (rawFactory);
+ }
+ }
+ }
+ Object::NotifyNewAggregate ();
+}
+
+void Icmpv6L4Protocol::SetNode (Ptr<Node> node)
+{
+ NS_LOG_FUNCTION (this << node);
+ m_node = node;
+}
+
+uint16_t Icmpv6L4Protocol::GetStaticProtocolNumber ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return PROT_NUMBER;
+}
+
+int Icmpv6L4Protocol::GetProtocolNumber () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return PROT_NUMBER;
+}
+
+int Icmpv6L4Protocol::GetVersion () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return 1;
+}
+
+void Icmpv6L4Protocol::DoDAD (Ipv6Address target, Ptr<Ipv6Interface> interface)
+{
+ NS_LOG_FUNCTION (this << target << interface);
+ Ipv6Address addr;
+
+ Ptr<Ipv6L3Protocol> ipv6 = m_node->GetObject<Ipv6L3Protocol> ();
+ NS_ASSERT (ipv6);
+
+ /* TODO : disable multicast loopback to prevent NS probing to be received by the sender */
+
+ Ptr<Packet> p = ForgeNS ("::" ,Ipv6Address::MakeSolicitedAddress (target), target, interface->GetDevice ()->GetAddress ());
+
+ /* update last packet UID */
+ interface->SetNsDadUid (target, p->GetUid ());
+ interface->Send (p, Ipv6Address::MakeSolicitedAddress (target));
+}
+
+enum Ipv6L4Protocol::RxStatus_e Icmpv6L4Protocol::Receive (Ptr<Packet> packet, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface)
+{
+ NS_LOG_FUNCTION (this << packet << src << dst << interface);
+ Ptr<Packet> p = packet->Copy ();
+ Ptr<Ipv6> ipv6 = m_node->GetObject<Ipv6> ();
+
+ switch (*p->PeekData ()) /* very ugly! try to find something better in the future */
+ {
+ case Icmpv6Header::ICMPV6_ND_ROUTER_SOLICITATION:
+ if (ipv6->IsForwarding (ipv6->GetInterfaceForDevice (interface->GetDevice ())))
+ {
+ HandleRS (p, src, dst, interface);
+ }
+ break;
+ case Icmpv6Header::ICMPV6_ND_ROUTER_ADVERTISEMENT:
+ if (!ipv6->IsForwarding (ipv6->GetInterfaceForDevice (interface->GetDevice ())))
+ {
+ HandleRA (p, src, dst, interface);
+ }
+ break;
+ case Icmpv6Header::ICMPV6_ND_NEIGHBOR_SOLICITATION:
+ HandleNS (p, src, dst, interface);
+ break;
+ case Icmpv6Header::ICMPV6_ND_NEIGHBOR_ADVERTISEMENT:
+ HandleNA (p, src, dst, interface);
+ break;
+ case Icmpv6Header::ICMPV6_ND_REDIRECTION:
+ HandleRedirection (p, src, dst, interface);
+ break;
+ case Icmpv6Header::ICMPV6_ECHO_REQUEST:
+ HandleEchoRequest (p, src, dst, interface);
+ break;
+ case Icmpv6Header::ICMPV6_ECHO_REPLY:
+ break;
+ case Icmpv6Header::ICMPV6_ERROR_DESTINATION_UNREACHABLE:
+ break;
+ case Icmpv6Header::ICMPV6_ERROR_PACKET_TOO_BIG:
+ break;
+ case Icmpv6Header::ICMPV6_ERROR_TIME_EXCEEDED:
+ break;
+ case Icmpv6Header::ICMPV6_ERROR_PARAMETER_ERROR:
+ break;
+ default:
+ NS_LOG_LOGIC ("Unknown ICMPv6 message type=" << (uint8_t)*p->PeekData ());
+ break;
+ }
+
+ return Ipv6L4Protocol::RX_OK;
+}
+
+void Icmpv6L4Protocol::HandleEchoRequest (Ptr<Packet> packet, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface)
+{
+ NS_LOG_FUNCTION (this << packet << src << dst << interface);
+ Icmpv6Echo request;
+ packet->RemoveHeader (request);
+
+ /* if we send message from ff02::* (link-local multicast), we use our link-local address */
+ SendEchoReply (dst.IsMulticast () ? interface->GetLinkLocalAddress ().GetAddress () : dst, src, request.GetId (), request.GetSeq (), packet);
+}
+
+void Icmpv6L4Protocol::HandleRA (Ptr<Packet> packet, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface)
+{
+ NS_LOG_FUNCTION (this << packet << src << dst << interface);
+ Ptr<Packet> p = packet->Copy ();
+ Icmpv6RA raHeader;
+ Ptr<Ipv6L3Protocol> ipv6 = m_node->GetObject<Ipv6L3Protocol> ();
+ Icmpv6OptionPrefixInformation prefixHdr;
+ Icmpv6OptionMtu mtuHdr;
+ Icmpv6OptionLinkLayerAddress llaHdr;
+ uint8_t type = 0;
+ bool next = true;
+ bool hasLla = false;
+ bool hasMtu = false;
+
+ p->RemoveHeader (raHeader);
+
+ while (next == true)
+ {
+ type = *p->PeekData ();
+
+ switch (type)
+ {
+ case Icmpv6Header::ICMPV6_OPT_PREFIX:
+ p->RemoveHeader (prefixHdr);
+ ipv6->AddAutoconfiguredAddress (ipv6->GetInterfaceForDevice (interface->GetDevice ()), prefixHdr.GetPrefix (), prefixHdr.GetPrefixLength (),
+ prefixHdr.GetFlags (), prefixHdr.GetValidTime (), prefixHdr.GetPreferredTime (), src);
+ break;
+ case Icmpv6Header::ICMPV6_OPT_MTU:
+ /* take in account the first MTU option */
+ if (!hasMtu)
+ {
+ p->RemoveHeader (mtuHdr);
+ hasMtu = true;
+ /* XXX case of multiple prefix on single interface */
+ /* interface->GetDevice ()->SetMtu (m.GetMtu ()); */
+ }
+ break;
+ case Icmpv6Header::ICMPV6_OPT_LINK_LAYER_SOURCE:
+ /* take in account the first LLA option */
+ if (!hasLla)
+ {
+ p->RemoveHeader (llaHdr);
+ ReceiveLLA (llaHdr, src, dst, interface);
+ hasLla = true;
+ }
+ break;
+ default:
+ /* unknow option, quit */
+ next = false;
+ }
+ }
+}
+
+void Icmpv6L4Protocol::ReceiveLLA (Icmpv6OptionLinkLayerAddress lla, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface)
+{
+ NS_LOG_FUNCTION (this << lla << src << dst << interface);
+ Address hardwareAddress;
+ NdiscCache::Entry* entry = NULL;
+ Ptr<NdiscCache> cache = FindCache (interface->GetDevice ());
+
+ /* check if we have this address in our cache */
+ entry = cache->Lookup (src);
+
+ if (!entry)
+ {
+ entry = cache->Add (src);
+ entry->SetRouter (true);
+ entry->SetMacAddress (lla.GetAddress ());
+ entry->MarkReachable ();
+ entry->StartReachableTimer ();
+ }
+ else
+ {
+ std::list<Ptr<Packet> > waiting;
+ if (entry->IsIncomplete ())
+ {
+ entry->StopRetransmitTimer ();
+ // mark it to reachable
+ waiting = entry->MarkReachable (lla.GetAddress ());
+ entry->StopReachableTimer ();
+ entry->StartReachableTimer ();
+ // send out waiting packet
+ for (std::list<Ptr<Packet> >::const_iterator it = waiting.begin (); it != waiting.end (); it++)
+ {
+ cache->GetInterface ()->Send (*it, src);
+ }
+ entry->ClearWaitingPacket ();
+ }
+ else
+ {
+ if (entry->GetMacAddress ()!=lla.GetAddress ())
+ {
+ entry->SetMacAddress (lla.GetAddress ());
+ entry->MarkStale ();
+ entry->SetRouter (true);
+ }
+ else
+ {
+ if (!entry->IsReachable ())
+ {
+ entry->StopProbeTimer ();
+ entry->StopDelayTimer ();
+ waiting = entry->MarkReachable (lla.GetAddress ());
+ if (entry->IsProbe ())
+ {
+ for (std::list<Ptr<Packet> >::const_iterator it = waiting.begin (); it != waiting.end (); it++)
+ {
+ cache->GetInterface ()->Send (*it, src);
+ }
+ }
+ entry->StopReachableTimer ();
+ entry->StartReachableTimer ();
+ }
+ }
+ }
+ }
+}
+
+void Icmpv6L4Protocol::HandleRS (Ptr<Packet> packet, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface)
+{
+ NS_LOG_FUNCTION (this << packet << src << dst << interface);
+ Ptr<Ipv6L3Protocol> ipv6 = m_node->GetObject<Ipv6L3Protocol> ();
+ Icmpv6RS rsHeader;
+ packet->RemoveHeader (rsHeader);
+ Address hardwareAddress;
+ Icmpv6OptionLinkLayerAddress lla (1);
+ NdiscCache::Entry* entry = NULL;
+ Ptr<NdiscCache> cache = FindCache (interface->GetDevice ());
+
+ if (src != Ipv6Address::GetAny ())
+ {
+ /* XXX search all options following the RS header */
+ /* test if the next option is SourceLinkLayerAddress */
+ if (*packet->PeekData () != Icmpv6Header::ICMPV6_OPT_LINK_LAYER_SOURCE)
+ {
+ return;
+ }
+ packet->RemoveHeader (lla);
+ NS_LOG_LOGIC ("Cache updated by RS");
+
+ entry = cache->Lookup (src);
+ if (!entry)
+ {
+ entry = cache->Add (src);
+ entry->SetRouter (false);
+ entry->MarkStale (lla.GetAddress ());
+ }
+ else if (entry->GetMacAddress () != lla.GetAddress ())
+ {
+ entry->MarkStale (lla.GetAddress ());
+ }
+ }
+}
+
+void Icmpv6L4Protocol::HandleNS (Ptr<Packet> packet, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface)
+{
+ NS_LOG_FUNCTION (this << packet << src << dst << interface);
+ Icmpv6NS nsHeader ("::");
+ Ipv6InterfaceAddress ifaddr;
+ uint32_t nb = interface->GetNAddresses ();
+ uint32_t i = 0;
+ bool found = false;
+
+ packet->RemoveHeader (nsHeader);
+
+ Ipv6Address target = nsHeader.GetIpv6Target ();
+
+ for (i = 0 ; i < nb ; i++)
+ {
+ ifaddr = interface->GetAddress (i);
+
+ if (ifaddr.GetAddress () == target)
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ NS_LOG_LOGIC ("Not a NS for us");
+ return;
+ }
+
+ if (packet->GetUid () == ifaddr.GetNsDadUid ())
+ {
+ /* don't process our own DAD probe */
+ NS_LOG_LOGIC ("Hey we receive our DAD probe!");
+ return;
+ }
+
+ Icmpv6OptionLinkLayerAddress lla (1);
+ Address hardwareAddress;
+ NdiscCache::Entry* entry = 0;
+ Ptr<NdiscCache> cache = FindCache (interface->GetDevice ());
+ uint8_t flags = 0;
+
+ /* XXX search all options following the NS header */
+
+ if (src != Ipv6Address::GetAny ())
+ {
+ if (*packet->PeekData () != Icmpv6Header::ICMPV6_OPT_LINK_LAYER_SOURCE)
+ {
+ return;
+ }
+
+ /* Get LLA */
+ packet->RemoveHeader (lla);
+
+ entry = cache->Lookup (src);
+ if (!entry)
+ {
+ entry = cache->Add (src);
+ entry->SetRouter (false);
+ entry->MarkStale (lla.GetAddress ());
+ }
+ else if (entry->GetMacAddress () != lla.GetAddress ())
+ {
+ entry->MarkStale (lla.GetAddress ());
+ }
+
+ flags = 3; /* S + O flags */
+ }
+ else
+ {
+ /* it means someone do a DAD */
+ flags = 1; /* O flag */
+ }
+
+ /* send a NA to src */
+ Ptr<Ipv6L3Protocol> ipv6 = m_node->GetObject<Ipv6L3Protocol> ();
+
+ if (ipv6->IsForwarding (ipv6->GetInterfaceForDevice (interface->GetDevice ())))
+ {
+ flags += 4; /* R flag */
+ }
+
+ hardwareAddress = interface->GetDevice ()->GetAddress ();
+ Ptr<Packet> p = ForgeNA (target.IsLinkLocal () ? interface->GetLinkLocalAddress ().GetAddress () : ifaddr.GetAddress (), src.IsAny () ? Ipv6Address::GetAllNodesMulticast () : src, &hardwareAddress, flags );
+ interface->Send (p, src.IsAny () ? Ipv6Address::GetAllNodesMulticast () : src);
+
+ /* not a NS for us discard it */
+}
+
+Ptr<Packet> Icmpv6L4Protocol::ForgeRS (Ipv6Address src, Ipv6Address dst, Address hardwareAddress)
+{
+ NS_LOG_FUNCTION (this << src << dst << hardwareAddress);
+ Ptr<Packet> p = Create<Packet> ();
+ Ipv6Header ipHeader;
+ Icmpv6RS rs;
+ Icmpv6OptionLinkLayerAddress llOption (1, hardwareAddress); /* we give our mac address in response */
+
+ NS_LOG_LOGIC ("Send RS ( from " << src << " to " << dst << ")");
+ p->AddHeader (llOption);
+
+ rs.CalculatePseudoHeaderChecksum (src, dst, p->GetSize () + rs.GetSerializedSize (), PROT_NUMBER);
+ p->AddHeader (rs);
+
+ ipHeader.SetSourceAddress (src);
+ ipHeader.SetDestinationAddress (dst);
+ ipHeader.SetNextHeader (PROT_NUMBER);
+ ipHeader.SetPayloadLength (p->GetSize ());
+ ipHeader.SetHopLimit (255);
+
+ p->AddHeader (ipHeader);
+
+ return p;
+}
+
+Ptr<Packet> Icmpv6L4Protocol::ForgeEchoRequest (Ipv6Address src, Ipv6Address dst, uint16_t id, uint16_t seq, Ptr<Packet> data)
+{
+ NS_LOG_FUNCTION (this << src << dst << id << seq << data);
+ Ptr<Packet> p = data->Copy ();
+ Ipv6Header ipHeader;
+ Icmpv6Echo req (1);
+
+ req.SetId (id);
+ req.SetSeq (seq);
+
+ p->AddHeader (req);
+
+ return p;
+}
+
+void Icmpv6L4Protocol::HandleNA (Ptr<Packet> packet, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface)
+{
+ NS_LOG_FUNCTION (this << packet << src << dst << interface);
+ Icmpv6NA naHeader;
+ Icmpv6OptionLinkLayerAddress lla (1);
+
+ packet->RemoveHeader (naHeader);
+ Ipv6Address target = naHeader.GetIpv6Target ();
+
+ Address hardwareAddress;
+ NdiscCache::Entry* entry = 0;
+ Ptr<NdiscCache> cache = FindCache (interface->GetDevice ());
+ std::list<Ptr<Packet> > waiting;
+
+ /* check if we have something in our cache */
+ entry = cache->Lookup (target);
+
+ if (!entry)
+ {
+ /* ouch!! we are victim of a DAD */
+ Ipv6InterfaceAddress ifaddr;
+ bool found = false;
+ uint32_t i = 0;
+ uint32_t nb = 0;
+
+ for (i = 0 ; i < nb ; i++)
+ {
+ if (ifaddr.GetAddress () == target)
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if (found)
+ {
+ if (ifaddr.GetState () == Ipv6InterfaceAddress::TENTATIVE || ifaddr.GetState () == Ipv6InterfaceAddress::TENTATIVE_OPTIMISTIC)
+ {
+ interface->SetState (ifaddr.GetAddress (), Ipv6InterfaceAddress::INVALID);
+ }
+ }
+ /* we have not initiated any communication with the target so... discard the NA */
+ return;
+ }
+
+ /* XXX search all options following the NA header */
+ /* Get LLA */
+ if (*packet->PeekData () != Icmpv6Header::ICMPV6_OPT_LINK_LAYER_TARGET)
+ {
+ return;
+ }
+ packet->RemoveHeader (lla);
+
+ if (entry->IsIncomplete ())
+ {
+ /* we receive a NA so stop the retransmission timer */
+ entry->StopRetransmitTimer ();
+
+ if (naHeader.GetFlagS ())
+ {
+ /* mark it to reachable */
+ waiting = entry->MarkReachable (lla.GetAddress ());
+ entry->StopReachableTimer ();
+ entry->StartReachableTimer ();
+ /* send out waiting packet */
+ for (std::list<Ptr<Packet> >::const_iterator it = waiting.begin (); it != waiting.end (); it++)
+ {
+ cache->GetInterface ()->Send (*it, src);
+ }
+ entry->ClearWaitingPacket ();
+ }
+ else
+ {
+ entry->MarkStale (lla.GetAddress ());
+ }
+
+ if (naHeader.GetFlagR ())
+ {
+ entry->SetRouter (true);
+ }
+ }
+ else
+ {
+ /* we receive a NA so stop the probe timer or delay timer if any */
+ entry->StopProbeTimer ();
+ entry->StopDelayTimer ();
+
+ /* if the Flag O is clear and mac address differs from the cache */
+ if (!naHeader.GetFlagO () && lla.GetAddress ()!=entry->GetMacAddress ())
+ {
+ if (entry->IsReachable ())
+ {
+ entry->MarkStale ();
+ }
+ return;
+ }
+ else
+ {
+ if ((!naHeader.GetFlagO () && lla.GetAddress () == entry->GetMacAddress ()) || naHeader.GetFlagO ()) /* XXX lake "no target link-layer address option supplied" */
+ {
+ entry->SetMacAddress (lla.GetAddress ());
+
+ if (naHeader.GetFlagS ())
+ {
+ if (!entry->IsReachable ())
+ {
+ if (entry->IsProbe ())
+ {
+ waiting = entry->MarkReachable (lla.GetAddress ());
+ for (std::list<Ptr<Packet> >::const_iterator it = waiting.begin (); it != waiting.end (); it++)
+ {
+ cache->GetInterface ()->Send (*it, src);
+ }
+ entry->ClearWaitingPacket ();
+ }
+ else
+ {
+ entry->MarkReachable (lla.GetAddress ());
+ }
+ }
+ entry->StopReachableTimer ();
+ entry->StartReachableTimer ();
+ }
+ else if (lla.GetAddress ()!=entry->GetMacAddress ())
+ {
+ entry->MarkStale ();
+ }
+ entry->SetRouter (naHeader.GetFlagR ());
+ }
+ }
+ }
+}
+
+void Icmpv6L4Protocol::HandleRedirection (Ptr<Packet> packet, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface)
+{
+ NS_LOG_FUNCTION (this << packet << src << dst << interface);
+ bool hasLla = false;
+ Ptr<Packet> p = packet->Copy ();
+ Icmpv6OptionLinkLayerAddress llOptionHeader (0);
+
+ Icmpv6Redirection redirectionHeader;
+ p->RemoveHeader (redirectionHeader);
+
+ /* little ugly try to find a better way */
+ if (*p->PeekData () == Icmpv6Header::ICMPV6_OPT_LINK_LAYER_TARGET)
+ {
+ hasLla = true;
+ p->RemoveHeader (llOptionHeader);
+ }
+
+ Icmpv6OptionRedirected redirectedOptionHeader;
+ p->RemoveHeader (redirectedOptionHeader);
+
+ Ipv6Address redirTarget = redirectionHeader.GetTarget ();
+ Ipv6Address redirDestination = redirectionHeader.GetDestination ();
+
+ if (hasLla)
+ {
+ /* update the cache if needed */
+ NdiscCache::Entry* entry = NULL;
+ Ptr<NdiscCache> cache = FindCache (interface->GetDevice ());
+
+ entry = cache->Lookup (redirTarget);
+ if (!entry)
+ {
+ entry = cache->Add (redirTarget);
+ /* destination and target different => necessarily a router */
+ entry->SetRouter (!redirTarget.IsEqual (redirDestination) ? true : false);
+ entry->SetMacAddress (llOptionHeader.GetAddress ());
+ entry->MarkStale ();
+ }
+ else
+ {
+ if (entry->IsIncomplete () || entry->GetMacAddress () != llOptionHeader.GetAddress ())
+ {
+ /* update entry to STALE */
+ if (entry->GetMacAddress ()!=llOptionHeader.GetAddress ())
+ {
+ entry->SetMacAddress (llOptionHeader.GetAddress ());
+ entry->MarkStale ();
+ }
+ }
+ else
+ {
+ /* stay unchanged */
+ }
+ }
+ }
+
+ /* add redirection in routing table */
+ Ptr<Ipv6> ipv6 = m_node->GetObject<Ipv6> ();
+
+ if (redirTarget.IsEqual (redirDestination))
+ {
+ ipv6->GetRoutingProtocol ()->NotifyAddRoute (redirDestination, Ipv6Prefix (128), Ipv6Address ("::"), ipv6->GetInterfaceForAddress (dst));
+ }
+ else
+ {
+ uint32_t ifIndex = ipv6->GetInterfaceForAddress (dst);
+ ipv6->GetRoutingProtocol ()->NotifyAddRoute (redirDestination, Ipv6Prefix (128), redirTarget, ifIndex);
+ }
+}
+
+void Icmpv6L4Protocol::SendMessage (Ptr<Packet> packet, Ipv6Address src, Ipv6Address dst, uint8_t ttl)
+{
+ NS_LOG_FUNCTION (this << packet << src << dst << (uint32_t)ttl);
+ Ptr<Ipv6L3Protocol> ipv6 = m_node->GetObject<Ipv6L3Protocol> ();
+ SocketIpTtlTag tag;
+ NS_ASSERT (ipv6 != 0);
+
+ tag.SetTtl (ttl);
+ packet->AddPacketTag (tag);
+ ipv6->Send (packet, src, dst, PROT_NUMBER, 0);
+}
+
+void Icmpv6L4Protocol::SendMessage (Ptr<Packet> packet, Ipv6Address dst, Icmpv6Header& icmpv6Hdr, uint8_t ttl)
+{
+ NS_LOG_FUNCTION (this << packet << dst << icmpv6Hdr << (uint32_t)ttl);
+ Ptr<Ipv6L3Protocol> ipv6 = m_node->GetObject<Ipv6L3Protocol> ();
+ NS_ASSERT (ipv6 != 0 && ipv6->GetRoutingProtocol () != 0);
+ Ipv6Header header;
+ SocketIpTtlTag tag;
+ Socket::SocketErrno err;
+ Ptr<Ipv6Route> route;
+ uint32_t oif = 0; //specify non-zero if bound to a source address
+
+ header.SetDestinationAddress (dst);
+ route = ipv6->GetRoutingProtocol ()->RouteOutput (packet, header, oif, err);
+
+ if (route != 0)
+ {
+ NS_LOG_LOGIC ("Route exists");
+ tag.SetTtl (ttl);
+ packet->AddPacketTag (tag);
+ Ipv6Address src = route->GetSource ();
+
+ icmpv6Hdr.CalculatePseudoHeaderChecksum (src, dst, packet->GetSize () + icmpv6Hdr.GetSerializedSize (), PROT_NUMBER);
+ packet->AddHeader (icmpv6Hdr);
+ ipv6->Send (packet, src, dst, PROT_NUMBER, route);
+ }
+ else
+ {
+ NS_LOG_WARN ("drop icmp message");
+ }
+}
+
+void Icmpv6L4Protocol::SendNA (Ipv6Address src, Ipv6Address dst, Address* hardwareAddress, uint8_t flags)
+{
+ NS_LOG_FUNCTION (this << src << dst << hardwareAddress << flags);
+ Ptr<Packet> p = Create<Packet> ();
+ Icmpv6NA na;
+ Icmpv6OptionLinkLayerAddress llOption (0, *hardwareAddress); /* not a source link layer */
+
+ NS_LOG_LOGIC ("Send NA ( from " << src << " to " << dst << " target " << src << ")");
+ na.SetIpv6Target (src);
+
+ if ((flags & 1))
+ {
+ na.SetFlagO (true);
+ }
+ if ((flags & 2) && src != Ipv6Address::GetAny ())
+ {
+ na.SetFlagS (true);
+ }
+ if ((flags & 4))
+ {
+ na.SetFlagR (true);
+ }
+
+ p->AddHeader (llOption);
+ na.CalculatePseudoHeaderChecksum (src, dst, p->GetSize () + na.GetSerializedSize (), PROT_NUMBER);
+ p->AddHeader (na);
+
+ SendMessage (p, src, dst, 255);
+}
+
+void Icmpv6L4Protocol::SendEchoReply (Ipv6Address src, Ipv6Address dst, uint16_t id, uint16_t seq, Ptr<Packet> data)
+{
+ NS_LOG_FUNCTION (this << src << dst << id << seq << data);
+ Ptr<Packet> p = data->Copy ();
+ Icmpv6Echo reply (0); /* echo reply */
+
+ reply.SetId (id);
+ reply.SetSeq (seq);
+
+ reply.CalculatePseudoHeaderChecksum (src, dst, p->GetSize () + reply.GetSerializedSize (), PROT_NUMBER);
+ p->AddHeader (reply);
+ SendMessage (p, src, dst, 64);
+}
+
+void Icmpv6L4Protocol::SendNS (Ipv6Address src, Ipv6Address dst, Ipv6Address target, Address hardwareAddress)
+{
+ NS_LOG_FUNCTION (this << src << dst << target << hardwareAddress);
+ Ptr<Packet> p = Create<Packet> ();
+ /* Ipv6Header ipHeader; */
+ Icmpv6NS ns (target);
+ Icmpv6OptionLinkLayerAddress llOption (1, hardwareAddress); /* we give our mac address in response */
+
+ /* if the source is unspec, multicast the NA to all-nodes multicast */
+ if (src == Ipv6Address::GetAny ())
+ {
+ dst = Ipv6Address::GetAllNodesMulticast ();
+ }
+
+ NS_LOG_LOGIC ("Send NS ( from " << src << " to " << dst << " target " << target <<")");
+
+ p->AddHeader (llOption);
+ ns.CalculatePseudoHeaderChecksum (src, dst, p->GetSize () + ns.GetSerializedSize (), PROT_NUMBER);
+ p->AddHeader (ns);
+ SendMessage (p, src, dst, 255);
+}
+
+void Icmpv6L4Protocol::SendRS (Ipv6Address src, Ipv6Address dst, Address hardwareAddress)
+{
+ NS_LOG_FUNCTION (this << src << dst << hardwareAddress);
+ Ptr<Packet> p = Create<Packet> ();
+ Icmpv6RS rs;
+ Icmpv6OptionLinkLayerAddress llOption (1, hardwareAddress); /* we give our mac address in response */
+
+ /* if the source is unspec, multicast the NA to all-nodes multicast */
+ if (src != Ipv6Address::GetAny ())
+ {
+ p->AddHeader (llOption);
+ }
+
+ NS_LOG_LOGIC ("Send RS ( from " << src << " to " << dst << ")");
+
+ rs.CalculatePseudoHeaderChecksum (src, dst, p->GetSize () + rs.GetSerializedSize (), PROT_NUMBER);
+ p->AddHeader (rs);
+ SendMessage (p, src, dst, 255);
+}
+
+void Icmpv6L4Protocol::SendErrorDestinationUnreachable (Ptr<Packet> malformedPacket, Ipv6Address dst, uint8_t code)
+{
+ NS_LOG_FUNCTION (this << malformedPacket << dst << (uint32_t)code);
+ Ptr<Packet> p = Create<Packet> ();
+ uint32_t malformedPacketSize = malformedPacket->GetSize ();
+ Icmpv6DestinationUnreachable header;
+
+ NS_LOG_LOGIC ("Send Destination Unreachable ( to " << dst << " code " << (uint32_t)code << " )");
+
+ /* 48 = sizeof IPv6 header + sizeof ICMPv6 error header */
+ if (malformedPacketSize <= 1280 - 48)
+ {
+ header.SetPacket (malformedPacket);
+ }
+ else
+ {
+ Ptr<Packet> fragment = malformedPacket->CreateFragment (0, 1280 - 48);
+ header.SetPacket (fragment);
+ }
+
+ header.SetCode (code);
+ SendMessage (p, dst, header, 255);
+}
+
+void Icmpv6L4Protocol::SendErrorTooBig (Ptr<Packet> malformedPacket, Ipv6Address dst, uint32_t mtu)
+{
+ NS_LOG_FUNCTION (this << malformedPacket << dst << mtu);
+ Ptr<Packet> p = Create<Packet> ();
+ uint32_t malformedPacketSize = malformedPacket->GetSize ();
+ Icmpv6TooBig header;
+
+ NS_LOG_LOGIC ("Send Too Big ( to " << dst << " )");
+
+ /* 48 = sizeof IPv6 header + sizeof ICMPv6 error header */
+ if (malformedPacketSize <= 1280 - 48)
+ {
+ header.SetPacket (malformedPacket);
+ }
+ else
+ {
+ Ptr<Packet> fragment = malformedPacket->CreateFragment (0, 1280 - 48);
+ header.SetPacket (fragment);
+ }
+
+ header.SetCode (0);
+ header.SetMtu (mtu);
+ SendMessage (p, dst, header, 255);
+}
+
+void Icmpv6L4Protocol::SendErrorTimeExceeded (Ptr<Packet> malformedPacket, Ipv6Address dst, uint8_t code)
+{
+ NS_LOG_FUNCTION (this<< malformedPacket << dst << code);
+ Ptr<Packet> p = Create<Packet> ();
+ uint32_t malformedPacketSize = malformedPacket->GetSize ();
+ Icmpv6TimeExceeded header;
+
+ NS_LOG_LOGIC ("Send Time Exceeded ( to " << dst << " code " << (uint32_t)code << " )");
+
+ /* 48 = sizeof IPv6 header + sizeof ICMPv6 error header */
+ if (malformedPacketSize <= 1280 - 48)
+ {
+ header.SetPacket (malformedPacket);
+ }
+ else
+ {
+ Ptr<Packet> fragment = malformedPacket->CreateFragment (0, 1280 - 48);
+ header.SetPacket (fragment);
+ }
+
+ header.SetCode (code);
+ SendMessage (p, dst, header, 255);
+}
+
+void Icmpv6L4Protocol::SendErrorParameterError (Ptr<Packet> malformedPacket, Ipv6Address dst, uint8_t code, uint32_t ptr)
+{
+ NS_LOG_FUNCTION (this << malformedPacket << dst << code << ptr);
+ Ptr<Packet> p = Create<Packet> ();
+ uint32_t malformedPacketSize = malformedPacket->GetSize ();
+ Icmpv6ParameterError header;
+
+ NS_LOG_LOGIC ("Send Parameter Error ( to " << dst << " code " << (uint32_t)code << " )");
+
+ /* 48 = sizeof IPv6 header + sizeof ICMPv6 error header */
+ if (malformedPacketSize <= 1280 -48 )
+ {
+ header.SetPacket (malformedPacket);
+ }
+ else
+ {
+ Ptr<Packet> fragment = malformedPacket->CreateFragment (0, 1280 - 48);
+ header.SetPacket (fragment);
+ }
+
+ header.SetCode (code);
+ header.SetPtr (ptr);
+ SendMessage (p, dst, header, 255);
+}
+
+void Icmpv6L4Protocol::SendRedirection (Ptr<Packet> redirectedPacket, Ipv6Address dst, Ipv6Address redirTarget, Ipv6Address redirDestination, Address redirHardwareTarget)
+{
+ NS_LOG_FUNCTION (this << redirectedPacket << dst << redirTarget << redirDestination << redirHardwareTarget);
+ uint32_t llaSize = 0;
+ Ptr<Packet> p = Create<Packet> ();
+ uint32_t redirectedPacketSize = redirectedPacket->GetSize ();
+ Icmpv6OptionLinkLayerAddress llOption (0);
+
+ NS_LOG_LOGIC ("Send Redirection ( to " << dst << " target " << redirTarget << " destination " << redirDestination << " )");
+
+ Icmpv6OptionRedirected redirectedOptionHeader;
+
+ if ((redirectedPacketSize % 8) != 0)
+ {
+ redirectedPacket->AddPaddingAtEnd (8 - (redirectedPacketSize % 8));
+ }
+
+ if (redirHardwareTarget.GetLength ())
+ {
+ llOption.SetAddress (redirHardwareTarget);
+ llaSize = llOption.GetSerializedSize ();
+ }
+
+ /* 56 = sizeof IPv6 header + sizeof ICMPv6 error header + sizeof redirected option */
+ if (redirectedPacketSize <= (1280 - 56 - llaSize))
+ {
+ redirectedOptionHeader.SetPacket (redirectedPacket);
+ }
+ else
+ {
+ Ptr<Packet> fragment = redirectedPacket->CreateFragment (0, 1280 - 56 - llaSize);
+ redirectedOptionHeader.SetPacket (fragment);
+ }
+
+ p->AddHeader (redirectedOptionHeader);
+
+ if (llaSize)
+ {
+ p->AddHeader (llOption);
+ }
+
+ Icmpv6Redirection redirectionHeader;
+ redirectionHeader.SetTarget (redirTarget);
+ redirectionHeader.SetDestination (redirDestination);
+ SendMessage (p, dst, redirectionHeader, 64);
+}
+
+Ptr<Packet> Icmpv6L4Protocol::ForgeNA (Ipv6Address src, Ipv6Address dst, Address* hardwareAddress, uint8_t flags)
+{
+ NS_LOG_FUNCTION (this << src << dst << hardwareAddress << (uint32_t)flags);
+ Ptr<Packet> p = Create<Packet> ();
+ Ipv6Header ipHeader;
+ Icmpv6NA na;
+ Icmpv6OptionLinkLayerAddress llOption (0, *hardwareAddress); /* we give our mac address in response */
+
+ NS_LOG_LOGIC ("Send NA ( from " << src << " to " << dst << ")");
+
+ /* forge the entire NA packet from IPv6 header to ICMPv6 link-layer option, so that the packet does not pass by Icmpv6L4Protocol::Lookup again */
+
+ p->AddHeader (llOption);
+ na.SetIpv6Target (src);
+
+ if ((flags & 1))
+ {
+ na.SetFlagO (true);
+ }
+ if ((flags & 2) && src != Ipv6Address::GetAny ())
+ {
+ na.SetFlagS (true);
+ }
+ if ((flags & 4))
+ {
+ na.SetFlagR (true);
+ }
+
+ na.CalculatePseudoHeaderChecksum (src, dst, p->GetSize () + na.GetSerializedSize (), PROT_NUMBER);
+ p->AddHeader (na);
+
+ ipHeader.SetSourceAddress (src);
+ ipHeader.SetDestinationAddress (dst);
+ ipHeader.SetNextHeader (PROT_NUMBER);
+ ipHeader.SetPayloadLength (p->GetSize ());
+ ipHeader.SetHopLimit (255);
+
+ p->AddHeader (ipHeader);
+
+ return p;
+}
+
+Ptr<Packet> Icmpv6L4Protocol::ForgeNS (Ipv6Address src, Ipv6Address dst, Ipv6Address target, Address hardwareAddress)
+{
+ NS_LOG_FUNCTION (this << src << dst << target << hardwareAddress);
+ Ptr<Packet> p = Create<Packet> ();
+ Ipv6Header ipHeader;
+ Icmpv6NS ns (target);
+ Icmpv6OptionLinkLayerAddress llOption (1, hardwareAddress); /* we give our mac address in response */
+
+ /* if the source is unspec, multicast the NA to all-nodes multicast */
+ if (src == Ipv6Address::GetAny ())
+ {
+ dst = Ipv6Address::GetAllNodesMulticast ();
+ }
+
+ NS_LOG_LOGIC ("Send NS ( from " << src << " to " << dst << " target " << target <<")");
+
+ p->AddHeader (llOption);
+ ns.CalculatePseudoHeaderChecksum (src, dst, p->GetSize () + ns.GetSerializedSize (), PROT_NUMBER);
+ p->AddHeader (ns);
+
+ ipHeader.SetSourceAddress (src);
+ ipHeader.SetDestinationAddress (dst);
+ ipHeader.SetNextHeader (PROT_NUMBER);
+ ipHeader.SetPayloadLength (p->GetSize ());
+ ipHeader.SetHopLimit (255);
+
+ p->AddHeader (ipHeader);
+
+ return p;
+}
+
+Ptr<NdiscCache> Icmpv6L4Protocol::FindCache (Ptr<NetDevice> device)
+{
+ NS_LOG_FUNCTION (this << device);
+
+ for (CacheList::const_iterator i = m_cacheList.begin () ; i != m_cacheList.end () ; i++)
+ {
+ if ((*i)->GetDevice () == device)
+ {
+ return *i;
+ }
+ }
+
+ NS_ASSERT (false);
+ /* quiet compiler */
+ return 0;
+}
+
+Ptr<NdiscCache> Icmpv6L4Protocol::CreateCache (Ptr<NetDevice> device, Ptr<Ipv6Interface> interface)
+{
+ Ptr<Ipv6L3Protocol> ipv6 = m_node->GetObject<Ipv6L3Protocol> ();
+ Ptr<NdiscCache> cache = CreateObject<NdiscCache> ();
+ cache->SetDevice (device, interface);
+
+ /* XXX : make a list of callback in net-device.cc
+ * else we override IPv4 flushing ARP table...
+ */
+/* device->SetLinkChangeCallback (MakeCallback (&NdiscCache::Flush, cache)); */
+ m_cacheList.push_back (cache);
+ return cache;
+}
+
+bool Icmpv6L4Protocol::Lookup (Ptr<Packet> p, Ipv6Address dst, Ptr<NetDevice> device, Ptr<NdiscCache> cache, Address* hardwareDestination)
+{
+ NS_LOG_FUNCTION (this << p << dst << device << hardwareDestination);
+
+ if (!cache)
+ {
+ /* try to find the cache */
+ cache = FindCache (device);
+ }
+
+ NdiscCache::Entry* entry = cache->Lookup (dst);
+ if (entry)
+ {
+ if (entry->IsReachable () || entry->IsDelay ())
+ {
+ /* XXX check reachability time */
+ /* send packet */
+ *hardwareDestination = entry->GetMacAddress ();
+ return true;
+ }
+ else if (entry->IsStale ())
+ {
+ /* *hardwareDestination = entry->GetMacAddress (); */
+ /* start delay timer */
+ entry->StartDelayTimer ();
+ entry->MarkDelay ();
+ *hardwareDestination = entry->GetMacAddress ();
+ return true;
+ }
+ else /* PROBE */
+ {
+ /* queue packet */
+ entry->AddWaitingPacket (p);
+ return false;
+ }
+ }
+ else
+ {
+ /* we contact this node for the first time
+ * add it to the cache and send an NS
+ */
+ Ipv6Address addr;
+ NdiscCache::Entry* entry = cache->Add (dst);
+ entry->MarkIncomplete (p);
+ entry->SetRouter (false);
+
+ if (dst.IsLinkLocal ())
+ {
+ addr = cache->GetInterface ()->GetLinkLocalAddress ().GetAddress ();
+ }
+ else if (cache->GetInterface ()->GetNAddresses () == 1) /* an interface have at least one address (link-local) */
+ {
+ /* try to resolve global address without having global address so return! */
+ cache->Remove (entry);
+ return false;
+ }
+ else
+ {
+ /* find source address that match destination */
+ addr = cache->GetInterface ()->GetAddressMatchingDestination (dst).GetAddress ();
+ }
+
+ SendNS (addr, Ipv6Address::MakeSolicitedAddress (dst), dst, cache->GetDevice ()->GetAddress ());
+
+ /* start retransmit timer */
+ entry->StartRetransmitTimer ();
+ return false;
+ }
+
+ return false;
+}
+
+void Icmpv6L4Protocol::FunctionDadTimeout (Ptr<Icmpv6L4Protocol> icmpv6, Ipv6Interface* interface, Ipv6Address addr)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ NS_LOG_LOGIC (interface << " " << addr);
+ Ipv6InterfaceAddress ifaddr;
+ bool found = false;
+ uint32_t i = 0;
+ uint32_t nb = interface->GetNAddresses ();
+
+ for (i = 0 ; i < nb ; i++)
+ {
+ ifaddr = interface->GetAddress (i);
+
+ if (ifaddr.GetAddress () == addr)
+ {
+ found = true;
+ break;
+ }
+ }
+
+ /* for the moment, this function is always called, if we was victim of a DAD the address is INVALID
+ * and we do not set it to PREFERRED
+ */
+ if (found && ifaddr.GetState () != Ipv6InterfaceAddress::INVALID)
+ {
+ interface->SetState (ifaddr.GetAddress (), Ipv6InterfaceAddress::PREFERRED);
+ NS_LOG_LOGIC ("DAD OK, interface in state PREFERRED");
+
+ /* send an RS if our interface is not forwarding (router) and if address is a link-local ones
+ * (because we will send RS with it)
+ */
+ Ptr<Ipv6> ipv6 = icmpv6->m_node->GetObject<Ipv6> ();
+
+ if (!ipv6->IsForwarding (ipv6->GetInterfaceForDevice (interface->GetDevice ())) && addr.IsLinkLocal ())
+ {
+ /* XXX because all nodes start at the same time, there will be many of RS arround 1 second of simulation time
+ * TODO Add random delays before sending RS
+ */
+ Simulator::Schedule (Seconds (0.0), &Icmpv6L4Protocol::SendRS, PeekPointer (icmpv6), ifaddr.GetAddress (), Ipv6Address::GetAllRoutersMulticast (), interface->GetDevice ()->GetAddress ());
+ }
+ }
+}
+
+} /* namespace ns3 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/icmpv6-l4-protocol.h Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,472 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ * David Gross <gdavid.devel@gmail.com>
+ * Mehdi Benamor <benamor.mehdi@ensi.rnu.tn>
+ */
+
+#ifndef ICMPV6_L4_PROTOCOL_H
+#define ICMPV6_L4_PROTOCOL_H
+
+#include <list>
+#include "ns3/ipv6-address.h"
+#include "ns3/ptr.h"
+#include "ns3/socket.h"
+#include "ns3/buffer.h"
+#include "icmpv6-header.h"
+#include "ipv6-l4-protocol.h"
+#include "ndisc-cache.h"
+#include "ipv6-l3-protocol.h"
+
+namespace ns3
+{
+
+class NetDevice;
+class Node;
+class Packet;
+class TraceContext;
+
+/**
+ * \class Icmpv6L4Protocol
+ * \brief An implementation of the ICMPv6 protocol.
+ */
+class Icmpv6L4Protocol : public Ipv6L4Protocol
+{
+ public:
+ /**
+ * \brief Interface ID
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief ICMPv6 protocol number (58).
+ */
+ static const uint8_t PROT_NUMBER;
+
+ /**
+ * \brief Neighbor Discovery router constants : max initial RA initial interval.
+ */
+ static const uint8_t MAX_INITIAL_RTR_ADVERT_INTERVAL;
+
+ /**
+ * \brief Neighbor Discovery router constants : max initial RA transmission.
+ */
+ static const uint8_t MAX_INITIAL_RTR_ADVERTISEMENTS;
+
+ /**
+ * \brief Neighbor Discovery router constants : max final RA transmission.
+ */
+ static const uint8_t MAX_FINAL_RTR_ADVERTISEMENTS;
+
+ /**
+ * \brief Neighbor Discovery router constants : min delay between RA.
+ */
+ static const uint8_t MIN_DELAY_BETWEEN_RAS;
+
+ /**
+ * \brief Neighbor Discovery router constants : max delay between RA.
+ */
+ static const uint32_t MAX_RA_DELAY_TIME;
+
+ /**
+ * \brief Neighbor Discovery host constants : max RS delay.
+ */
+ static const uint8_t MAX_RTR_SOLICITATION_DELAY;
+
+ /**
+ * \brief Neighbor Discovery host constants : RS interval.
+ */
+ static const uint8_t RTR_SOLICITATION_INTERVAL;
+
+ /**
+ * \brief Neighbor Discovery host constants : max RS transmission.
+ */
+ static const uint8_t MAX_RTR_SOLICITATIONS;
+
+ /**
+ * \brief Neighbor Discovery node constants : max multicast solicitations.
+ */
+ static const uint8_t MAX_MULTICAST_SOLICIT;
+
+ /**
+ * \brief Neighbor Discovery node constants : max unicast solicitations.
+ */
+ static const uint8_t MAX_UNICAST_SOLICIT;
+
+ /**
+ * \brief Neighbor Discovery node constants : max anycast delay.
+ */
+ static const uint8_t MAX_ANYCAST_DELAY_TIME;
+
+ /**
+ * \brief Neighbor Discovery node constants : max NA transmission.
+ */
+ static const uint8_t MAX_NEIGHBOR_ADVERTISEMENT;
+
+ /**
+ * \brief Neighbor Discovery node constants : reachable time.
+ */
+ static const uint32_t REACHABLE_TIME;
+
+ /**
+ * \brief Neighbor Discovery node constants : retransmission timer.
+ */
+ static const uint32_t RETRANS_TIMER;
+
+ /**
+ * \brief Neighbor Discovery node constants : delay for the first probe.
+ */
+ static const uint8_t DELAY_FIRST_PROBE_TIME;
+
+ /**
+ * \brief Neighbor Discovery node constants : min random factor.
+ */
+ static const double MIN_RANDOM_FACTOR;
+
+ /**
+ * \brief Neighbor Discovery node constants : max random factor.
+ */
+ static const double MAX_RANDOM_FACTOR;
+
+ /**
+ * \brief Get ICMPv6 protocol number.
+ * \return protocol number
+ */
+ static uint16_t GetStaticProtocolNumber ();
+
+ /**
+ * \brief Constructor.
+ */
+ Icmpv6L4Protocol ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Icmpv6L4Protocol ();
+
+ /**
+ * \brief Set the node.
+ * \param node the node to set
+ */
+ void SetNode (Ptr<Node> node);
+
+ /**
+ * \brief This method is called by AddAgregate and completes the aggregation
+ * by setting the node in the ICMPv6 stack and adding ICMPv6 factory to
+ * IPv6 stack connected to the node.
+ */
+ void NotifyNewAggregate ();
+
+ /**
+ * \brief Get the protocol number.
+ * \return protocol number
+ */
+ virtual int GetProtocolNumber () const;
+
+ /**
+ * \brief Get the version of the protocol.
+ * \return version
+ */
+ virtual int GetVersion () const;
+
+ /**
+ * \brief Send a packet via ICMPv6, note that packet already contains ICMPv6 header.
+ * \param packet the packet to send which contains ICMPv6 header
+ * \param src source address
+ * \param dst destination address
+ * \param ttl next hop limit
+ */
+ void SendMessage (Ptr<Packet> packet, Ipv6Address src, Ipv6Address dst, uint8_t ttl);
+
+ /**
+ * \brief Send a packet via ICMPv6.
+ * \param packet the packet to send
+ * \param dst destination address
+ * \param icmpv6Hdr ICMPv6 header (needed to calculate checksum
+ * after source address is determined by routing stuff
+ * \param ttl next hop limit
+ */
+ void SendMessage (Ptr<Packet> packet, Ipv6Address dst, Icmpv6Header& icmpv6Hdr, uint8_t ttl);
+
+ /**
+ * \brief Do the Duplication Address Detection (DAD).
+ * \param target target address
+ * \param interface interface
+ */
+ void DoDAD (Ipv6Address target, Ptr<Ipv6Interface> interface);
+
+ /**
+ * \brief Send a Neighbor Adverstisement.
+ * \param src source IPv6 address
+ * \param dst destination IPv6 address
+ * \param hardwareAddress our MAC address
+ * \param flags to set (4 = flag R, 2 = flag S, 3 = flag O)
+ */
+ void SendNA (Ipv6Address src, Ipv6Address dst, Address* hardwareAddress, uint8_t flags);
+
+ /**
+ * \brief Send a Echo Reply.
+ * \param src source IPv6 address
+ * \param dst destination IPv6 address
+ * \param id id of the packet
+ * \param seq sequence number
+ * \param data auxiliary data
+ * \todo Change data to be a char[], change it too in icmpv6-header.
+ */
+ void SendEchoReply (Ipv6Address src, Ipv6Address dst, uint16_t id, uint16_t seq, Ptr<Packet> data);
+
+ /**
+ * \brief Send a Neighbor Solicitation.
+ * \param src source IPv6 address
+ * \param dst destination IPv6 addresss
+ * \param target target IPv6 address
+ * \param hardwareAddress our mac address
+ */
+ void SendNS (Ipv6Address src, Ipv6Address dst, Ipv6Address target, Address hardwareAddress);
+
+ /**
+ * \brief Send an error Destination Unreachable.
+ * \param malformedPacket the malformed packet
+ * \param dst destination IPv6 address
+ * \param code code of the error
+ */
+ void SendErrorDestinationUnreachable (Ptr<Packet> malformedPacket, Ipv6Address dst, uint8_t code);
+
+ /**
+ * \brief Send an error Too Big.
+ * \param malformedPacket the malformed packet
+ * \param dst destination IPv6 address
+ * \param mtu the mtu
+ */
+ void SendErrorTooBig (Ptr<Packet> malformedPacket, Ipv6Address dst, uint32_t mtu);
+
+ /**
+ * \brief Send an error Time Exceeded.
+ * \param malformedPacket the malformed packet
+ * \param dst destination IPv6 address
+ * \param code code of the error
+ */
+ void SendErrorTimeExceeded (Ptr<Packet> malformedPacket, Ipv6Address dst, uint8_t code);
+
+ /**
+ * \brief Send an error Parameter Error.
+ * \param malformedPacket the malformed packet
+ * \param dst destination IPv6 address
+ * \param code code of the error
+ * \param ptr byte of p where the error is located
+ */
+ void SendErrorParameterError (Ptr<Packet> malformedPacket, Ipv6Address dst, uint8_t code, uint32_t ptr);
+
+ /**
+ * \brief Send an ICMPv6 Redirection.
+ * \param redirectedPacket the redirected packet
+ * \param dst destination IPv6 address
+ * \param redirTarget IPv6 target address for Icmpv6Redirection
+ * \param redirDestination IPv6 destination address for Icmpv6Redirection
+ * \param redirHardwareTarget L2 target address for Icmpv6OptionRdirected
+ */
+ void SendRedirection (Ptr<Packet> redirectedPacket, Ipv6Address dst, Ipv6Address redirTarget, Ipv6Address redirDestination, Address redirHardwareTarget);
+
+ /**
+ * \brief Forge a Neighbor Solicitation.
+ * \param src source IPv6 address
+ * \param dst destination IPv6 addresss
+ * \param target target IPv6 address
+ * \param hardwareAddress our mac address
+ * \return NS packet (with IPv6 header)
+ */
+ Ptr<Packet> ForgeNS (Ipv6Address src, Ipv6Address dst, Ipv6Address target, Address hardwareAddress);
+
+ /**
+ * \brief Forge a Neighbor Advertisement.
+ * \param src source IPv6 address
+ * \param dst destination IPv6 addresss
+ * \param hardwareAddress our mac address
+ * \param flags flags (bitfield => R (4), S (2), O (1))
+ * \return NA packet (with IPv6 header)
+ */
+ Ptr<Packet> ForgeNA (Ipv6Address src, Ipv6Address dst, Address* hardwareAddress, uint8_t flags);
+
+ /**
+ * \brief Forge a Router Solicitation.
+ * \param src source IPv6 address
+ * \param dst destination IPv6 addresss
+ * \param hardwareAddress our mac address
+ * \return RS packet (with IPv6 header)
+ */
+ Ptr<Packet> ForgeRS (Ipv6Address src, Ipv6Address dst, Address hardwareAddress);
+
+ /**
+ * \brief Forge an Echo Request.
+ * \param src source address
+ * \param dst destination address
+ * \param id ID of the packet
+ * \param seq sequence number
+ * \param data the data
+ * \return Echo Request packet (without IPv6 header)
+ */
+ Ptr<Packet> ForgeEchoRequest (Ipv6Address src, Ipv6Address dst, uint16_t id, uint16_t seq, Ptr<Packet> data);
+
+ /**
+ * \brief Receive method.
+ * \param p the packet
+ * \param src source address
+ * \param dst destination address
+ * \param interface the interface from which the packet is coming
+ */
+ virtual enum Ipv6L4Protocol::RxStatus_e Receive (Ptr<Packet> p, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface);
+
+ /**
+ * \brief Do the Duplication Address Detection.
+ * It consists in sending a NS with our IPv6 as target. If
+ * we received a NA with matched target address, we could not use the address,
+ * else the address pass from TENTATIVE to PERMANENT.
+ * \param addr IPv6 address to test
+ * \param interface interface
+ */
+ void DoDad (Ipv6Address addr, Ptr<Ipv6Interface> interface);
+
+ /**
+ * \brief Function called when DAD timeout.
+ * \param icmpv6 Icmpv6L4Protocol instance
+ * \param interface the interface
+ * \param addr the IPv6 address
+ */
+ static void FunctionDadTimeout (Ptr<Icmpv6L4Protocol> icmpv6, Ipv6Interface* interface, Ipv6Address addr);
+
+ /**
+ * \brief Lookup in the ND cache for the IPv6 address (similar as ARP protocol).
+ * \param p the packet
+ * \param dst destination address
+ * \param device device
+ * \param cache the neighbor cache
+ * \param hardwareDestination hardware address
+ * \return true if the address is in the ND cache, the hardwareDestination is updated.
+ */
+ bool Lookup (Ptr<Packet> p, Ipv6Address dst, Ptr<NetDevice> device, Ptr<NdiscCache> cache, Address* hardwareDestination);
+
+ /**
+ * \brief Send a Router Solicitation.
+ * \param src link-local source address
+ * \param dst destination address (usealy ff02::2 i.e all-routers)
+ * \param hardwareAddress link-layer address (SHOULD be included if src is not ::
+ */
+ void SendRS (Ipv6Address src, Ipv6Address dst, Address hardwareAddress);
+
+ /**
+ * \brief Create a neighbor cache.
+ * \param device thet NetDevice
+ * \param interface the IPv6 interface
+ * \return a smart pointer of NdCache or 0 if problem
+ */
+ Ptr<NdiscCache> CreateCache (Ptr<NetDevice> device, Ptr<Ipv6Interface> interface);
+
+ protected:
+ /**
+ * \brief Dispose this object.
+ */
+ virtual void DoDispose ();
+
+ private:
+
+ typedef std::list<Ptr<NdiscCache> > CacheList;
+
+ /**
+ * \brief The node.
+ */
+ Ptr<Node> m_node;
+
+ /**
+ * \brief A list of cache by device.
+ */
+ CacheList m_cacheList;
+
+ /**
+ * \brief Receive Neighbor Solicitation method.
+ * \param p the packet
+ * \param src source address
+ * \param dst destination address
+ * \param interface the interface from which the packet is coming
+ */
+ void HandleNS (Ptr<Packet> p, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface);
+
+ /**
+ * \brief Receive Router Solicitation method.
+ * \param p the packet
+ * \param src source address
+ * \param dst destination address
+ * \param interface the interface from which the packet is coming
+ */
+ void HandleRS (Ptr<Packet> p, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface);
+
+ /**
+ * \brief Receive Router Advertisement method.
+ * \param p the packet
+ * \param src source address
+ * \param dst destination address
+ * \param interface the interface from which the packet is coming
+ */
+ void HandleRA (Ptr<Packet> p, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface);
+
+ /**
+ * \brief Receive Echo Request method.
+ * \param p the packet
+ * \param src source address
+ * \param dst destination address
+ * \param interface the interface from which the packet is coming
+ */
+ void HandleEchoRequest (Ptr<Packet> p, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface);
+
+ /**
+ * \brief Receive Neighbor Advertisement method.
+ * \param p the packet
+ * \param src source address
+ * \param dst destination address
+ * \param interface the interface from which the packet is coming
+ */
+ void HandleNA (Ptr<Packet> p, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface);
+
+ /**
+ * \brief Receive Redirection method.
+ * \param p the packet
+ * \param src source address
+ * \param dst destination address
+ * \param interface the interface from which the packet is coming
+ */
+ void HandleRedirection (Ptr<Packet> p, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface);
+
+ /**
+ * \brief Link layer address option processing.
+ * \param lla LLA option
+ * \param src source address
+ * \param dst destination address
+ * \param interface the interface from which the packet is coming
+ */
+ void ReceiveLLA (Icmpv6OptionLinkLayerAddress lla, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface);
+
+ /**
+ * \brief Get the cache corresponding to the device.
+ * \param device the device
+ */
+ Ptr<NdiscCache> FindCache (Ptr<NetDevice> device);
+};
+
+} /* namespace ns3 */
+
+#endif /* ICMPV6_L4_PROTOCOL_H */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv6-autoconfigured-prefix.cc Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,201 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008-2009 Telecom Bretagne
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mehdi Benamor <benamor.mehdi@ensi.rnu.tn>
+ */
+
+#include <stdlib.h>
+#include "ns3/log.h"
+#include "ns3/packet.h"
+#include "ns3/node.h"
+
+#include "ipv6-autoconfigured-prefix.h"
+
+NS_LOG_COMPONENT_DEFINE ("Ipv6AutoconfiguredPrefix");
+
+namespace ns3
+{
+ uint32_t Ipv6AutoconfiguredPrefix::m_prefixId = 0;
+
+ Ipv6AutoconfiguredPrefix::Ipv6AutoconfiguredPrefix (Ptr<Node> node, uint32_t interface, Ipv6Address prefix, Ipv6Prefix mask, uint32_t preferredLifeTime, uint32_t validLifeTime, Ipv6Address router)
+ {
+ m_node = node;
+ m_interface = interface;
+ m_validLifeTime = validLifeTime;
+ m_preferredLifeTime = preferredLifeTime;
+ m_id = m_prefixId;
+ m_prefixId ++;
+ m_preferred = false;
+ m_valid = false;
+ m_prefix = prefix;
+ m_mask = mask;
+ m_defaultGatewayRouter = router;
+ }
+
+ Ipv6AutoconfiguredPrefix::~Ipv6AutoconfiguredPrefix ()
+ {
+ }
+
+ void Ipv6AutoconfiguredPrefix::SetDefaultGatewayRouter (Ipv6Address router)
+ {
+ m_defaultGatewayRouter = router;
+ }
+
+ Ipv6Address Ipv6AutoconfiguredPrefix::GetDefaultGatewayRouter () const
+ {
+ return m_defaultGatewayRouter;
+ }
+
+ void Ipv6AutoconfiguredPrefix::SetInterface (uint32_t interface)
+ {
+ m_interface = interface;
+ }
+
+ uint32_t Ipv6AutoconfiguredPrefix::GetInterface () const
+ {
+ return m_interface;
+ }
+
+ void Ipv6AutoconfiguredPrefix::SetPreferredLifeTime (uint32_t t)
+ {
+ m_preferredLifeTime = t;
+ }
+
+ uint32_t Ipv6AutoconfiguredPrefix::GetPreferredLifeTime () const
+ {
+ return m_preferredLifeTime;
+ }
+
+ void Ipv6AutoconfiguredPrefix::SetValidLifeTime (uint32_t t)
+ {
+ m_validLifeTime = t;
+ }
+
+ uint32_t Ipv6AutoconfiguredPrefix::GetValidLifeTime () const
+ {
+ return m_validLifeTime;
+ }
+
+ void Ipv6AutoconfiguredPrefix::MarkPreferredTime ()
+ {
+ m_preferred = true;
+ }
+
+ void Ipv6AutoconfiguredPrefix::MarkValidTime ()
+ {
+ m_preferred = false;
+ m_valid = true;
+ }
+
+ void Ipv6AutoconfiguredPrefix::FunctionPreferredTimeout ()
+ {
+ NS_LOG_INFO ("Preferred Time expired for " << m_prefix);
+ m_preferred = false;
+ MarkValidTime ();
+ StartValidTimer ();
+ }
+
+ void Ipv6AutoconfiguredPrefix::FunctionValidTimeout ()
+ {
+ NS_LOG_INFO ("Valid Time expired for " << m_prefix);
+ m_valid = false;
+ RemoveMe ();
+ }
+
+ void Ipv6AutoconfiguredPrefix::StartPreferredTimer ()
+ {
+ NS_LOG_INFO ("Start PreferredTimer for " << m_prefix);
+ m_preferredTimer.SetFunction (&Ipv6AutoconfiguredPrefix::FunctionPreferredTimeout, this);
+ m_preferredTimer.SetDelay (Seconds (m_preferredLifeTime));
+ m_preferredTimer.Schedule ();
+ }
+
+ void Ipv6AutoconfiguredPrefix::StartValidTimer ()
+ {
+ NS_LOG_INFO ("Start ValidTimer for " << m_prefix);
+ m_validTimer.SetFunction (&Ipv6AutoconfiguredPrefix::FunctionValidTimeout, this);
+ m_validTimer.SetDelay (Seconds (m_validLifeTime - m_preferredLifeTime));
+ m_validTimer.Schedule ();
+ }
+
+ void Ipv6AutoconfiguredPrefix::StopPreferredTimer ()
+ {
+ NS_LOG_INFO ("Stop PreferredTimer for " << m_prefix);
+ m_preferredTimer.Cancel ();
+ }
+
+ void Ipv6AutoconfiguredPrefix::StopValidTimer ()
+ {
+ NS_LOG_INFO ("Stop ValidTimer for " << m_prefix);
+ m_validTimer.Cancel ();
+ }
+
+ void Ipv6AutoconfiguredPrefix::RemoveMe ()
+ {
+ NS_LOG_INFO ("The prefix " << m_prefix << " will be removed on interface " << m_interface);
+ Ptr<Ipv6L3Protocol> ipv6 = m_node->GetObject<Ipv6L3Protocol> ();
+ ipv6->RemoveAutoconfiguredAddress (m_interface, m_prefix, m_mask, m_defaultGatewayRouter);
+ }
+
+ void Ipv6AutoconfiguredPrefix::SetPreferred ()
+ {
+ m_preferred = true;
+ }
+
+ void Ipv6AutoconfiguredPrefix::SetValid ()
+ {
+ m_preferred = false;
+ m_valid = true;
+ }
+
+ uint32_t Ipv6AutoconfiguredPrefix::GetId () const
+ {
+ return m_id;
+ }
+
+ bool Ipv6AutoconfiguredPrefix::IsPreferred () const
+ {
+ return m_preferred;
+ }
+
+ bool Ipv6AutoconfiguredPrefix::IsValid () const
+ {
+ return m_valid;
+ }
+
+ Ipv6Address Ipv6AutoconfiguredPrefix::GetPrefix () const
+ {
+ return m_prefix;
+ }
+
+ void Ipv6AutoconfiguredPrefix::SetPrefix (Ipv6Address prefix)
+ {
+ m_prefix = prefix;
+ }
+
+ Ipv6Prefix Ipv6AutoconfiguredPrefix::GetMask () const
+ {
+ return m_mask;
+ }
+
+ void Ipv6AutoconfiguredPrefix::SetMask (Ipv6Prefix mask)
+ {
+ m_mask = mask;
+ }
+
+} /* namespace ns3 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv6-autoconfigured-prefix.h Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,279 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008-2009 Telecom Bretagne
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mehdi Benamor <benamor.mehdi@ensi.rnu.tn>
+ */
+
+#ifndef IPV6_AUTOCONFIGURED_PREFIX_H
+#define IPV6_AUTOCONFIGURED_PREFIX_H
+
+#include <list>
+#include <vector>
+#include <ostream>
+
+#include "ns3/timer.h"
+#include "ns3/ipv6-address.h"
+#include "ipv6-l3-protocol.h"
+#include "ipv6-interface.h"
+
+namespace ns3
+{
+
+/**
+ * \class Ipv6AutoconfiguredPrefix
+ * \brief Router prefix information.
+ */
+class Ipv6AutoconfiguredPrefix : public Object
+{
+ public:
+ /**
+ * \brief Constructor.
+ * \param node node
+ * \param interface interface index
+ * \param prefix IPv6 address
+ * \param mask bitmask prefix
+ * \param preferredLifeTime the preferred life time
+ * \param validLifeTime the valid life time
+ * \param router if it the prefix that configure the default gateway
+ */
+ Ipv6AutoconfiguredPrefix (Ptr<Node> node, uint32_t interface, Ipv6Address prefix, Ipv6Prefix mask, uint32_t preferredLifeTime, uint32_t validLifeTime, Ipv6Address router = Ipv6Address ("::"));
+
+ /**
+ * \brief Destructor.
+ */
+ ~Ipv6AutoconfiguredPrefix ();
+
+ /**
+ * \brief Set the default gateway router.
+ * \param router IPv6 link-local address of the default router
+ */
+ void SetDefaultGatewayRouter (Ipv6Address router);
+
+ /**
+ * \brief Get the default gateway address.
+ * \return IPv6 link-local address of the default router
+ */
+ Ipv6Address GetDefaultGatewayRouter () const;
+
+ /**
+ * \brief Get the interface index.
+ * \return interface index
+ */
+ uint32_t GetInterface () const;
+
+ /**
+ * \brief Set the interface.
+ * \param interface interface index to set
+ */
+ void SetInterface (uint32_t interface);
+
+ /**
+ * \brief Get the prefix preferred life time.
+ * \return preferred life time
+ */
+ uint32_t GetPreferredLifeTime () const;
+
+ /**
+ * \brief Set the prefix preferred life time.
+ * \param p the prefix preferred life time
+ */
+ void SetPreferredLifeTime (uint32_t p);
+
+ /**
+ * \brief Get the prefix valid life time.
+ * \return valid life time
+ */
+ uint32_t GetValidLifeTime (void) const;
+
+ /**
+ * \brief Set the prefix valid life time
+ * \param v the prefix valid life time
+ */
+ void SetValidLifeTime (uint32_t v);
+
+ /**
+ * \brief Test if the prefix is preferred
+ * \return true if prefix is in preferred state, false otherwise
+ */
+ bool IsPreferred () const;
+
+ /**
+ * \brief Test if the prefix is valid.
+ * \return true if prefix is in valid state, false otherwise
+ */
+ bool IsValid () const;
+
+ /**
+ * \brief Set the prefix as preferred
+ */
+ void SetPreferred ();
+
+ /**
+ * \brief Set the prefix as valid
+ */
+ void SetValid ();
+
+ /**
+ * \brief Start the preferred timer
+ */
+ void StartPreferredTimer ();
+
+ /**
+ * \brief Start the valid timer
+ */
+ void StartValidTimer ();
+
+ /**
+ * \brief Stop the preferred timer
+ */
+ void StopPreferredTimer ();
+
+ /**
+ * \brief Stop the valid timer
+ */
+ void StopValidTimer ();
+
+ /**
+ * \brief Set the prefix as preferred
+ */
+ void MarkPreferredTime ();
+
+ /**
+ * \brief Set the prefix as valid
+ */
+ void MarkValidTime ();
+
+ /**
+ * \brief Signal that the preferred time expired and start the valid timer
+ */
+ void FunctionPreferredTimeout ();
+
+ /**
+ * \brief Signal that the valid time expired
+ */
+ void FunctionValidTimeout ();
+
+ /**
+ * \brief Remove this prefix from the prefix list
+ */
+ void RemoveMe ();
+
+ /**
+ * \brief Get the prefix identificator
+ * \return id of the prefix.
+ */
+ uint32_t GetId () const;
+
+ /**
+ * \brief Get the prefix address
+ * \return prefix address
+ */
+ Ipv6Address GetPrefix () const;
+
+ /**
+ * \brief Set the prefix address
+ * \param prefix prefix address to set
+ */
+ void SetPrefix (Ipv6Address prefix);
+
+ /**
+ * \brief Get the bitmask prefix.
+ * \return bitmask prefix
+ */
+ Ipv6Prefix GetMask () const;
+
+ /**
+ * \brief Set the bitmask prefix.
+ * \param mask prefix
+ */
+ void SetMask (Ipv6Prefix mask);
+
+ private:
+ /**
+ * \brief a static identifier.
+ */
+ static uint32_t m_prefixId;
+
+ /**
+ * \brief the identifier of this prefix.
+ */
+ uint32_t m_id;
+
+ /**
+ * \brief The node.
+ */
+ Ptr<Node> m_node;
+
+ /**
+ * \brief The prefix IP6 address.
+ */
+ Ipv6Address m_prefix;
+
+ /**
+ * \brief The prefix bitmask (length).
+ */
+ Ipv6Prefix m_mask;
+
+ /**
+ * \brief Default gateway router
+ * If the RA received also configured the default gateway,
+ * this variable has the link-local address. Otherwise this
+ * is "::"
+ */
+ Ipv6Address m_defaultGatewayRouter;
+
+ /**
+ * \brief The interface index (which is stored the address
+ * corresponding of the prefix).
+ */
+ uint32_t m_interface;
+
+ /**
+ * \brief the valid life time.
+ */
+ uint32_t m_validLifeTime;
+
+ /**
+ * \brief the preferred life time.
+ */
+ uint32_t m_preferredLifeTime;
+
+ /**
+ * \brief true if the prefix is preferred.
+ */
+ bool m_preferred;
+
+ /**
+ * \brief true if the prefix is valid.
+ */
+ bool m_valid;
+
+ /**
+ * \brief the timer for preferred life time.
+ */
+ Timer m_preferredTimer;
+
+ /**
+ * \brief the timer for valid life time.
+ */
+ Timer m_validTimer;
+};
+
+} /* namespace ns3 */
+
+#endif /* IPV6_AUTOCONFIGURED_PREFIX_H */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv6-end-point-demux.cc Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,318 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#include "ipv6-end-point-demux.h"
+#include "ipv6-end-point.h"
+#include "ns3/log.h"
+
+namespace ns3
+{
+
+NS_LOG_COMPONENT_DEFINE ("Ipv6EndPointDemux");
+
+Ipv6EndPointDemux::Ipv6EndPointDemux ()
+ : m_ephemeral (49152)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+Ipv6EndPointDemux::~Ipv6EndPointDemux ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
+ {
+ Ipv6EndPoint *endPoint = *i;
+ delete endPoint;
+ }
+ m_endPoints.clear ();
+}
+
+bool Ipv6EndPointDemux::LookupPortLocal (uint16_t port)
+{
+ NS_LOG_FUNCTION (this << port);
+ for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
+ {
+ if ((*i)->GetLocalPort () == port)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool Ipv6EndPointDemux::LookupLocal (Ipv6Address addr, uint16_t port)
+{
+ NS_LOG_FUNCTION (this << addr << port);
+ for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
+ {
+ if ((*i)->GetLocalPort () == port &&
+ (*i)->GetLocalAddress () == addr)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+Ipv6EndPoint* Ipv6EndPointDemux::Allocate ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ uint16_t port = AllocateEphemeralPort ();
+ if (port == 0)
+ {
+ NS_LOG_WARN ("Ephemeral port allocation failed.");
+ return 0;
+ }
+ Ipv6EndPoint *endPoint = new Ipv6EndPoint (Ipv6Address::GetAny (), port);
+ m_endPoints.push_back (endPoint);
+ NS_LOG_DEBUG ("Now have >>" << m_endPoints.size () << "<< endpoints.");
+ return endPoint;
+}
+
+Ipv6EndPoint* Ipv6EndPointDemux::Allocate (Ipv6Address address)
+{
+ NS_LOG_FUNCTION (this << address);
+ uint16_t port = AllocateEphemeralPort ();
+ if (port == 0)
+ {
+ NS_LOG_WARN ("Ephemeral port allocation failed.");
+ return 0;
+ }
+ Ipv6EndPoint *endPoint = new Ipv6EndPoint (address, port);
+ m_endPoints.push_back (endPoint);
+ NS_LOG_DEBUG ("Now have >>" << m_endPoints.size () << "<< endpoints.");
+ return endPoint;
+}
+
+Ipv6EndPoint* Ipv6EndPointDemux::Allocate (uint16_t port)
+{
+ NS_LOG_FUNCTION (this << port);
+
+ return Allocate (Ipv6Address::GetAny (), port);
+}
+
+Ipv6EndPoint* Ipv6EndPointDemux::Allocate (Ipv6Address address, uint16_t port)
+{
+ NS_LOG_FUNCTION (this << address << port);
+ if (LookupLocal (address, port))
+ {
+ NS_LOG_WARN ("Duplicate address/port; failing.");
+ return 0;
+ }
+ Ipv6EndPoint *endPoint = new Ipv6EndPoint (address, port);
+ m_endPoints.push_back (endPoint);
+ NS_LOG_DEBUG ("Now have >>" << m_endPoints.size () << "<< endpoints.");
+ return endPoint;
+}
+
+Ipv6EndPoint* Ipv6EndPointDemux::Allocate (Ipv6Address localAddress, uint16_t localPort,
+ Ipv6Address peerAddress, uint16_t peerPort)
+{
+ NS_LOG_FUNCTION (this << localAddress << localPort << peerAddress << peerPort);
+ for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
+ {
+ if ((*i)->GetLocalPort () == localPort &&
+ (*i)->GetLocalAddress () == localAddress &&
+ (*i)->GetPeerPort () == peerPort &&
+ (*i)->GetPeerAddress () == peerAddress)
+ {
+ NS_LOG_WARN ("No way we can allocate this end-point.");
+ /* no way we can allocate this end-point. */
+ return 0;
+ }
+ }
+ Ipv6EndPoint *endPoint = new Ipv6EndPoint (localAddress, localPort);
+ endPoint->SetPeer (peerAddress, peerPort);
+ m_endPoints.push_back (endPoint);
+
+ NS_LOG_DEBUG ("Now have >>" << m_endPoints.size () << "<< endpoints.");
+
+ return endPoint;
+}
+
+void Ipv6EndPointDemux::DeAllocate (Ipv6EndPoint *endPoint)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
+ {
+ if (*i == endPoint)
+ {
+ delete endPoint;
+ m_endPoints.erase (i);
+ break;
+ }
+ }
+}
+
+/*
+ * If we have an exact match, we return it.
+ * Otherwise, if we find a generic match, we return it.
+ * Otherwise, we return 0.
+ */
+Ipv6EndPointDemux::EndPoints Ipv6EndPointDemux::Lookup (Ipv6Address daddr, uint16_t dport,
+ Ipv6Address saddr, uint16_t sport,
+ Ptr<Ipv6Interface> incomingInterface)
+{
+ NS_LOG_FUNCTION (this << daddr << dport << saddr << sport << incomingInterface);
+
+ EndPoints retval1; /* Matches exact on local port, wildcards on others */
+ EndPoints retval2; /* Matches exact on local port/adder, wildcards on others */
+ EndPoints retval3; /* Matches all but local address */
+ EndPoints retval4; /* Exact match on all 4 */
+
+ NS_LOG_DEBUG ("Looking up endpoint for destination address " << daddr);
+ for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
+ {
+ Ipv6EndPoint* endP = *i;
+ NS_LOG_DEBUG ("Looking at endpoint dport=" << endP->GetLocalPort ()
+ << " daddr=" << endP->GetLocalAddress ()
+ << " sport=" << endP->GetPeerPort ()
+ << " saddr=" << endP->GetPeerAddress ());
+ if (endP->GetLocalPort () != dport)
+ {
+ NS_LOG_LOGIC ("Skipping endpoint " << &endP
+ << " because endpoint dport "
+ << endP->GetLocalPort ()
+ << " does not match packet dport " << dport);
+ continue;
+ }
+
+/* Ipv6Address incomingInterfaceAddr = incomingInterface->GetAddress (); */
+ NS_LOG_DEBUG ("dest addr " << daddr);
+
+ bool localAddressMatchesWildCard = endP->GetLocalAddress () == Ipv6Address::GetAny ();
+ bool localAddressMatchesExact = endP->GetLocalAddress () == daddr;
+ bool localAddressMatchesAllRouters = endP->GetLocalAddress () == Ipv6Address::GetAllRoutersMulticast ();
+
+ /* if no match here, keep looking */
+ if (!(localAddressMatchesExact || localAddressMatchesWildCard))
+ continue;
+ bool remotePeerMatchesExact = endP->GetPeerPort () == sport;
+ bool remotePeerMatchesWildCard = endP->GetPeerPort () == 0;
+ bool remoteAddressMatchesExact = endP->GetPeerAddress () == saddr;
+ bool remoteAddressMatchesWildCard = endP->GetPeerAddress () == Ipv6Address::GetAny ();
+
+ /* If remote does not match either with exact or wildcard,i
+ skip this one */
+ if (!(remotePeerMatchesExact || remotePeerMatchesWildCard))
+ continue;
+ if (!(remoteAddressMatchesExact || remoteAddressMatchesWildCard))
+ continue;
+
+ /* Now figure out which return list to add this one to */
+ if (localAddressMatchesWildCard &&
+ remotePeerMatchesWildCard &&
+ remoteAddressMatchesWildCard)
+ { /* Only local port matches exactly */
+ retval1.push_back (endP);
+ }
+ if ((localAddressMatchesExact || (localAddressMatchesAllRouters))&&
+ remotePeerMatchesWildCard &&
+ remoteAddressMatchesWildCard)
+ { /* Only local port and local address matches exactly */
+ retval2.push_back (endP);
+ }
+ if (localAddressMatchesWildCard &&
+ remotePeerMatchesExact &&
+ remoteAddressMatchesExact)
+ { /* All but local address */
+ retval3.push_back (endP);
+ }
+ if (localAddressMatchesExact &&
+ remotePeerMatchesExact &&
+ remoteAddressMatchesExact)
+ { /* All 4 match */
+ retval4.push_back (endP);
+ }
+ }
+
+ /* Here we find the most exact match */
+ if (!retval4.empty ()) return retval4;
+ if (!retval3.empty ()) return retval3;
+ if (!retval2.empty ()) return retval2;
+ return retval1; /* might be empty if no matches */
+}
+
+Ipv6EndPoint* Ipv6EndPointDemux::SimpleLookup (Ipv6Address dst, uint16_t dport, Ipv6Address src, uint16_t sport)
+{
+ uint32_t genericity = 3;
+ Ipv6EndPoint *generic = 0;
+
+ for (EndPointsI i = m_endPoints.begin () ; i != m_endPoints.end () ; i++)
+ {
+ uint32_t tmp = 0;
+
+ if ((*i)->GetLocalPort () != dport)
+ {
+ continue;
+ }
+
+ if ((*i)->GetLocalAddress () == dst && (*i)->GetPeerPort () == sport &&
+ (*i)->GetPeerAddress () == src)
+ {
+ /* this is an exact match. */
+ return *i;
+ }
+
+ if ((*i)->GetLocalAddress () == Ipv6Address::GetAny ())
+ {
+ tmp ++;
+ }
+
+ if ((*i)->GetPeerAddress () == Ipv6Address::GetAny ())
+ {
+ tmp ++;
+ }
+
+ if (tmp < genericity)
+ {
+ generic = (*i);
+ genericity = tmp;
+ }
+ }
+ return generic;
+}
+
+uint16_t Ipv6EndPointDemux::AllocateEphemeralPort ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ uint16_t port = m_ephemeral;
+ do
+ {
+ port++;
+ if (port == 65535)
+ {
+ port = 49152;
+ }
+ if (!LookupPortLocal (port))
+ {
+ return port;
+ }
+ } while (port != m_ephemeral);
+ return 0;
+}
+
+Ipv6EndPointDemux::EndPoints Ipv6EndPointDemux::GetEndPoints () const
+{
+ return m_endPoints;
+}
+
+} /* namespace ns3 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv6-end-point-demux.h Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,160 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#ifndef IPV6_END_POINT_DEMUX_H
+#define IPV6_END_POINT_DEMUX_H
+
+#include <stdint.h>
+#include <list>
+#include "ns3/ipv6-address.h"
+#include "ipv6-interface.h"
+
+namespace ns3
+{
+
+class Ipv6EndPoint;
+
+/**
+ * \class Ipv6EndPointDemux
+ * \brief Demultiplexor for end points.
+ */
+class Ipv6EndPointDemux
+{
+ public:
+ typedef std::list<Ipv6EndPoint *>EndPoints;
+ typedef std::list<Ipv6EndPoint *>::iterator EndPointsI;
+
+ /**
+ * \brief Constructor.
+ */
+ Ipv6EndPointDemux ();
+
+ /**
+ * \brief Destructor.
+ */
+ ~Ipv6EndPointDemux ();
+
+ /**
+ * \brief Lookup for port local.
+ * \param port port to test
+ * \return true if a port local is in EndPoints, false otherwise
+ */
+ bool LookupPortLocal (uint16_t port);
+
+ /**
+ * \brief Lookup for address and port.
+ * \param addr address to test
+ * \param port port to test
+ * \return true if there is a match in EndPoints, false otherwise
+ */
+ bool LookupLocal (Ipv6Address addr, uint16_t port);
+
+ /**
+ * \brief lookup for a match with all the parameters.
+ * \param dst destination address to test
+ * \param dport destination port to test
+ * \param src source address to test
+ * \param sport source port to test
+ * \param incomingInterface the incoming interface
+ * \return list en IPv6EndPoints (could be 0 element)
+ */
+ EndPoints Lookup (Ipv6Address dst, uint16_t dport, Ipv6Address src, uint16_t sport, Ptr<Ipv6Interface> incomingInterface);
+
+ /**
+ * \brief Simple lookup for a four-tuple match.
+ * \param dst destination address to test
+ * \param dport destination port to test
+ * \param src source address to test
+ * \param sport source port to test
+ * \return match or 0 if not found
+ */
+ Ipv6EndPoint* SimpleLookup (Ipv6Address dst, uint16_t dport, Ipv6Address src, uint16_t sport);
+
+ /**
+ * \brief Allocate a Ipv6EndPoint.
+ * \return an empty Ipv6EndPoint instance
+ */
+ Ipv6EndPoint *Allocate (void);
+
+ /**
+ * \brief Allocate a Ipv6EndPoint.
+ * \return an empty Ipv6EndPoint instance
+ */
+ Ipv6EndPoint *Allocate (Ipv6Address address);
+
+ /**
+ * \brief Allocate a Ipv6EndPoint.
+ * \param port local port
+ * \return an Ipv6EndPoint instance
+ */
+ Ipv6EndPoint *Allocate (uint16_t port);
+
+ /**
+ * \brief Allocate a Ipv6EndPoint.
+ * \param address local address
+ * \param port local port
+ * \return an Ipv6EndPoint instance
+ */
+ Ipv6EndPoint *Allocate (Ipv6Address address, uint16_t port);
+
+ /**
+ * \brief Allocate a Ipv6EndPoint.
+ * \param localAddress local address
+ * \param localPort local port
+ * \param peerAddress peer address
+ * \param peerPort peer port
+ * \return an Ipv6EndPoint instance
+ */
+ Ipv6EndPoint *Allocate (Ipv6Address localAddress, uint16_t localPort, Ipv6Address peerAddress, uint16_t peerPort);
+
+ /**
+ * \brief Remove a end point.
+ * \param endPoint the end point to remove
+ */
+ void DeAllocate (Ipv6EndPoint *endPoint);
+
+ /**
+ * \brief Get the entire list of end points registered.
+ * \return list of Ipv6EndPoint
+ */
+ EndPoints GetEndPoints () const;
+
+ private:
+ /**
+ * \brief Allocate a ephemeral port.
+ * \return a port
+ */
+ uint16_t AllocateEphemeralPort ();
+
+ /**
+ * \brief The ephemeral port.
+ */
+ uint16_t m_ephemeral;
+
+ /**
+ * \brief A list of IPv6 end points.
+ */
+ EndPoints m_endPoints;
+};
+
+} /* namespace ns3 */
+
+#endif /* IPV6_END_POINT_DEMUX_H */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv6-end-point.cc Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,128 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#include "ipv6-end-point.h"
+#include "ns3/packet.h"
+#include "ns3/log.h"
+#include "ns3/simulator.h"
+
+namespace ns3
+{
+
+NS_LOG_COMPONENT_DEFINE ("Ipv6EndPoint");
+
+Ipv6EndPoint::Ipv6EndPoint (Ipv6Address addr, uint16_t port)
+ : m_localAddr (addr),
+ m_localPort (port),
+ m_peerAddr (Ipv6Address::GetAny ()),
+ m_peerPort (0)
+{
+}
+
+Ipv6EndPoint::~Ipv6EndPoint ()
+{
+ if (!m_destroyCallback.IsNull ())
+ {
+ m_destroyCallback ();
+ }
+}
+
+Ipv6Address Ipv6EndPoint::GetLocalAddress ()
+{
+ return m_localAddr;
+}
+
+void Ipv6EndPoint::SetLocalAddress (Ipv6Address addr)
+{
+ m_localAddr = addr;
+}
+
+uint16_t Ipv6EndPoint::GetLocalPort ()
+{
+ return m_localPort;
+}
+
+void Ipv6EndPoint::SetLocalPort (uint16_t port)
+{
+ m_localPort = port;
+}
+
+Ipv6Address Ipv6EndPoint::GetPeerAddress ()
+{
+ return m_peerAddr;
+}
+
+uint16_t Ipv6EndPoint::GetPeerPort ()
+{
+ return m_peerPort;
+}
+
+void Ipv6EndPoint::SetPeer (Ipv6Address addr, uint16_t port)
+{
+ m_peerAddr = addr;
+ m_peerPort = port;
+}
+
+void Ipv6EndPoint::SetRxCallback (Callback<void, Ptr<Packet>, Ipv6Address, uint16_t> callback)
+{
+ m_rxCallback = callback;
+}
+
+void Ipv6EndPoint::SetIcmpCallback (Callback<void,Ipv6Address,uint8_t,uint8_t,uint8_t,uint32_t> callback)
+{
+ m_icmpCallback = callback;
+}
+
+void Ipv6EndPoint::SetDestroyCallback (Callback<void> callback)
+{
+ m_destroyCallback = callback;
+}
+
+void Ipv6EndPoint::ForwardUp (Ptr<Packet> p, Ipv6Address addr, uint16_t port)
+{
+ if (!m_rxCallback.IsNull ())
+ {
+ m_rxCallback (p, addr, port);
+ }
+}
+
+void Ipv6EndPoint::ForwardIcmp (Ipv6Address src, uint8_t ttl, uint8_t type,
+ uint8_t code, uint32_t info)
+{
+ if (!m_icmpCallback.IsNull ())
+ {
+ Simulator::ScheduleNow (&Ipv6EndPoint::DoForwardIcmp, this,
+ src, ttl, type, code, info);
+ }
+}
+
+void Ipv6EndPoint::DoForwardUp (Ptr<Packet> p, Ipv6Address saddr, uint16_t sport)
+{
+ m_rxCallback (p, saddr, sport);
+}
+
+void Ipv6EndPoint::DoForwardIcmp (Ipv6Address src, uint8_t ttl, uint8_t type,
+ uint8_t code, uint32_t info)
+{
+ m_icmpCallback (src, ttl, type, code, info);
+}
+
+} /* namespace ns3 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv6-end-point.h Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,193 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#ifndef IPV6_END_POINT_H
+#define IPV6_END_POINT_H
+
+#include <stdint.h>
+#include "ns3/ipv6-address.h"
+#include "ns3/callback.h"
+
+namespace ns3
+{
+
+class Header;
+class Packet;
+
+/**
+ * \class Ipv6EndPoint
+ * \brief An IPv6 end point, four tuples identification.
+ */
+class Ipv6EndPoint
+{
+ public:
+ /**
+ * \brief Constructor.
+ * \param addr the IPv6 address
+ * \param port the port
+ */
+ Ipv6EndPoint (Ipv6Address addr, uint16_t port);
+
+ /**
+ * \brief Destructor.
+ */
+ ~Ipv6EndPoint ();
+
+ /**
+ * \brief Get the local address.
+ * \return the local address
+ */
+ Ipv6Address GetLocalAddress ();
+
+ /**
+ * \brief Set the local address.
+ * \param addr the address to set
+ */
+ void SetLocalAddress (Ipv6Address addr);
+
+ /**
+ * \brief Get the local port.
+ * \return the local port
+ */
+ uint16_t GetLocalPort ();
+
+ /**
+ * \brief Set the local port.
+ * \param port the port to set
+ */
+ void SetLocalPort (uint16_t port);
+
+ /**
+ * \brief Get the peer address.
+ * \return the peer address
+ */
+ Ipv6Address GetPeerAddress ();
+
+ /**
+ * \brief Get the peer port.
+ * \return the peer port
+ */
+ uint16_t GetPeerPort ();
+
+ /**
+ * \brief Set the peer informations (address and port).
+ * \param addr peer address
+ * \param port peer port
+ */
+ void SetPeer (Ipv6Address addr, uint16_t port);
+
+ /**
+ * \brief Set the reception callback.
+ * \param callback callback function
+ */
+ void SetRxCallback (Callback<void, Ptr<Packet>, Ipv6Address, uint16_t> callback);
+
+ /**
+ * \brief Set the ICMP callback.
+ * \param callback callback function
+ */
+ void SetIcmpCallback (Callback<void, Ipv6Address, uint8_t, uint8_t, uint8_t, uint32_t> callback);
+
+ /**
+ * \brief Set the default destroy callback.
+ * \param callback callback function
+ */
+ void SetDestroyCallback (Callback<void> callback);
+
+ /**
+ * \brief Forward the packet to the upper level.
+ * \param p the packet
+ * \param addr source address
+ * \param port source port
+ */
+ void ForwardUp (Ptr<Packet> p, Ipv6Address addr, uint16_t port);
+
+ /**
+ * \brief Function called from an L4Protocol implementation
+ * to notify an endpoint of an icmp message reception.
+ * \param src source IPv6 address
+ * \param ttl time-to-live
+ * \param type ICMPv6 type
+ * \param code ICMPv6 code
+ * \param info ICMPv6 info
+ */
+ void ForwardIcmp (Ipv6Address src, uint8_t ttl, uint8_t type,
+ uint8_t code, uint32_t info);
+
+ private:
+ /**
+ * \brief ForwardUp wrapper.
+ * \param p packet
+ * \param saddr source IPv6 address
+ * \param sport source port
+ */
+ void DoForwardUp (Ptr<Packet> p, Ipv6Address saddr, uint16_t sport);
+
+ /**
+ * \brief ForwardIcmp wrapper.
+ * \param src source IPv6 address
+ * \param ttl time-to-live
+ * \param type ICMPv6 type
+ * \param code ICMPv6 code
+ * \param info ICMPv6 info
+ */
+ void DoForwardIcmp (Ipv6Address src, uint8_t ttl, uint8_t type,
+ uint8_t code, uint32_t info);
+
+ /**
+ * \brief The local address.
+ */
+ Ipv6Address m_localAddr;
+
+ /**
+ * \brief The local port.
+ */
+ uint16_t m_localPort;
+
+ /**
+ * \brief The peer address.
+ */
+ Ipv6Address m_peerAddr;
+
+ /**
+ * \brief The peer port.
+ */
+ uint16_t m_peerPort;
+
+ /**
+ * \brief The RX callback.
+ */
+ Callback<void, Ptr<Packet>, Ipv6Address, uint16_t> m_rxCallback;
+
+ /**
+ * \brief The ICMPv6 callback.
+ */
+ Callback<void, Ipv6Address, uint8_t, uint8_t, uint8_t, uint32_t> m_icmpCallback;
+
+ /**
+ * \brief The destroy callback.
+ */
+ Callback<void> m_destroyCallback;
+};
+
+} /* namespace ns3 */
+
+#endif /* IPV6_END_POINT_H */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv6-interface.cc Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,453 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#include "ipv6-interface.h"
+#include "ns3/net-device.h"
+#include "loopback-net-device.h"
+#include "ns3/log.h"
+#include "ns3/node.h"
+#include <ns3/packet.h>
+
+#include "icmpv6-l4-protocol.h"
+
+namespace ns3
+{
+
+NS_LOG_COMPONENT_DEFINE ("Ipv6Interface");
+
+TypeId Ipv6Interface::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ipv6Interface")
+ .SetParent<Object> ()
+ ;
+ return tid;
+}
+
+Ipv6Interface::Ipv6Interface ()
+ : m_ifup (false),
+ m_forwarding (true),
+ m_metric (1),
+ m_node (0),
+ m_device (0),
+ m_curHopLimit (0),
+ m_baseReachableTime (0),
+ m_reachableTime (0),
+ m_retransTimer (0)
+{
+ NS_LOG_FUNCTION (this);
+}
+
+Ipv6Interface::~Ipv6Interface ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+void Ipv6Interface::DoDispose ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ Object::DoDispose ();
+}
+
+void Ipv6Interface::DoSetup ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ if (m_node == 0 || m_device == 0)
+ {
+ return;
+ }
+
+ if (!m_device->NeedsArp ())
+ {
+ return;
+ }
+
+ /* set up link-local address */
+ if (!DynamicCast<LoopbackNetDevice> (m_device)) /* no autoconf for ip6-localhost */
+ {
+ Address addr = GetDevice ()->GetAddress ();
+
+ if (Mac48Address::IsMatchingType (addr))
+ {
+ Ipv6InterfaceAddress ifaddr = Ipv6InterfaceAddress (Ipv6Address::MakeAutoconfiguredLinkLocalAddress (Mac48Address::ConvertFrom (addr)), Ipv6Prefix (64));
+ AddAddress (ifaddr);
+ }
+ else
+ {
+ NS_ASSERT_MSG (false, "IPv6 autoconf for this kind of address not implemented.");
+ }
+ }
+
+ Ptr<Icmpv6L4Protocol> icmpv6 = m_node->GetObject<Ipv6L3Protocol> ()->GetIcmpv6 ();
+ m_ndCache = icmpv6->CreateCache (m_device, this);
+}
+
+void Ipv6Interface::SetNode (Ptr<Node> node)
+{
+ NS_LOG_FUNCTION (this << node);
+ m_node = node;
+ DoSetup ();
+}
+
+void Ipv6Interface::SetDevice (Ptr<NetDevice> device)
+{
+ NS_LOG_FUNCTION (this << device);
+ m_device = device;
+ DoSetup ();
+}
+
+Ptr<NetDevice> Ipv6Interface::GetDevice () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_device;
+}
+
+void Ipv6Interface::SetMetric (uint16_t metric)
+{
+ NS_LOG_FUNCTION (this << metric);
+ m_metric = metric;
+}
+
+uint16_t Ipv6Interface::GetMetric () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_metric;
+}
+
+bool Ipv6Interface::IsUp () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_ifup;
+}
+
+bool Ipv6Interface::IsDown () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return !m_ifup;
+}
+
+void Ipv6Interface::SetUp ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ if (m_ifup)
+ {
+ return;
+ }
+ m_ifup = true;
+}
+
+void Ipv6Interface::SetDown ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_ifup = false;
+ m_addresses.clear ();
+}
+
+bool Ipv6Interface::IsForwarding () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_forwarding;
+}
+
+void Ipv6Interface::SetForwarding (bool forwarding)
+{
+ NS_LOG_FUNCTION (this << forwarding);
+ m_forwarding = forwarding;
+}
+
+bool Ipv6Interface::AddAddress (Ipv6InterfaceAddress iface)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ Ipv6Address addr = iface.GetAddress ();
+
+ /* DAD handling */
+ if (!addr.IsAny ())
+ {
+ for (Ipv6InterfaceAddressListCI it = m_addresses.begin () ; it != m_addresses.end () ; ++it)
+ {
+ if ((*it).GetAddress () == addr)
+ {
+ return false;
+ }
+ }
+
+ m_addresses.push_back (iface);
+
+ if (!addr.IsAny () || !addr.IsLocalhost ())
+ {
+ /* DAD handling */
+ Ptr<Icmpv6L4Protocol> icmpv6 = m_node->GetObject<Ipv6L3Protocol> ()->GetIcmpv6 ();
+
+ if (icmpv6)
+ {
+ Simulator::Schedule (Seconds (0.), &Icmpv6L4Protocol::DoDAD, icmpv6, addr, this);
+ Simulator::Schedule (Seconds (1.), &Icmpv6L4Protocol::FunctionDadTimeout, icmpv6, this, addr);
+ }
+ }
+ return true;
+ }
+
+ /* bad address */
+ return false;
+}
+
+Ipv6InterfaceAddress Ipv6Interface::GetLinkLocalAddress () const
+{
+ /* IPv6 interface has always at least one IPv6 link-local address */
+ NS_LOG_FUNCTION_NOARGS ();
+
+ for (Ipv6InterfaceAddressListCI it = m_addresses.begin () ; it != m_addresses.end () ; ++it)
+ {
+ if ((*it).GetAddress ().IsLinkLocal ())
+ {
+ return (*it);
+ }
+ }
+ NS_ASSERT_MSG (false, "No link-local address on interface " << this);
+ Ipv6InterfaceAddress addr;
+ return addr; /* quiet compiler */
+}
+
+Ipv6InterfaceAddress Ipv6Interface::GetAddress (uint32_t index) const
+{
+ NS_LOG_FUNCTION (this << index);
+ uint32_t i = 0;
+
+ if (m_addresses.size () > index)
+ {
+ for (Ipv6InterfaceAddressListCI it = m_addresses.begin () ; it != m_addresses.end () ; ++it)
+ {
+ if (i == index)
+ {
+ return (*it);
+ }
+ i++;
+ }
+ }
+
+ NS_ASSERT_MSG (false, "Address " << index << " not found");
+ Ipv6InterfaceAddress addr;
+ return addr; /* quiet compiler */
+}
+
+uint32_t Ipv6Interface::GetNAddresses () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_addresses.size ();
+}
+
+Ipv6InterfaceAddress Ipv6Interface::RemoveAddress (uint32_t index)
+{
+ NS_LOG_FUNCTION (this << index);
+ uint32_t i = 0;
+
+ if (m_addresses.size () < index)
+ {
+ NS_ASSERT_MSG (false, "Try to remove index that don't exist in Ipv6Interface::RemoveAddress");
+ }
+
+ for (Ipv6InterfaceAddressListI it = m_addresses.begin () ; it != m_addresses.end () ; ++it)
+ {
+ if (i == index)
+ {
+ Ipv6InterfaceAddress iface = (*it);
+ m_addresses.erase (it);
+ return iface;
+ }
+
+ i++;
+ }
+
+ NS_ASSERT_MSG (false, "Address " << index << " not found");
+ Ipv6InterfaceAddress addr;
+ return addr; /* quiet compiler */
+}
+
+Ipv6InterfaceAddress Ipv6Interface::GetAddressMatchingDestination (Ipv6Address dst)
+{
+ NS_LOG_FUNCTION (this << dst);
+
+ for (Ipv6InterfaceAddressList::const_iterator it = m_addresses.begin () ; it != m_addresses.end () ; ++it)
+ {
+ Ipv6InterfaceAddress ifaddr = (*it);
+
+ if (ifaddr.GetPrefix ().IsMatch (ifaddr.GetAddress (), dst))
+ {
+ return ifaddr;
+ }
+ }
+
+/* NS_ASSERT_MSG (false, "Not matching address."); */
+ Ipv6InterfaceAddress ret;
+ return ret; /* quiet compiler */
+}
+
+void Ipv6Interface::Send (Ptr<Packet> p, Ipv6Address dest)
+{
+ NS_LOG_FUNCTION (this << p << dest);
+ Ptr<Ipv6L3Protocol> ipv6 = m_node->GetObject<Ipv6L3Protocol> ();
+
+ if (!IsUp ())
+ {
+ return;
+ }
+
+ /* check if destination is localhost (::1) */
+ if (DynamicCast<LoopbackNetDevice> (m_device))
+ {
+ /* XXX additional checks needed here (such as whether multicast
+ * goes to loopback)?
+ */
+ m_device->Send (p, m_device->GetBroadcast (), Ipv6L3Protocol::PROT_NUMBER);
+ return;
+ }
+
+ /* check if destination is for one of our interface */
+ for (Ipv6InterfaceAddressListCI it = m_addresses.begin () ; it != m_addresses.end () ; ++it)
+ {
+ if (dest == (*it).GetAddress ())
+ {
+ ipv6->Receive (m_device, p, Ipv6L3Protocol::PROT_NUMBER,
+ m_device->GetBroadcast (),
+ m_device->GetBroadcast (),
+ NetDevice::PACKET_HOST // note: linux uses PACKET_LOOPBACK here
+ );
+ return;
+ }
+ }
+
+ /* other address */
+ if (m_device->NeedsArp ())
+ {
+ NS_LOG_LOGIC ("Needs ARP" << " " << dest);
+ Ptr<Icmpv6L4Protocol> icmpv6 = ipv6->GetIcmpv6 ();
+ Address hardwareDestination;
+ bool found = false;
+
+ NS_ASSERT (icmpv6);
+
+ if (dest.IsMulticast ())
+ {
+ NS_LOG_LOGIC ("IsMulticast");
+ NS_ASSERT_MSG (m_device->IsMulticast (), "Ipv6Interface::SendTo (): Sending multicast packet over non-multicast device");
+
+ hardwareDestination = m_device->GetMulticast (dest);
+ found = true;
+ }
+ else
+ {
+ NS_LOG_LOGIC ("NDISC Lookup");
+ found = icmpv6->Lookup (p, dest, GetDevice (), m_ndCache, &hardwareDestination);
+ }
+
+ if (found)
+ {
+ NS_LOG_LOGIC ("Address Resolved. Send.");
+ m_device ->Send (p, hardwareDestination, Ipv6L3Protocol::PROT_NUMBER);
+ }
+ }
+ else
+ {
+ NS_LOG_LOGIC ("Doesn't need ARP");
+ m_device->Send (p, m_device->GetBroadcast (), Ipv6L3Protocol::PROT_NUMBER);
+ }
+}
+
+void Ipv6Interface::SetCurHopLimit (uint8_t curHopLimit)
+{
+ NS_LOG_FUNCTION (this << curHopLimit);
+ m_curHopLimit = curHopLimit;
+}
+
+uint8_t Ipv6Interface::GetCurHopLimit () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_curHopLimit;
+}
+
+void Ipv6Interface::SetBaseReachableTime (uint16_t baseReachableTime)
+{
+ NS_LOG_FUNCTION (this << baseReachableTime);
+ m_baseReachableTime = baseReachableTime;
+}
+
+uint16_t Ipv6Interface::GetBaseReachableTime () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_baseReachableTime;
+}
+
+void Ipv6Interface::SetReachableTime (uint16_t reachableTime)
+{
+ NS_LOG_FUNCTION (this << reachableTime);
+ m_reachableTime = reachableTime;
+}
+
+uint16_t Ipv6Interface::GetReachableTime () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_reachableTime;
+}
+
+void Ipv6Interface::SetRetransTimer (uint16_t retransTimer)
+{
+ NS_LOG_FUNCTION (this << retransTimer);
+ m_retransTimer = retransTimer;
+}
+
+uint16_t Ipv6Interface::GetRetransTimer () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_retransTimer;
+}
+
+void Ipv6Interface::SetState (Ipv6Address address, Ipv6InterfaceAddress::State_e state)
+{
+ NS_LOG_FUNCTION (this << address << state);
+
+ for (Ipv6InterfaceAddressListI it = m_addresses.begin () ; it != m_addresses.end () ; ++it)
+ {
+ if ((*it).GetAddress () == address)
+ {
+ (*it).SetState (state);
+ return;
+ }
+ }
+ /* not found, maybe address has expired */
+}
+
+void Ipv6Interface::SetNsDadUid (Ipv6Address address, uint32_t uid)
+{
+ NS_LOG_FUNCTION (this << address << uid);
+
+ for (Ipv6InterfaceAddressListI it = m_addresses.begin () ; it != m_addresses.end () ; ++it)
+ {
+ if ((*it).GetAddress () == address)
+ {
+ (*it).SetNsDadUid (uid);
+ return;
+ }
+ }
+ /* not found, maybe address has expired */
+}
+
+} /* namespace ns3 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv6-interface.h Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,322 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#ifndef IPV6_INTERFACE_H
+#define IPV6_INTERFACE_H
+
+#include <list>
+
+#include "ns3/ipv6-address.h"
+#include "ns3/ipv6-interface-address.h"
+#include "ns3/ptr.h"
+#include "ns3/object.h"
+#include "ns3/timer.h"
+
+#include "ndisc-cache.h"
+
+namespace ns3
+{
+
+class NetDevice;
+class Packet;
+class Node;
+
+/**
+ * \class Ipv6Interface
+ * \brief The IPv6 representation of a network interface
+ *
+ * By default IPv6 interfaces are created in the "down" state
+ * with IP "fe80::1" and a /64 prefix. Before becoming useable,
+ * the user must invoke SetUp on them once the final IPv6 address
+ * and mask has been set.
+ */
+class Ipv6Interface : public Object
+{
+ public:
+ /**
+ * \brief Get the type ID
+ * \return type ID
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Constructs an Ipv6Interface.
+ */
+ Ipv6Interface ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Ipv6Interface ();
+
+ /**
+ * \brief Set node associated with interface.
+ * \param node node
+ */
+ void SetNode (Ptr<Node> node);
+
+ /**
+ * \brief Set the NetDevice.
+ * \param device NetDevice
+ */
+ void SetDevice (Ptr<NetDevice> device);
+
+ /**
+ * \brief Get the NetDevice.
+ * \return the NetDevice associated with this interface
+ */
+ virtual Ptr<NetDevice> GetDevice () const;
+
+ /**
+ * \brief Set the metric.
+ * \param metric configured routing metric (cost) of this interface
+ */
+ void SetMetric (uint16_t metric);
+
+ /**
+ * \brief Get the metric
+ * \return the metric
+ */
+ uint16_t GetMetric () const;
+
+ /**
+ * \brief Is the interface UP ?
+ * \return true if interface is enabled, false otherwise.
+ */
+ bool IsUp () const;
+
+ /**
+ * \brief Is the interface DOWN ?
+ * \return true if interface is disabled, false otherwise.
+ */
+ bool IsDown () const;
+
+ /**
+ * \brief Enable this interface.
+ */
+ void SetUp ();
+
+ /**
+ * \brief Disable this interface.
+ */
+ void SetDown ();
+
+ /**
+ * \brief If the interface allows forwarding packets.
+ * \return true if forwarding is enabled, false otherwise
+ */
+ bool IsForwarding () const;
+
+ /**
+ * \brief Set forwarding enabled or not.
+ * \param forward forwarding state
+ */
+ void SetForwarding (bool forward);
+
+ /**
+ * \brief Set the current hop limit.
+ * \param curHopLimit the value to set
+ */
+ void SetCurHopLimit (uint8_t curHopLimit);
+
+ /**
+ * \brief Get the current hop limit value.
+ * \return current hop limit
+ */
+ uint8_t GetCurHopLimit () const;
+
+ /**
+ * \brief Set the base reachable time.
+ * \param baseReachableTime the value to set
+ */
+ void SetBaseReachableTime (uint16_t baseReachableTime);
+
+ /**
+ * \brief Get the base reachable time.
+ * \return base reachable time
+ */
+ uint16_t GetBaseReachableTime () const;
+
+ /**
+ * \brief Set the reachable time.
+ * \param reachableTime value to set
+ */
+ void SetReachableTime (uint16_t reachableTime);
+
+ /**
+ * \brief Get the reachable time.
+ * \return reachable time
+ */
+ uint16_t GetReachableTime () const;
+
+ /**
+ * \brief Set the retransmission timer.
+ * \param retransTimer value to set
+ */
+ void SetRetransTimer (uint16_t retransTimer);
+
+ /**
+ * \brief Get the retransmission timer.
+ * \return retransmission timer
+ */
+ uint16_t GetRetransTimer () const;
+
+ /**
+ * \brief Send a packet through this interface.
+ * \param p packet to send
+ * \param dest next hop address of packet.
+ *
+ * \note This method will eventually call the private SendTo
+ * method which must be implemented by subclasses.
+ */
+ void Send (Ptr<Packet> p, Ipv6Address dest);
+
+ /**
+ * \brief Add an IPv6 address.
+ * \param iface address to add
+ * \return true if address was added, false otherwise
+ */
+ bool AddAddress (Ipv6InterfaceAddress iface);
+
+ /**
+ * \brief Get link-local address from IPv6 interface.
+ * \return link-local Ipv6InterfaceAddress, assert if not found
+ */
+ Ipv6InterfaceAddress GetLinkLocalAddress () const;
+
+ /**
+ * \brief Get an address from IPv6 interface.
+ * \param index index
+ * \return Ipv6InterfaceAddress address whose index is i
+ */
+ Ipv6InterfaceAddress GetAddress (uint32_t index) const;
+
+ /**
+ * \brief Get an address which is in the same network prefix as destination.
+ * \param dst destination address
+ * \return Corresponding Ipv6InterfaceAddress or assert if not found
+ */
+ Ipv6InterfaceAddress GetAddressMatchingDestination (Ipv6Address dst);
+
+ /**
+ * \brief Get number of addresses on this IPv6 interface.
+ * \return number of address
+ */
+ uint32_t GetNAddresses (void) const;
+
+ /**
+ * \brief Remove an address from interface.
+ * \param index index to remove
+ * \return Ipv6InterfaceAddress address whose index is index
+ */
+ Ipv6InterfaceAddress RemoveAddress (uint32_t index);
+
+ /**
+ * \brief Update state of an interface address.
+ * \param address IPv6 address
+ * \param state new state
+ */
+ void SetState (Ipv6Address address, Ipv6InterfaceAddress::State_e state);
+
+ /**
+ * \brief Update NS DAD packet UID of an interface address.
+ * \param address IPv6 address
+ * \param uid packet UID
+ */
+ void SetNsDadUid (Ipv6Address address, uint32_t uid);
+
+ protected:
+ /**
+ * \brief Dispose this object.
+ */
+ virtual void DoDispose ();
+
+ private:
+ typedef std::list<Ipv6InterfaceAddress> Ipv6InterfaceAddressList;
+ typedef std::list<Ipv6InterfaceAddress>::iterator Ipv6InterfaceAddressListI;
+ typedef std::list<Ipv6InterfaceAddress>::const_iterator Ipv6InterfaceAddressListCI;
+
+ /**
+ * \brief Initialize interface.
+ */
+ void DoSetup ();
+
+ /**
+ * \brief The addresses assigned to this interface.
+ */
+ Ipv6InterfaceAddressList m_addresses;
+
+ /**
+ * \brief The state of this interface.
+ */
+ bool m_ifup;
+
+ /**
+ * \brief Forwarding state.
+ */
+ bool m_forwarding;
+
+ /**
+ * \brief The metric.
+ */
+ uint16_t m_metric;
+
+ /**
+ * \brief Node associated with this interface.
+ */
+ Ptr<Node> m_node;
+
+ /**
+ * \brief NetDevice associated with this interface.
+ */
+ Ptr<NetDevice> m_device;
+
+ /**
+ * \brief Neighbor cache.
+ */
+ Ptr<NdiscCache> m_ndCache;
+
+ /**
+ * \brief Current hop limit.
+ */
+ uint8_t m_curHopLimit;
+
+ /**
+ * \brief Base value used for computing the random reachable time value (in millisecond).
+ */
+ uint16_t m_baseReachableTime;
+
+ /**
+ * \brief Reachable time (in millisecond).
+ * The time a neighbor is considered reachable after receiving a reachability confirmation.
+ */
+ uint16_t m_reachableTime;
+
+ /**
+ * \brief Retransmission timer (in millisecond).
+ * Time between retransmission of NS.
+ */
+ uint16_t m_retransTimer;
+};
+
+} /* namespace ns3 */
+
+#endif /* IPV6_INTERFACE_H */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv6-l3-protocol.cc Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,911 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#include "ns3/log.h"
+#include "ns3/node.h"
+#include "ns3/uinteger.h"
+#include "ns3/vector.h"
+#include "ns3/callback.h"
+#include "ns3/trace-source-accessor.h"
+#include "ns3/object-vector.h"
+#include "ns3/ipv6-routing-protocol.h"
+#include "ns3/ipv6-route.h"
+
+#include "loopback-net-device.h"
+#include "ipv6-l3-protocol.h"
+#include "ipv6-l4-protocol.h"
+#include "ipv6-interface.h"
+#include "ipv6-raw-socket-impl.h"
+#include "ipv6-autoconfigured-prefix.h"
+#include "icmpv6-l4-protocol.h"
+
+namespace ns3
+{
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6L3Protocol);
+
+NS_LOG_COMPONENT_DEFINE ("Ipv6L3Protocol");
+
+const uint16_t Ipv6L3Protocol::PROT_NUMBER = 0x86DD;
+
+TypeId Ipv6L3Protocol::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ipv6L3Protocol")
+ .SetParent<Ipv6> ()
+ .AddConstructor<Ipv6L3Protocol> ()
+ .AddAttribute ("DefaultTtl", "The TTL value set by default on all outgoing packets generated on this node.",
+ UintegerValue (64),
+ MakeUintegerAccessor (&Ipv6L3Protocol::m_defaultTtl),
+ MakeUintegerChecker<uint8_t> ())
+ .AddTraceSource ("Tx", "Send IPv6 packet to outgoing interface.",
+ MakeTraceSourceAccessor (&Ipv6L3Protocol::m_txTrace))
+ .AddTraceSource ("Rx", "Receive IPv6 packet from incoming interface.",
+ MakeTraceSourceAccessor (&Ipv6L3Protocol::m_rxTrace))
+ .AddTraceSource ("Drop", "Drop IPv6 packet",
+ MakeTraceSourceAccessor (&Ipv6L3Protocol::m_dropTrace))
+ .AddAttribute ("InterfaceList", "The set of IPv6 interfaces associated to this IPv6 stack.",
+ ObjectVectorValue (),
+ MakeObjectVectorAccessor (&Ipv6L3Protocol::m_interfaces),
+ MakeObjectVectorChecker<Ipv6Interface> ())
+ ;
+ return tid;
+}
+
+Ipv6L3Protocol::Ipv6L3Protocol ()
+ : m_nInterfaces (0)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+Ipv6L3Protocol::~Ipv6L3Protocol ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+void Ipv6L3Protocol::DoDispose ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ /* clear protocol and interface list */
+ for (L4List_t::iterator it = m_protocols.begin () ; it != m_protocols.end () ; ++it)
+ {
+ *it = 0;
+ }
+ m_protocols.clear ();
+
+ /* remove interfaces */
+ for (Ipv6InterfaceList::iterator it = m_interfaces.begin () ; it != m_interfaces.end (); ++it)
+ {
+ *it = 0;
+ }
+ m_interfaces.clear ();
+
+ /* remove raw sockets */
+ for (SocketList::iterator it = m_sockets.begin () ; it != m_sockets.end () ; ++it)
+ {
+ *it = 0;
+ }
+ m_sockets.clear ();
+
+ /* remove list of prefix */
+ for (Ipv6AutoconfiguredPrefixListI it = m_prefixes.begin () ; it != m_prefixes.end () ; ++it)
+ {
+ (*it)->StopValidTimer ();
+ (*it)->StopPreferredTimer ();
+ (*it) = 0;
+ }
+ m_prefixes.clear ();
+
+
+ m_node = 0;
+ m_routingProtocol = 0;
+ Object::DoDispose ();
+}
+
+void Ipv6L3Protocol::SetRoutingProtocol (Ptr<Ipv6RoutingProtocol> routingProtocol)
+{
+ NS_LOG_FUNCTION (this << routingProtocol);
+ m_routingProtocol = routingProtocol;
+ m_routingProtocol->SetIpv6 (this);
+}
+
+Ptr<Ipv6RoutingProtocol> Ipv6L3Protocol::GetRoutingProtocol () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_routingProtocol;
+}
+
+uint32_t Ipv6L3Protocol::AddInterface (Ptr<NetDevice> device)
+{
+ NS_LOG_FUNCTION (this << device);
+ Ptr<Node> node = GetObject<Node> ();
+ Ptr<Ipv6Interface> interface = CreateObject<Ipv6Interface> ();
+
+ node->RegisterProtocolHandler (MakeCallback (&Ipv6L3Protocol::Receive, this), Ipv6L3Protocol::PROT_NUMBER, device);
+ interface->SetNode (m_node);
+ interface->SetDevice (device);
+ interface->SetForwarding (m_ipForward);
+ return AddIpv6Interface (interface);
+}
+
+uint32_t Ipv6L3Protocol::AddIpv6Interface (Ptr<Ipv6Interface> interface)
+{
+ NS_LOG_FUNCTION (this << interface);
+ uint32_t index = m_nInterfaces;
+
+ m_interfaces.push_back (interface);
+ m_nInterfaces++;
+ return index;
+}
+
+Ptr<Ipv6Interface> Ipv6L3Protocol::GetInterface (uint32_t index) const
+{
+ NS_LOG_FUNCTION (this << index);
+ uint32_t tmp = 0;
+
+ for (Ipv6InterfaceList::const_iterator it = m_interfaces.begin () ; it != m_interfaces.end () ; it++)
+ {
+ if (index == tmp)
+ {
+ return *it;
+ }
+ tmp++;
+ }
+ return 0;
+}
+
+uint32_t Ipv6L3Protocol::GetNInterfaces () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_nInterfaces;
+}
+
+int32_t Ipv6L3Protocol::GetInterfaceForAddress (Ipv6Address address) const
+{
+ NS_LOG_FUNCTION (this << address);
+ int32_t index = 0;
+
+ for (Ipv6InterfaceList::const_iterator it = m_interfaces.begin () ; it != m_interfaces.end () ; it++)
+ {
+ uint32_t j = 0;
+ uint32_t max = (*it)->GetNAddresses ();
+
+ for (j = 0 ; j < max ; j++)
+ {
+ if ((*it)->GetAddress (j).GetAddress () == address)
+ {
+ return index;
+ }
+ }
+ index++;
+ }
+ return -1;
+}
+
+int32_t Ipv6L3Protocol::GetInterfaceForPrefix (Ipv6Address address, Ipv6Prefix mask) const
+{
+ NS_LOG_FUNCTION (this << address << mask);
+ int32_t index = 0;
+
+ for (Ipv6InterfaceList::const_iterator it = m_interfaces.begin () ; it != m_interfaces.end () ; it++)
+ {
+ uint32_t j = 0;
+ for (j = 0 ; j < (*it)->GetNAddresses () ; j++)
+ {
+ if ((*it)->GetAddress (j).GetAddress ().CombinePrefix (mask) == address.CombinePrefix (mask))
+ {
+ return index;
+ }
+ }
+ index++;
+ }
+ return -1;
+}
+
+Ptr<NetDevice> Ipv6L3Protocol::GetNetDevice (uint32_t i)
+{
+ NS_LOG_FUNCTION (this << i);
+ return GetInterface (i)->GetDevice ();
+}
+
+int32_t Ipv6L3Protocol::GetInterfaceForDevice (Ptr<const NetDevice> device) const
+{
+ NS_LOG_FUNCTION (this << device);
+ int32_t index = 0;
+
+ for (Ipv6InterfaceList::const_iterator it = m_interfaces.begin () ; it != m_interfaces.end () ; it++)
+ {
+ if ((*it)->GetDevice () == device)
+ {
+ return index;
+ }
+ index++;
+ }
+ return -1;
+}
+
+void Ipv6L3Protocol::AddAutoconfiguredAddress (uint32_t interface, Ipv6Address network, Ipv6Prefix mask, uint8_t flags, uint32_t validTime, uint32_t preferredTime, Ipv6Address defaultRouter)
+{
+ NS_LOG_FUNCTION (this << interface << network << mask << (uint32_t)flags << validTime << preferredTime);
+ Ipv6InterfaceAddress address;
+
+ Address addr = GetInterface (interface)->GetDevice ()->GetAddress ();
+
+ if (flags & (1<< 6)) /* auto flag */
+ {
+ /* XXX : add other L2 address case */
+ if (Mac48Address::IsMatchingType (addr))
+ {
+ address = Ipv6InterfaceAddress (Ipv6Address::MakeAutoconfiguredAddress (Mac48Address::ConvertFrom (addr), network));
+ }
+ else
+ {
+ NS_FATAL_ERROR ("Unknown method to make autoconfigured address for this kind of device.");
+ return;
+ }
+
+ /* see if we have already the prefix */
+ for (Ipv6AutoconfiguredPrefixListI it = m_prefixes.begin () ; it != m_prefixes.end () ; ++it)
+ {
+ if ((*it)->GetInterface () == interface && (*it)->GetPrefix () == network && (*it)->GetMask () == mask)
+ {
+ (*it)->StopPreferredTimer ();
+ (*it)->StopValidTimer ();
+ (*it)->StartPreferredTimer ();
+
+ /* Suppose a link with two prefixes advertised,
+ * when first prefix (which is the default route) expires,
+ * the second ones router has to be default router
+ */
+ GetRoutingProtocol ()->NotifyAddRoute (Ipv6Address::GetAny (), Ipv6Prefix ((uint8_t)0), defaultRouter, interface, network);
+ return;
+ }
+ }
+
+ /* no prefix found, add autoconfigured address and the prefix */
+ NS_LOG_INFO ("Autoconfigured address is :" << address.GetAddress ());
+ AddAddress (interface, address);
+
+ /* add default router
+ * check to know if default route already exists is done
+ * in Ipv6StaticRouting class
+ *
+ * If default route is already set, this function does nothing.
+ */
+ GetRoutingProtocol ()->NotifyAddRoute (Ipv6Address::GetAny (), Ipv6Prefix ((uint8_t)0), defaultRouter, interface, network);
+
+ Ptr<Ipv6AutoconfiguredPrefix> aPrefix = CreateObject<Ipv6AutoconfiguredPrefix> (m_node, interface, network, mask, preferredTime, validTime, defaultRouter);
+ aPrefix->StartPreferredTimer ();
+
+ m_prefixes.push_back (aPrefix);
+ }
+}
+
+void Ipv6L3Protocol::RemoveAutoconfiguredAddress (uint32_t interface, Ipv6Address network, Ipv6Prefix mask, Ipv6Address defaultRouter)
+{
+ NS_LOG_FUNCTION (this << interface << network << mask);
+ Ptr<Ipv6Interface> iface = GetInterface (interface);
+ Address addr = iface->GetDevice ()->GetAddress ();
+ uint32_t max = iface->GetNAddresses ();
+ uint32_t i = 0;
+ Ipv6Address toFound = Ipv6Address::MakeAutoconfiguredAddress (Mac48Address::ConvertFrom (addr), network);
+
+ for (i = 0 ; i < max ; i++)
+ {
+ if (iface->GetAddress (i).GetAddress () == toFound)
+ {
+ RemoveAddress (interface, i);
+ break;
+ }
+ }
+
+ /* remove from list of autoconfigured address */
+ for (Ipv6AutoconfiguredPrefixListI it = m_prefixes.begin () ; it != m_prefixes.end () ; ++it)
+ {
+ if ((*it)->GetInterface () == interface && (*it)->GetPrefix () == network && (*it)->GetMask () == mask)
+ {
+ *it = 0;
+ m_prefixes.erase (it);
+ break;
+ }
+ }
+
+ GetRoutingProtocol ()->NotifyRemoveRoute (Ipv6Address::GetAny (), Ipv6Prefix ((uint8_t)0), defaultRouter, interface);
+}
+
+bool Ipv6L3Protocol::AddAddress (uint32_t i, Ipv6InterfaceAddress address)
+{
+ NS_LOG_FUNCTION (this << i << address);
+ Ptr<Ipv6Interface> interface = GetInterface (i);
+ bool ret = interface->AddAddress (address);
+
+ if (m_routingProtocol != 0)
+ {
+ m_routingProtocol->NotifyAddAddress (i, address);
+ }
+ return ret;
+}
+
+uint32_t Ipv6L3Protocol::GetNAddresses (uint32_t i) const
+{
+ NS_LOG_FUNCTION (this << i);
+ Ptr<Ipv6Interface> interface = GetInterface (i);
+ return interface->GetNAddresses ();
+}
+
+Ipv6InterfaceAddress Ipv6L3Protocol::GetAddress (uint32_t i, uint32_t addressIndex) const
+{
+ NS_LOG_FUNCTION (this << i << addressIndex);
+ Ptr<Ipv6Interface> interface = GetInterface (i);
+ return interface->GetAddress (addressIndex);
+}
+
+bool Ipv6L3Protocol::RemoveAddress (uint32_t i, uint32_t addressIndex)
+{
+ NS_LOG_FUNCTION (this << i << addressIndex);
+ Ptr<Ipv6Interface> interface = GetInterface (i);
+ Ipv6InterfaceAddress address = interface->RemoveAddress (addressIndex);
+
+ if (address != Ipv6InterfaceAddress ())
+ {
+ if (m_routingProtocol != 0)
+ {
+ m_routingProtocol->NotifyRemoveAddress (i, address);
+ }
+ return true;
+ }
+ return false;
+}
+
+void Ipv6L3Protocol::SetMetric (uint32_t i, uint16_t metric)
+{
+ NS_LOG_FUNCTION (this << i << metric);
+ Ptr<Ipv6Interface> interface = GetInterface (i);
+ interface->SetMetric (metric);
+}
+
+uint16_t Ipv6L3Protocol::GetMetric (uint32_t i) const
+{
+ NS_LOG_FUNCTION (this << i);
+ Ptr<Ipv6Interface> interface = GetInterface (i);
+ return interface->GetMetric ();
+}
+
+uint16_t Ipv6L3Protocol::GetMtu (uint32_t i) const
+{
+ NS_LOG_FUNCTION (this << i);
+ Ptr<Ipv6Interface> interface = GetInterface (i);
+ return interface->GetDevice ()->GetMtu ();
+}
+
+bool Ipv6L3Protocol::IsUp (uint32_t i) const
+{
+ NS_LOG_FUNCTION (this << i);
+ Ptr<Ipv6Interface> interface = GetInterface (i);
+ return interface->IsUp ();
+}
+
+void Ipv6L3Protocol::SetUp (uint32_t i)
+{
+ NS_LOG_FUNCTION (this << i);
+ Ptr<Ipv6Interface> interface = GetInterface (i);
+
+ interface->SetUp ();
+
+ if (m_routingProtocol != 0)
+ {
+ m_routingProtocol->NotifyInterfaceUp (i);
+ }
+}
+
+void Ipv6L3Protocol::SetDown (uint32_t i)
+{
+ NS_LOG_FUNCTION (this << i);
+ Ptr<Ipv6Interface> interface = GetInterface (i);
+
+ interface->SetDown ();
+
+ if (m_routingProtocol != 0)
+ {
+ m_routingProtocol->NotifyInterfaceDown (i);
+ }
+}
+
+void Ipv6L3Protocol::SetupLoopback ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ Ptr<Ipv6Interface> interface = CreateObject<Ipv6Interface> ();
+ Ptr<LoopbackNetDevice> device = 0;
+ uint32_t i = 0;
+
+ /* see if we have already an loopback NetDevice */
+ for (i = 0 ; i < m_node->GetNDevices () ; i++)
+ {
+ if (device = DynamicCast<LoopbackNetDevice> (m_node->GetDevice (i)))
+ {
+ break;
+ }
+ }
+
+ if (device == 0)
+ {
+ device = CreateObject<LoopbackNetDevice> ();
+ m_node->AddDevice (device);
+ }
+
+ interface->SetDevice (device);
+ interface->SetNode (m_node);
+ Ipv6InterfaceAddress ifaceAddr = Ipv6InterfaceAddress (Ipv6Address::GetLoopback (), Ipv6Prefix (128));
+ interface->AddAddress (ifaceAddr);
+ uint32_t index = AddIpv6Interface (interface);
+ Ptr<Node> node = GetObject<Node> ();
+ node->RegisterProtocolHandler (MakeCallback (&Ipv6L3Protocol::Receive, this), Ipv6L3Protocol::PROT_NUMBER, device);
+ interface->SetUp ();
+
+ if (m_routingProtocol != 0)
+ {
+ m_routingProtocol->NotifyInterfaceUp (index);
+ }
+}
+
+bool Ipv6L3Protocol::IsForwarding (uint32_t i) const
+{
+ NS_LOG_FUNCTION (this << i);
+ Ptr<Ipv6Interface> interface = GetInterface (i);
+
+ NS_LOG_LOGIC ("Forwarding state: " << interface->IsForwarding ());
+ return interface->IsForwarding ();
+}
+
+void Ipv6L3Protocol::SetForwarding (uint32_t i, bool val)
+{
+ NS_LOG_FUNCTION (this << i << val);
+ Ptr<Ipv6Interface> interface = GetInterface (i);
+ interface->SetForwarding (val);
+}
+
+void Ipv6L3Protocol::SetIpForward (bool forward)
+{
+ NS_LOG_FUNCTION (this << forward);
+ m_ipForward = forward;
+
+ for (Ipv6InterfaceList::const_iterator it = m_interfaces.begin () ; it != m_interfaces.end (); it++)
+ {
+ (*it)->SetForwarding (forward);
+ }
+}
+
+bool Ipv6L3Protocol::GetIpForward () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_ipForward;
+}
+
+void Ipv6L3Protocol::NotifyNewAggregate ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ if (m_node == 0)
+ {
+ Ptr<Node> node = this->GetObject<Node> ();
+ // verify that it's a valid node and that
+ // the node has not been set before
+ if (node != 0)
+ {
+ this->SetNode (node);
+ }
+ }
+ Object::NotifyNewAggregate ();
+}
+
+void Ipv6L3Protocol::SetNode (Ptr<Node> node)
+{
+ NS_LOG_FUNCTION (this << node);
+ m_node = node;
+ /* add LoopbackNetDevice if needed, and an Ipv6Interface on top of it */
+ SetupLoopback ();
+}
+
+void Ipv6L3Protocol::Insert (Ptr<Ipv6L4Protocol> protocol)
+{
+ NS_LOG_FUNCTION (this << protocol);
+ m_protocols.push_back (protocol);
+}
+
+void Ipv6L3Protocol::Remove (Ptr<Ipv6L4Protocol> protocol)
+{
+ NS_LOG_FUNCTION (this << protocol);
+ m_protocols.remove (protocol);
+}
+
+Ptr<Ipv6L4Protocol> Ipv6L3Protocol::GetProtocol (int protocolNumber) const
+{
+ NS_LOG_FUNCTION (this << protocolNumber);
+
+ for (L4List_t::const_iterator i = m_protocols.begin () ; i != m_protocols.end () ; ++i)
+ {
+ if ((*i)->GetProtocolNumber () == protocolNumber)
+ {
+ return *i;
+ }
+ }
+ return 0;
+}
+
+Ptr<Socket> Ipv6L3Protocol::CreateRawSocket ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ Ptr<Ipv6RawSocketImpl> sock = CreateObject<Ipv6RawSocketImpl> ();
+ sock->SetNode (m_node);
+ m_sockets.push_back (sock);
+ return sock;
+}
+
+void Ipv6L3Protocol::DeleteRawSocket (Ptr<Socket> socket)
+{
+ NS_LOG_FUNCTION (this << socket);
+
+ for (SocketList::iterator it = m_sockets.begin () ; it != m_sockets.end () ; ++it)
+ {
+ if ((*it) == socket)
+ {
+ m_sockets.erase (it);
+ return;
+ }
+ }
+}
+
+Ptr<Icmpv6L4Protocol> Ipv6L3Protocol::GetIcmpv6 () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ Ptr<Ipv6L4Protocol> protocol = GetProtocol (Icmpv6L4Protocol::GetStaticProtocolNumber ());
+
+ if (protocol)
+ {
+ return protocol->GetObject<Icmpv6L4Protocol> ();
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+void Ipv6L3Protocol::SetDefaultTtl (uint8_t ttl)
+{
+ NS_LOG_FUNCTION (this << ttl);
+ m_defaultTtl = ttl;
+}
+
+void Ipv6L3Protocol::Send (Ptr<Packet> packet, Ipv6Address source, Ipv6Address destination, uint8_t protocol, Ptr<Ipv6Route> route)
+{
+ NS_LOG_FUNCTION (this << packet << source << destination << (uint32_t)protocol << route);
+ Ipv6Header hdr;
+ uint8_t ttl = m_defaultTtl;
+ SocketIpTtlTag tag;
+ bool found = packet->RemovePacketTag (tag);
+
+ if (found)
+ {
+ ttl = tag.GetTtl ();
+ }
+
+ /* Handle 3 cases:
+ * 1) Packet is passed in with a route entry
+ * 2) Packet is passed in with a route entry but route->GetGateway is not set (e.g., same network)
+ * 3) route is NULL (e.g., a raw socket call or ICMPv6)
+ */
+
+ /* 1) */
+ if (route && route->GetGateway () != Ipv6Address::GetZero ())
+ {
+ NS_LOG_LOGIC ("Ipv6L3Protocol::Send case 1: passed in with a route");
+ hdr = BuildHeader (source, destination, protocol, packet->GetSize (), ttl);
+ SendRealOut (route, packet, hdr);
+ return;
+ }
+
+ /* 2) */
+ if (route && route->GetGateway () == Ipv6Address::GetZero ())
+ {
+ NS_LOG_LOGIC ("Ipv6L3Protocol::Send case 1: probably sent to machine on same IPv6 network");
+ /* NS_FATAL_ERROR ("This case is not yet implemented"); */
+ hdr = BuildHeader (source, destination, protocol, packet->GetSize (), ttl);
+ SendRealOut (route, packet, hdr);
+ return;
+ }
+
+ /* 3) */
+ NS_LOG_LOGIC ("Ipv6L3Protocol::Send case 3: passed in with no route " << destination);
+ Socket::SocketErrno err;
+ uint32_t oif = 0;
+ Ptr<Ipv6Route> newRoute = 0;
+
+ hdr = BuildHeader (source, destination, protocol, packet->GetSize (), ttl);
+
+ if (!source.IsAny ())
+ {
+ int32_t index = GetInterfaceForAddress (source);
+ NS_ASSERT (index >= 0);
+ oif = index;
+ }
+
+ newRoute = m_routingProtocol->RouteOutput (packet, hdr, oif, err);
+
+ if (newRoute)
+ {
+ SendRealOut (newRoute, packet, hdr);
+ }
+ else
+ {
+ NS_LOG_WARN ("No route to host, drop!");
+ m_dropTrace (packet);
+ }
+}
+
+void Ipv6L3Protocol::Receive (Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol, const Address &from, const Address &to, NetDevice::PacketType packetType)
+{
+ NS_LOG_FUNCTION (this << device << p << protocol << from << to << packetType);
+ NS_LOG_LOGIC ("Packet from " << from << " received on node " << m_node->GetId ());
+ uint32_t interface = 0;
+ Ptr<Packet> packet = p->Copy ();
+ Ptr<Ipv6Interface> ipv6Interface = 0;
+
+ for (Ipv6InterfaceList::const_iterator it = m_interfaces.begin () ; it != m_interfaces.end () ; it++)
+ {
+ ipv6Interface = *it;
+
+ if (ipv6Interface->GetDevice () == device)
+ {
+ if (ipv6Interface->IsUp ())
+ {
+ m_rxTrace (packet, interface);
+ break;
+ }
+ else
+ {
+ NS_LOG_LOGIC ("Dropping received packet-- interface is down");
+ m_dropTrace (packet);
+ return;
+ }
+ }
+ interface++;
+ }
+
+ Ipv6Header hdr;
+ packet->RemoveHeader (hdr);
+
+ /* forward up to IPv6 raw sockets */
+ for (SocketList::iterator it = m_sockets.begin () ; it != m_sockets.end () ; ++it)
+ {
+ Ptr<Ipv6RawSocketImpl> socket = *it;
+ socket->ForwardUp (packet, hdr, device);
+ }
+
+ m_routingProtocol->RouteInput (packet, hdr, device,
+ MakeCallback (&Ipv6L3Protocol::IpForward, this),
+ MakeCallback (&Ipv6L3Protocol::IpMulticastForward, this),
+ MakeCallback (&Ipv6L3Protocol::LocalDeliver, this),
+ MakeCallback (&Ipv6L3Protocol::RouteInputError, this)
+ );
+}
+
+void Ipv6L3Protocol::SendRealOut (Ptr<Ipv6Route> route, Ptr<Packet> packet, Ipv6Header const& ipHeader)
+{
+ NS_LOG_FUNCTION (this << route << packet << ipHeader);
+
+ packet->AddHeader (ipHeader);
+
+ if (!route)
+ {
+ NS_LOG_LOGIC ("No route to host, drop!.");
+ return;
+ }
+
+ Ptr<NetDevice> dev = route->GetOutputDevice ();
+ int32_t interface = GetInterfaceForDevice (dev);
+ NS_ASSERT (interface >= 0);
+
+ Ptr<Ipv6Interface> outInterface = GetInterface (interface);
+ NS_LOG_LOGIC ("Send via NetDevice ifIndex " << dev->GetIfIndex () << " Ipv6InterfaceIndex " << interface);
+
+ NS_ASSERT (packet->GetSize () <= outInterface->GetDevice ()->GetMtu ());
+
+ if (!route->GetGateway ().IsEqual (Ipv6Address::GetAny ()))
+ {
+ if (outInterface->IsUp ())
+ {
+ NS_LOG_LOGIC ("Send to gateway " << route->GetGateway ());
+ m_txTrace (packet, interface);
+ outInterface->Send (packet, route->GetGateway ());
+ }
+ else
+ {
+ NS_LOG_LOGIC ("Dropping-- outgoing interface is down: " << route->GetGateway ());
+ m_dropTrace (packet);
+ }
+ }
+ else
+ {
+ if (outInterface->IsUp ())
+ {
+ NS_LOG_LOGIC ("Send to destination " << ipHeader.GetDestinationAddress ());
+ m_txTrace (packet, interface);
+ outInterface->Send (packet, ipHeader.GetDestinationAddress ());
+ }
+ else
+ {
+ NS_LOG_LOGIC ("Dropping-- outgoing interface is down: " << ipHeader.GetDestinationAddress ());
+ m_dropTrace (packet);
+ }
+ }
+}
+
+void Ipv6L3Protocol::IpForward (Ptr<Ipv6Route> rtentry, Ptr<const Packet> p, const Ipv6Header& header)
+{
+ NS_LOG_FUNCTION (this << rtentry << p << header);
+ NS_LOG_LOGIC ("Forwarding logic for node: " << m_node->GetId ());
+
+ // Forwarding
+ Ipv6Header ipHeader = header;
+ Ptr<Packet> packet = p->Copy ();
+ ipHeader.SetHopLimit (ipHeader.GetHopLimit () - 1);
+
+ if (ipHeader.GetSourceAddress ().IsLinkLocal ())
+ {
+ /* no forward for link-local address */
+ return;
+ }
+
+ if (ipHeader.GetHopLimit () == 0)
+ {
+ // Do not reply to ICMPv6 or to multicast IPv6 address
+ if (ipHeader.GetNextHeader () != Icmpv6L4Protocol::PROT_NUMBER &&
+ ipHeader.GetDestinationAddress ().IsMulticast () == false)
+ {
+ packet->AddHeader (ipHeader);
+ GetIcmpv6 ()->SendErrorTimeExceeded (packet, ipHeader.GetSourceAddress (), Icmpv6Header::ICMPV6_HOPLIMIT);
+ }
+ NS_LOG_WARN ("TTL exceeded. Drop.");
+ m_dropTrace (packet);
+ return;
+ }
+
+ /* ICMPv6 Redirect */
+
+ /* if we forward to a machine on the same network as the source,
+ * we send him an ICMPv6 redirect message to notify him that a short route
+ * exists.
+ */
+ if ((!rtentry->GetGateway ().IsAny () && rtentry->GetGateway ().CombinePrefix (Ipv6Prefix (64)) == header.GetSourceAddress ().CombinePrefix (Ipv6Prefix (64))) ||
+ (rtentry->GetDestination ().CombinePrefix (Ipv6Prefix (64)) == header.GetSourceAddress ().CombinePrefix (Ipv6Prefix (64))))
+ {
+ NS_LOG_LOGIC ("ICMPv6 redirect!");
+ Ptr<Icmpv6L4Protocol> icmpv6 = GetIcmpv6 ();
+ Address hardwareTarget;
+ Ipv6Address dst = header.GetDestinationAddress ();
+ Ipv6Address src = header.GetSourceAddress ();
+ Ipv6Address target = rtentry->GetGateway ();
+ Ptr<Packet> copy = p->Copy ();
+
+ if (target.IsAny ())
+ {
+ target = dst;
+ }
+
+ copy->AddHeader (header);
+
+ if (icmpv6->Lookup (copy, target, rtentry->GetOutputDevice (), 0, &hardwareTarget))
+ {
+ icmpv6->SendRedirection (copy, src, target, dst, hardwareTarget);
+ }
+ else
+ {
+ icmpv6->SendRedirection (copy, src, target, dst, Address ());
+ }
+ }
+
+ SendRealOut (rtentry, packet, ipHeader);
+}
+
+void Ipv6L3Protocol::IpMulticastForward (Ptr<Ipv6MulticastRoute> mrtentry, Ptr<const Packet> p, const Ipv6Header& header)
+{
+ NS_LOG_FUNCTION (this << mrtentry << p << header);
+ NS_LOG_LOGIC ("Multicast forwarding logic for node: " << m_node->GetId ());
+
+ // The output interfaces we could forward this onto are encoded
+ // in the OutputTtl of the Ipv6MulticastRoute
+ for (uint32_t i = 0 ; i < Ipv6MulticastRoute::MAX_INTERFACES ; i++)
+ {
+ if (mrtentry->GetOutputTtl (i) < Ipv6MulticastRoute::MAX_TTL)
+ {
+ Ptr<Packet> packet = p->Copy ();
+ Ipv6Header h = header;
+ h.SetHopLimit (header.GetHopLimit () - 1);
+ if (h.GetHopLimit () == 0)
+ {
+ NS_LOG_WARN ("TTL exceeded. Drop.");
+ m_dropTrace (packet);
+ return;
+ }
+
+ NS_LOG_LOGIC ("Forward multicast via interface " << i);
+ Ptr<Ipv6Route> rtentry = Create<Ipv6Route> ();
+ rtentry->SetSource (h.GetSourceAddress ());
+ rtentry->SetDestination (h.GetDestinationAddress ());
+ rtentry->SetGateway (Ipv6Address::GetAny ());
+ rtentry->SetOutputDevice (GetNetDevice (i));
+ SendRealOut (rtentry, packet, h);
+ return;
+ }
+ }
+}
+
+void Ipv6L3Protocol::LocalDeliver (Ptr<const Packet> packet, Ipv6Header const& ip, uint32_t iif)
+{
+ NS_LOG_FUNCTION (this << packet << ip << iif);
+ Ptr<Packet> p = packet->Copy ();
+ Ptr<Ipv6L4Protocol> protocol = GetProtocol (ip.GetNextHeader ());
+
+ if (protocol)
+ {
+ Ptr<Packet> copy = p->Copy ();
+ enum Ipv6L4Protocol::RxStatus_e status = protocol->Receive (p, ip.GetSourceAddress (), ip.GetDestinationAddress (), GetInterface (iif));
+
+ switch (status)
+ {
+ case Ipv6L4Protocol::RX_OK:
+ break;
+ case Ipv6L4Protocol::RX_CSUM_FAILED:
+ break;
+ case Ipv6L4Protocol::RX_ENDPOINT_UNREACH:
+ if (ip.GetDestinationAddress ().IsMulticast ())
+ {
+ /* do not rely on multicast address */
+ break;
+ }
+
+ copy->AddHeader (ip);
+ GetIcmpv6 ()->SendErrorDestinationUnreachable (copy, ip.GetSourceAddress (), Icmpv6Header::ICMPV6_PORT_UNREACHABLE);
+ }
+ }
+}
+
+void Ipv6L3Protocol::RouteInputError (Ptr<const Packet> p, const Ipv6Header& ipHeader, Socket::SocketErrno sockErrno)
+{
+ NS_LOG_FUNCTION (this << p << ipHeader << sockErrno);
+ NS_LOG_LOGIC ("Route input failure-- dropping packet to " << ipHeader << " with errno " << sockErrno);
+ m_dropTrace (p);
+}
+
+Ipv6Header Ipv6L3Protocol::BuildHeader (Ipv6Address src, Ipv6Address dst, uint8_t protocol, uint16_t payloadSize, uint8_t ttl)
+{
+ NS_LOG_FUNCTION (this << src << dst << (uint32_t)protocol << (uint32_t)payloadSize << (uint32_t)ttl);
+ Ipv6Header hdr;
+
+ hdr.SetSourceAddress (src);
+ hdr.SetDestinationAddress (dst);
+ hdr.SetNextHeader (protocol);
+ hdr.SetPayloadLength (payloadSize);
+ hdr.SetHopLimit (ttl);
+ return hdr;
+}
+
+} /* namespace ns3 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv6-l3-protocol.h Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,486 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#ifndef IPV6_L3_PROTOCOL_H
+#define IPV6_L3_PROTOCOL_H
+
+#include <list>
+
+#include "ns3/traced-callback.h"
+
+#include "ns3/net-device.h"
+#include "ns3/ipv6.h"
+#include "ns3/ipv6-address.h"
+#include "ns3/ipv6-header.h"
+
+namespace ns3
+{
+
+class Node;
+class Ipv6Interface;
+class Ipv6L4Protocol;
+class Ipv6Route;
+class Ipv6MulticastRoute;
+class Ipv6RawSocketImpl;
+class Icmpv6L4Protocol;
+class Ipv6AutoconfiguredPrefix;
+
+/**
+ * \class Ipv6L3Protocol
+ * \brief IPv6 layer implementation.
+ */
+class Ipv6L3Protocol : public Ipv6
+{
+ public:
+ /**
+ * \brief Get the type ID of this class.
+ * \return type ID
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief The protocol number for IPv6 (0x86DD).
+ */
+ static const uint16_t PROT_NUMBER;
+
+ /**
+ * \brief Constructor.
+ */
+ Ipv6L3Protocol ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Ipv6L3Protocol ();
+
+ /**
+ * \brief Set node for this stack.
+ * \param node node to set
+ */
+ void SetNode (Ptr<Node> node);
+
+ /**
+ * \brief Add an L4 protocol.
+ * \param protocol L4 protocol
+ */
+ void Insert (Ptr<Ipv6L4Protocol> protocol);
+
+ /**
+ * \brief Remove an L4 protocol.
+ * \param protocol L4 protocol to remove
+ */
+ void Remove (Ptr<Ipv6L4Protocol> protocol);
+
+ /**
+ * \brief Get L4 protocol by protocol number.
+ * \param protocolNumber protocol number
+ * \return corresponding Ipv6L4Protocol or 0 if not found
+ */
+ Ptr<Ipv6L4Protocol> GetProtocol (int protocolNumber) const;
+
+ /**
+ * \brief Create raw IPv6 socket.
+ * \return newly raw socket
+ */
+ Ptr<Socket> CreateRawSocket ();
+
+ /**
+ * \brief Remove raw IPv6 socket.
+ * \param socket socket to remove
+ */
+ void DeleteRawSocket (Ptr<Socket> socket);
+
+ /**
+ * \brief Set the default TTL.
+ * \param ttl TTL to set
+ */
+ void SetDefaultTtl (uint8_t ttl);
+
+ /**
+ * \brief Receive method when a packet arrive in the stack.
+ * This method removes IPv6 header and forward up to L4 protocol.
+ *
+ * \param device network device
+ * \param p the packet
+ * \param protocol next header value
+ * \param from address of the correspondant
+ * \param to address of the destination
+ * \param packetType type of the packet
+ */
+ void Receive (Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol, const Address &from, const Address &to, NetDevice::PacketType packetType);
+
+ /**
+ * \brief Higher-level layers call this method to send a packet
+ * down the stack to the MAC and PHY layers.
+ *
+ * \param packet packet to send
+ * \param source source address of packet
+ * \param destination address of packet
+ * \param protocol number of packet
+ * \param route route to take
+ */
+ void Send (Ptr<Packet> packet, Ipv6Address source, Ipv6Address destination, uint8_t protocol, Ptr<Ipv6Route> route);
+
+ /**
+ * \brief Set routing protocol for this stack.
+ * \param routingProtocol IPv6 routing protocol to set
+ */
+ void SetRoutingProtocol (Ptr<Ipv6RoutingProtocol> routingProtocol);
+
+ /**
+ * \brief Get current routing protocol used.
+ * \return routing protocol
+ */
+ Ptr<Ipv6RoutingProtocol> GetRoutingProtocol () const;
+
+ /**
+ * \brief Add IPv6 interface for a device.
+ * \param device net device
+ * \return interface index
+ */
+ uint32_t AddInterface (Ptr<NetDevice> device);
+
+ /**
+ * \brief Get an interface.
+ * \param i interface index
+ * \return IPv6 interface pointer
+ */
+ Ptr<Ipv6Interface> GetInterface (uint32_t i) const;
+
+ /**
+ * \brief Get current number of interface on this stack.
+ * \return number of interface registered
+ */
+ uint32_t GetNInterfaces () const;
+
+ /**
+ * \brief Get interface index which has specified IPv6 address
+ * \param addr IPv6 address
+ * \return interface index or -1 if not found
+ */
+ int32_t GetInterfaceForAddress (Ipv6Address addr) const;
+
+ /**
+ * \brief Get interface index which match specified address/prefix.
+ * \param addr IPv6 address
+ * \param mask IPv6 prefix (mask)
+ * \return interface index or -1 if not found
+ */
+ int32_t GetInterfaceForPrefix (Ipv6Address addr, Ipv6Prefix mask) const;
+
+ /**
+ * \brief Get interface index which is on a specified net device.
+ * \param device net device
+ */
+ int32_t GetInterfaceForDevice (Ptr<const NetDevice> device) const;
+
+ /**
+ * \brief Add an address on interface.
+ * \param i interface index
+ * \param address to add
+ */
+ bool AddAddress (uint32_t i, Ipv6InterfaceAddress address);
+
+ /**
+ * \brief Get an address.
+ * \param interfaceIndex interface index
+ * \param addressIndex address index on the interface
+ * \return Ipv6InterfaceAddress or assert if not found
+ */
+ Ipv6InterfaceAddress GetAddress (uint32_t interfaceIndex, uint32_t addressIndex) const;
+
+ /**
+ * \brief Get number of address for an interface.
+ * \return number of address
+ */
+ uint32_t GetNAddresses (uint32_t interface) const;
+
+ /**
+ * \brief Remove an address from an interface.
+ * \param interfaceIndex interface index
+ * \param addressIndex address index on the interface
+ */
+ bool RemoveAddress (uint32_t interfaceIndex, uint32_t addressIndex);
+
+ /**
+ * \brief Set metric for an interface.
+ * \param i index
+ * \param metric
+ */
+ void SetMetric (uint32_t i, uint16_t metric);
+
+ /**
+ * \brief Get metric for an interface.
+ * \param i index
+ * \return metric
+ */
+ uint16_t GetMetric (uint32_t i) const;
+
+ /**
+ * \brief Get MTU for an interface.
+ * \param i index
+ * \return MTU
+ */
+ uint16_t GetMtu (uint32_t i) const;
+
+ /**
+ * \brief Is specified interface up ?
+ * \param i interface index
+ */
+ bool IsUp (uint32_t i) const;
+
+ /**
+ * \brief Set an interface up.
+ * \param i interface index
+ */
+ void SetUp (uint32_t i);
+
+ /**
+ * \brief set an interface down.
+ * \param i interface index
+ */
+ void SetDown (uint32_t i);
+
+ /**
+ * \brief Is interface allows forwarding ?
+ * \param i interface index
+ */
+ bool IsForwarding (uint32_t i) const;
+
+ /**
+ * \brief Enable or disable forwarding on interface
+ * \param i interface index
+ * \param val true = enable forwarding, false = disable
+ */
+ void SetForwarding (uint32_t i, bool val);
+
+ /**
+ * \brief Get device by index.
+ * \param i device index on this stack
+ * \return NetDevice pointer
+ */
+ Ptr<NetDevice> GetNetDevice (uint32_t i);
+
+ /**
+ * \brief Get ICMPv6 protocol.
+ * \return Icmpv6L4Protocol pointer
+ */
+ Ptr<Icmpv6L4Protocol> GetIcmpv6 () const;
+
+ /**
+ * \brief Add an autoconfigured address with RA information.
+ * \param interface interface index
+ * \param network network prefix
+ * \param mask network mask
+ * \param flags flags of the prefix information option (home agent, ...)
+ * \param validTime valid time of the prefix
+ * \param preferredTime preferred time of the prefix
+ * \param defaultRouter default router address
+ */
+ void AddAutoconfiguredAddress (uint32_t interface, Ipv6Address network, Ipv6Prefix mask, uint8_t flags, uint32_t validTime, uint32_t preferredTime, Ipv6Address defaultRouter = Ipv6Address::GetZero ());
+
+ /**
+ * \brief Remove an autoconfigured address.
+ *
+ * Typically it is used when an autoconfigured address expires.
+ * \param interface interface index
+ * \param network network prefix
+ * \param mask network mask
+ * \param defaultRouter gateway
+ */
+ void RemoveAutoconfiguredAddress (uint32_t interface, Ipv6Address network, Ipv6Prefix mask, Ipv6Address defaultRouter);
+
+ protected:
+ /**
+ * \brief Dispose object.
+ */
+ virtual void DoDispose ();
+
+ /**
+ * \brief Notify other components connected to the node that a new stack member is now connected.
+ *
+ * This will be used to notify Layer 3 protocol of layer 4 protocol stack to connect them together.
+ */
+ virtual void NotifyNewAggregate ();
+
+ private:
+ /* for unit-tests */
+ friend class Ipv6L3ProtocolTest;
+
+ typedef std::list<Ptr<Ipv6Interface> > Ipv6InterfaceList;
+ typedef std::list<Ptr<Ipv6RawSocketImpl> > SocketList;
+ typedef std::list<Ptr<Ipv6L4Protocol> > L4List_t;
+
+ typedef std::list< Ptr<Ipv6AutoconfiguredPrefix> > Ipv6AutoconfiguredPrefixList;
+ typedef std::list< Ptr<Ipv6AutoconfiguredPrefix> >::iterator Ipv6AutoconfiguredPrefixListI;
+
+ /**
+ * \brief Callback to trace TX (transmission) packets.
+ */
+ TracedCallback<Ptr<const Packet>, uint32_t> m_txTrace;
+
+ /**
+ * \brief Callback to trace RX (reception) packets.
+ */
+ TracedCallback<Ptr<const Packet>, uint32_t> m_rxTrace;
+
+ /**
+ * \brief Callback to trace drop packets.
+ */
+ TracedCallback<Ptr<const Packet> > m_dropTrace;
+
+ /**
+ * \brief Copy constructor.
+ * \param o object to copy
+ */
+ Ipv6L3Protocol (const Ipv6L3Protocol& o);
+
+ /**
+ * \brief Copy constructor.
+ * \param o object to copy
+ */
+ Ipv6L3Protocol &operator = (const Ipv6L3Protocol& o);
+
+ /**
+ * \brief Construct an IPv6 header.
+ * \param src source IPv6 address
+ * \param dst destination IPv6 address
+ * \param protocol L4 protocol
+ * \param payloadSize payload size
+ * \param ttl TTL
+ * \return newly created IPv6 header
+ */
+ Ipv6Header BuildHeader (Ipv6Address src, Ipv6Address dst, uint8_t protocol,
+ uint16_t payloadSize, uint8_t ttl);
+
+ /**
+ * \brief Send packet with route.
+ * \param route route
+ * \param packet packet to send
+ * \param ipHeader IPv6 header to add to the packet
+ */
+ void SendRealOut (Ptr<Ipv6Route> route, Ptr<Packet> packet, Ipv6Header const& ipHeader);
+
+ /**
+ * \brief Forward a packet.
+ * \param rtentry route
+ * \param p packet to forward
+ * \param header IPv6 header to add to the packet
+ */
+ void IpForward (Ptr<Ipv6Route> rtentry, Ptr<const Packet> p, const Ipv6Header& header);
+
+ /**
+ * \brief Forward a packet in multicast.
+ * \param mrtentry route
+ * \param p packet to forward
+ * \param header IPv6 header to add to the packet
+ */
+ void IpMulticastForward (Ptr<Ipv6MulticastRoute> mrtentry, Ptr<const Packet> p, const Ipv6Header& header);
+
+ /**
+ * \brief Deliver a packet.
+ * \param p packet delivered
+ * \param ip IPv6 header
+ * \param iif input interface packet was received
+ */
+ void LocalDeliver (Ptr<const Packet> p, Ipv6Header const& ip, uint32_t iif);
+
+ /**
+ * \brief Fallback when no route is found.
+ * \param p packet
+ * \param ipHeader IPv6 header
+ * \param sockErrno error number
+ */
+ void RouteInputError (Ptr<const Packet> p, const Ipv6Header& ipHeader, Socket::SocketErrno sockErrno);
+
+ /**
+ * \brief Add an IPv6 interface to the stack.
+ * \param interface interface to add
+ * \return index of newly added interface
+ */
+ uint32_t AddIpv6Interface (Ptr<Ipv6Interface> interface);
+
+ /**
+ * \brief Setup loopback interface.
+ */
+ void SetupLoopback ();
+
+ /**
+ * \brief Set IPv6 forwarding state.
+ * \param forward IPv6 forwarding enabled or not
+ */
+ virtual void SetIpForward (bool forward);
+
+ /**
+ * \brief Get IPv6 forwarding state.
+ * \return forwarding state (enabled or not)
+ */
+ virtual bool GetIpForward () const;
+
+ /**
+ * \brief Node attached to stack.
+ */
+ Ptr<Node> m_node;
+
+ /**
+ * \brief Forwarding packets (i.e. router mode) state.
+ */
+ bool m_ipForward;
+
+ /**
+ * \brief List of transport protocol.
+ */
+ L4List_t m_protocols;
+
+ /**
+ * \brief List of IPv6 interfaces.
+ */
+ Ipv6InterfaceList m_interfaces;
+
+ /**
+ * \brief Number of IPv6 interfaces managed by the stack.
+ */
+ uint32_t m_nInterfaces;
+
+ /**
+ * \brief Default TTL for outgoing packets.
+ */
+ uint8_t m_defaultTtl;
+
+ /**
+ * \brief Routing protocol.
+ */
+ Ptr<Ipv6RoutingProtocol> m_routingProtocol;
+
+ /**
+ * \brief List of IPv6 raw sockets.
+ */
+ SocketList m_sockets;
+
+ /**
+ * \brief List of IPv6 prefix received from RA.
+ */
+ Ipv6AutoconfiguredPrefixList m_prefixes;
+};
+
+} /* namespace ns3 */
+
+#endif /* IPV6_L3_PROTOCOL_H */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv6-l4-protocol.cc Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#include "ipv6-l4-protocol.h"
+#include "ns3/uinteger.h"
+
+namespace ns3
+{
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6L4Protocol);
+
+TypeId Ipv6L4Protocol::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ipv6L4Protocol")
+ .SetParent<Object> ()
+ .AddAttribute ("ProtocolNumber", "The IPv6 protocol number.",
+ UintegerValue (0),
+ MakeUintegerAccessor (&Ipv6L4Protocol::GetProtocolNumber),
+ MakeUintegerChecker<int> ())
+ ;
+ return tid;
+}
+
+Ipv6L4Protocol::~Ipv6L4Protocol ()
+{
+}
+
+void Ipv6L4Protocol::ReceiveIcmp (Ipv6Address icmpSource, uint8_t icmpTtl,
+ uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo,
+ Ipv6Address payloadSource, Ipv6Address payloadDestination,
+ const uint8_t* payload)
+{}
+
+} /* namespace ns3 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv6-l4-protocol.h Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,106 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#ifndef IPV6_L4_PROTOCOL_H
+#define IPV6_L4_PROTOCOL_H
+
+#include "ns3/object.h"
+#include "ipv6-interface.h"
+
+namespace ns3
+{
+
+class Packet;
+class Ipv6Address;
+class TraceContext;
+
+/**
+ * \class Ipv6L4Protocol
+ * \brief IPv6 L4 protocol abstract class
+ */
+class Ipv6L4Protocol : public Object
+{
+ public:
+ /**
+ * \enum RxStatus_e
+ * \brief Status of receive.
+ */
+ enum RxStatus_e
+ {
+ RX_OK,
+ RX_CSUM_FAILED,
+ RX_ENDPOINT_UNREACH
+ };
+
+ /**
+ * \brief Get the type identificator.
+ * \return type identificator
+ */
+ static TypeId GetTypeId (void);
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Ipv6L4Protocol ();
+
+ /**
+ * \brief Get the protocol number.
+ * \return protocol number
+ */
+ virtual int GetProtocolNumber () const = 0;
+
+ /**
+ * \brief Receive method.
+ *
+ * Called from lower-level layers to send the packet up
+ * in the stack.
+ * \param p packet to forward up
+ * \param src source address of packet received
+ * \param dst address of packet received
+ * \param incomingInterface the Ipv6Interface on which the packet arrived
+ * \return status (OK, destination unreachable or checksum failed)
+ */
+ virtual enum RxStatus_e Receive (Ptr<Packet> p, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> incomingInterface) = 0;
+
+ /**
+ * \param icmpSource the source address of the ICMPv6 message
+ * \param icmpTtl the ttl of the ICMPv6 message
+ * \param icmpType the 'type' field of the ICMPv6 message
+ * \param icmpCode the 'code' field of the ICMPv6 message
+ * \param icmpInfo extra information dependent on the ICMPv6 message
+ * generated by Icmpv6L4Protocol
+ * \param payloadSource the source address of the packet which triggered
+ * the ICMPv6 message
+ * \param payloadDestination the destination address of the packet which
+ * triggered the ICMPv6 message.
+ * \param payload the first 8 bytes of the UDP header of the packet
+ * which triggered the ICMPv6 message.
+ */
+ virtual void ReceiveIcmp (Ipv6Address icmpSource, uint8_t icmpTtl,
+ uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo,
+ Ipv6Address payloadSource, Ipv6Address payloadDestination,
+ const uint8_t* payload);
+
+};
+
+} /* namespace ns3 */
+
+#endif /* IPV6_L4_PROTOCOL_H */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv6-raw-socket-factory-impl.cc Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,16 @@
+#include "ipv6-raw-socket-factory-impl.h"
+#include "ipv6-l3-protocol.h"
+#include "ns3/socket.h"
+
+namespace ns3
+{
+
+Ptr<Socket> Ipv6RawSocketFactoryImpl::CreateSocket ()
+{
+ Ptr<Ipv6L3Protocol> ipv6 = GetObject<Ipv6L3Protocol> ();
+ Ptr<Socket> socket = ipv6->CreateRawSocket ();
+ return socket;
+}
+
+} /* namespace ns3 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv6-raw-socket-factory-impl.h Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,25 @@
+#ifndef IPV6_RAW_SOCKET_FACTORY_IMPL_H
+#define IPV6_RAW_SOCKET_FACTORY_IMPL_H
+
+#include "ns3/ipv6-raw-socket-factory.h"
+
+namespace ns3
+{
+
+/**
+ * \class Ipv6RawSocketFactoryImpl
+ * \brief Implementation of IPv6 raw socket factory.
+ */
+class Ipv6RawSocketFactoryImpl : public Ipv6RawSocketFactory
+{
+public:
+ /**
+ * \brief Create a raw IPv6 socket.
+ */
+ virtual Ptr<Socket> CreateSocket ();
+};
+
+} /* namespace ns3 */
+
+#endif /* IPV6_RAW_SOCKET_FACTORY_IMPL_H */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv6-raw-socket-impl.cc Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,338 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#include "ns3/inet6-socket-address.h"
+#include "ns3/node.h"
+#include "ns3/packet.h"
+#include "ns3/uinteger.h"
+#include "ns3/log.h"
+#include "ns3/ipv6-route.h"
+#include "ns3/ipv6-routing-protocol.h"
+
+#include "ipv6-l3-protocol.h"
+
+#include "icmpv6-header.h"
+#include "icmpv6-l4-protocol.h"
+#include "ipv6-raw-socket-impl.h"
+
+namespace ns3
+{
+
+NS_LOG_COMPONENT_DEFINE ("Ipv6RawSocketImpl");
+
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6RawSocketImpl);
+
+TypeId Ipv6RawSocketImpl::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ipv6RawSocketImpl")
+ .SetParent<Socket> ()
+ .AddAttribute ("Protocol", "Protocol number to match.",
+ UintegerValue (0),
+ MakeUintegerAccessor (&Ipv6RawSocketImpl::m_protocol),
+ MakeUintegerChecker<uint16_t> ())
+ .AddAttribute ("IcmpFilter", "Any ICMPv6 header whose type field matches a bit in this filter is dropped.",
+ UintegerValue (0),
+ MakeUintegerAccessor (&Ipv6RawSocketImpl::m_icmpFilter),
+ MakeUintegerChecker<uint32_t> ())
+ ;
+ return tid;
+}
+
+Ipv6RawSocketImpl::Ipv6RawSocketImpl ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_err = Socket::ERROR_NOTERROR;
+ m_node = 0;
+ m_src = Ipv6Address::GetAny ();
+ m_dst = Ipv6Address::GetAny ();
+ m_protocol = 0;
+ m_shutdownSend = false;
+ m_shutdownRecv = false;
+}
+
+Ipv6RawSocketImpl::~Ipv6RawSocketImpl ()
+{
+}
+
+void Ipv6RawSocketImpl::DoDispose ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_node = 0;
+ Socket::DoDispose ();
+}
+
+void Ipv6RawSocketImpl::SetNode (Ptr<Node> node)
+{
+ NS_LOG_FUNCTION (this << node);
+ m_node = node;
+}
+
+Ptr<Node> Ipv6RawSocketImpl::GetNode () const
+{
+ return m_node;
+}
+
+enum Socket::SocketErrno Ipv6RawSocketImpl::GetErrno () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_err;
+}
+
+int Ipv6RawSocketImpl::Bind (const Address& address)
+{
+ NS_LOG_FUNCTION (this << address);
+
+ if (!Inet6SocketAddress::IsMatchingType (address))
+ {
+ m_err = Socket::ERROR_INVAL;
+ return -1;
+ }
+ Inet6SocketAddress ad = Inet6SocketAddress::ConvertFrom (address);
+ m_src = ad.GetIpv6 ();
+ return 0;
+}
+
+int Ipv6RawSocketImpl::Bind ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_src = Ipv6Address::GetAny ();
+ return 0;
+}
+
+int Ipv6RawSocketImpl::GetSockName (Address& address) const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ address = Inet6SocketAddress (m_src, 0);
+ return 0;
+}
+
+int Ipv6RawSocketImpl::Close ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ Ptr<Ipv6L3Protocol> ipv6 = m_node->GetObject<Ipv6L3Protocol> ();
+
+ if (ipv6)
+ {
+ ipv6->DeleteRawSocket (this);
+ }
+ return 0;
+}
+
+int Ipv6RawSocketImpl::ShutdownSend ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_shutdownSend = true;
+ return 0;
+}
+
+int Ipv6RawSocketImpl::ShutdownRecv ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_shutdownRecv = true;
+ return 0;
+}
+
+int Ipv6RawSocketImpl::Connect (const Address& address)
+{
+ NS_LOG_FUNCTION (this << address);
+
+ if (!Inet6SocketAddress::IsMatchingType (address))
+ {
+ m_err = Socket::ERROR_INVAL;
+ return -1;
+ }
+
+ Inet6SocketAddress ad = Inet6SocketAddress::ConvertFrom (address);
+ m_dst = ad.GetIpv6 ();
+ return 0;
+}
+
+int Ipv6RawSocketImpl::Listen ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_err = Socket::ERROR_OPNOTSUPP;
+ return -1;
+}
+
+int Ipv6RawSocketImpl::Send (Ptr<Packet> p, uint32_t flags)
+{
+ NS_LOG_FUNCTION (this << p << flags);
+ Inet6SocketAddress to = Inet6SocketAddress (m_dst, m_protocol);
+ return SendTo (p, flags, to);
+}
+
+int Ipv6RawSocketImpl::SendTo (Ptr<Packet> p, uint32_t flags, const Address& toAddress)
+{
+ NS_LOG_FUNCTION (this << p << flags << toAddress);
+
+ if (!Inet6SocketAddress::IsMatchingType (toAddress))
+ {
+ m_err = Socket::ERROR_INVAL;
+ return -1;
+ }
+
+ if (m_shutdownSend)
+ {
+ return 0;
+ }
+
+ Inet6SocketAddress ad = Inet6SocketAddress::ConvertFrom (toAddress);
+ Ptr<Ipv6L3Protocol> ipv6 = m_node->GetObject<Ipv6L3Protocol> ();
+ Ipv6Address dst = ad.GetIpv6 ();
+
+ if (ipv6->GetRoutingProtocol ())
+ {
+ Ipv6Header hdr;
+ hdr.SetDestinationAddress (dst);
+ SocketErrno err = ERROR_NOTERROR;
+ Ptr<Ipv6Route> route = 0;
+ uint32_t oif = 0; /* specify non-zero if bound to a source address */
+
+ if (!m_src.IsAny ())
+ {
+ int32_t index = ipv6->GetInterfaceForAddress (m_src);
+ NS_ASSERT (index >= 0);
+ oif = index;
+ }
+
+ route = ipv6->GetRoutingProtocol ()->RouteOutput (p, hdr, oif, err);
+
+ if (route)
+ {
+ NS_LOG_LOGIC ("Route exists");
+ if (m_protocol == Icmpv6L4Protocol::GetStaticProtocolNumber ())
+ {
+ /* calculate checksum here for ICMPv6 echo request (sent by ping6)
+ * as we cannot determine source IPv6 address at application level
+ */
+ if (*p->PeekData () == Icmpv6Header::ICMPV6_ECHO_REQUEST)
+ {
+ Icmpv6Echo hdr (1);
+ p->RemoveHeader (hdr);
+ hdr.CalculatePseudoHeaderChecksum (route->GetSource (), dst, p->GetSize () + hdr.GetSerializedSize (), Icmpv6L4Protocol::GetStaticProtocolNumber ());
+ p->AddHeader (hdr);
+ }
+ }
+
+ ipv6->Send (p, route->GetSource (), dst, m_protocol, route);
+ }
+ else
+ {
+ NS_LOG_DEBUG ("No route, dropped!");
+ }
+ }
+ return 0;
+}
+
+Ptr<Packet> Ipv6RawSocketImpl::Recv (uint32_t maxSize, uint32_t flags)
+{
+ NS_LOG_FUNCTION (this << maxSize << flags);
+ Address tmp;
+ return RecvFrom (maxSize, flags, tmp);
+}
+
+Ptr<Packet> Ipv6RawSocketImpl::RecvFrom (uint32_t maxSize, uint32_t flags, Address& fromAddress)
+{
+ NS_LOG_FUNCTION (this << maxSize << flags << fromAddress);
+
+ if (m_data.empty ())
+ {
+ return 0;
+ }
+
+ /* get packet */
+ struct Data data = m_data.front ();
+ m_data.pop_front ();
+
+ if (data.packet->GetSize () > maxSize)
+ {
+ Ptr<Packet> first = data.packet->CreateFragment (0, maxSize);
+ data.packet->RemoveAtStart (maxSize);
+ m_data.push_front (data);
+ return first;
+ }
+
+ fromAddress = Inet6SocketAddress (data.fromIp, data.fromProtocol);
+ return data.packet;
+}
+
+uint32_t Ipv6RawSocketImpl::GetTxAvailable () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return 0xffffffff;
+}
+
+uint32_t Ipv6RawSocketImpl::GetRxAvailable () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ uint32_t rx = 0;
+
+ for (std::list<Data>::const_iterator it = m_data.begin () ; it != m_data.end () ; ++it)
+ {
+ rx+= (it->packet)->GetSize ();
+ }
+
+ return rx;
+}
+
+bool Ipv6RawSocketImpl::ForwardUp (Ptr<const Packet> p, Ipv6Header hdr, Ptr<NetDevice> device)
+{
+ NS_LOG_FUNCTION (this << *p << hdr << device);
+
+ if (m_shutdownRecv)
+ {
+ return false;
+ }
+
+ if ((m_src == Ipv6Address::GetAny () || hdr.GetDestinationAddress () == m_src) &&
+ (m_dst == Ipv6Address::GetAny () || hdr.GetSourceAddress () == m_dst) &&
+ hdr.GetNextHeader () == m_protocol)
+ {
+ Ptr<Packet> copy = p->Copy ();
+
+ if (m_protocol == Icmpv6L4Protocol::GetStaticProtocolNumber ())
+ {
+ /* filter */
+ Icmpv6Header icmpHeader;
+ copy->PeekHeader (icmpHeader);
+ uint8_t type = icmpHeader.GetType ();
+
+ if ((1 << type) & m_icmpFilter)
+ {
+ /* packet filtered */
+ return false;
+ }
+ }
+
+ copy->AddHeader (hdr);
+ struct Data data;
+ data.packet = copy;
+ data.fromIp = hdr.GetSourceAddress ();
+ data.fromProtocol = hdr.GetNextHeader ();
+ m_data.push_back (data);
+ NotifyDataRecv ();
+ return true;
+ }
+ return false;
+}
+
+} /* namespace ns3 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv6-raw-socket-impl.h Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,255 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#ifndef IPV6_RAW_SOCKET_IMPL_H
+#define IPV6_RAW_SOCKET_IMPL_H
+
+#include <list>
+
+#include "ns3/socket.h"
+#include "ns3/ipv6-address.h"
+#include "ns3/ipv6-header.h"
+
+namespace ns3
+{
+
+class NetDevice;
+class Node;
+
+/**
+ * \class Ipv6RawSocketImpl
+ * \brief IPv6 raw socket.
+ */
+class Ipv6RawSocketImpl : public Socket
+{
+ public:
+ /**
+ * \brief Get the type ID of this class.
+ * \return type ID
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Constructor.
+ */
+ Ipv6RawSocketImpl ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Ipv6RawSocketImpl ();
+
+ /**
+ * \brief Set the node.
+ * \param node node to set
+ */
+ void SetNode (Ptr<Node> node);
+
+ /**
+ * \brief Get last error number.
+ * \return error number
+ */
+ virtual enum Socket::SocketErrno GetErrno () const;
+
+ /**
+ * \brief Get node.
+ * \return node associated with this raw socket.
+ */
+ virtual Ptr<Node> GetNode () const;
+
+ /**
+ * \brief Bind the socket to address.
+ * \param address bind to this address
+ * \return 0 if success, -1 otherwise
+ */
+ virtual int Bind (const Address& address);
+
+ /**
+ * \brief Bind socket.
+ * \return 0 if success, -1 otherwise
+ */
+ virtual int Bind ();
+
+ /**
+ * \brief Get socket address.
+ * \param address socket address if method success
+ * \return 0 if success, -1 otherwise
+ */
+ virtual int GetSockName (Address& address) const;
+
+ /**
+ * \brief Close the socket.
+ * \return 0 if success, -1 otherwise
+ */
+ virtual int Close ();
+
+ /**
+ * \brief Shutdown send capability.
+ * \return 0 if success, -1 otherwise
+ */
+ virtual int ShutdownSend ();
+
+ /**
+ * \brief Shutdown receive capability.
+ * \return 0 if success, -1 otherwise
+ */
+ virtual int ShutdownRecv ();
+
+ /**
+ * \brief Connect to address.
+ * \param address address
+ * \return 0 if success, -1 otherwise
+ */
+ virtual int Connect (const Address& address);
+
+ /**
+ * \brief Listen.
+ * \return 0 if success, -1 otherwise
+ */
+ virtual int Listen ();
+
+ /**
+ * \brief Get TX size available.
+ * \return TX size
+ */
+ virtual uint32_t GetTxAvailable () const;
+
+ /**
+ * \brief Get RX size available.
+ * \return RX size
+ */
+ virtual uint32_t GetRxAvailable () const;
+
+ /**
+ * \brief Send a packet.
+ * \param p packet to send
+ * \param flags additionnal flags
+ * \return 0 if success, -1 otherwise
+ */
+ virtual int Send (Ptr<Packet> p, uint32_t flags);
+
+ /**
+ * \brief Send a packet.
+ * \param p packet to send
+ * \param flags additionnal flags
+ * \param toAddress destination address
+ * \return 0 if success, -1 otherwise
+ */
+ virtual int SendTo (Ptr<Packet> p, uint32_t flags, const Address& toAddress);
+
+ /**
+ * \brief Receive packet.
+ * \param maxSize maximum size
+ * \param flags additionnal flags
+ * \return packet received
+ */
+ virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags);
+
+ /**
+ * \brief Receive packet.
+ * \param maxSize maximum size
+ * \param flags additionnal flags
+ * \param fromAddress source address
+ * \return packet received
+ */
+ virtual Ptr<Packet> RecvFrom (uint32_t maxSize, uint32_t flags, Address& fromAddress);
+
+ /**
+ * \brief Set protocol field.
+ * \param protocol protocol to set
+ */
+ void SetProtocol (uint16_t protocol);
+
+ /**
+ * \brief Forward up to receive method.
+ * \param p packet
+ * \param hdr IPv6 header
+ * \param device device
+ * \return true if forwarded, false otherwise
+ */
+ bool ForwardUp (Ptr<const Packet> p, Ipv6Header hdr, Ptr<NetDevice> device);
+
+ private:
+ /**
+ * \struct Data
+ * \brief IPv6 raw data and additionnal information.
+ */
+ struct Data
+ {
+ Ptr<Packet> packet; /**< Packet data */
+ Ipv6Address fromIp; /**< Source address */
+ uint16_t fromProtocol; /**< Protocol used */
+ };
+
+ /**
+ * \brief Dispose object.
+ */
+ virtual void DoDispose ();
+
+ /**
+ * \brief Last error number.
+ */
+ enum Socket::SocketErrno m_err;
+
+ /**
+ * \brief Node.
+ */
+ Ptr<Node> m_node;
+
+ /**
+ * \brief Source address.
+ */
+ Ipv6Address m_src;
+
+ /**
+ * \brief Destination address.
+ */
+ Ipv6Address m_dst;
+
+ /**
+ * \brief Protocol.
+ */
+ uint16_t m_protocol;
+
+ /**
+ * \brief Packet waiting to be processed.
+ */
+ std::list<struct Data> m_data;
+
+ /**
+ * \brief Flag to shutdown send capability.
+ */
+ bool m_shutdownSend;
+
+ /**
+ * \brief Flag to shutdown receive capability.
+ */
+ bool m_shutdownRecv;
+
+ /**
+ * \brief ICMPv6 filter.
+ */
+ uint32_t m_icmpFilter;
+};
+
+} /* namespace ns3 */
+
+#endif /* IPV6_RAW_SOCKET_IMPL_H */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv6-test.cc Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,145 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#ifdef RUN_SELF_TESTS
+
+#include "ns3/simulator.h"
+#include "ns3/test.h"
+#include "ns3/log.h"
+#include "ns3/inet6-socket-address.h"
+#include "ns3/node.h"
+#include "ns3/csma-net-device.h"
+
+#include "icmpv6-l4-protocol.h"
+#include "ipv6-interface.h"
+
+namespace ns3
+{
+
+/**
+ * \class Ipv6L3ProtocolTest
+ * \brief Ipv6L3Protocol unit tests.
+ */
+class Ipv6L3ProtocolTest : public Test
+{
+ public:
+ /**
+ * \brief Constructor.
+ */
+ Ipv6L3ProtocolTest ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Ipv6L3ProtocolTest ();
+
+ /**
+ * \brief Run unit tests for this class.
+ * \return true if all tests have passed, false otherwise
+ */
+ virtual bool RunTests ();
+};
+
+Ipv6L3ProtocolTest::Ipv6L3ProtocolTest () : Test ("Ipv6L3Protocol")
+{
+}
+
+Ipv6L3ProtocolTest::~Ipv6L3ProtocolTest ()
+{
+}
+
+bool Ipv6L3ProtocolTest::RunTests ()
+{
+ bool result = true;
+ Ptr<Node> node = CreateObject<Node> ();
+ Ptr<Ipv6L3Protocol> ipv6 = CreateObject<Ipv6L3Protocol> ();
+ Ptr<Icmpv6L4Protocol> icmpv6 = CreateObject<Icmpv6L4Protocol> ();
+ Ptr<Ipv6Interface> interface = CreateObject<Ipv6Interface> ();
+ Ptr<Ipv6Interface> interface2 = CreateObject<Ipv6Interface> ();
+ Ptr<CsmaNetDevice> device = CreateObject<CsmaNetDevice> ();
+ Ptr<CsmaNetDevice> device2 = CreateObject<CsmaNetDevice> ();
+ uint32_t index = 0;
+
+ /* init */
+ node->AggregateObject (ipv6);
+ node->AggregateObject (icmpv6);
+ ipv6->Insert (icmpv6);
+
+ /* first real interface (loopback is also installed) */
+ node->AddDevice (device);
+ interface->SetDevice (device);
+ interface->SetNode (node);
+ index = ipv6->AddIpv6Interface (interface);
+ NS_TEST_ASSERT_EQUAL (index, 1);
+
+ /* second interface */
+ node->AddDevice (device2);
+ interface2->SetDevice (device2);
+ interface2->SetNode (node);
+ index = ipv6->AddIpv6Interface (interface2);
+ NS_TEST_ASSERT_EQUAL (index, 2);
+
+ Ipv6InterfaceAddress ifaceAddr = interface->GetLinkLocalAddress ();
+ NS_TEST_ASSERT_EQUAL (ifaceAddr.GetAddress ().IsLinkLocal (), true);
+
+ interface->SetUp ();
+ NS_TEST_ASSERT_EQUAL (interface->GetNAddresses (), 1); /* interface has always a link-local address */
+
+ interface2->SetUp ();
+
+ Ipv6InterfaceAddress ifaceAddr1 = Ipv6InterfaceAddress ("2001:1234:5678:9000::1", Ipv6Prefix (64));
+ interface->AddAddress (ifaceAddr1);
+ Ipv6InterfaceAddress ifaceAddr2 = Ipv6InterfaceAddress ("2001:ffff:5678:9000::1", Ipv6Prefix (64));
+ interface->AddAddress (ifaceAddr2);
+
+ Ipv6InterfaceAddress ifaceAddr3 = Ipv6InterfaceAddress ("2001:ffff:5678:9001::2", Ipv6Prefix (64));
+ interface2->AddAddress (ifaceAddr3);
+
+ uint32_t num = interface->GetNAddresses ();
+ NS_TEST_ASSERT_EQUAL (num, 3); /* 2 global addresses + link-local ones */
+
+ num = interface2->GetNAddresses ();
+ NS_TEST_ASSERT_EQUAL (num, 2); /* 1 global addresses + link-local ones */
+
+ interface->RemoveAddress (2);
+ num = interface->GetNAddresses ();
+ NS_TEST_ASSERT_EQUAL (num, 2);
+
+ Ipv6InterfaceAddress output = interface->GetAddress (1);
+ NS_TEST_ASSERT_EQUAL (ifaceAddr1, output);
+
+ index = ipv6->GetInterfaceForPrefix ("2001:1234:5678:9000::0", Ipv6Prefix (64));
+ NS_TEST_ASSERT_EQUAL (index, 1); /* link-local address is always index 0 */
+
+ index = ipv6->GetInterfaceForAddress ("2001:ffff:5678:9001::2");
+ NS_TEST_ASSERT_EQUAL (index, 2);
+
+ index = ipv6->GetInterfaceForAddress ("2001:ffff:5678:9000::1"); /* address we just remove */
+ NS_TEST_ASSERT_EQUAL (index, (uint32_t)-1);
+
+ return result;
+}
+
+static Ipv6L3ProtocolTest gIpv6L3ProtocolTest;
+
+} /* namespace ns3 */
+
+#endif /* RUN_SELF_TESTS */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ndisc-cache.cc Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,513 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#include "ns3/log.h"
+#include "ns3/uinteger.h"
+#include "ns3/node.h"
+
+#include "ipv6-l3-protocol.h"
+#include "icmpv6-l4-protocol.h"
+#include "ndisc-cache.h"
+
+namespace ns3
+{
+
+NS_LOG_COMPONENT_DEFINE ("NdiscCache");
+
+TypeId NdiscCache::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::NdiscCache")
+ .SetParent<Object> ()
+ .AddAttribute ("UnresolvedQueueSize",
+ "Size of the queue for packets pending an NA reply.",
+ UintegerValue (DEFAULT_UNRES_QLEN),
+ MakeUintegerAccessor (&NdiscCache::m_unresQlen),
+ MakeUintegerChecker<uint32_t> ())
+ ;
+ return tid;
+}
+
+NdiscCache::NdiscCache ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+NdiscCache::~NdiscCache ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ Flush ();
+}
+
+void NdiscCache::DoDispose ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ Flush ();
+ m_device = 0;
+ m_interface = 0;
+ Object::DoDispose ();
+}
+
+void NdiscCache::SetDevice (Ptr<NetDevice> device, Ptr<Ipv6Interface> interface)
+{
+ NS_LOG_FUNCTION (this << device << interface);
+ m_device = device;
+ m_interface = interface;
+}
+
+Ptr<Ipv6Interface> NdiscCache::GetInterface () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_interface;
+}
+
+Ptr<NetDevice> NdiscCache::GetDevice () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_device;
+}
+
+NdiscCache::Entry* NdiscCache::Lookup (Ipv6Address dst)
+{
+ NS_LOG_FUNCTION (this << dst);
+
+ if (m_ndCache.find (dst) != m_ndCache.end ())
+ {
+ NdiscCache::Entry* entry = m_ndCache[dst];
+ return entry;
+ }
+ return 0;
+}
+
+NdiscCache::Entry* NdiscCache::Add (Ipv6Address to)
+{
+ NS_LOG_FUNCTION (this << to);
+ NS_ASSERT (m_ndCache.find (to) == m_ndCache.end ());
+
+ NdiscCache::Entry* entry = new NdiscCache::Entry (this);
+ entry->SetIpv6Address (to);
+ m_ndCache[to] = entry;
+ return entry;
+}
+
+void NdiscCache::Remove (NdiscCache::Entry* entry)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ for (CacheI i = m_ndCache.begin () ; i != m_ndCache.end () ; i++)
+ {
+ if ((*i).second == entry)
+ {
+ m_ndCache.erase (i);
+ entry->ClearWaitingPacket ();
+ delete entry;
+ return;
+ }
+ }
+}
+
+void NdiscCache::Flush ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ for (CacheI i = m_ndCache.begin () ; i != m_ndCache.end () ; i++)
+ {
+ delete (*i).second; /* delete the pointer NdiscCache::Entry */
+ }
+
+ m_ndCache.erase (m_ndCache.begin (), m_ndCache.end ());
+}
+
+void NdiscCache::SetUnresQlen (uint32_t unresQlen)
+{
+ NS_LOG_FUNCTION (this << unresQlen);
+ m_unresQlen = unresQlen;
+}
+
+uint32_t NdiscCache::GetUnresQlen ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_unresQlen;
+}
+
+NdiscCache::Entry::Entry (NdiscCache* nd)
+ : m_ndCache (nd),
+ m_waiting (),
+ m_router (false),
+ m_nsRetransmit (0)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+void NdiscCache::Entry::SetRouter (bool router)
+{
+ NS_LOG_FUNCTION (this << router);
+ m_router = router;
+}
+
+bool NdiscCache::Entry::IsRouter () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_router;
+}
+
+void NdiscCache::Entry::AddWaitingPacket (Ptr<Packet> p)
+{
+ NS_LOG_FUNCTION (this << p);
+
+ if (m_waiting.size () >= m_ndCache->GetUnresQlen ())
+ {
+ /* we store only m_unresQlen packet => first packet in first packet remove */
+ /* XXX report packet as 'dropped' */
+ m_waiting.remove (0);
+ }
+ m_waiting.push_back (p);
+}
+
+void NdiscCache::Entry::ClearWaitingPacket ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ /* XXX report packets as 'dropped' */
+ m_waiting.clear ();
+}
+
+void NdiscCache::Entry::FunctionReachableTimeout ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ this->MarkStale ();
+}
+
+void NdiscCache::Entry::FunctionRetransmitTimeout ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ Ptr<Icmpv6L4Protocol> icmpv6 = m_ndCache->GetDevice ()->GetNode ()->GetObject<Ipv6L3Protocol> ()->GetIcmpv6 ();
+ Ipv6Address addr;
+
+ /* determine source address */
+ if (m_ipv6Address.IsLinkLocal ())
+ {
+ addr = m_ndCache->GetInterface ()->GetLinkLocalAddress ().GetAddress ();;
+ }
+ else if (!m_ipv6Address.IsAny ())
+ {
+ addr = m_ndCache->GetInterface ()->GetAddressMatchingDestination (m_ipv6Address).GetAddress ();
+
+ if (addr.IsAny ()) /* maybe address has expired */
+ {
+ /* delete the entry */
+ m_ndCache->Remove (this);
+ return;
+ }
+ }
+
+ if (GetNSRetransmit () < icmpv6->MAX_MULTICAST_SOLICIT)
+ {
+ IncNSRetransmit ();
+
+ icmpv6->SendNS (addr, Ipv6Address::MakeSolicitedAddress (m_ipv6Address), m_ipv6Address, m_ndCache->GetDevice ()->GetAddress ());
+ /* arm the timer again */
+ StartRetransmitTimer ();
+ }
+ else
+ {
+ Ptr<Packet> malformedPacket = m_waiting.front ();
+ if (malformedPacket == 0)
+ {
+ malformedPacket = Create<Packet> ();
+ }
+
+ icmpv6->SendErrorDestinationUnreachable (malformedPacket, addr, Icmpv6Header::ICMPV6_ADDR_UNREACHABLE);
+
+ /* delete the entry */
+ m_ndCache->Remove (this);
+ }
+}
+
+void NdiscCache::Entry::FunctionDelayTimeout ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ Ptr<Ipv6L3Protocol> ipv6 = m_ndCache->GetDevice ()->GetNode ()->GetObject<Ipv6L3Protocol> ();
+ Ptr<Icmpv6L4Protocol> icmpv6 = ipv6->GetIcmpv6 ();
+ Ipv6Address addr;
+
+ this->MarkProbe ();
+
+ if (m_ipv6Address.IsLinkLocal ())
+ {
+ addr = m_ndCache->GetInterface ()->GetLinkLocalAddress ().GetAddress ();
+ }
+ else if (!m_ipv6Address.IsAny ())
+ {
+ addr = m_ndCache->GetInterface ()->GetAddressMatchingDestination (m_ipv6Address).GetAddress ();
+ if (addr.IsAny ()) /* maybe address has expired */
+ {
+ /* delete the entry */
+ m_ndCache->Remove (this);
+ return;
+ }
+ }
+ else
+ {
+ /* should not happen */
+ return;
+ }
+
+ Ptr<Packet> p = icmpv6->ForgeNS (addr, m_ipv6Address, m_ipv6Address, m_ndCache->GetDevice ()->GetAddress ());
+ m_ndCache->GetDevice ()->Send (p, this->GetMacAddress (), Ipv6L3Protocol::PROT_NUMBER);
+
+ ResetNSRetransmit ();
+ IncNSRetransmit ();
+ StartProbeTimer ();
+}
+
+void NdiscCache::Entry::FunctionProbeTimeout ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ Ptr<Ipv6L3Protocol> ipv6 = m_ndCache->GetDevice ()->GetNode ()->GetObject<Ipv6L3Protocol> ();
+ Ptr<Icmpv6L4Protocol> icmpv6 = ipv6->GetIcmpv6 ();
+
+ if (GetNSRetransmit () < icmpv6->MAX_UNICAST_SOLICIT)
+ {
+ Ipv6Address addr;
+
+ if (m_ipv6Address.IsLinkLocal ())
+ {
+ addr = m_ndCache->GetInterface ()->GetLinkLocalAddress ().GetAddress ();
+ }
+ else if (!m_ipv6Address.IsAny ())
+ {
+ addr = m_ndCache->GetInterface ()->GetAddressMatchingDestination (m_ipv6Address).GetAddress ();
+ if (addr.IsAny ()) /* maybe address has expired */
+ {
+ /* delete the entry */
+ m_ndCache->Remove (this);
+ return;
+ }
+ }
+ else
+ {
+ /* should not happen */
+ return;
+ }
+
+ IncNSRetransmit ();
+ /* icmpv6->SendNS (m_ndCache->GetInterface ()->GetLinkLocalAddress (), m_ipv6Address, m_ipv6Address, m_ndCache->GetDevice ()->GetAddress ()); */
+ Ptr<Packet> p = icmpv6->ForgeNS (addr, m_ipv6Address, m_ipv6Address, m_ndCache->GetDevice ()->GetAddress ());
+ m_ndCache->GetDevice ()->Send (p, this->GetMacAddress (), Ipv6L3Protocol::PROT_NUMBER);
+
+ /* arm the timer again */
+ StartProbeTimer ();
+ }
+ else
+ {
+ /* delete the entry */
+ m_ndCache->Remove (this);
+ }
+}
+
+void NdiscCache::Entry::SetIpv6Address (Ipv6Address ipv6Address)
+{
+ NS_LOG_FUNCTION (this << ipv6Address);
+ m_ipv6Address = ipv6Address;
+}
+
+uint8_t NdiscCache::Entry::GetNSRetransmit () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_nsRetransmit;
+}
+
+void NdiscCache::Entry::IncNSRetransmit ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_nsRetransmit++;
+}
+
+void NdiscCache::Entry::ResetNSRetransmit ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_nsRetransmit = 0;
+}
+
+Time NdiscCache::Entry::GetLastReachabilityConfirmation () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_lastReachabilityConfirmation;
+}
+
+void NdiscCache::Entry::UpdateLastReachabilityconfirmation ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+void NdiscCache::Entry::StartReachableTimer ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_reachableTimer.SetFunction (&NdiscCache::Entry::FunctionReachableTimeout, this);
+ m_reachableTimer.SetDelay (MilliSeconds (Icmpv6L4Protocol::REACHABLE_TIME));
+ m_reachableTimer.Schedule ();
+}
+
+void NdiscCache::Entry::StopReachableTimer ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_reachableTimer.Cancel ();
+}
+
+void NdiscCache::Entry::StartProbeTimer ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_probeTimer.SetFunction (&NdiscCache::Entry::FunctionProbeTimeout, this);
+ m_probeTimer.SetDelay (MilliSeconds (Icmpv6L4Protocol::RETRANS_TIMER));
+ m_probeTimer.Schedule ();
+}
+
+void NdiscCache::Entry::StopProbeTimer ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_probeTimer.Cancel ();
+ ResetNSRetransmit ();
+}
+
+
+void NdiscCache::Entry::StartDelayTimer ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_delayTimer.SetFunction (&NdiscCache::Entry::FunctionDelayTimeout, this);
+ m_delayTimer.SetDelay (Seconds (Icmpv6L4Protocol::DELAY_FIRST_PROBE_TIME));
+ m_delayTimer.Schedule ();
+}
+
+void NdiscCache::Entry::StopDelayTimer ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_delayTimer.Cancel ();
+ ResetNSRetransmit ();
+}
+
+void NdiscCache::Entry::StartRetransmitTimer ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_retransTimer.SetFunction (&NdiscCache::Entry::FunctionRetransmitTimeout, this);
+ m_retransTimer.SetDelay (MilliSeconds (Icmpv6L4Protocol::RETRANS_TIMER));
+ m_retransTimer.Schedule ();
+}
+
+void NdiscCache::Entry::StopRetransmitTimer ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_retransTimer.Cancel ();
+ ResetNSRetransmit ();
+}
+
+void NdiscCache::Entry::MarkIncomplete (Ptr<Packet> p)
+{
+ NS_LOG_FUNCTION (this << p);
+ m_state = INCOMPLETE;
+
+ if (p)
+ {
+ m_waiting.push_back (p);
+ }
+}
+
+std::list<Ptr<Packet> > NdiscCache::Entry::MarkReachable (Address mac)
+{
+ NS_LOG_FUNCTION (this << mac);
+ m_state = REACHABLE;
+ m_macAddress = mac;
+ return m_waiting;
+}
+
+void NdiscCache::Entry::MarkProbe ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_state = PROBE;
+}
+
+void NdiscCache::Entry::MarkStale ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_state = STALE;
+}
+
+void NdiscCache::Entry::MarkReachable ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_state = REACHABLE;
+}
+
+std::list<Ptr<Packet> > NdiscCache::Entry::MarkStale (Address mac)
+{
+ NS_LOG_FUNCTION (this << mac);
+ m_state = STALE;
+ m_macAddress = mac;
+ return m_waiting;
+}
+
+void NdiscCache::Entry::MarkDelay ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_state = DELAY;
+}
+
+bool NdiscCache::Entry::IsStale () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return (m_state == STALE);
+}
+
+bool NdiscCache::Entry::IsReachable () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return (m_state == REACHABLE);
+}
+
+bool NdiscCache::Entry::IsDelay () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return (m_state == DELAY);
+}
+
+bool NdiscCache::Entry::IsIncomplete () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return (m_state == INCOMPLETE);
+}
+
+bool NdiscCache::Entry::IsProbe () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return (m_state == PROBE);
+}
+
+Address NdiscCache::Entry::GetMacAddress () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_macAddress;
+}
+
+void NdiscCache::Entry::SetMacAddress (Address mac)
+{
+ NS_LOG_FUNCTION (this << mac);
+ m_macAddress = mac;
+}
+
+} /* namespace ns3 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ndisc-cache.h Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,449 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#ifndef NDISC_CACHE_H
+#define NDISC_CACHE_H
+
+#include <stdint.h>
+
+#include <list>
+
+#include "ns3/packet.h"
+#include "ns3/nstime.h"
+#include "ns3/net-device.h"
+#include "ns3/ipv6-address.h"
+#include "ns3/ptr.h"
+#include "ns3/timer.h"
+#include "ns3/sgi-hashmap.h"
+
+#include "ipv6-interface.h"
+
+namespace ns3
+{
+
+class NetDevice;
+class Ipv6Interface;
+
+/**
+ * \class NdiscCache
+ * \brief IPv6 Neighbor Discovery cache.
+ */
+class NdiscCache : public Object
+{
+ public:
+ class Entry;
+
+ /**
+ * \brief Get the type ID
+ * \return type ID
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Default value for unres qlen.
+ */
+ static const uint32_t DEFAULT_UNRES_QLEN = 3;
+
+ /**
+ * \brief Constructor.
+ */
+ NdiscCache ();
+
+ /**
+ * \brief Destructor.
+ */
+ ~NdiscCache ();
+
+ /**
+ * \brief Get the NetDevice associated with this cache.
+ * \return NetDevice
+ */
+ Ptr<NetDevice> GetDevice () const;
+
+ /**
+ * \brief Get the Ipv6Interface associated with this cache.
+ */
+ Ptr<Ipv6Interface> GetInterface () const;
+
+ /**
+ * \brief Lookup in the cache.
+ * \param dst destination address
+ * \return the entry if found, 0 otherwise
+ */
+ NdiscCache::Entry* Lookup (Ipv6Address dst);
+
+ /**
+ * \brief Add an entry.
+ * \param to address to add
+ * \return an new Entry
+ */
+ NdiscCache::Entry* Add (Ipv6Address to);
+
+ /**
+ * \brief Delete an entry.
+ * \param entry pointer to delete from the list.
+ */
+ void Remove (NdiscCache::Entry* entry);
+
+ /**
+ * \brief Flush the cache.
+ */
+ void Flush ();
+
+ /**
+ * \brief Set the max number of waiting packet.
+ * \param unresQlen value to set
+ */
+ void SetUnresQlen (uint32_t unresQlen);
+
+ /**
+ * \brief Get the max number of waiting packet.
+ * \return max number
+ */
+ uint32_t GetUnresQlen ();
+
+ /**
+ * \brief Set the device and interface.
+ * \param device the device
+ * \param interface the IPv6 interface
+ */
+ void SetDevice (Ptr<NetDevice> device, Ptr<Ipv6Interface> interface);
+
+ /**
+ * \class Entry
+ * \brief A record that holds information about an NdiscCache entry.
+ */
+ class Entry
+ {
+ public:
+ /**
+ * \brief Constructor.
+ * \param nd The NdiscCache this entry belongs to.
+ */
+ Entry (NdiscCache* nd);
+
+ /**
+ * \brief Changes the state to this entry to INCOMPLETE.
+ * \param p packet that wait to be sent
+ */
+ void MarkIncomplete (Ptr<Packet> p);
+
+ /**
+ * \brief Changes the state to this entry to REACHABLE.
+ * \param mac MAC address
+ * \return the list of packet waiting
+ */
+ std::list<Ptr<Packet> > MarkReachable (Address mac);
+
+ /**
+ * \brief Changes the state to this entry to PROBE.
+ */
+ void MarkProbe ();
+
+ /**
+ * \brief Changes the state to this entry to STALE.
+ * \param mac L2 address
+ * \return the list of packet waiting
+ */
+ std::list<Ptr<Packet> > MarkStale (Address mac);
+
+ /**
+ * \brief Changes the state to this entry to STALE.
+ */
+ void MarkStale ();
+
+ /**
+ * \brief Changes the state to this entry to REACHABLE.
+ */
+ void MarkReachable ();
+
+ /**
+ * \brief Change the state to this entry to DELAY.
+ */
+ void MarkDelay ();
+
+ /**
+ * \brief Add a packet (or replace old value) in the queue.
+ * \param p packet to add
+ */
+ void AddWaitingPacket (Ptr<Packet> p);
+
+ /**
+ * \brief Clear the waiting packet list.
+ */
+ void ClearWaitingPacket ();
+
+ /**
+ * \brief Is the entry STALE
+ * \return true if the entry is in STALE state, false otherwise
+ */
+ bool IsStale () const;
+
+ /**
+ * \brief Is the entry REACHABLE
+ * \return true if the entry is in REACHABLE state, false otherwise
+ */
+ bool IsReachable () const;
+
+ /**
+ * \brief Is the entry DELAY
+ * \return true if the entry is in DELAY state, false otherwise
+ */
+ bool IsDelay () const;
+
+ /**
+ * \brief Is the entry INCOMPLETE
+ * \return true if the entry is in INCOMPLETE state, false otherwise
+ */
+ bool IsIncomplete () const;
+
+ /**
+ * \brief Is the entry PROBE
+ * \return true if the entry is in PROBE state, false otherwise
+ */
+ bool IsProbe () const;
+
+ /**
+ * \brief Get the MAC address of this entry.
+ * \return the L2 address
+ */
+ Address GetMacAddress () const;
+
+ /**
+ * \brief Set the MAC address of this entry.
+ * \param mac the MAC address to set
+ */
+ void SetMacAddress (Address mac);
+
+ /**
+ * \brief If the entry is a host or a router.
+ * \return true if the node is a router, 0 if it is a host
+ */
+ bool IsRouter () const;
+
+ /**
+ * \brief Set the node type.
+ * \param router true is a router, false means a host
+ */
+ void SetRouter (bool router);
+
+ /**
+ * \brief Get the number of NS retransmit.
+ * \return number of NS that have been retransmit
+ */
+ uint8_t GetNSRetransmit () const;
+
+ /**
+ * \brief Increment NS retransmit.
+ */
+ void IncNSRetransmit ();
+
+ /**
+ * \brief Reset NS retransmit (=0).
+ */
+ void ResetNSRetransmit ();
+
+ /**
+ * \brief Get the time of last reachability confirmation.
+ * \return time
+ */
+ Time GetLastReachabilityConfirmation () const;
+
+ /**
+ * \brief Update the time of last reachability confirmation.
+ */
+ void UpdateLastReachabilityconfirmation ();
+
+ /**
+ * \brief Start the reachable timer.
+ */
+ void StartReachableTimer ();
+
+ /**
+ * \brief Stop the reachable timer.
+ */
+ void StopReachableTimer ();
+
+ /**
+ * \brief Start retransmit timer.
+ */
+ void StartRetransmitTimer ();
+
+ /**
+ * \brief Stop retransmit timer.
+ */
+ void StopRetransmitTimer ();
+
+ /**
+ * \brief Start probe timer.
+ */
+ void StartProbeTimer ();
+
+ /**
+ * \brief Stop probe timer.
+ */
+ void StopProbeTimer ();
+
+ /**
+ * \brief Start delay timer.
+ */
+ void StartDelayTimer ();
+
+ /**
+ * \brief Stop delay timer.
+ */
+ void StopDelayTimer ();
+
+ /**
+ * \brief Function called when reachable timer timeout.
+ */
+ void FunctionReachableTimeout ();
+
+ /**
+ * \brief Function called when retransmit timer timeout.
+ * It verify that the NS retransmit has reached the max so discard the entry
+ * otherwise it retransmit a NS.
+ */
+ void FunctionRetransmitTimeout ();
+
+ /**
+ * \brief Function called when probe timer timeout.
+ */
+ void FunctionProbeTimeout ();
+
+ /**
+ * \brief Function called when delay timer timeout.
+ */
+ void FunctionDelayTimeout ();
+
+ /**
+ * \brief Set the IPv6 address.
+ * \param ipv6Address IPv6 address
+ */
+ void SetIpv6Address (Ipv6Address ipv6Address);
+
+ private:
+ /**
+ * \brief The IPv6 address.
+ */
+ Ipv6Address m_ipv6Address;
+
+ /**
+ * \brief The Entry state enumeration.
+ */
+ enum NdiscCacheEntryState_e
+ {
+ INCOMPLETE, /**< No mapping between IPv6 and L2 addresses */
+ REACHABLE, /**< Mapping exists between IPv6 and L2 addresses */
+ STALE, /**< Mapping is stale */
+ DELAY, /**< Try to wait contact from remote host */
+ PROBE /**< Try to contact IPv6 address to know again its L2 address */
+ };
+
+ /**
+ * \brief The state of the entry.
+ */
+ NdiscCacheEntryState_e m_state;
+
+ /**
+ * \brief the NdiscCache associated.
+ */
+ NdiscCache* m_ndCache;
+
+ /**
+ * \brief The MAC address.
+ */
+ Address m_macAddress;
+
+ /**
+ * \brief The list of packet waiting.
+ */
+ std::list<Ptr<Packet> > m_waiting;
+
+ /**
+ * \brief Type of node (router or host).
+ */
+ bool m_router;
+
+ /**
+ * \brief Reachable timer (used for NUD in REACHABLE state).
+ */
+ Timer m_reachableTimer;
+
+ /**
+ * \brief Retransmission timer (used for NUD in INCOMPLETE state).
+ */
+ Timer m_retransTimer;
+
+ /**
+ * \brief Probe timer (used for NUD in PROBE state).
+ */
+ Timer m_probeTimer;
+
+ /**
+ * \brief Delay timer (used for NUD when in DELAY state).
+ */
+ Timer m_delayTimer;
+
+ /**
+ * \brief Last time we see a reachability confirmation.
+ */
+ Time m_lastReachabilityConfirmation;
+
+ /**
+ * \brief Number of NS retransmission.
+ */
+ uint8_t m_nsRetransmit;
+ };
+
+ private:
+ typedef sgi::hash_map<Ipv6Address, NdiscCache::Entry *, Ipv6AddressHash> Cache;
+ typedef sgi::hash_map<Ipv6Address, NdiscCache::Entry *, Ipv6AddressHash>::iterator CacheI;
+
+ /**
+ * \brief Dispose this object.
+ */
+ void DoDispose ();
+
+ /**
+ * \brief The NetDevice.
+ */
+ Ptr<NetDevice> m_device;
+
+ /**
+ * \brief the interface.
+ */
+ Ptr<Ipv6Interface> m_interface;
+
+ /**
+ * A list of Entry.
+ */
+ Cache m_ndCache;
+
+ /**
+ * \brief Max number of packet stored in m_waiting.
+ */
+ uint32_t m_unresQlen;
+};
+
+} /* namespace ns3 */
+
+#endif /* NDISC_CACHE_H */
+
--- a/src/internet-stack/nsc-tcp-l4-protocol.cc Tue Aug 25 20:12:53 2009 +0400
+++ b/src/internet-stack/nsc-tcp-l4-protocol.cc Wed Aug 26 15:29:03 2009 +0400
@@ -32,8 +32,10 @@
#include "ipv4-end-point.h"
#include "ipv4-l3-protocol.h"
#include "nsc-tcp-l4-protocol.h"
+#include "nsc-tcp-socket-impl.h"
#include "nsc-sysctl.h"
#include "nsc-tcp-socket-factory-impl.h"
+#include "sim_interface.h"
#include "tcp-typedefs.h"
@@ -54,13 +56,39 @@
/* see http://www.iana.org/assignments/protocol-numbers */
const uint8_t NscTcpL4Protocol::PROT_NUMBER = 6;
-ObjectFactory
-NscTcpL4Protocol::GetDefaultRttEstimatorFactory (void)
+class NscInterfaceImpl : public ISendCallback, public IInterruptCallback
{
- ObjectFactory factory;
- factory.SetTypeId (RttMeanDeviation::GetTypeId ());
- return factory;
+public:
+ NscInterfaceImpl (Ptr<NscTcpL4Protocol> prot);
+private:
+ virtual void send_callback(const void *data, int datalen);
+ virtual void wakeup();
+ virtual void gettime(unsigned int *, unsigned int *);
+private:
+ Ptr<NscTcpL4Protocol> m_prot;
+};
+
+NscInterfaceImpl::NscInterfaceImpl (Ptr<NscTcpL4Protocol> prot)
+ : m_prot (prot)
+{}
+
+void
+NscInterfaceImpl::send_callback(const void *data, int datalen)
+{
+ m_prot->send_callback (data, datalen);
}
+void
+NscInterfaceImpl::wakeup()
+{
+ m_prot->wakeup ();
+}
+void
+NscInterfaceImpl::gettime(unsigned int *sec, unsigned int *usec)
+{
+ m_prot->gettime (sec,usec);
+}
+
+
TypeId
NscTcpL4Protocol::GetTypeId (void)
@@ -68,11 +96,6 @@
static TypeId tid = TypeId ("ns3::NscTcpL4Protocol")
.SetParent<Ipv4L4Protocol> ()
.AddConstructor<NscTcpL4Protocol>()
- .AddAttribute ("RttEstimatorFactory",
- "How RttEstimator objects are created.",
- ObjectFactoryValue (GetDefaultRttEstimatorFactory ()),
- MakeObjectFactoryAccessor (&NscTcpL4Protocol::m_rttFactory),
- MakeObjectFactoryChecker ())
.AddAttribute ("SocketList", "The list of sockets associated to this protocol.",
ObjectVectorValue (),
MakeObjectVectorAccessor (&NscTcpL4Protocol::m_sockets),
@@ -95,6 +118,7 @@
NscTcpL4Protocol::NscTcpL4Protocol ()
: m_endPoints (new Ipv4EndPointDemux ()),
m_nscStack (0),
+ m_nscInterface (new NscInterfaceImpl (this)),
m_softTimer (Timer::CANCEL_ON_DESTROY)
{
m_dlopenHandle = NULL;
@@ -139,7 +163,7 @@
FCreateStack create = (FCreateStack)dlsym(m_dlopenHandle, "nsc_create_stack");
NS_ASSERT(create);
- m_nscStack = create(this, this, external_rand);
+ m_nscStack = create(m_nscInterface, m_nscInterface, external_rand);
int hzval = m_nscStack->get_hz();
NS_ASSERT(hzval > 0);
@@ -212,6 +236,8 @@
m_endPoints = 0;
}
m_node = 0;
+ delete m_nscInterface;
+ m_nscInterface = 0;
Ipv4L4Protocol::DoDispose ();
}
@@ -220,11 +246,9 @@
{
NS_LOG_FUNCTION (this);
- Ptr<RttEstimator> rtt = m_rttFactory.Create<RttEstimator> ();
Ptr<NscTcpSocketImpl> socket = CreateObject<NscTcpSocketImpl> ();
socket->SetNode (m_node);
socket->SetTcp (this);
- socket->SetRtt (rtt);
m_sockets.push_back (socket);
return socket;
}
--- a/src/internet-stack/nsc-tcp-l4-protocol.h Tue Aug 25 20:12:53 2009 +0400
+++ b/src/internet-stack/nsc-tcp-l4-protocol.h Wed Aug 26 15:29:03 2009 +0400
@@ -23,27 +23,27 @@
#include "ns3/ipv4-address.h"
#include "ns3/ptr.h"
#include "ns3/object-factory.h"
-#include "ipv4-end-point-demux.h"
+#include "ns3/timer.h"
#include "ipv4-l4-protocol.h"
-#include "ipv4-interface.h"
-#include "tcp-header.h"
-
-#include "ns3/timer.h"
-#include "sim_interface.h"
-#include "nsc-tcp-socket-impl.h"
+struct INetStack;
namespace ns3 {
class Node;
class Socket;
-class TcpHeader;
+class Ipv4EndPointDemux;
+class Ipv4Interface;
+class NscTcpSocketImpl;
+class Ipv4EndPoint;
+class NscInterfaceImpl;
+
/**
* \ingroup nsctcp
*
* \brief Nsc wrapper glue, to interface with the Ipv4 protocol underneath.
*/
-class NscTcpL4Protocol : public Ipv4L4Protocol, ISendCallback, IInterruptCallback {
+class NscTcpL4Protocol : public Ipv4L4Protocol {
public:
static const uint8_t PROT_NUMBER;
static TypeId GetTypeId (void);
@@ -86,6 +86,10 @@
Ipv4Address const &destination,
Ptr<Ipv4Interface> incomingInterface);
+protected:
+ virtual void DoDispose (void);
+ virtual void NotifyNewAggregate ();
+private:
// NSC callbacks.
// NSC invokes these hooks to interact with the simulator.
// In any case, these methods are only to be called by NSC.
@@ -93,29 +97,23 @@
// send_callback is invoked by NSCs 'ethernet driver' to re-inject
// a packet (i.e. an octet soup consisting of an IP Header, TCP Header
// and user payload, if any), into ns-3.
- virtual void send_callback(const void *data, int datalen);
+ void send_callback(const void *data, int datalen);
// This is called by the NSC stack whenever something of interest
// has happened, e.g. when data arrives on a socket, a listen socket
// has a new connection pending, etc.
- virtual void wakeup();
+ void wakeup();
// This is called by the Linux stack RNG initialization.
// Its also used by the cradle code to add a timestamp to
// printk/printf/debug output.
- virtual void gettime(unsigned int *, unsigned int *);
-
-protected:
- virtual void DoDispose (void);
- virtual void NotifyNewAggregate ();
-private:
+ void gettime(unsigned int *sec, unsigned int *usec);
+ void AddInterface (void);
+ void SoftInterrupt (void);
+ friend class NscInterfaceImpl;
+ friend class NscTcpSocketImpl;
Ptr<Node> m_node;
Ipv4EndPointDemux *m_endPoints;
- ObjectFactory m_rttFactory;
-private:
- void AddInterface (void);
- void SoftInterrupt (void);
- static ObjectFactory GetDefaultRttEstimatorFactory (void);
- friend class NscTcpSocketImpl;
INetStack* m_nscStack;
+ NscInterfaceImpl *m_nscInterface;
void *m_dlopenHandle;
std::string m_nscLibrary;
Timer m_softTimer;
--- a/src/internet-stack/nsc-tcp-socket-impl.cc Tue Aug 25 20:12:53 2009 +0400
+++ b/src/internet-stack/nsc-tcp-socket-impl.cc Wed Aug 26 15:29:03 2009 +0400
@@ -74,7 +74,6 @@
m_state (CLOSED),
m_closeOnEmpty (false),
m_txBufferSize (0),
- m_rtt (0),
m_lastMeasuredRtt (Seconds(0.0))
{
NS_LOG_FUNCTION (this);
@@ -104,7 +103,6 @@
m_cWnd (sock.m_cWnd),
m_ssThresh (sock.m_ssThresh),
m_initialCWnd (sock.m_initialCWnd),
- m_rtt (0),
m_lastMeasuredRtt (Seconds(0.0)),
m_cnTimeout (sock.m_cnTimeout),
m_cnCount (sock.m_cnCount),
@@ -119,11 +117,6 @@
{
m_txBuffer = sock.m_txBuffer;
}
- //copy the rtt if necessary
- if (sock.m_rtt)
- {
- m_rtt = sock.m_rtt->Copy();
- }
//can't "copy" the endpoint just yes, must do this when we know the peer info
//too; this is in SYN_ACK_TX
}
@@ -165,11 +158,6 @@
m_nscTcpSocket = tcp->m_nscStack->new_tcp_socket();
m_tcp = tcp;
}
-void
-NscTcpSocketImpl::SetRtt (Ptr<RttEstimator> rtt)
-{
- m_rtt = rtt;
-}
enum Socket::SocketErrno
--- a/src/internet-stack/nsc-tcp-socket-impl.h Tue Aug 25 20:12:53 2009 +0400
+++ b/src/internet-stack/nsc-tcp-socket-impl.h Wed Aug 26 15:29:03 2009 +0400
@@ -30,7 +30,8 @@
#include "tcp-typedefs.h"
#include "pending-data.h"
#include "sequence-number.h"
-#include "rtt-estimator.h"
+
+struct INetStreamSocket;
namespace ns3 {
@@ -63,7 +64,6 @@
void SetNode (Ptr<Node> node);
void SetTcp (Ptr<NscTcpL4Protocol> tcp);
- void SetRtt (Ptr<RttEstimator> rtt);
virtual enum SocketErrno GetErrno (void) const;
virtual Ptr<Node> GetNode (void) const;
@@ -158,7 +158,6 @@
uint32_t m_initialCWnd; //Initial cWnd value
// Round trip time estimation
- Ptr<RttEstimator> m_rtt;
Time m_lastMeasuredRtt;
// Timer-related members
--- a/src/internet-stack/sgi-hashmap.h Tue Aug 25 20:12:53 2009 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/* This code snippet was ripped out of the gcc
- * documentation and slightly modified to work
- * with gcc 4.x
- */
-#ifndef SGI_HASHMAP_H
-#define SGI_HASHMAP_H
-
-/* To use gcc extensions.
- */
-#ifdef __GNUC__
- #if __GNUC__ < 3
- #include <hash_map.h>
-namespace sgi { using ::hash_map; }; // inherit globals
- #else
- #if __GNUC__ < 4
- #include <ext/hash_map>
- #if __GNUC_MINOR__ == 0
-namespace sgi = std; // GCC 3.0
- #else
-namespace sgi = ::__gnu_cxx; // GCC 3.1 and later
- #endif
- #else // gcc 4.x and later
- #if __GNUC_MINOR__ < 3
- #include <ext/hash_map>
-namespace sgi = ::__gnu_cxx;
- #else
-#undef __DEPRECATED
- #include <backward/hash_map>
-namespace sgi = ::__gnu_cxx;
- #endif
- #endif
- #endif
-#else // ... there are other compilers, right?
-namespace sgi = std;
-#endif
-
-
-#endif /* SGI_HASHMAP_H */
--- a/src/internet-stack/tcp-l4-protocol.cc Tue Aug 25 20:12:53 2009 +0400
+++ b/src/internet-stack/tcp-l4-protocol.cc Wed Aug 26 15:29:03 2009 +0400
@@ -34,7 +34,8 @@
#include "ipv4-end-point.h"
#include "ipv4-l3-protocol.h"
#include "tcp-socket-factory-impl.h"
-
+#include "tcp-socket-impl.h"
+#include "rtt-estimator.h"
#include "tcp-typedefs.h"
#include <vector>
@@ -558,17 +559,18 @@
}
void
-TcpL4Protocol::SendPacket (Ptr<Packet> packet, TcpHeader outgoingHeader,
+TcpL4Protocol::SendPacket (Ptr<Packet> packet, const TcpHeader &outgoing,
Ipv4Address saddr, Ipv4Address daddr)
{
NS_LOG_LOGIC("TcpL4Protocol " << this
- << " sending seq " << outgoingHeader.GetSequenceNumber()
- << " ack " << outgoingHeader.GetAckNumber()
- << " flags " << std::hex << (int)outgoingHeader.GetFlags() << std::dec
+ << " sending seq " << outgoing.GetSequenceNumber()
+ << " ack " << outgoing.GetAckNumber()
+ << " flags " << std::hex << (int)outgoing.GetFlags() << std::dec
<< " data size " << packet->GetSize());
NS_LOG_FUNCTION (this << packet << saddr << daddr);
// XXX outgoingHeader cannot be logged
+ TcpHeader outgoingHeader = outgoing;
outgoingHeader.SetLength (5); //header length in units of 32bit words
/* outgoingHeader.SetUrgentPointer (0); //XXX */
if(Node::ChecksumEnabled ())
--- a/src/internet-stack/tcp-l4-protocol.h Tue Aug 25 20:12:53 2009 +0400
+++ b/src/internet-stack/tcp-l4-protocol.h Wed Aug 26 15:29:03 2009 +0400
@@ -27,19 +27,17 @@
#include "ns3/ipv4-address.h"
#include "ns3/ptr.h"
#include "ns3/object-factory.h"
-#include "ipv4-end-point-demux.h"
#include "ipv4-l4-protocol.h"
-#include "ipv4-interface.h"
-
-#include "tcp-socket-impl.h"
-#include "tcp-header.h"
-#include "tcp-typedefs.h"
namespace ns3 {
class Node;
class Socket;
class TcpHeader;
+class Ipv4EndPointDemux;
+class Ipv4Interface;
+class TcpSocketImpl;
+class Ipv4EndPoint;
/**
* \ingroup tcp
@@ -120,7 +118,7 @@
ObjectFactory m_rttFactory;
private:
friend class TcpSocketImpl;
- void SendPacket (Ptr<Packet>, TcpHeader,
+ void SendPacket (Ptr<Packet>, const TcpHeader &,
Ipv4Address, Ipv4Address);
static ObjectFactory GetDefaultRttEstimatorFactory (void);
--- a/src/internet-stack/tcp-socket-impl.cc Tue Aug 25 20:12:53 2009 +0400
+++ b/src/internet-stack/tcp-socket-impl.cc Wed Aug 26 15:29:03 2009 +0400
@@ -36,6 +36,8 @@
#include "tcp-socket-impl.h"
#include "tcp-l4-protocol.h"
#include "ipv4-end-point.h"
+#include "tcp-header.h"
+#include "rtt-estimator.h"
#include <algorithm>
--- a/src/internet-stack/tcp-test.cc Tue Aug 25 20:12:53 2009 +0400
+++ b/src/internet-stack/tcp-test.cc Wed Aug 26 15:29:03 2009 +0400
@@ -31,17 +31,18 @@
#include "ns3/simple-net-device.h"
#include "ns3/drop-tail-queue.h"
#include "ns3/config.h"
+#include "ns3/ipv4-static-routing.h"
+#include "ns3/ipv4-list-routing.h"
+#include "ns3/node.h"
+#include "ns3/inet-socket-address.h"
+#include "ns3/uinteger.h"
+
#include "ipv4-end-point.h"
#include "arp-l3-protocol.h"
#include "ipv4-l3-protocol.h"
#include "icmpv4-l4-protocol.h"
#include "udp-l4-protocol.h"
#include "tcp-l4-protocol.h"
-#include "ns3/ipv4-static-routing.h"
-#include "ns3/ipv4-list-routing.h"
-
-#include "ns3/node.h"
-#include "ns3/inet-socket-address.h"
#include <string>
--- a/src/internet-stack/udp-l4-protocol.h Tue Aug 25 20:12:53 2009 +0400
+++ b/src/internet-stack/udp-l4-protocol.h Wed Aug 26 15:29:03 2009 +0400
@@ -26,7 +26,6 @@
#include "ns3/packet.h"
#include "ns3/ipv4-address.h"
#include "ns3/ptr.h"
-#include "ipv4-end-point-demux.h"
#include "ipv4-l4-protocol.h"
namespace ns3 {
@@ -34,6 +33,8 @@
class Node;
class Socket;
class Ipv4Route;
+class Ipv4EndPointDemux;
+class Ipv4EndPoint;
/**
* \ingroup udp
* \brief Implementation of the UDP protocol
--- a/src/internet-stack/wscript Tue Aug 25 20:12:53 2009 +0400
+++ b/src/internet-stack/wscript Wed Aug 26 15:29:03 2009 +0400
@@ -99,6 +99,18 @@
'icmpv4.cc',
'icmpv4-l4-protocol.cc',
'loopback-net-device.cc',
+ 'ipv6-interface.cc',
+ 'ndisc-cache.cc',
+ 'icmpv6-header.cc',
+ 'ipv6-l3-protocol.cc',
+ 'ipv6-end-point.cc',
+ 'ipv6-end-point-demux.cc',
+ 'ipv6-l4-protocol.cc',
+ 'ipv6-raw-socket-factory-impl.cc',
+ 'ipv6-raw-socket-impl.cc',
+ 'ipv6-autoconfigured-prefix.cc',
+ 'icmpv6-l4-protocol.cc',
+ 'ipv6-test.cc'
]
headers = bld.new_task_gen('ns3header')
@@ -108,11 +120,20 @@
'tcp-header.h',
'sequence-number.h',
'icmpv4.h',
- ]
+ 'icmpv6-header.h',
+ 'ipv4-l3-protocol.h',
+ 'arp-l3-protocol.h',
+ 'udp-l4-protocol.h',
+ 'tcp-l4-protocol.h',
+ 'icmpv4-l4-protocol.h',
+ 'ipv4-l4-protocol.h',
+ 'arp-cache.h',
+ ]
if bld.env['NSC_ENABLED']:
obj.source.append ('nsc-tcp-socket-impl.cc')
obj.source.append ('nsc-tcp-l4-protocol.cc')
obj.source.append ('nsc-tcp-socket-factory-impl.cc')
obj.source.append ('nsc-sysctl.cc')
+ headers.source.append('nsc-tcp-l4-protocol.h')
obj.uselib = 'DL'
--- a/src/node/inet6-socket-address.cc Tue Aug 25 20:12:53 2009 +0400
+++ b/src/node/inet6-socket-address.cc Wed Aug 26 15:29:03 2009 +0400
@@ -24,31 +24,31 @@
namespace ns3 {
Inet6SocketAddress::Inet6SocketAddress (Ipv6Address ipv6, uint16_t port)
-: m_ipv6(ipv6),
+ : m_ipv6(ipv6),
m_port(port)
{
}
Inet6SocketAddress::Inet6SocketAddress (Ipv6Address ipv6)
-: m_ipv6(ipv6),
+ : m_ipv6(ipv6),
m_port(0)
{
}
- Inet6SocketAddress::Inet6SocketAddress (const char* ipv6, uint16_t port)
-: m_ipv6(Ipv6Address(ipv6)),
+Inet6SocketAddress::Inet6SocketAddress (const char* ipv6, uint16_t port)
+ : m_ipv6(Ipv6Address(ipv6)),
m_port(port)
{
}
- Inet6SocketAddress::Inet6SocketAddress (const char* ipv6)
-: m_ipv6(Ipv6Address(ipv6)),
+Inet6SocketAddress::Inet6SocketAddress (const char* ipv6)
+ : m_ipv6(Ipv6Address(ipv6)),
m_port(0)
{
}
- Inet6SocketAddress::Inet6SocketAddress (uint16_t port)
-: m_ipv6(Ipv6Address::GetAny()),
+Inet6SocketAddress::Inet6SocketAddress (uint16_t port)
+ : m_ipv6(Ipv6Address::GetAny()),
m_port(port)
{
}
--- a/src/node/ipv4-address.cc Tue Aug 25 20:12:53 2009 +0400
+++ b/src/node/ipv4-address.cc Wed Aug 26 15:29:03 2009 +0400
@@ -18,6 +18,7 @@
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
+#include <stdlib.h>
#include "ns3/log.h"
#include "ipv4-address.h"
#include "ns3/assert.h"
@@ -28,26 +29,29 @@
#define ASCII_DOT (0x2e)
#define ASCII_ZERO (0x30)
+#define ASCII_SLASH (0x2f)
static uint32_t
AsciiToIpv4Host (char const *address)
{
uint32_t host = 0;
- while (true) {
- uint8_t byte = 0;
- while (*address != ASCII_DOT &&
- *address != 0) {
- byte *= 10;
- byte += *address - ASCII_ZERO;
+ while (true)
+ {
+ uint8_t byte = 0;
+ while (*address != ASCII_DOT && *address != 0)
+ {
+ byte *= 10;
+ byte += *address - ASCII_ZERO;
+ address++;
+ }
+ host <<= 8;
+ host |= byte;
+ if (*address == 0)
+ {
+ break;
+ }
address++;
}
- host <<= 8;
- host |= byte;
- if (*address == 0) {
- break;
- }
- address++;
- }
return host;
}
@@ -63,9 +67,18 @@
Ipv4Mask::Ipv4Mask (uint32_t mask)
: m_mask (mask)
{}
+
Ipv4Mask::Ipv4Mask (char const *mask)
{
- m_mask = AsciiToIpv4Host (mask);
+ if (*mask == ASCII_SLASH)
+ {
+ m_mask = static_cast<uint32_t> (atoi (++mask));
+ NS_ASSERT (m_mask <= 32);
+ }
+ else
+ {
+ m_mask = AsciiToIpv4Host (mask);
+ }
}
bool
@@ -133,6 +146,20 @@
return ones;
}
+uint16_t
+Ipv4Mask::GetPrefixLength (void) const
+{
+ uint16_t tmp = 0;
+ uint32_t mask = m_mask;
+ while (mask != 0 )
+ {
+ mask = mask << 1;
+ tmp++;
+ }
+ return tmp;
+}
+
+
Ipv4Address::Ipv4Address ()
: m_address (0x66666666)
{}
--- a/src/node/ipv4-address.h Tue Aug 25 20:12:53 2009 +0400
+++ b/src/node/ipv4-address.h Wed Aug 26 15:29:03 2009 +0400
@@ -198,11 +198,26 @@
* \ingroup address
*
* \brief a class to represent an Ipv4 address mask
+ *
+ * The constructor takes arguments according to a few formats.
+ * Ipv4Mask ("255.255.255.255"), Ipv4Mask ("/32"), and Ipv4Mask (0xffffffff)
+ * are all equivalent.
*/
class Ipv4Mask {
public:
+ /**
+ * Will initialize to a garbage value (0x66666666)
+ */
Ipv4Mask ();
+ /**
+ * param mask bitwise integer representation of the mask
+ *
+ * For example, the integer input 0xffffff00 yields a 24-bit mask
+ */
Ipv4Mask (uint32_t mask);
+ /**
+ * \param mask String constant either in "255.255.255.0" or "/24" format
+ */
Ipv4Mask (char const *mask);
/**
* \param a first address to compare
@@ -238,6 +253,10 @@
*/
void Print (std::ostream &os) const;
/**
+ * \return the prefix length of mask (the yy in x.x.x.x/yy notation)
+ */
+ uint16_t GetPrefixLength (void) const;
+ /**
* \return the 255.0.0.0 mask corresponding to a typical loopback address
*/
static Ipv4Mask GetLoopback (void);
--- a/src/node/ipv6-address.cc Tue Aug 25 20:12:53 2009 +0400
+++ b/src/node/ipv6-address.cc Wed Aug 26 15:29:03 2009 +0400
@@ -74,13 +74,13 @@
a += (k[0] +((ub4)k[1]<<8) +((ub4)k[2]<<16) +((ub4)k[3]<<24));
b += (k[4] +((ub4)k[5]<<8) +((ub4)k[6]<<16) +((ub4)k[7]<<24));
c += (k[8] +((ub4)k[9]<<8) +((ub4)k[10]<<16)+((ub4)k[11]<<24));
- mix(a,b,c);
+ mix(a, b, c);
k += 12; len -= 12;
}
/*------------------------------------- handle the last 11 bytes */
c += length;
- switch(len) /* all the case statements fall through */
+ switch (len) /* all the case statements fall through */
{
case 11: c+=((ub4)k[10]<<24);
case 10: c+=((ub4)k[9]<<16);
@@ -96,7 +96,7 @@
case 1 : a+=k[0];
/* case 0: nothing left to add */
}
- mix(a,b,c);
+ mix(a, b, c);
/*-------------------------------------------- report the result */
return c;
}
@@ -119,7 +119,7 @@
int ch, seen_xdigits;
unsigned int val;
- memset((tp = tmp), '\0', 16 /* NS_IN6ADDRSZ*/);
+ memset ((tp = tmp), '\0', 16 /* NS_IN6ADDRSZ*/);
endp = tp + 16 /*NS_IN6ADDRSZ*/;
colonp = NULL;
/* Leading :: requires some special handling. */
@@ -133,8 +133,8 @@
{
const char *pch;
- if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
- pch = strchr((xdigits = xdigits_u), ch);
+ if ((pch = strchr ((xdigits = xdigits_l), ch)) == NULL)
+ pch = strchr ((xdigits = xdigits_u), ch);
if (pch != NULL)
{
val <<= 4;
@@ -184,7 +184,7 @@
if (colonp != NULL)
{
/*
- * Since some memmove()'s erroneously fail to handle
+ * Since some memmove ()'s erroneously fail to handle
* overlapping regions, we'll do the shift by hand.
*/
const int n = tp - colonp;
@@ -202,24 +202,24 @@
if (tp != endp)
return (0);
- /* memcpy(dst, tmp, NS_IN6ADDRSZ); */
- memcpy(addr, tmp, 16);
+ /* memcpy (dst, tmp, NS_IN6ADDRSZ); */
+ memcpy (addr, tmp, 16);
return (1);
}
Ipv6Address::Ipv6Address ()
{
- memset(m_address, 0x00, 16);
+ memset (m_address, 0x00, 16);
}
Ipv6Address::Ipv6Address (Ipv6Address const& addr)
{
- memcpy(m_address, addr.m_address, 16);
+ memcpy (m_address, addr.m_address, 16);
}
Ipv6Address::Ipv6Address (Ipv6Address const* addr)
{
- memcpy(m_address, addr->m_address, 16);
+ memcpy (m_address, addr->m_address, 16);
}
Ipv6Address::Ipv6Address (char const* address)
@@ -230,7 +230,7 @@
Ipv6Address::Ipv6Address (uint8_t address[16])
{
/* 128 bit => 16 bytes */
- memcpy(m_address, address, 16);
+ memcpy (m_address, address, 16);
}
Ipv6Address::~Ipv6Address ()
@@ -246,12 +246,12 @@
void Ipv6Address::Set (uint8_t address[16])
{
/* 128 bit => 16 bytes */
- memcpy(m_address, address, 16);
+ memcpy (m_address, address, 16);
}
void Ipv6Address::Serialize (uint8_t buf[16]) const
{
- memcpy(buf, m_address, 16);
+ memcpy (buf, m_address, 16);
}
Ipv6Address Ipv6Address::Deserialize (const uint8_t buf[16])
@@ -266,16 +266,16 @@
uint8_t buf[16];
uint8_t buf2[16];
- addr.CopyTo(buf);
- prefix.GetBytes(buf2);
+ addr.CopyTo (buf);
+ prefix.GetBytes (buf2);
- memcpy(buf2 + 8, buf, 3);
+ memcpy (buf2 + 8, buf, 3);
buf2[11] = 0xff;
buf2[12] = 0xfe;
- memcpy(buf2 + 13, buf + 3, 3);
+ memcpy (buf2 + 13, buf + 3, 3);
buf2[8] |= 0x02;
- ret.Set(buf2);
+ ret.Set (buf2);
return ret;
}
@@ -285,18 +285,18 @@
uint8_t buf[16];
uint8_t buf2[16];
- addr.CopyTo(buf);
+ addr.CopyTo (buf);
- memset(buf2, 0x00, sizeof(buf2));
+ memset (buf2, 0x00, sizeof (buf2));
buf2[0] = 0xfe;
buf2[1] = 0x80;
- memcpy(buf2 + 8, buf, 3);
+ memcpy (buf2 + 8, buf, 3);
buf2[11] = 0xff;
buf2[12] = 0xfe;
- memcpy(buf2 + 13, buf + 3, 3);
+ memcpy (buf2 + 13, buf + 3, 3);
buf2[8] |= 0x02;
- ret.Set(buf2);
+ ret.Set (buf2);
return ret;
}
@@ -306,9 +306,9 @@
uint8_t buf2[16];
Ipv6Address ret;
- addr.Serialize(buf2);
+ addr.Serialize (buf2);
- memset(buf, 0x00, sizeof(buf));
+ memset (buf, 0x00, sizeof (buf));
buf[0] = 0xff;
buf[1] = 0x02;
buf[11] = 0x01;
@@ -317,40 +317,40 @@
buf[14] = buf2[14];
buf[15] = buf2[15];
- ret.Set(buf);
+ ret.Set (buf);
return ret;
}
void Ipv6Address::Print (std::ostream& os) const
{
- os << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[0]
- << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[1] << ":"
- << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[2]
- << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[3] << ":"
- << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[4]
- << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[5] << ":"
- << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[6]
- << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[7] << ":"
- << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[8]
- << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[9] << ":"
- << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[10]
- << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[11] << ":"
- << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[12]
- << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[13] << ":"
- << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[14]
- << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[15]
- << std::dec << std::setfill(' ');
+ os << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_address[0]
+ << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_address[1] << ":"
+ << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_address[2]
+ << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_address[3] << ":"
+ << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_address[4]
+ << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_address[5] << ":"
+ << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_address[6]
+ << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_address[7] << ":"
+ << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_address[8]
+ << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_address[9] << ":"
+ << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_address[10]
+ << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_address[11] << ":"
+ << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_address[12]
+ << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_address[13] << ":"
+ << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_address[14]
+ << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_address[15]
+ << std::dec << std::setfill (' ');
}
bool Ipv6Address::IsLocalhost () const
{
- static Ipv6Address localhost("::1");
+ static Ipv6Address localhost ("::1");
return (*this == localhost);
}
bool Ipv6Address::IsMulticast () const
{
- if(m_address[0] == 0xff)
+ if (m_address[0] == 0xff)
{
return true;
}
@@ -364,15 +364,15 @@
uint8_t pref[16];
unsigned int i = 0;
- memcpy(addr, m_address, 16);
- ((Ipv6Prefix)prefix).GetBytes(pref);
+ memcpy (addr, m_address, 16);
+ ((Ipv6Prefix)prefix).GetBytes (pref);
/* a little bit ugly... */
- for(i = 0 ; i < 16 ; i++)
+ for (i = 0 ; i < 16 ; i++)
{
addr[i] = addr[i] & pref[i];
}
- ipv6.Set(addr);
+ ipv6.Set (addr);
return ipv6;
}
@@ -380,9 +380,9 @@
{
uint8_t buf[16];
- Serialize(buf);
+ Serialize (buf);
- if(buf[0] == 0xff &&
+ if (buf[0] == 0xff &&
buf[1] == 0x02 &&
buf[11] == 0x01 &&
buf[12] == 0xff)
@@ -394,31 +394,31 @@
bool Ipv6Address::IsAllNodesMulticast () const
{
- static Ipv6Address allnodes("ff02::1");
+ static Ipv6Address allnodes ("ff02::1");
return (*this == allnodes);
}
bool Ipv6Address::IsAllRoutersMulticast () const
{
- static Ipv6Address allrouters("ff02::2");
+ static Ipv6Address allrouters ("ff02::2");
return (*this == allrouters);
}
bool Ipv6Address::IsAllHostsMulticast () const
{
- static Ipv6Address allhosts("ff02::3");
+ static Ipv6Address allhosts ("ff02::3");
return (*this == allhosts);
}
bool Ipv6Address::IsAny () const
{
- static Ipv6Address any("::");
+ static Ipv6Address any ("::");
return (*this == any);
}
bool Ipv6Address::IsMatchingType (const Address& address)
{
- return address.CheckCompatible(GetType(), 16);
+ return address.CheckCompatible (GetType (), 16);
}
Ipv6Address::operator Address () const
@@ -430,7 +430,7 @@
{
uint8_t buf[16];
Serialize (buf);
- return Address(GetType(), buf, 16);
+ return Address (GetType (), buf, 16);
}
Ipv6Address Ipv6Address::ConvertFrom (const Address &address)
@@ -443,55 +443,55 @@
uint8_t Ipv6Address::GetType (void)
{
- static uint8_t type = Address::Register();
+ static uint8_t type = Address::Register ();
return type;
}
Ipv6Address Ipv6Address::GetZero ()
{
- Ipv6Address zero("::");
+ Ipv6Address zero ("::");
return zero;
}
Ipv6Address Ipv6Address::GetAny ()
{
- Ipv6Address any("::");
+ Ipv6Address any ("::");
return any;
}
Ipv6Address Ipv6Address::GetAllNodesMulticast ()
{
- Ipv6Address nmc("ff02::1");
+ Ipv6Address nmc ("ff02::1");
return nmc;
}
Ipv6Address Ipv6Address::GetAllRoutersMulticast ()
{
- Ipv6Address rmc("ff02::2");
+ Ipv6Address rmc ("ff02::2");
return rmc;
}
Ipv6Address Ipv6Address::GetAllHostsMulticast ()
{
- Ipv6Address hmc("ff02::3");
+ Ipv6Address hmc ("ff02::3");
return hmc;
}
Ipv6Address Ipv6Address::GetLoopback ()
{
- static Ipv6Address loopback("::1");
+ static Ipv6Address loopback ("::1");
return loopback;
}
void Ipv6Address::GetBytes (uint8_t buf[16]) const
{
- memcpy(buf, m_address, 16);
+ memcpy (buf, m_address, 16);
}
bool Ipv6Address::IsLinkLocal () const
{
- Ipv6Address linkLocal("fe80::0");
- if(!IsMulticast() && ((Ipv6Address*)this)->CombinePrefix(Ipv6Prefix(64))==linkLocal)
+ Ipv6Address linkLocal ("fe80::0");
+ if (!IsMulticast () && ((Ipv6Address*)this)->CombinePrefix (Ipv6Prefix (64))==linkLocal)
{
return true;
}
@@ -500,7 +500,7 @@
bool Ipv6Address::IsEqual (const Ipv6Address& other) const
{
- if(!memcmp(m_address, other.m_address, 16))
+ if (!memcmp (m_address, other.m_address, 16))
{
return true;
}
@@ -509,7 +509,7 @@
std::ostream& operator << (std::ostream& os, Ipv6Address const& address)
{
- address.Print(os);
+ address.Print (os);
return os;
}
@@ -523,17 +523,17 @@
Ipv6Prefix::Ipv6Prefix ()
{
- memset(m_prefix, 0x00, 16);
+ memset (m_prefix, 0x00, 16);
}
Ipv6Prefix::Ipv6Prefix (char const* prefix)
{
- AsciiToIpv6Host(prefix, m_prefix);
+ AsciiToIpv6Host (prefix, m_prefix);
}
Ipv6Prefix::Ipv6Prefix (uint8_t prefix[16])
{
- memcpy(m_prefix, prefix, 16);
+ memcpy (m_prefix, prefix, 16);
}
Ipv6Prefix::Ipv6Prefix (uint8_t prefix)
@@ -542,24 +542,24 @@
unsigned int mod=0;
unsigned int i=0;
- memset(m_prefix, 0x00, 16);
+ memset (m_prefix, 0x00, 16);
- NS_ASSERT(prefix <= 128);
+ NS_ASSERT (prefix <= 128);
nb = prefix / 8;
mod = prefix % 8;
- memset(m_prefix, 0xff, nb);
+ memset (m_prefix, 0xff, nb);
- if(mod)
+ if (mod)
{
m_prefix[nb] = 0xff << (8-mod);
}
- if(nb < 16)
+ if (nb < 16)
{
nb++;
- for(i = nb; i < 16 ; i++)
+ for (i = nb; i < 16 ; i++)
{
m_prefix[i] = 0x00;
}
@@ -568,12 +568,12 @@
Ipv6Prefix::Ipv6Prefix (Ipv6Prefix const& prefix)
{
- memcpy(m_prefix, prefix.m_prefix, 16);
+ memcpy (m_prefix, prefix.m_prefix, 16);
}
Ipv6Prefix::Ipv6Prefix (Ipv6Prefix const* prefix)
{
- memcpy(m_prefix, prefix->m_prefix, 16);
+ memcpy (m_prefix, prefix->m_prefix, 16);
}
Ipv6Prefix::~Ipv6Prefix ()
@@ -587,13 +587,13 @@
uint8_t addrB[16];
unsigned int i = 0;
- a.GetBytes(addrA);
- b.GetBytes(addrB);
+ a.GetBytes (addrA);
+ b.GetBytes (addrB);
/* a little bit ugly... */
- for(i = 0 ; i < 16 ; i++)
+ for (i = 0 ; i < 16 ; i++)
{
- if((addrA[i] & m_prefix[i]) != (addrB[i] & m_prefix[i]))
+ if ((addrA[i] & m_prefix[i]) != (addrB[i] & m_prefix[i]))
{
return false;
}
@@ -603,44 +603,44 @@
void Ipv6Prefix::Print (std::ostream &os) const
{
- os << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[0]
- << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[1] << ":"
- << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[2]
- << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[3] << ":"
- << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[4]
- << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[5] << ":"
- << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[6]
- << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[7] << ":"
- << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[8]
- << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[9] << ":"
- << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[10]
- << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[11] << ":"
- << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[12]
- << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[13] << ":"
- << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[14]
- << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[15];
+ os << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_prefix[0]
+ << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_prefix[1] << ":"
+ << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_prefix[2]
+ << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_prefix[3] << ":"
+ << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_prefix[4]
+ << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_prefix[5] << ":"
+ << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_prefix[6]
+ << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_prefix[7] << ":"
+ << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_prefix[8]
+ << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_prefix[9] << ":"
+ << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_prefix[10]
+ << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_prefix[11] << ":"
+ << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_prefix[12]
+ << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_prefix[13] << ":"
+ << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_prefix[14]
+ << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_prefix[15];
}
Ipv6Prefix Ipv6Prefix::GetLoopback ()
{
- Ipv6Prefix prefix((uint8_t)128);
+ Ipv6Prefix prefix ((uint8_t)128);
return prefix;
}
Ipv6Prefix Ipv6Prefix::GetZero ()
{
- Ipv6Prefix prefix((uint8_t)0);
+ Ipv6Prefix prefix ((uint8_t)0);
return prefix;
}
void Ipv6Prefix::GetBytes (uint8_t buf[16]) const
{
- memcpy(buf, m_prefix, 16);
+ memcpy (buf, m_prefix, 16);
}
bool Ipv6Prefix::IsEqual (const Ipv6Prefix& other) const
{
- if(!memcmp(m_prefix, other.m_prefix, 16))
+ if (!memcmp (m_prefix, other.m_prefix, 16))
{
return true;
}
@@ -671,13 +671,13 @@
return !a.IsEqual (b);
}
-size_t Ipv6AddressHash::operator() (Ipv6Address const &x) const
+size_t Ipv6AddressHash::operator () (Ipv6Address const &x) const
{
uint8_t buf[16];
- x.GetBytes(buf);
+ x.GetBytes (buf);
- return lookuphash(buf, sizeof(buf), 0);
+ return lookuphash (buf, sizeof (buf), 0);
}
ATTRIBUTE_HELPER_CPP (Ipv6Address);
--- a/src/node/ipv6-address.h Tue Aug 25 20:12:53 2009 +0400
+++ b/src/node/ipv6-address.h Wed Aug 26 15:29:03 2009 +0400
@@ -415,7 +415,7 @@
class Ipv6AddressHash : public std::unary_function<Ipv6Address, size_t>
{
public:
- size_t operator() (Ipv6Address const &x) const;
+ size_t operator () (Ipv6Address const &x) const;
};
bool operator == (Ipv6Prefix const &a, Ipv6Prefix const &b);
--- a/src/node/ipv6-header.cc Tue Aug 25 20:12:53 2009 +0400
+++ b/src/node/ipv6-header.cc Wed Aug 26 15:29:03 2009 +0400
@@ -31,16 +31,15 @@
NS_OBJECT_ENSURE_REGISTERED (Ipv6Header);
Ipv6Header::Ipv6Header ()
-: m_version (6),
+ : m_version (6),
m_trafficClass (0),
m_flowLabel (1),
m_payloadLength (0),
m_nextHeader (0),
m_hopLimit (0)
{
-
- SetSourceAddress (Ipv6Address("::"));
- SetDestinationAddress(Ipv6Address ("::"));
+ SetSourceAddress (Ipv6Address ("::"));
+ SetDestinationAddress (Ipv6Address ("::"));
}
void Ipv6Header::SetTrafficClass (uint8_t traffic)
@@ -157,8 +156,8 @@
i.WriteU8(m_nextHeader);
i.WriteU8(m_hopLimit);
- WriteTo(i, m_sourceAddress);
- WriteTo(i, m_destinationAddress);
+ WriteTo (i, m_sourceAddress);
+ WriteTo (i, m_destinationAddress);
}
uint32_t Ipv6Header::Deserialize (Buffer::Iterator start)
@@ -169,7 +168,7 @@
vTcFl = i.ReadNtohU32();
m_version = vTcFl >> 28;
- NS_ASSERT((m_version) == 6);
+ NS_ASSERT ((m_version) == 6);
m_trafficClass = (uint8_t)((vTcFl >> 20) & 0x000000ff);
m_flowLabel = vTcFl & 0xfff00000;
@@ -177,10 +176,10 @@
m_nextHeader = i.ReadU8();
m_hopLimit = i.ReadU8();
- ReadFrom(i, m_sourceAddress);
- ReadFrom(i, m_destinationAddress);
+ ReadFrom (i, m_sourceAddress);
+ ReadFrom (i, m_destinationAddress);
- return GetSerializedSize();
+ return GetSerializedSize ();
}
} /* namespace ns3 */
--- a/src/node/ipv6-header.h Tue Aug 25 20:12:53 2009 +0400
+++ b/src/node/ipv6-header.h Wed Aug 26 15:29:03 2009 +0400
@@ -39,21 +39,21 @@
*/
enum NextHeader_e
{
- IPV6_EXT_HOP_BY_HOP=0,
- IPV6_IPV4=4,
- IPV6_TCP=6,
- IPV6_UDP=17,
- IPV6_IPV6=41,
- IPV6_EXT_ROUTING=43,
- IPV6_EXT_FRAGMENTATION=44,
- IPV6_EXT_CONFIDENTIALITY=50,
- IPV6_EXT_AUTHENTIFICATION,
- IPV6_ICMPV6=58,
- IPV6_EXT_END,
- IPV6_EXT_DESTINATION,
- IPV6_SCTP=135,
- IPV6_EXT_MOBILITY=135,
- IPV6_UDP_LITE,
+ IPV6_EXT_HOP_BY_HOP = 0,
+ IPV6_IPV4 = 4,
+ IPV6_TCP = 6,
+ IPV6_UDP = 17,
+ IPV6_IPV6 = 41,
+ IPV6_EXT_ROUTING = 43,
+ IPV6_EXT_FRAGMENTATION = 44,
+ IPV6_EXT_CONFIDENTIALITY = 50,
+ IPV6_EXT_AUTHENTIFICATION = 51,
+ IPV6_ICMPV6 = 58,
+ IPV6_EXT_END = 59,
+ IPV6_EXT_DESTINATION = 60,
+ IPV6_SCTP = 135,
+ IPV6_EXT_MOBILITY = 135,
+ IPV6_UDP_LITE = 136,
};
/**
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ipv6-interface-address.cc Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,170 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#include <iostream>
+
+#include "ns3/log.h"
+#include "ns3/assert.h"
+#include "ipv6-interface-address.h"
+
+namespace ns3
+{
+
+NS_LOG_COMPONENT_DEFINE ("Ipv6InterfaceAddress");
+
+Ipv6InterfaceAddress::Ipv6InterfaceAddress ()
+ : m_address (Ipv6Address ()),
+ m_prefix (Ipv6Prefix ()),
+ m_state (TENTATIVE_OPTIMISTIC),
+ m_scope (HOST),
+ m_nsDadUid (0)
+{
+ NS_LOG_FUNCTION (this);
+}
+
+Ipv6InterfaceAddress::Ipv6InterfaceAddress (Ipv6Address address)
+{
+ NS_LOG_FUNCTION (this << address);
+ m_prefix = Ipv6Prefix (64);
+ SetAddress (address);
+ SetState (TENTATIVE_OPTIMISTIC);
+ m_nsDadUid = 0;
+}
+
+Ipv6InterfaceAddress::Ipv6InterfaceAddress (Ipv6Address address, Ipv6Prefix prefix)
+{
+ NS_LOG_FUNCTION (this << address << prefix);
+ m_prefix = prefix;
+ SetAddress (address);
+ SetState (TENTATIVE_OPTIMISTIC);
+ m_nsDadUid = 0;
+}
+
+Ipv6InterfaceAddress::Ipv6InterfaceAddress (const Ipv6InterfaceAddress& o)
+ : m_address (o.m_address),
+ m_prefix (o.m_prefix),
+ m_state (o.m_state),
+ m_scope (o.m_scope),
+ m_nsDadUid (o.m_nsDadUid)
+{}
+
+Ipv6InterfaceAddress::~Ipv6InterfaceAddress ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+Ipv6Address Ipv6InterfaceAddress::GetAddress () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_address;
+}
+
+void Ipv6InterfaceAddress::SetAddress (Ipv6Address address)
+{
+ NS_LOG_FUNCTION (this << address);
+ m_address = address;
+
+ if (address.IsLocalhost ())
+ {
+ m_scope = HOST;
+ /* localhost address is always /128 prefix */
+ m_prefix = Ipv6Prefix (128);
+ }
+ if (address.IsLinkLocal ())
+ {
+ m_scope = LINKLOCAL;
+ /* link-local address is always /64 prefix */
+ m_prefix = Ipv6Prefix (64);
+ }
+ else
+ {
+ m_scope = GLOBAL;
+ }
+}
+
+Ipv6Prefix Ipv6InterfaceAddress::GetPrefix () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_prefix;
+}
+
+void Ipv6InterfaceAddress::SetState (Ipv6InterfaceAddress::State_e state)
+{
+ NS_LOG_FUNCTION (this << state);
+ m_state = state;
+}
+
+Ipv6InterfaceAddress::State_e Ipv6InterfaceAddress::GetState () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_state;
+}
+
+void Ipv6InterfaceAddress::SetScope (Ipv6InterfaceAddress::Scope_e scope)
+{
+ NS_LOG_FUNCTION (this << scope);
+ m_scope = scope;
+}
+
+Ipv6InterfaceAddress::Scope_e Ipv6InterfaceAddress::GetScope () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_scope;
+}
+
+std::ostream& operator<< (std::ostream& os, const Ipv6InterfaceAddress &addr)
+{
+ os << "address=" << addr.GetAddress () << "; prefix=" <<
+ addr.GetPrefix () << "; scope=" << addr.GetScope ();
+ return os;
+}
+
+uint32_t Ipv6InterfaceAddress::GetNsDadUid () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_nsDadUid;
+}
+
+void Ipv6InterfaceAddress::SetNsDadUid (uint32_t nsDadUid)
+{
+ NS_LOG_FUNCTION (this << nsDadUid);
+ m_nsDadUid = nsDadUid;
+}
+
+#if 0
+void Ipv6InterfaceAddress::StartDadTimer (Ptr<Ipv6Interface> interface)
+{
+ NS_LOG_FUNCTION (this << interface);
+ m_dadTimer.SetFunction (&Icmpv6L4Protocol::FunctionDadTimeout);
+ m_dadTimer.SetArguments (interface, m_address);
+ m_dadTimer.Schedule (Seconds (1));
+ m_dadId = Simulator::Schedule (Seconds (1.), &Icmpv6L4Protocol::FunctionDadTimeout, interface, m_address);
+}
+
+void Ipv6InterfaceAddress::StopDadTimer ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ m_dadTimer.Cancel ();
+ Simulator::Cancel (m_dadId);
+}
+#endif
+
+} /* namespace ns3 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ipv6-interface-address.h Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,209 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#ifndef IPV6_INTERFACE_ADDRESS_H
+#define IPV6_INTERFACE_ADDRESS_H
+
+#include <stdint.h>
+
+#include "ipv6-address.h"
+
+namespace ns3
+{
+
+/**
+ * \ingroup address
+ * \class Ipv6InterfaceAddress
+ * \brief IPv6 address associated with an interface.
+ */
+class Ipv6InterfaceAddress
+{
+ public:
+ /**
+ * \enum State_e
+ * \brief State of an address associated with an interface.
+ */
+ enum State_e
+ {
+ TENTATIVE, /**< Address is tentative, no packet can be sent unless DAD finished */
+ DEPRECATED, /**< Address is deprecated and should not be used */
+ PREFERRED, /**< Preferred address */
+ PERMANENT, /**< Permanent address */
+ HOMEADDRESS, /**< Address is a HomeAddress */
+ TENTATIVE_OPTIMISTIC, /**< Address is tentative but we are optimistic so we can send packet even if DAD is not yet finished */
+ INVALID, /**< Invalid state (after a DAD failed) */
+ };
+
+ /**
+ * \enum Scope_e
+ * \brief Scope of address.
+ */
+ enum Scope_e
+ {
+ HOST, /**< Localhost (::1/128) */
+ LINKLOCAL, /**< Link-local address (fe80::/64) */
+ GLOBAL, /**< Global address (2000::/3) */
+ };
+
+ /**
+ * \brief Default constructor.
+ */
+ Ipv6InterfaceAddress ();
+
+ /**
+ * \brief Constructor. Prefix is 64 by default.
+ * \param address the IPv6 address to set
+ */
+ Ipv6InterfaceAddress (Ipv6Address address);
+
+ /**
+ * \brief Constructor.
+ * \param address IPv6 address to set
+ * \param prefix IPv6 prefix
+ */
+ Ipv6InterfaceAddress (Ipv6Address address, Ipv6Prefix prefix);
+
+ /**
+ * \brief Copy constructor.
+ * \param o object to copy
+ */
+ Ipv6InterfaceAddress (const Ipv6InterfaceAddress& o);
+
+ /**
+ * \brief Destructor.
+ */
+ ~Ipv6InterfaceAddress ();
+
+ /**
+ * \brief Set IPv6 address (and scope).
+ * \param address IPv6 address to set
+ */
+ void SetAddress (Ipv6Address address);
+
+ /**
+ * \brief Get the IPv6 address.
+ * \return IPv6 address
+ */
+ Ipv6Address GetAddress () const;
+
+ /**
+ * \brief Get the IPv6 prefix.
+ * \return IPv6 prefix
+ */
+ Ipv6Prefix GetPrefix () const;
+
+ /**
+ * \brief Set the state.
+ * \param state the state
+ */
+ void SetState (Ipv6InterfaceAddress::State_e state);
+
+ /**
+ * \brief Get the address state.
+ * \return address state
+ */
+ Ipv6InterfaceAddress::State_e GetState () const;
+
+ /**
+ * \brief Set the scope.
+ * \param scope the scope of address
+ */
+ void SetScope (Ipv6InterfaceAddress::Scope_e scope);
+
+ /**
+ * \brief Get address scope.
+ * \return scope
+ */
+ Ipv6InterfaceAddress::Scope_e GetScope () const;
+
+ /**
+ * \brief Set the latest DAD probe packet UID.
+ * \param uid packet uid
+ */
+ void SetNsDadUid (uint32_t uid);
+
+ /**
+ * \brief Get the latest DAD probe packet UID.
+ * \return uid
+ */
+ uint32_t GetNsDadUid () const;
+
+#if 0
+ /**
+ * \brief Start the DAD timer.
+ * \param interface interface
+ */
+ void StartDadTimer (Ptr<Ipv6Interface> interface);
+
+ /**
+ * \brief Stop the DAD timer.
+ */
+ void StopDadTimer ();
+#endif
+
+ private:
+ /**
+ * \brief The IPv6 address.
+ */
+ Ipv6Address m_address;
+
+ /**
+ * \brief The IPv6 prefix.
+ */
+ Ipv6Prefix m_prefix;
+
+ /**
+ * \brief State of the address.
+ */
+ State_e m_state;
+
+ /**
+ * \brief Scope of the address.
+ */
+ Scope_e m_scope;
+
+ friend bool operator == (Ipv6InterfaceAddress const& a, Ipv6InterfaceAddress const& b);
+ friend bool operator != (Ipv6InterfaceAddress const& a, Ipv6InterfaceAddress const& b);
+
+ /**
+ * \brief Last DAD probe packet UID.
+ */
+ uint32_t m_nsDadUid;
+};
+
+std::ostream& operator<< (std::ostream& os, const Ipv6InterfaceAddress &addr);
+
+/* follow Ipv6InterfaceAddress way, maybe not inline them */
+inline bool operator == (const Ipv6InterfaceAddress& a, const Ipv6InterfaceAddress& b)
+{
+ return (a.m_address == b.m_address && a.m_prefix == b.m_prefix &&
+ a.m_state == b.m_state && a.m_scope == b.m_scope);
+}
+
+inline bool operator != (const Ipv6InterfaceAddress& a, const Ipv6InterfaceAddress& b)
+{
+ return (a.m_address != b.m_address || a.m_prefix != b.m_prefix ||
+ a.m_state != b.m_state || a.m_scope != b.m_scope);
+}
+
+} /* namespace ns3 */
+
+#endif /* IPV6_INTERFACE_ADDRESS_H */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ipv6-raw-socket-factory.cc Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,37 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#include "ipv6-raw-socket-factory.h"
+#include "ns3/uinteger.h"
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6RawSocketFactory);
+
+TypeId Ipv6RawSocketFactory::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ipv6RawSocketFactory")
+ .SetParent<SocketFactory> ()
+ ;
+ return tid;
+}
+
+} // namespace ns3
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ipv6-raw-socket-factory.h Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,52 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#ifndef IPV6_RAW_SOCKET_FACTORY_H
+#define IPV6_RAW_SOCKET_FACTORY_H
+
+#include "socket-factory.h"
+
+namespace ns3
+{
+
+class Socket;
+
+/**
+ * \ingroup socket
+ *
+ * \brief API to create IPv6 RAW socket instances
+ *
+ * This abstract class defines the API for IPv6 RAW socket factory.
+ *
+ */
+class Ipv6RawSocketFactory : public SocketFactory
+{
+ public:
+ /**
+ * \brief Get the type ID of this class.
+ * \return type ID
+ */
+ static TypeId GetTypeId (void);
+};
+
+} // namespace ns3
+
+#endif /* IPV6_RAW_SOCKET_FACTORY_H */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ipv6-route.cc Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,147 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#include <iostream>
+
+#include "net-device.h"
+
+#include "ipv6-route.h"
+
+namespace ns3
+{
+
+Ipv6Route::Ipv6Route ()
+{
+}
+
+Ipv6Route::~Ipv6Route ()
+{
+}
+
+void Ipv6Route::SetDestination (Ipv6Address dest)
+{
+ m_dest = dest;
+}
+
+Ipv6Address
+Ipv6Route::GetDestination () const
+{
+ return m_dest;
+}
+
+void Ipv6Route::SetSource (Ipv6Address src)
+{
+ m_source = src;
+}
+
+Ipv6Address Ipv6Route::GetSource () const
+{
+ return m_source;
+}
+
+void Ipv6Route::SetGateway (Ipv6Address gw)
+{
+ m_gateway = gw;
+}
+
+Ipv6Address Ipv6Route::GetGateway () const
+{
+ return m_gateway;
+}
+
+void Ipv6Route::SetOutputDevice (Ptr<NetDevice> outputDevice)
+{
+ m_outputDevice = outputDevice;
+}
+
+Ptr<NetDevice> Ipv6Route::GetOutputDevice () const
+{
+ return m_outputDevice;
+}
+
+std::ostream& operator<< (std::ostream& os, Ipv6Route const& route)
+{
+ os << "source=" << route.GetSource () << " dest="<< route.GetDestination () <<" gw=" << route.GetGateway ();
+ return os;
+}
+
+Ipv6MulticastRoute::Ipv6MulticastRoute ()
+{
+ uint32_t initial_ttl = MAX_TTL;
+
+ /* Initialize array to MAX_TTL, which means that all interfaces are "off" */
+ for (uint32_t i = 0; i < MAX_INTERFACES; i++)
+ {
+ m_ttls.push_back (initial_ttl);
+ }
+}
+
+Ipv6MulticastRoute::~Ipv6MulticastRoute ()
+{
+}
+
+void Ipv6MulticastRoute::SetGroup (const Ipv6Address group)
+{
+ m_group = group;
+}
+
+Ipv6Address Ipv6MulticastRoute::GetGroup () const
+{
+ return m_group;
+}
+
+void Ipv6MulticastRoute::SetOrigin (const Ipv6Address origin)
+{
+ m_origin = origin;
+}
+
+Ipv6Address Ipv6MulticastRoute::GetOrigin () const
+{
+ return m_origin;
+}
+
+void Ipv6MulticastRoute::SetParent (uint32_t parent)
+{
+ m_parent = parent;
+}
+
+uint32_t Ipv6MulticastRoute::GetParent () const
+{
+ return m_parent;
+}
+
+void Ipv6MulticastRoute::SetOutputTtl (uint32_t oif, uint32_t ttl)
+{
+ m_ttls[oif] = ttl;
+}
+
+uint32_t Ipv6MulticastRoute::GetOutputTtl (uint32_t oif) const
+{
+ return m_ttls[oif];
+}
+
+std::ostream& operator<< (std::ostream& os, Ipv6MulticastRoute const& route)
+{
+ os << "origin=" << route.GetOrigin () << " group="<< route.GetGroup () <<" parent=" << route.GetParent ();
+ return os;
+}
+
+} /* namespace ns3 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ipv6-route.h Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,227 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#ifndef IPV6_ROUTE_H
+#define IPV6_ROUTE_H
+
+#include <list>
+#include <vector>
+#include <ostream>
+
+#include "ns3/ref-count-base.h"
+#include "ipv6-address.h"
+
+namespace ns3
+{
+
+class NetDevice;
+
+/**
+ * \ingroup ipv6Routing
+ * \class Ipv6Route
+ * \brief IPv6 route cache entry.
+ */
+class Ipv6Route : public RefCountBase
+{
+ public:
+ /**
+ * \brief Constructor.
+ */
+ Ipv6Route ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Ipv6Route ();
+
+ /**
+ * \brief Set destination address.
+ * \param dest IPv6 destination address
+ */
+ void SetDestination (Ipv6Address dest);
+
+ /**
+ * \brief Get destination address.
+ * \return destination address
+ */
+ Ipv6Address GetDestination () const;
+
+ /**
+ * \brief Set source address.
+ * \param src IPv6 source address
+ */
+ void SetSource (Ipv6Address src);
+
+ /**
+ * \brief Get source address.
+ * \return source address
+ */
+ Ipv6Address GetSource () const;
+
+ /**
+ * \brief Set gateway address.
+ * \param gw IPv6 gateway address
+ */
+ void SetGateway (Ipv6Address gw);
+
+ /**
+ * \brief Get gateway address.
+ * \return gateway address
+ */
+ Ipv6Address GetGateway () const;
+
+ /**
+ * \brief Set output device for outgoing packets.
+ * \param outputDevice output device
+ */
+ void SetOutputDevice (Ptr<NetDevice> outputDevice);
+
+ /**
+ * \brief Get output device.
+ * \return output device
+ */
+ Ptr<NetDevice> GetOutputDevice () const;
+
+ private:
+ /**
+ * \brief Destination address.
+ */
+ Ipv6Address m_dest;
+
+ /**
+ * \brief source address.
+ */
+ Ipv6Address m_source;
+
+ /**
+ * \brief Gateway address.
+ */
+ Ipv6Address m_gateway;
+
+ /**
+ * \brief Output device.
+ */
+ Ptr<NetDevice> m_outputDevice;
+};
+
+std::ostream& operator<< (std::ostream& os, Ipv6Route const& route);
+
+/**
+ * \ingroup ipv6Routing
+ * \class Ipv6MulticastRoute
+ * \brief IPv6 multicast route entry.
+ */
+class Ipv6MulticastRoute : public RefCountBase
+{
+ public:
+ /**
+ * \brief Maximum number of multicast interfaces on a router.
+ */
+ static const uint32_t MAX_INTERFACES = 16;
+
+ /**
+ * \brief Maximum Time-To-Live (TTL).
+ */
+ static const uint32_t MAX_TTL = 255;
+
+ /**
+ * \brief Constructor.
+ */
+ Ipv6MulticastRoute ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Ipv6MulticastRoute ();
+
+ /**
+ * \brief Set IPv6 group.
+ * \param group Ipv6Address of the multicast group
+ */
+ void SetGroup (const Ipv6Address group);
+
+ /**
+ * \brief Get IPv6 group.
+ * \return Ipv6Address of the multicast group
+ */
+ Ipv6Address GetGroup (void) const;
+
+ /**
+ * \brief Set origin address.
+ * \param origin Ipv6Address of the origin address
+ */
+ void SetOrigin (const Ipv6Address origin);
+
+ /**
+ * \brief Get source address.
+ * \return Ipv6Address of the origin address
+ */
+ Ipv6Address GetOrigin (void) const;
+
+ /**
+ * \param iif Parent (input interface) for this route
+ */
+ void SetParent (uint32_t iif);
+ /**
+ * \return Parent (input interface) for this route
+ */
+ uint32_t GetParent (void) const;
+
+ /**
+ * \param oif Outgoing interface index
+ * \param ttl time-to-live for this route
+ */
+ void SetOutputTtl (uint32_t oif, uint32_t ttl);
+
+ /**
+ * \brief Get output TTL.
+ * \param oif outgoing interface
+ * \return TTL for this route
+ */
+ uint32_t GetOutputTtl (uint32_t oif) const;
+
+ private:
+ /**
+ * \brief IPv6 group.
+ */
+ Ipv6Address m_group;
+
+ /**
+ * \brief IPv6 origin (source).
+ */
+ Ipv6Address m_origin;
+
+ /**
+ * \brief Source interface.
+ */
+ uint32_t m_parent;
+
+ /**
+ * \brief TTLs;
+ */
+ std::vector<uint32_t> m_ttls;
+};
+
+std::ostream& operator<< (std::ostream& os, Ipv6MulticastRoute const& route);
+
+} /* namespace ns3 */
+
+#endif /* IPV6_ROUTE_H */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ipv6-routing-protocol.cc Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,39 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* taken from src/node/ipv4-routing-protocol.cc and adapted to IPv6 */
+
+#include "ns3/assert.h"
+#include "ipv6-route.h"
+#include "ipv6-routing-protocol.h"
+
+namespace ns3
+{
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6RoutingProtocol);
+
+TypeId Ipv6RoutingProtocol::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ipv6RoutingProtocol")
+ .SetParent<Object> ()
+ ;
+ return tid;
+}
+
+} /* namespace ns3 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ipv6-routing-protocol.h Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,170 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* taken from src/node/ipv4-routing-protocol.h and adapted to IPv6 */
+
+#ifndef IPV6_ROUTING_PROTOCOL_H
+#define IPV6_ROUTING_PROTOCOL_H
+
+#include "ns3/packet.h"
+#include "ns3/callback.h"
+#include "ns3/object.h"
+#include "ns3/socket.h"
+#include "ipv6-header.h"
+#include "ipv6-interface-address.h"
+#include "ipv6.h"
+
+namespace ns3 {
+
+class Ipv6MulticastRoute;
+class Ipv6Route;
+class NetDevice;
+
+/**
+ * \ingroup node
+ * \defgroup ipv6Routing Ipv6 Routing
+ *
+ * Abstract base class for Ipv6 routing protocols. Defines two
+ * virtual functions for packet routing and forwarding. The first,
+ * RouteOutput (), is used for locally originated packets, and the second,
+ * RouteInput (), is used for forwarding and/or delivering received packets.
+ * Also defines the signatures of four callbacks used in RouteInput ().
+ *
+ */
+class Ipv6RoutingProtocol : public Object
+{
+public:
+ static TypeId GetTypeId (void);
+
+ typedef Callback<void, Ptr<Ipv6Route>, Ptr<const Packet>, const Ipv6Header &> UnicastForwardCallback;
+ typedef Callback<void, Ptr<Ipv6MulticastRoute>, Ptr<const Packet>, const Ipv6Header &> MulticastForwardCallback;
+ typedef Callback<void, Ptr<const Packet>, const Ipv6Header &, uint32_t > LocalDeliverCallback;
+ typedef Callback<void, Ptr<const Packet>, const Ipv6Header &, Socket::SocketErrno > ErrorCallback;
+
+ /**
+ * \brief Query routing cache for an existing route, for an outbound packet
+ *
+ * This lookup is used by transport protocols. It does not cause any
+ * packet to be forwarded, and is synchronous. Can be used for
+ * multicast or unicast. The Linux equivalent is ip_route_output ()
+ *
+ * \param p packet to be routed. Note that this method may modify the packet.
+ * Callers may also pass in a null pointer.
+ * \param header input parameter (used to form key to search for the route)
+ * \param oif Output interface index. May be zero, or may be bound via
+ * socket options to a particular output interface.
+ * \param sockerr Output parameter; socket errno
+ *
+ * \returns a code that indicates what happened in the lookup
+ */
+ virtual Ptr<Ipv6Route> RouteOutput (Ptr<Packet> p, const Ipv6Header &header, uint32_t oif, Socket::SocketErrno &sockerr) = 0;
+
+ /**
+ * \brief Route an input packet (to be forwarded or locally delivered)
+ *
+ * This lookup is used in the forwarding process. The packet is
+ * handed over to the Ipv6RoutingProtocol, and will get forwarded onward
+ * by one of the callbacks. The Linux equivalent is ip_route_input ().
+ * There are four valid outcomes, and a matching callbacks to handle each.
+ *
+ * \param p received packet
+ * \param header input parameter used to form a search key for a route
+ * \param idev Pointer to ingress network device
+ * \param ucb Callback for the case in which the packet is to be forwarded
+ * as unicast
+ * \param mcb Callback for the case in which the packet is to be forwarded
+ * as multicast
+ * \param lcb Callback for the case in which the packet is to be locally
+ * delivered
+ * \param ecb Callback to call if there is an error in forwarding
+ * \returns true if the Ipv6RoutingProtocol takes responsibility for
+ * forwarding or delivering the packet, false otherwise
+ */
+ virtual bool RouteInput (Ptr<const Packet> p, const Ipv6Header &header, Ptr<const NetDevice> idev,
+ UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+ LocalDeliverCallback lcb, ErrorCallback ecb) = 0;
+
+ /**
+ * \param interface the index of the interface we are being notified about
+ *
+ * Protocols are expected to implement this method to be notified of the state change of
+ * an interface in a node.
+ */
+ virtual void NotifyInterfaceUp (uint32_t interface) = 0;
+ /**
+ * \param interface the index of the interface we are being notified about
+ *
+ * Protocols are expected to implement this method to be notified of the state change of
+ * an interface in a node.
+ */
+ virtual void NotifyInterfaceDown (uint32_t interface) = 0;
+
+ /**
+ * \param interface the index of the interface we are being notified about
+ * \param address a new address being added to an interface
+ *
+ * Protocols are expected to implement this method to be notified whenever
+ * a new address is added to an interface. Typically used to add a 'network route' on an
+ * interface. Can be invoked on an up or down interface.
+ */
+ virtual void NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address) = 0;
+
+ /**
+ * \param interface the index of the interface we are being notified about
+ * \param address a new address being added to an interface
+ *
+ * Protocols are expected to implement this method to be notified whenever
+ * a new address is removed from an interface. Typically used to remove the 'network route' of an
+ * interface. Can be invoked on an up or down interface.
+ */
+ virtual void NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address) = 0;
+
+ /**
+ * \brief Notify a new route.
+ *
+ * Typically this is used to add another route from IPv6 stack (i.e. ICMPv6
+ * redirect case, ...).
+ * \param dst destination address
+ * \param mask destination mask
+ * \param nextHop nextHop for this destination
+ * \param interface output interface
+ * \param prefixToUse prefix to use as source with this route
+ */
+ virtual void NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ()) = 0;
+
+ /**
+ * \brief Notify route removing.
+ * \param dst destination address
+ * \param mask destination mask
+ * \param nextHop nextHop for this destination
+ * \param interface output interface
+ */
+ virtual void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface) = 0;
+
+ /**
+ * \param ipv6 the ipv6 object this routing protocol is being associated with
+ *
+ * Typically, invoked directly or indirectly from ns3::Ipv6::SetRoutingProtocol
+ */
+ virtual void SetIpv6 (Ptr<Ipv6> ipv6) = 0;
+};
+
+} //namespace ns3
+
+#endif /* IPV6_ROUTING_PROTOCOL_H */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ipv6.cc Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,60 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+/* taken from src/node/ipv4.h and adapted to IPv6 */
+
+#include "ns3/assert.h"
+#include "ns3/node.h"
+#include "ns3/boolean.h"
+#include "ipv6.h"
+
+namespace ns3
+{
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6);
+
+TypeId Ipv6::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::Ipv6")
+ .SetParent<Object> ()
+ .AddAttribute ("IpForward", "Globally enable or disable IP forwarding for all current and future IPv6 devices.",
+ BooleanValue (false),
+ MakeBooleanAccessor (&Ipv6::SetIpForward,
+ &Ipv6::GetIpForward),
+ MakeBooleanChecker ())
+#if 0
+ .AddAttribute ("MtuDiscover", "If enabled, every outgoing IPv6 packet will have the DF flag set.",
+ BooleanValue (false),
+ MakeBooleanAccessor (&UdpSocket::SetMtuDiscover,
+ &UdpSocket::GetMtuDiscover),
+ MakeBooleanChecker ())
+#endif
+ ;
+ return tid;
+}
+
+Ipv6::Ipv6 ()
+{}
+
+Ipv6::~Ipv6 ()
+{}
+
+} /* namespace ns3 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ipv6.h Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,289 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+/* taken from src/node/ipv4.h and adapted to IPv6 */
+
+#ifndef IPV6_H
+#define IPV6_H
+
+#include <stdint.h>
+#include "ns3/object.h"
+#include "ns3/socket.h"
+#include "ns3/callback.h"
+#include "ipv6-address.h"
+#include "ipv6-interface-address.h"
+
+namespace ns3 {
+
+class Node;
+class NetDevice;
+class Packet;
+class Ipv6RoutingProtocol;
+
+/**
+ * \ingroup node
+ * \defgroup ipv6 Ipv6
+ */
+
+/**
+ * \ingroup ipv6
+ * \brief Access to the IPv6 forwarding table, interfaces, and configuration
+ *
+ * This class defines the API to manipulate the following aspects of
+ * the IPv6 implementation:
+ * -# set/get an Ipv6RoutingProtocol
+ * -# register a NetDevice for use by the IPv6 layer (basically, to
+ * create IPv6-related state such as addressing and neighbor cache that
+ * is associated with a NetDevice)
+ * -# manipulate the status of the NetDevice from the IPv6 perspective,
+ * such as marking it as Up or Down,
+ * -# adding, deleting, and getting addresses associated to the IPv6
+ * interfaces.
+ * -# exporting IPv6 configuration attributes
+ *
+ * Each NetDevice has conceptually a single IPv6 interface associated
+ * with it (the corresponding structure in the Linux IPv6 implementation
+ * is struct in_device). Each interface may have one or more IPv6
+ * addresses associated with it. Each IPv6 address may have different
+ * subnet mask, scope, etc., so all of this per-address information
+ * is stored in an Ipv6InterfaceAddress class (the corresponding
+ * structure in Linux is struct in6_ifaddr)
+ *
+ * IPv6 attributes such as whether IP forwarding is enabled and disabled
+ * are also stored in this class
+ *
+ * TO DO: Add API to allow access to the IPv6 neighbor table
+ *
+ * \see Ipv6RoutingProtocol
+ * \see Ipv6InterfaceAddress
+ */
+class Ipv6 : public Object
+{
+public:
+ static TypeId GetTypeId (void);
+
+ /**
+ * \brief Constructor.
+ */
+ Ipv6 ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Ipv6 ();
+
+ /**
+ * \brief Register a new routing protocol to be used by this IPv6 stack
+ *
+ * This call will replace any routing protocol that has been previously
+ * registered. If you want to add multiple routing protocols, you must
+ * add them to a Ipv6ListRoutingProtocol directly.
+ *
+ * \param routingProtocol smart pointer to Ipv6RoutingProtocol object
+ */
+ virtual void SetRoutingProtocol (Ptr<Ipv6RoutingProtocol> routingProtocol) = 0;
+
+ /**
+ * \brief Get the routing protocol to be used by this IPv6 stack
+ *
+ * \returns smart pointer to Ipv6RoutingProtocol object, or null pointer if none
+ */
+ virtual Ptr<Ipv6RoutingProtocol> GetRoutingProtocol (void) const = 0;
+
+ /**
+ * \param device device to add to the list of IPv6 interfaces
+ * which can be used as output interfaces during packet forwarding.
+ * \returns the index of the IPv6 interface added.
+ *
+ * Once a device has been added, it can never be removed: if you want
+ * to disable it, you can invoke Ipv6::SetDown which will
+ * make sure that it is never used during packet forwarding.
+ */
+ virtual uint32_t AddInterface (Ptr<NetDevice> device) = 0;
+
+ /**
+ * \returns the number of interfaces added by the user.
+ */
+ virtual uint32_t GetNInterfaces (void) const = 0;
+
+ /**
+ * \brief Return the interface number of the interface that has been
+ * assigned the specified IP address.
+ *
+ * \param address The IP address being searched for
+ * \returns The interface number of the IPv6 interface with the given
+ * address or -1 if not found.
+ *
+ * Each IP interface has one or more IP addresses associated with it.
+ * This method searches the list of interfaces for one that holds a
+ * particular address. This call takes an IP address as a parameter and
+ * returns the interface number of the first interface that has been assigned
+ * that address, or -1 if not found. There must be an exact match.
+ */
+ virtual int32_t GetInterfaceForAddress (Ipv6Address address) const = 0;
+
+ /**
+ * \brief Return the interface number of first interface found that
+ * has an IPv6 address within the prefix specified by the input
+ * address and mask parameters
+ *
+ * \param address The IP address assigned to the interface of interest.
+ * \param mask The IP prefix to use in the mask
+ * \returns The interface number of the IPv6 interface with the given
+ * address or -1 if not found.
+ *
+ * Each IP interface has one or more IP addresses associated with it.
+ * This method searches the list of interfaces for the first one found
+ * that holds an address that is included within the prefix
+ * formed by the input address and mask parameters. The value -1 is
+ * returned if no match is found.
+ */
+ virtual int32_t GetInterfaceForPrefix (Ipv6Address address,
+ Ipv6Prefix mask) const = 0;
+
+ /**
+ * \param interface The interface number of an IPv6 interface.
+ * \returns The NetDevice associated with the IPv6 interface number.
+ */
+ virtual Ptr<NetDevice> GetNetDevice (uint32_t interface) = 0;
+
+ /**
+ * \param device The NetDevice for an Ipv6Interface
+ * \returns The interface number of an IPv6 interface or -1 if not found.
+ */
+ virtual int32_t GetInterfaceForDevice (Ptr<const NetDevice> device) const = 0;
+
+ /**
+ * \param interface Interface number of an IPv6 interface
+ * \param address Ipv6InterfaceAddress address to associate with the underlying IPv6 interface
+ * \returns true if the operation succeeded
+ */
+ virtual bool AddAddress (uint32_t interface, Ipv6InterfaceAddress address) = 0;
+
+ /**
+ * \param interface Interface number of an IPv6 interface
+ * \returns the number of Ipv6InterfaceAddress entries for the interface.
+ */
+ virtual uint32_t GetNAddresses (uint32_t interface) const = 0;
+
+ /**
+ * Because addresses can be removed, the addressIndex is not guaranteed
+ * to be static across calls to this method.
+ *
+ * \param interface Interface number of an IPv6 interface
+ * \param addressIndex index of Ipv6InterfaceAddress
+ * \returns the Ipv6InterfaceAddress associated to the interface and addresIndex
+ */
+ virtual Ipv6InterfaceAddress GetAddress (uint32_t interface, uint32_t addressIndex) const = 0;
+
+ /**
+ * Remove the address at addressIndex on named interface. The addressIndex
+ * for all higher indices will decrement by one after this method is called;
+ * so, for example, to remove 5 addresses from an interface i, one could
+ * call RemoveAddress (i, 0); 5 times.
+ *
+ * \param interface Interface number of an IPv6 interface
+ * \param addressIndex index of Ipv6InterfaceAddress to remove
+ * \returns true if the operation succeeded
+ */
+ virtual bool RemoveAddress (uint32_t interface, uint32_t addressIndex) = 0;
+
+ /**
+ * \param interface The interface number of an IPv6 interface
+ * \param metric routing metric (cost) associated to the underlying
+ * IPv6 interface
+ */
+ virtual void SetMetric (uint32_t interface, uint16_t metric) = 0;
+
+ /**
+ * \param interface The interface number of an IPv6 interface
+ * \returns routing metric (cost) associated to the underlying
+ * IPv6 interface
+ */
+ virtual uint16_t GetMetric (uint32_t interface) const = 0;
+
+ /**
+ * \param interface Interface number of IPv6 interface
+ * \returns the Maximum Transmission Unit (in bytes) associated
+ * to the underlying IPv6 interface
+ */
+ virtual uint16_t GetMtu (uint32_t interface) const = 0;
+
+ /**
+ * \param interface Interface number of IPv6 interface
+ * \returns true if the underlying interface is in the "up" state,
+ * false otherwise.
+ */
+ virtual bool IsUp (uint32_t interface) const = 0;
+
+ /**
+ * \param interface Interface number of IPv6 interface
+ *
+ * Set the interface into the "up" state. In this state, it is
+ * considered valid during IPv6 forwarding.
+ */
+ virtual void SetUp (uint32_t interface) = 0;
+
+ /**
+ * \param interface Interface number of IPv6 interface
+ *
+ * Set the interface into the "down" state. In this state, it is
+ * ignored during IPv6 forwarding.
+ */
+ virtual void SetDown (uint32_t interface) = 0;
+
+ /**
+ * \param interface Interface number of IPv6 interface
+ * \returns true if IPv6 forwarding enabled for input datagrams on this device
+ */
+ virtual bool IsForwarding (uint32_t interface) const = 0;
+
+ /**
+ * \param interface Interface number of IPv6 interface
+ * \param val Value to set the forwarding flag
+ *
+ * If set to true, IPv6 forwarding is enabled for input datagrams on this device
+ */
+ virtual void SetForwarding (uint32_t interface, bool val) = 0;
+
+ /**
+ * \brief Any interface magic number.
+ */
+ static const uint32_t IF_ANY = 0xffffffff;
+
+private:
+ // Indirect the IPv6 attributes through private pure virtual methods
+ /**
+ * \brief Set IPv6 forwarding state.
+ * \param forward IPv6 forwarding enabled or not
+ */
+ virtual void SetIpForward (bool forward) = 0;
+
+ /**
+ * \brief Get IPv6 forwarding state.
+ * \return forwarding state (enabled or not)
+ */
+ virtual bool GetIpForward (void) const = 0;
+};
+
+} // namespace ns3
+
+#endif /* IPV6_H */
+
--- a/src/node/wscript Tue Aug 25 20:12:53 2009 +0400
+++ b/src/node/wscript Wed Aug 26 15:29:03 2009 +0400
@@ -33,13 +33,18 @@
'tcp-socket.cc',
'tcp-socket-factory.cc',
'ipv4.cc',
+ 'ipv4-raw-socket-factory.cc',
'application.cc',
'simple-channel.cc',
'simple-net-device.cc',
'inet6-socket-address.cc',
'ipv6-address.cc',
'ipv6-header.cc',
- 'ipv4-raw-socket-factory.cc',
+ 'ipv6-interface-address.cc',
+ 'ipv6-route.cc',
+ 'ipv6.cc',
+ 'ipv6-raw-socket-factory.cc',
+ 'ipv6-routing-protocol.cc',
]
headers = bld.new_task_gen('ns3header')
@@ -56,7 +61,7 @@
'ipv4-address-generator.h',
'ipv4-header.h',
'net-device.h',
- 'address-utils.h',
+ 'address-utils.h',
'ipv4-route.h',
'ipv4-routing-protocol.h',
'queue.h',
@@ -74,11 +79,16 @@
'tcp-socket.h',
'tcp-socket-factory.h',
'ipv4.h',
+ 'ipv4-raw-socket-factory.h',
'application.h',
'simple-channel.h',
'simple-net-device.h',
'inet6-socket-address.h',
'ipv6-address.h',
'ipv6-header.h',
- 'ipv4-raw-socket-factory.h',
+ 'ipv6-interface-address.h',
+ 'ipv6-route.h',
+ 'ipv6.h',
+ 'ipv6-raw-socket-factory.h',
+ 'ipv6-routing-protocol.h',
]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/list-routing/ipv6-list-routing.cc Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,423 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include "ns3/log.h"
+#include "ns3/ipv6.h"
+#include "ns3/ipv6-route.h"
+#include "ns3/node.h"
+#include "ns3/ipv6-static-routing.h"
+#include "ipv6-list-routing.h"
+
+NS_LOG_COMPONENT_DEFINE ("Ipv6ListRouting");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6ListRouting);
+
+TypeId
+Ipv6ListRouting::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::Ipv6ListRouting")
+ .SetParent<Ipv6RoutingProtocol> ()
+ .AddConstructor<Ipv6ListRouting> ()
+ ;
+ return tid;
+}
+
+
+Ipv6ListRouting::Ipv6ListRouting ()
+ : m_ipv6 (0)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+Ipv6ListRouting::~Ipv6ListRouting ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+void
+Ipv6ListRouting::DoDispose (void)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ for (Ipv6RoutingProtocolList::iterator rprotoIter = m_routingProtocols.begin ();
+ rprotoIter != m_routingProtocols.end (); rprotoIter++)
+ {
+ // Note: Calling dispose on these protocols causes memory leak
+ // The routing protocols should not maintain a pointer to
+ // this object, so Dispose () shouldn't be necessary.
+ (*rprotoIter).second = 0;
+ }
+ m_routingProtocols.clear ();
+ m_ipv6 = 0;
+}
+
+Ptr<Ipv6Route>
+Ipv6ListRouting::RouteOutput (Ptr<Packet> p, const Ipv6Header &header, uint32_t oif, enum Socket::SocketErrno &sockerr)
+{
+ NS_LOG_FUNCTION (this << header.GetDestinationAddress () << header.GetSourceAddress () << oif);
+ Ptr<Ipv6Route> route;
+
+ for (Ipv6RoutingProtocolList::const_iterator i = m_routingProtocols.begin ();
+ i != m_routingProtocols.end (); i++)
+ {
+ NS_LOG_LOGIC ("Checking protocol " << (*i).second->GetInstanceTypeId () << " with priority " << (*i).first);
+ NS_LOG_LOGIC ("Requesting source address for destination " << header.GetDestinationAddress ());
+ route = (*i).second->RouteOutput (p, header, oif, sockerr);
+ if (route)
+ {
+ NS_LOG_LOGIC ("Found route " << route);
+ sockerr = Socket::ERROR_NOTERROR;
+ return route;
+ }
+ }
+ NS_LOG_LOGIC ("Done checking " << GetTypeId ());
+ NS_LOG_LOGIC ("");
+ sockerr = Socket::ERROR_NOROUTETOHOST;
+ return 0;
+}
+
+// Patterned after Linux ip_route_input and ip_route_input_slow
+bool
+Ipv6ListRouting::RouteInput (Ptr<const Packet> p, const Ipv6Header &header, Ptr<const NetDevice> idev,
+ UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+ LocalDeliverCallback lcb, ErrorCallback ecb)
+{
+ bool retVal = false;
+ NS_LOG_FUNCTION (p << header << idev);
+ NS_LOG_LOGIC ("RouteInput logic for node: " << m_ipv6->GetObject<Node> ()->GetId ());
+
+ NS_ASSERT (m_ipv6 != 0);
+ // Check if input device supports IP
+ NS_ASSERT (m_ipv6->GetInterfaceForDevice (idev) >= 0);
+ uint32_t iif = m_ipv6->GetInterfaceForDevice (idev);
+ Ipv6Address dst = header.GetDestinationAddress ();
+
+ // Multicast recognition; handle local delivery here
+ //
+ if (dst.IsMulticast ())
+ {
+#ifdef NOTYET
+ if (m_ipv6->MulticastCheckGroup (iif, dst))
+#endif
+ if (true)
+ {
+ NS_LOG_LOGIC ("Multicast packet for me-- local deliver");
+ Ptr<Packet> packetCopy = p->Copy ();
+ // Here may want to disable lcb callback in recursive RouteInput
+ // call below
+ lcb (packetCopy, header, iif);
+ // Fall through-- we may also need to forward this
+ retVal = true;
+ }
+
+ /* do not forward link-local multicast address */
+ if (dst == Ipv6Address::GetAllNodesMulticast () || dst == Ipv6Address::GetAllRoutersMulticast () || dst == Ipv6Address::GetAllHostsMulticast ())
+ {
+ return retVal;
+ }
+
+ for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
+ m_routingProtocols.begin (); rprotoIter != m_routingProtocols.end ();
+ rprotoIter++)
+ {
+ NS_LOG_LOGIC ("Multicast packet for me-- trying to forward");
+ if ((*rprotoIter).second->RouteInput (p, header, idev, ucb, mcb, lcb, ecb))
+ {
+ retVal = true;
+ }
+ }
+ return retVal;
+ }
+
+ // TODO: Configurable option to enable RFC 1222 Strong End System Model
+ // Right now, we will be permissive and allow a source to send us
+ // a packet to one of our other interface addresses; that is, the
+ // destination unicast address does not match one of the iif addresses,
+ // but we check our other interfaces. This could be an option
+ // (to remove the outer loop immediately below and just check iif).
+ for (uint32_t j = 0; j < m_ipv6->GetNInterfaces (); j++)
+ {
+ for (uint32_t i = 0; i < m_ipv6->GetNAddresses (j); i++)
+ {
+ Ipv6InterfaceAddress iaddr = m_ipv6->GetAddress (j, i);
+ Ipv6Address addr = iaddr.GetAddress ();
+ if (addr.IsEqual (header.GetDestinationAddress ()))
+ {
+ if (j == iif)
+ {
+ NS_LOG_LOGIC ("For me (destination " << addr << " match)");
+ }
+ else
+ {
+ NS_LOG_LOGIC ("For me (destination " << addr << " match) on another interface " << header.GetDestinationAddress ());
+ }
+ lcb (p, header, iif);
+ return true;
+ }
+ NS_LOG_LOGIC ("Address "<< addr << " not a match");
+ }
+ }
+ // Check if input device supports IP forwarding
+ if (m_ipv6->IsForwarding (iif) == false)
+ {
+ NS_LOG_LOGIC ("Forwarding disabled for this interface");
+ ecb (p, header, Socket::ERROR_NOROUTETOHOST);
+ return false;
+ }
+ // Next, try to find a route
+ for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
+ m_routingProtocols.begin ();
+ rprotoIter != m_routingProtocols.end ();
+ rprotoIter++)
+ {
+ if ((*rprotoIter).second->RouteInput (p, header, idev, ucb, mcb, lcb, ecb))
+ {
+ return true;
+ }
+ }
+ // No routing protocol has found a route.
+ return retVal;
+}
+
+void
+Ipv6ListRouting::NotifyInterfaceUp (uint32_t interface)
+{
+ NS_LOG_FUNCTION (this << interface);
+ for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
+ m_routingProtocols.begin ();
+ rprotoIter != m_routingProtocols.end ();
+ rprotoIter++)
+ {
+ (*rprotoIter).second->NotifyInterfaceUp (interface);
+ }
+}
+void
+Ipv6ListRouting::NotifyInterfaceDown (uint32_t interface)
+{
+ NS_LOG_FUNCTION (this << interface);
+ for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
+ m_routingProtocols.begin ();
+ rprotoIter != m_routingProtocols.end ();
+ rprotoIter++)
+ {
+ (*rprotoIter).second->NotifyInterfaceDown (interface);
+ }
+}
+void
+Ipv6ListRouting::NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address)
+{
+ NS_LOG_FUNCTION (this << interface << address);
+ for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
+ m_routingProtocols.begin ();
+ rprotoIter != m_routingProtocols.end ();
+ rprotoIter++)
+ {
+ (*rprotoIter).second->NotifyAddAddress (interface, address);
+ }
+}
+void
+Ipv6ListRouting::NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address)
+{
+ NS_LOG_FUNCTION (this << interface << address);
+ for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
+ m_routingProtocols.begin ();
+ rprotoIter != m_routingProtocols.end ();
+ rprotoIter++)
+ {
+ (*rprotoIter).second->NotifyRemoveAddress (interface, address);
+ }
+}
+
+void Ipv6ListRouting::NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
+{
+ NS_LOG_FUNCTION (this << dst << mask << nextHop << interface);
+ for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
+ m_routingProtocols.begin ();
+ rprotoIter != m_routingProtocols.end ();
+ rprotoIter++)
+ {
+ (*rprotoIter).second->NotifyAddRoute (dst, mask, nextHop, interface, prefixToUse);
+ }
+}
+
+void Ipv6ListRouting::NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface)
+{
+ NS_LOG_FUNCTION (this << dst << mask << nextHop << interface);
+ for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
+ m_routingProtocols.begin ();
+ rprotoIter != m_routingProtocols.end ();
+ rprotoIter++)
+ {
+ (*rprotoIter).second->NotifyRemoveRoute (dst, mask, nextHop, interface);
+ }
+}
+
+void
+Ipv6ListRouting::SetIpv6 (Ptr<Ipv6> ipv6)
+{
+ NS_LOG_FUNCTION (this << ipv6);
+ NS_ASSERT (m_ipv6 == 0);
+ for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
+ m_routingProtocols.begin ();
+ rprotoIter != m_routingProtocols.end ();
+ rprotoIter++)
+ {
+ (*rprotoIter).second->SetIpv6 (ipv6);
+ }
+ m_ipv6 = ipv6;
+}
+
+void
+Ipv6ListRouting::AddRoutingProtocol (Ptr<Ipv6RoutingProtocol> routingProtocol, int16_t priority)
+{
+ NS_LOG_FUNCTION (this << routingProtocol->GetInstanceTypeId () << priority);
+ m_routingProtocols.push_back (std::make_pair (priority, routingProtocol));
+ m_routingProtocols.sort ( Compare );
+ if (m_ipv6 != 0)
+ {
+ routingProtocol->SetIpv6 (m_ipv6);
+ }
+}
+
+uint32_t
+Ipv6ListRouting::GetNRoutingProtocols (void) const
+{
+ NS_LOG_FUNCTION (this);
+ return m_routingProtocols.size ();
+}
+
+Ptr<Ipv6RoutingProtocol>
+Ipv6ListRouting::GetRoutingProtocol (uint32_t index, int16_t& priority) const
+{
+ NS_LOG_FUNCTION (index);
+ if (index > m_routingProtocols.size ())
+ {
+ NS_FATAL_ERROR ("Ipv6ListRouting::GetRoutingProtocol (): index " << index << " out of range");
+ }
+ uint32_t i = 0;
+ for (Ipv6RoutingProtocolList::const_iterator rprotoIter = m_routingProtocols.begin ();
+ rprotoIter != m_routingProtocols.end (); rprotoIter++, i++)
+ {
+ if (i == index)
+ {
+ priority = (*rprotoIter).first;
+ return (*rprotoIter).second;
+ }
+ }
+ return 0;
+}
+
+bool
+Ipv6ListRouting::Compare (const Ipv6RoutingProtocolEntry& a, const Ipv6RoutingProtocolEntry& b)
+{
+ return a.first > b.first;
+}
+
+
+} // namespace ns3
+
+#ifdef RUN_SELF_TESTS
+
+#include "ns3/test.h"
+#include "ipv6-list-routing.h"
+#include "ns3/ipv6-routing-protocol.h"
+
+namespace ns3 {
+
+class Ipv6ARouting : public Ipv6RoutingProtocol {
+public:
+ Ptr<Ipv6Route> RouteOutput (Ptr<Packet> p, const Ipv6Header &header, uint32_t oif, Socket::SocketErrno &sockerr) { return 0;}
+ bool RouteInput (Ptr<const Packet> p, const Ipv6Header &header, Ptr<const NetDevice> idev,
+ UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+ LocalDeliverCallback lcb, ErrorCallback ecb) {return false;}
+ void NotifyInterfaceUp (uint32_t interface) {}
+ void NotifyInterfaceDown (uint32_t interface) {}
+ void NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address) {}
+ void NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address) {}
+ void NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ()) {}
+ void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface) {}
+ void SetIpv6 (Ptr<Ipv6> ipv6) {}
+};
+
+class Ipv6BRouting : public Ipv6RoutingProtocol {
+public:
+ Ptr<Ipv6Route> RouteOutput (Ptr<Packet> p, const Ipv6Header &header, uint32_t oif, Socket::SocketErrno &sockerr) { return 0;}
+ bool RouteInput (Ptr<const Packet> p, const Ipv6Header &header, Ptr<const NetDevice> idev,
+ UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+ LocalDeliverCallback lcb, ErrorCallback ecb) {return false;}
+ void NotifyInterfaceUp (uint32_t interface) {}
+ void NotifyInterfaceDown (uint32_t interface) {}
+ void NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address) {}
+ void NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address) {}
+ void NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ()) {}
+ void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface) {}
+ void SetIpv6 (Ptr<Ipv6> ipv6) {}
+};
+
+class Ipv6ListRoutingTest: public Test {
+public:
+ virtual bool RunTests (void);
+ Ipv6ListRoutingTest ();
+};
+
+Ipv6ListRoutingTest::Ipv6ListRoutingTest ()
+ : Test ("Ipv6ListRouting") {}
+
+bool
+Ipv6ListRoutingTest::RunTests (void)
+{
+ bool result = true;
+ Ptr<Ipv6ListRouting> lr = CreateObject<Ipv6ListRouting> ();
+ Ptr<Ipv6RoutingProtocol> aRouting = CreateObject<Ipv6ARouting> ();
+ Ptr<Ipv6RoutingProtocol> bRouting = CreateObject<Ipv6BRouting> ();
+ // The Ipv6ARouting should be added with higher priority (larger integer
+ // value) and will be fetched first below
+ lr->AddRoutingProtocol (aRouting, 10);
+ lr->AddRoutingProtocol (bRouting, 5);
+ int16_t first = 3;
+ int16_t second = 3;
+ uint32_t num = lr->GetNRoutingProtocols ();
+ NS_TEST_ASSERT_EQUAL (num, 2);
+ Ptr<Ipv6RoutingProtocol> firstRp = lr->GetRoutingProtocol (0, first);
+ NS_TEST_ASSERT_EQUAL (10, first);
+ NS_TEST_ASSERT_EQUAL (firstRp, aRouting);
+ Ptr<Ipv6RoutingProtocol> secondRp = lr->GetRoutingProtocol (1, second);
+ NS_TEST_ASSERT_EQUAL (5, second);
+ NS_TEST_ASSERT_EQUAL (secondRp, bRouting);
+
+ // Test negative values
+ lr = CreateObject<Ipv6ListRouting> ();
+ // The Ipv6BRouting should be added with higher priority (larger integer value)
+ lr->AddRoutingProtocol (aRouting, -10);
+ lr->AddRoutingProtocol (bRouting, -5);
+ num = lr->GetNRoutingProtocols ();
+ NS_TEST_ASSERT_EQUAL (num, 2);
+ firstRp = lr->GetRoutingProtocol (0, first);
+ NS_TEST_ASSERT_EQUAL (-5, first);
+ NS_TEST_ASSERT_EQUAL (firstRp, bRouting);
+
+ return result;
+}
+
+static Ipv6ListRoutingTest gIpv6ListRoutingTest;
+
+} // namespace ns3
+
+#endif /* RUN_SELF_TESTS */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/list-routing/ipv6-list-routing.h Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,105 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef IPV6_LIST_ROUTING_H
+#define IPV6_LIST_ROUTING_H
+
+#include <list>
+#include "ns3/ipv6-routing-protocol.h"
+
+namespace ns3 {
+
+/**
+ * \ingroup routing
+ * \defgroup ipv6ListRouting Ipv6 List Routing
+ */
+/**
+ * \ingroup ipv6ListRouting
+ *
+ * This class is a specialization of Ipv6RoutingProtocol that allows
+ * other instances of Ipv6RoutingProtocol to be inserted in a
+ * prioritized list. Routing protocols in the list are consulted one
+ * by one, from highest to lowest priority, until a routing protocol
+ * is found that will take the packet (this corresponds to a non-zero
+ * return value to RouteOutput, or a return value of true to RouteInput).
+ * The order by which routing protocols with the same priority value
+ * are consulted is undefined.
+ *
+ */
+class Ipv6ListRouting : public Ipv6RoutingProtocol
+{
+public:
+ static TypeId GetTypeId (void);
+
+ Ipv6ListRouting ();
+ virtual ~Ipv6ListRouting ();
+
+ /**
+ * \brief Register a new routing protocol to be used in this IPv4 stack
+ *
+ * \param routingProtocol new routing protocol implementation object
+ * \param priority priority to give to this routing protocol.
+ * Values may range between -32768 and +32767.
+ */
+ virtual void AddRoutingProtocol (Ptr<Ipv6RoutingProtocol> routingProtocol, int16_t priority);
+ /**
+ * \return number of routing protocols in the list
+ */
+ virtual uint32_t GetNRoutingProtocols (void) const;
+ /**
+ * Return pointer to routing protocol stored at index, with the
+ * first protocol (index 0) the highest priority, the next one (index 1)
+ * the second highest priority, and so on. The priority parameter is an
+ * output parameter and it returns the integer priority of the protocol.
+ *
+ * \return pointer to routing protocol indexed by
+ * \param index index of protocol to return
+ * \param priority output parameter, set to the priority of the protocol
+ being returned
+ */
+ virtual Ptr<Ipv6RoutingProtocol> GetRoutingProtocol (uint32_t index, int16_t& priority) const;
+
+ // Below are from Ipv6RoutingProtocol
+ virtual Ptr<Ipv6Route> RouteOutput (Ptr<Packet> p, const Ipv6Header &header, uint32_t oif, Socket::SocketErrno &sockerr);
+
+ virtual bool RouteInput (Ptr<const Packet> p, const Ipv6Header &header, Ptr<const NetDevice> idev,
+ UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+ LocalDeliverCallback lcb, ErrorCallback ecb);
+ virtual void NotifyInterfaceUp (uint32_t interface);
+ virtual void NotifyInterfaceDown (uint32_t interface);
+ virtual void NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address);
+ virtual void NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address);
+ virtual void NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ());
+ virtual void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface);
+ virtual void SetIpv6 (Ptr<Ipv6> ipv6);
+
+protected:
+ void DoDispose (void);
+private:
+ typedef std::pair<int16_t, Ptr<Ipv6RoutingProtocol> > Ipv6RoutingProtocolEntry;
+ typedef std::list<Ipv6RoutingProtocolEntry> Ipv6RoutingProtocolList;
+ Ipv6RoutingProtocolList m_routingProtocols;
+ static bool Compare (const Ipv6RoutingProtocolEntry& a, const Ipv6RoutingProtocolEntry& b);
+ Ptr<Ipv6> m_ipv6;
+
+};
+
+} //namespace ns3
+
+#endif /* IPV6_LIST_ROUTING_H */
+
--- a/src/routing/list-routing/wscript Tue Aug 25 20:12:53 2009 +0400
+++ b/src/routing/list-routing/wscript Wed Aug 26 15:29:03 2009 +0400
@@ -4,10 +4,12 @@
module = bld.create_ns3_module('list-routing', ['node'])
module.source = [
'ipv4-list-routing.cc',
+ 'ipv6-list-routing.cc',
]
headers = bld.new_task_gen('ns3header')
headers.module = 'list-routing'
headers.source = [
'ipv4-list-routing.h',
+ 'ipv6-list-routing.h',
]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/static-routing/ipv6-routing-table-entry.cc Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,331 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#include "ipv6-routing-table-entry.h"
+#include "ns3/assert.h"
+
+namespace ns3
+{
+
+Ipv6RoutingTableEntry::Ipv6RoutingTableEntry ()
+{
+}
+
+Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6RoutingTableEntry const& route)
+ : m_dest (route.m_dest),
+ m_destNetworkPrefix (route.m_destNetworkPrefix),
+ m_gateway (route.m_gateway),
+ m_interface (route.m_interface),
+ m_prefixToUse (route.m_prefixToUse)
+{
+}
+
+Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6RoutingTableEntry const* route)
+ : m_dest (route->m_dest),
+ m_destNetworkPrefix (route->m_destNetworkPrefix),
+ m_gateway (route->m_gateway),
+ m_interface (route->m_interface),
+ m_prefixToUse (route->m_prefixToUse)
+{
+}
+
+Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6Address dest, Ipv6Address gateway, uint32_t interface)
+ : m_dest (dest),
+ m_destNetworkPrefix (Ipv6Prefix::GetZero ()),
+ m_gateway (gateway),
+ m_interface (interface),
+ m_prefixToUse (Ipv6Address ("::"))
+{
+}
+
+Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6Address dest, uint32_t interface)
+ : m_dest (dest),
+ m_destNetworkPrefix (Ipv6Prefix (128)),
+ m_gateway (Ipv6Address::GetZero ()),
+ m_interface (interface),
+ m_prefixToUse (Ipv6Address ("::"))
+{
+}
+
+Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address gateway, uint32_t interface, Ipv6Address prefixToUse)
+ : m_dest (network),
+ m_destNetworkPrefix (networkPrefix),
+ m_gateway (gateway),
+ m_interface (interface),
+ m_prefixToUse (prefixToUse)
+{
+}
+
+Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address gateway, uint32_t interface)
+ : m_dest (network),
+ m_destNetworkPrefix (networkPrefix),
+ m_gateway (gateway),
+ m_interface (interface),
+ m_prefixToUse (Ipv6Address::GetZero ())
+{
+}
+
+
+Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface, Ipv6Address prefixToUse)
+ : m_dest (network),
+ m_destNetworkPrefix (networkPrefix),
+ m_gateway (Ipv6Address::GetZero ()),
+ m_interface (interface),
+ m_prefixToUse (prefixToUse)
+{
+}
+
+Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface)
+ : m_dest (network),
+ m_destNetworkPrefix (networkPrefix),
+ m_gateway (Ipv6Address::GetZero ()),
+ m_interface (interface),
+ m_prefixToUse (Ipv6Address ("::"))
+{
+}
+
+Ipv6RoutingTableEntry::~Ipv6RoutingTableEntry ()
+{
+}
+
+bool Ipv6RoutingTableEntry::IsHost () const
+{
+ static Ipv6Prefix prefix (128);
+ if (m_destNetworkPrefix.IsEqual (prefix))
+ {
+ return true;
+ }
+ return false;
+}
+
+Ipv6Address Ipv6RoutingTableEntry::GetDest () const
+{
+ return m_dest;
+}
+
+Ipv6Address Ipv6RoutingTableEntry::GetPrefixToUse () const
+{
+ return m_prefixToUse;
+}
+
+void Ipv6RoutingTableEntry::SetPrefixToUse (Ipv6Address prefix)
+{
+ m_prefixToUse = prefix;
+}
+
+bool Ipv6RoutingTableEntry::IsNetwork () const
+{
+ return !IsHost ();
+}
+
+bool Ipv6RoutingTableEntry::IsDefault () const
+{
+ if (m_dest.IsEqual (Ipv6Address::GetZero ()))
+ {
+ return true;
+ }
+ return false;
+}
+
+Ipv6Address Ipv6RoutingTableEntry::GetDestNetwork () const
+{
+ return m_dest;
+}
+
+Ipv6Prefix Ipv6RoutingTableEntry::GetDestNetworkPrefix () const
+{
+ return m_destNetworkPrefix;
+}
+
+bool Ipv6RoutingTableEntry::IsGateway () const
+{
+ if (m_gateway.IsEqual (Ipv6Address::GetZero ()))
+ {
+ return false;
+ }
+ return true;
+}
+
+Ipv6Address Ipv6RoutingTableEntry::GetGateway () const
+{
+ return m_gateway;
+}
+
+Ipv6RoutingTableEntry Ipv6RoutingTableEntry::CreateHostRouteTo (Ipv6Address dest, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
+{
+ return Ipv6RoutingTableEntry (dest, Ipv6Prefix (128), nextHop, interface, prefixToUse);
+}
+
+Ipv6RoutingTableEntry Ipv6RoutingTableEntry::CreateHostRouteTo (Ipv6Address dest, uint32_t interface)
+{
+ return Ipv6RoutingTableEntry (dest, interface);
+}
+
+Ipv6RoutingTableEntry Ipv6RoutingTableEntry::CreateNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface)
+{
+ return Ipv6RoutingTableEntry (network, networkPrefix, nextHop, interface);
+}
+
+Ipv6RoutingTableEntry Ipv6RoutingTableEntry::CreateNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
+{
+ return Ipv6RoutingTableEntry (network, networkPrefix, nextHop, interface, prefixToUse);
+}
+
+Ipv6RoutingTableEntry Ipv6RoutingTableEntry::CreateNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface)
+{
+ return Ipv6RoutingTableEntry (network, networkPrefix, interface, network);
+}
+
+Ipv6RoutingTableEntry Ipv6RoutingTableEntry::CreateDefaultRoute (Ipv6Address nextHop, uint32_t interface)
+{
+ return Ipv6RoutingTableEntry (Ipv6Address::GetZero (), nextHop, interface);
+}
+
+uint32_t Ipv6RoutingTableEntry::GetInterface () const
+{
+ return m_interface;
+}
+
+std::ostream& operator<< (std::ostream& os, Ipv6RoutingTableEntry const& route)
+{
+ if (route.IsDefault ())
+ {
+ NS_ASSERT (route.IsGateway ());
+ os << "default out =" << route.GetInterface () << ", next hop =" << route.GetGateway ();
+ }
+ else if (route.IsHost ())
+ {
+ if (route.IsGateway ())
+ {
+ os << "host ="<< route.GetDest () <<
+ ", out =" << route.GetInterface () <<
+ ", next hop =" << route.GetGateway ();
+ }
+ else
+ {
+ os << "host =" << route.GetDest () <<
+ ", out =" << route.GetInterface ();
+ }
+ }
+ else if (route.IsNetwork ())
+ {
+ if (route.IsGateway ())
+ {
+ os << "network =" << route.GetDestNetwork () <<
+ ", mask =" << route.GetDestNetworkPrefix () <<
+ ",out =" << route.GetInterface () <<
+ ", next hop =" << route.GetGateway ();
+ }
+ else
+ {
+ os << "network =" << route.GetDestNetwork () <<
+ ", mask =" << route.GetDestNetworkPrefix () <<
+ ",out =" << route.GetInterface ();
+ }
+ }
+ else
+ {
+ NS_ASSERT (false);
+ }
+ return os;
+}
+
+Ipv6MulticastRoutingTableEntry::Ipv6MulticastRoutingTableEntry ()
+{
+}
+
+Ipv6MulticastRoutingTableEntry::Ipv6MulticastRoutingTableEntry (Ipv6MulticastRoutingTableEntry const & route)
+ : m_origin (route.m_origin),
+ m_group (route.m_group),
+ m_inputInterface (route.m_inputInterface),
+ m_outputInterfaces (route.m_outputInterfaces)
+{
+}
+
+Ipv6MulticastRoutingTableEntry::Ipv6MulticastRoutingTableEntry (Ipv6MulticastRoutingTableEntry const* route)
+ : m_origin (route->m_origin),
+ m_group (route->m_group),
+ m_inputInterface (route->m_inputInterface),
+ m_outputInterfaces (route->m_outputInterfaces)
+{
+}
+
+Ipv6MulticastRoutingTableEntry::Ipv6MulticastRoutingTableEntry (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector<uint32_t> outputInterfaces)
+ : m_origin (origin),
+ m_group (group),
+ m_inputInterface (inputInterface),
+ m_outputInterfaces (outputInterfaces)
+{
+}
+
+Ipv6Address Ipv6MulticastRoutingTableEntry::GetOrigin () const
+{
+ return m_origin;
+}
+
+Ipv6Address Ipv6MulticastRoutingTableEntry::GetGroup () const
+{
+ return m_group;
+}
+
+uint32_t Ipv6MulticastRoutingTableEntry::GetInputInterface () const
+{
+ return m_inputInterface;
+}
+
+uint32_t Ipv6MulticastRoutingTableEntry::GetNOutputInterfaces () const
+{
+ return m_outputInterfaces.size ();
+}
+
+uint32_t Ipv6MulticastRoutingTableEntry::GetOutputInterface (uint32_t n) const
+{
+ NS_ASSERT_MSG (n < m_outputInterfaces.size (), "Ipv6MulticastRoutingTableEntry::GetOutputInterface () : index out of bounds");
+
+ return m_outputInterfaces[n];
+}
+
+std::vector <uint32_t> Ipv6MulticastRoutingTableEntry::GetOutputInterfaces () const
+{
+ return m_outputInterfaces;
+}
+
+Ipv6MulticastRoutingTableEntry Ipv6MulticastRoutingTableEntry::CreateMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector<uint32_t> outputInterfaces)
+{
+ return Ipv6MulticastRoutingTableEntry (origin, group, inputInterface, outputInterfaces);
+}
+
+std::ostream& operator<< (std::ostream& os, Ipv6MulticastRoutingTableEntry const& route)
+{
+ os << "origin =" << route.GetOrigin () <<
+ ", group =" << route.GetGroup () <<
+ ", input interface =" << route.GetInputInterface () <<
+ ", output interfaces =";
+
+ for (uint32_t i = 0; i < route.GetNOutputInterfaces (); ++i)
+ {
+ os << route.GetOutputInterface (i) << " ";
+ }
+
+ return os;
+}
+
+} /* namespace ns3 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/static-routing/ipv6-routing-table-entry.h Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,372 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#ifndef IPV6_ROUTING_TABLE_ENTRY_H
+#define IPV6_ROUTING_TABLE_ENTRY_H
+
+#include <list>
+#include <vector>
+#include <ostream>
+
+#include "ns3/ipv6-address.h"
+
+namespace ns3
+{
+
+/**
+ * \class Ipv6RoutingTableEntry
+ * \brief A record of an IPv6 route.
+ */
+class Ipv6RoutingTableEntry
+{
+ public:
+ /**
+ * \brief Constructor.
+ */
+ Ipv6RoutingTableEntry ();
+
+ /**
+ * \brief Copy constructor.
+ * \param route the route to copy
+ */
+ Ipv6RoutingTableEntry (Ipv6RoutingTableEntry const & route);
+
+ /**
+ * \brief Copy constructor.
+ * \param route the route to copy
+ */
+ Ipv6RoutingTableEntry (Ipv6RoutingTableEntry const* route);
+
+ /**
+ * \brief Destructor
+ */
+ ~Ipv6RoutingTableEntry ();
+
+ /**
+ * \brief Is the route entry correspond to a host ?
+ * \return true if the route is a host, false otherwise
+ */
+ bool IsHost () const;
+
+ /**
+ * \brief Get the destination.
+ * \return the IPv6 address of the destination of this route
+ */
+ Ipv6Address GetDest () const;
+
+ /**
+ * \brief Get the prefix to use (for multihomed link).
+ * \return prefix address to use
+ */
+ Ipv6Address GetPrefixToUse () const;
+
+ /**
+ * \brief Set the prefix to use.
+ * \param prefix prefix to use
+ */
+ void SetPrefixToUse (Ipv6Address prefix);
+
+ /**
+ * \brief Is the route entry correspond to a network ?
+ * \return true if the route is a network, false otherwise
+ */
+ bool IsNetwork () const;
+
+ /**
+ * \brief Get the destination network.
+ * \return the destination network
+ */
+ Ipv6Address GetDestNetwork () const;
+
+ /**
+ * \brief Get the destination prefix.
+ * \return the destination prefix
+ */
+ Ipv6Prefix GetDestNetworkPrefix () const;
+
+ /**
+ * \brief Is it the default route ?
+ * \return true if this route is a default route, false otherwise
+ */
+ bool IsDefault () const;
+
+ /**
+ * \brief Is it the gateway ?
+ * \return true if this route is a gateway, false otherwise
+ */
+ bool IsGateway () const;
+
+ /**
+ * \brief Get the gateway.
+ * \return the IPv6 address of the gateway
+ */
+ Ipv6Address GetGateway () const;
+
+ /**
+ * \brief Get the interface index.
+ * \return the index of the interface
+ */
+ uint32_t GetInterface () const;
+
+ /**
+ * \brief Create a route to a host.
+ * \param dest destination address
+ * \param nextHop next hop address to route the packet
+ * \param interface interface index
+ * \param prefixToUse prefix that should be used for source address for this destination
+ * \return IPv6Route object
+ */
+ static Ipv6RoutingTableEntry CreateHostRouteTo (Ipv6Address dest, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse=Ipv6Address ());
+
+ /**
+ * \brief Create a route to a host.
+ * \param dest destination address
+ * \param interface interface index
+ * \return IPv6Route object
+ */
+ static Ipv6RoutingTableEntry CreateHostRouteTo (Ipv6Address dest, uint32_t interface);
+
+ /**
+ * \brief Create a route to a network.
+ * \param network network address
+ * \param networkPrefix network prefix
+ * \param nextHop next hop address to route the packet
+ * \param interface interface index
+ * \return IPv6Route object
+ */
+ static Ipv6RoutingTableEntry CreateNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface);
+
+ /**
+ * \brief Create a route to a network.
+ * \param network network address
+ * \param networkPrefix network prefix
+ * \param nextHop next hop address to route the packet
+ * \param interface interface index
+ * \param prefixToUse prefix that should be used for source address for this destination
+ * \return IPv6Route object
+ */
+ static Ipv6RoutingTableEntry CreateNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse);
+
+ /**
+ * \brief Create a route to a network.
+ * \param network network address
+ * \param networkPrefix network prefix
+ * \param interface interface index
+ * \return IPv6Route object
+ */
+ static Ipv6RoutingTableEntry CreateNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface);
+
+ /**
+ * \brief Create a default route.
+ * \param nextHop next hop address to route the packet
+ * \param interface interface index
+ * \return IPv6Route object
+ */
+ static Ipv6RoutingTableEntry CreateDefaultRoute (Ipv6Address nextHop, uint32_t interface);
+
+ private:
+ /**
+ * \brief Constructor.
+ * \param network network address
+ * \param prefix network prefix
+ * \param gateway the gateway
+ * \param interface the interface index
+ */
+ Ipv6RoutingTableEntry (Ipv6Address network, Ipv6Prefix prefix, Ipv6Address gateway, uint32_t interface);
+
+ /**
+ * \brief Constructor.
+ * \param network network address
+ * \param prefix network prefix
+ * \param interface the interface index
+ * \param prefixToUse prefix to use
+ */
+ Ipv6RoutingTableEntry (Ipv6Address network, Ipv6Prefix prefix, uint32_t interface, Ipv6Address prefixToUse);
+
+ /**
+ * \brief Constructor.
+ * \param network network address
+ * \param prefix network prefix
+ * \param gateway the gateway
+ * \param interface the interface index
+ * \param prefixToUse prefix to use
+ */
+ Ipv6RoutingTableEntry (Ipv6Address network, Ipv6Prefix prefix, Ipv6Address gateway, uint32_t interface, Ipv6Address prefixToUse);
+
+ /**
+ * \brief Constructor.
+ * \param dest destination address
+ * \param prefix destiation prefix
+ * \param interface interface index
+ */
+ Ipv6RoutingTableEntry (Ipv6Address dest, Ipv6Prefix prefix, uint32_t interface);
+
+ /**
+ * \brief Constructor.
+ * \param dest destination address
+ * \param gateway the gateway
+ * \param interface interface index
+ */
+ Ipv6RoutingTableEntry (Ipv6Address dest, Ipv6Address gateway, uint32_t interface);
+
+ /**
+ * \brief Constructor.
+ * \param dest destination address
+ * \param interface interface index
+ */
+ Ipv6RoutingTableEntry (Ipv6Address dest, uint32_t interface);
+
+ /**
+ * \brief IPv6 address of the destination.
+ */
+ Ipv6Address m_dest;
+
+ /**
+ * \brief IPv6 prefix of the destination
+ */
+ Ipv6Prefix m_destNetworkPrefix;
+
+ /**
+ * \brief IPv6 address of the gateway.
+ */
+ Ipv6Address m_gateway;
+
+ /**
+ * \brief The interface index.
+ */
+ uint32_t m_interface;
+
+ /**
+ * \brief Prefix to use.
+ */
+ Ipv6Address m_prefixToUse;
+
+};
+
+std::ostream& operator<< (std::ostream& os, Ipv6RoutingTableEntry const& route);
+
+/**
+ * \class Ipv6MulticastRoutingTableEntry
+ * \brief A record of an IPv6 multicast route.
+ */
+class Ipv6MulticastRoutingTableEntry
+{
+ public:
+ /**
+ * \brief Constructor.
+ */
+ Ipv6MulticastRoutingTableEntry ();
+
+ /**
+ * \brief Copy constructor.
+ * \param route the route to copy
+ */
+ Ipv6MulticastRoutingTableEntry (Ipv6MulticastRoutingTableEntry const & route);
+
+ /**
+ * \brief Copy constructor.
+ * \param route the route to copy
+ */
+ Ipv6MulticastRoutingTableEntry (Ipv6MulticastRoutingTableEntry const* route);
+
+ /**
+ * \brief Get the source of this route
+ * \return IPv6 address of the source of this route
+ */
+ Ipv6Address GetOrigin () const;
+
+ /**
+ * \brief Get the group.
+ * \return IPv6 address of the multicast group of this route
+ */
+ Ipv6Address GetGroup () const;
+
+ /**
+ * \brief Get the input interface address.
+ * \return input interface index
+ */
+ uint32_t GetInputInterface () const;
+
+ /**
+ * \brief Get the number of output interfaces of this route.
+ * \return number of output interfaces of this route.
+ */
+ uint32_t GetNOutputInterfaces () const;
+
+ /**
+ * \brief Get a specified output interface.
+ * \param n index
+ * \return a specified output interface
+ */
+ uint32_t GetOutputInterface (uint32_t n) const;
+
+ /**
+ * \brief Get all of the output interfaces of this route.
+ * \return a vector of all output interfaces of this route
+ */
+ std::vector<uint32_t> GetOutputInterfaces () const;
+
+ /**
+ * \brief Create a multicast route.
+ * \param origin IPv6 address of the origin source
+ * \param group Ipv6Address of the group
+ * \param inputInterface interface number
+ * \param outputInterfaces list of output interface number
+ * \return a multicast route
+ */
+ static Ipv6MulticastRoutingTableEntry CreateMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector<uint32_t> outputInterfaces);
+
+ private:
+ /**
+ * \brief Constructor.
+ * \param origin IPv6 address of the source
+ * \param group IPv6 address of the group
+ * \param inputInterface interface number
+ * \param outputInterfaces list of output interface number
+ */
+ Ipv6MulticastRoutingTableEntry (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector<uint32_t> outputInterfaces);
+
+ /**
+ * \brief The IPv6 address of the source.
+ */
+ Ipv6Address m_origin;
+
+ /**
+ * \brief The IPv6 address of the group.
+ */
+ Ipv6Address m_group;
+
+ /**
+ * \brief The input interface.
+ */
+ uint32_t m_inputInterface;
+
+ /**
+ * \brief The output interfaces.
+ */
+ std::vector<uint32_t> m_outputInterfaces;
+};
+
+std::ostream& operator<< (std::ostream& os, Ipv6MulticastRoutingTableEntry const& route);
+
+} /* namespace ns3 */
+
+#endif /* IPV6_ROUTING_TABLE_ENTRY_H */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/static-routing/ipv6-static-routing.cc Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,793 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#include "ns3/log.h"
+#include "ns3/packet.h"
+#include "ns3/ipv6-route.h"
+#include "ns3/net-device.h"
+
+#include "ipv6-static-routing.h"
+#include "ipv6-routing-table-entry.h"
+
+namespace ns3
+{
+
+NS_LOG_COMPONENT_DEFINE ("Ipv6StaticRouting");
+
+TypeId Ipv6StaticRouting::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ipv6StaticRouting")
+ .SetParent<Ipv6RoutingProtocol> ()
+ .AddConstructor<Ipv6StaticRouting> ()
+ ;
+ return tid;
+}
+
+Ipv6StaticRouting::Ipv6StaticRouting ()
+ : m_defaultRoute (0),
+ m_ipv6 (0)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+Ipv6StaticRouting::~Ipv6StaticRouting ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+void Ipv6StaticRouting::SetIpv6 (Ptr<Ipv6> ipv6)
+{
+ NS_LOG_FUNCTION (this << ipv6);
+ NS_ASSERT (m_ipv6 == 0 && ipv6 != 0);
+ uint32_t i = 0;
+ m_ipv6 = ipv6;
+
+ for (i = 0 ; i < m_ipv6->GetNInterfaces () ; i++)
+ {
+ if (m_ipv6->IsUp (i))
+ {
+ NotifyInterfaceUp (i);
+ }
+ else
+ {
+ NotifyInterfaceDown (i);
+ }
+ }
+}
+
+void Ipv6StaticRouting::AddHostRouteTo (Ipv6Address dst, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
+{
+ NS_LOG_FUNCTION (this << dst << nextHop << interface << prefixToUse);
+ Ipv6RoutingTableEntry* route = new Ipv6RoutingTableEntry ();
+ *route = Ipv6RoutingTableEntry::CreateHostRouteTo (dst, nextHop, interface, prefixToUse);
+ m_hostRoutes.push_back (route);
+}
+
+void Ipv6StaticRouting::AddHostRouteTo (Ipv6Address dst, uint32_t interface)
+{
+ NS_LOG_FUNCTION (this << dst << interface);
+ Ipv6RoutingTableEntry* route = new Ipv6RoutingTableEntry ();
+ *route = Ipv6RoutingTableEntry::CreateHostRouteTo (dst, interface);
+ m_hostRoutes.push_back (route);
+}
+
+void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface)
+{
+ NS_LOG_FUNCTION (this << network << networkPrefix << nextHop << interface);
+ Ipv6RoutingTableEntry* route = new Ipv6RoutingTableEntry ();
+ *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, nextHop, interface);
+ m_networkRoutes.push_back (route);
+}
+
+void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
+{
+ NS_LOG_FUNCTION (this << network << networkPrefix << nextHop << interface << prefixToUse);
+ Ipv6RoutingTableEntry* route = new Ipv6RoutingTableEntry ();
+ *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, nextHop, interface, prefixToUse);
+ m_networkRoutes.push_back (route);
+}
+
+
+void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface)
+{
+ NS_LOG_FUNCTION (this << network << networkPrefix << interface);
+ Ipv6RoutingTableEntry* route = new Ipv6RoutingTableEntry ();
+ *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, interface);
+ m_networkRoutes.push_back (route);
+}
+
+void Ipv6StaticRouting::SetDefaultRoute (Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
+{
+ NS_LOG_FUNCTION (this << nextHop << interface << prefixToUse);
+ Ipv6RoutingTableEntry* route = new Ipv6RoutingTableEntry ();
+ *route = Ipv6RoutingTableEntry::CreateDefaultRoute (nextHop, interface);
+ route->SetPrefixToUse (prefixToUse);
+ delete m_defaultRoute;
+ m_defaultRoute = route;
+}
+
+void Ipv6StaticRouting::RemoveDefaultRoute ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ if (m_defaultRoute)
+ {
+ delete m_defaultRoute;
+ m_defaultRoute = 0;
+ }
+}
+
+void Ipv6StaticRouting::AddMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector<uint32_t> outputInterfaces)
+{
+ NS_LOG_FUNCTION (this << origin << group << inputInterface);
+ Ipv6MulticastRoutingTableEntry* route = new Ipv6MulticastRoutingTableEntry ();
+ *route = Ipv6MulticastRoutingTableEntry::CreateMulticastRoute (origin, group, inputInterface, outputInterfaces);
+ m_multicastRoutes.push_back (route);
+}
+
+void Ipv6StaticRouting::SetDefaultMulticastRoute (uint32_t outputInterface)
+{
+ NS_LOG_FUNCTION (this << outputInterface);
+ Ipv6RoutingTableEntry *route = new Ipv6RoutingTableEntry ();
+ Ipv6Address network = Ipv6Address ("ff00::"); /* RFC 3513 */
+ Ipv6Prefix networkMask = Ipv6Prefix (8);
+ *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkMask, outputInterface);
+ m_networkRoutes.push_back (route);
+}
+
+uint32_t Ipv6StaticRouting::GetNMulticastRoutes () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return m_multicastRoutes.size ();
+}
+
+Ipv6MulticastRoutingTableEntry Ipv6StaticRouting::GetMulticastRoute (uint32_t index) const
+{
+ NS_LOG_FUNCTION (this << index);
+ NS_ASSERT_MSG (index < m_multicastRoutes.size (), "Ipv6StaticRouting::GetMulticastRoute () : Index out of range");
+
+ if (index < m_multicastRoutes.size ())
+ {
+ uint32_t tmp = 0;
+ for (MulticastRoutesCI i = m_multicastRoutes.begin () ; i != m_multicastRoutes.end () ; i++)
+ {
+ if (tmp == index)
+ {
+ return *i;
+ }
+ tmp++;
+ }
+ }
+ return 0;
+}
+
+bool Ipv6StaticRouting::RemoveMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface)
+{
+ NS_LOG_FUNCTION (this << origin << group << inputInterface);
+ for (MulticastRoutesI i = m_multicastRoutes.begin (); i != m_multicastRoutes.end (); i++)
+ {
+ Ipv6MulticastRoutingTableEntry *route = *i;
+ if (origin == route->GetOrigin () &&
+ group == route->GetGroup () &&
+ inputInterface == route->GetInputInterface ())
+ {
+ delete *i;
+ m_multicastRoutes.erase (i);
+ return true;
+ }
+ }
+ return false;
+}
+
+void Ipv6StaticRouting::RemoveMulticastRoute (uint32_t index)
+{
+ NS_LOG_FUNCTION (this << index);
+ uint32_t tmp = 0;
+
+ for (MulticastRoutesI i = m_multicastRoutes.begin () ; i != m_multicastRoutes.end () ; i++)
+ {
+ if (tmp == index)
+ {
+ delete *i;
+ m_multicastRoutes.erase (i);
+ return;
+ }
+ tmp++;
+ }
+}
+
+bool Ipv6StaticRouting::HasNetworkDest (Ipv6Address network, uint32_t interfaceIndex)
+{
+ NS_LOG_FUNCTION (this << network << interfaceIndex);
+
+ /* in the network table */
+ for (NetworkRoutesI j = m_networkRoutes.begin () ; j != m_networkRoutes.end () ; j++)
+ {
+ NS_ASSERT ((*j)->IsNetwork ());
+ Ipv6Prefix prefix = (*j)->GetDestNetworkPrefix ();
+ Ipv6Address entry = (*j)->GetDestNetwork ();
+
+ if (prefix.IsMatch (network, entry) && (*j)->GetInterface () == interfaceIndex)
+ {
+ return true;
+ }
+ }
+
+ /* beuh!!! not route at all */
+ return false;
+}
+
+Ptr<Ipv6Route> Ipv6StaticRouting::LookupStatic (Ipv6Address dst, uint32_t interface)
+{
+ NS_LOG_FUNCTION (this << dst << interface);
+ Ptr<Ipv6Route> rtentry = 0;
+
+ /* when sending on link-local multicast, there have to be interface specified */
+ if (dst == Ipv6Address::GetAllNodesMulticast () || dst.IsSolicitedMulticast () ||
+ dst == Ipv6Address::GetAllRoutersMulticast () || dst == Ipv6Address::GetAllHostsMulticast ())
+ {
+ NS_ASSERT_MSG (interface > 0, "Try to send on link-local multicast address, and no interface index is given!");
+ rtentry = Create<Ipv6Route> ();
+ rtentry->SetSource (SourceAddressSelection (interface, dst));
+ rtentry->SetDestination (dst);
+ rtentry->SetGateway (Ipv6Address::GetZero ());
+ rtentry->SetOutputDevice (m_ipv6->GetNetDevice (interface));
+ return rtentry;
+ }
+
+ /* is the destination in hosts table */
+ for (HostRoutesCI i = m_hostRoutes.begin () ; i != m_hostRoutes.end () ; i++)
+ {
+ NS_ASSERT ((*i)->IsHost ());
+ if ((*i)->GetDest ().IsEqual (dst))
+ {
+ if (!interface || interface == (*i)->GetInterface ())
+ {
+ NS_LOG_LOGIC ("Found global host route " << *i);
+ Ipv6RoutingTableEntry* route = (*i);
+ rtentry = Create<Ipv6Route> ();
+ uint32_t interfaceIdx = route->GetInterface ();
+ rtentry->SetDestination (route->GetDest ());
+
+ if (route->GetGateway ().IsAny ())
+ {
+ rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetDest ()));
+ }
+ else
+ {
+ rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetGateway ()));
+ }
+
+ rtentry->SetGateway (route->GetGateway ());
+ rtentry->SetOutputDevice (m_ipv6->GetNetDevice (interfaceIdx));
+ return rtentry;
+ }
+ }
+ }
+
+ /* or in the network table */
+ for (NetworkRoutesI j = m_networkRoutes.begin () ; j != m_networkRoutes.end () ; j++)
+ {
+ NS_ASSERT ((*j)->IsNetwork ());
+ Ipv6Prefix prefix = (*j)->GetDestNetworkPrefix ();
+ Ipv6Address entry = (*j)->GetDestNetwork ();
+
+ if (prefix.IsMatch (dst, entry))
+ {
+ /* if interface is given, check the route will output on this interface */
+ if (!interface || interface == (*j)->GetInterface ())
+ {
+ NS_LOG_LOGIC ("Found global network route " << *j);
+ Ipv6RoutingTableEntry* route = (*j);
+ rtentry = Create<Ipv6Route>();
+ uint32_t interfaceIdx = route->GetInterface ();
+ rtentry->SetDestination (route->GetDest ());
+
+ if (route->GetGateway ().IsAny ())
+ {
+ rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetDest ()));
+ }
+ else
+ {
+ rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetGateway ()));
+ }
+
+ rtentry->SetGateway (route->GetGateway ());
+ rtentry->SetOutputDevice (m_ipv6->GetNetDevice (interfaceIdx));
+ return rtentry;
+ }
+ }
+ }
+
+ /* not found, return the default route if any */
+ if (m_defaultRoute != 0)
+ {
+ NS_ASSERT (m_defaultRoute->IsDefault ());
+ NS_LOG_LOGIC ("Found global network route via default route " << m_defaultRoute);
+ Ipv6RoutingTableEntry* route = m_defaultRoute;
+ rtentry = Create<Ipv6Route>();
+ uint32_t interfaceIdx = route->GetInterface ();
+ rtentry->SetDestination (route->GetDest ());
+ rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetPrefixToUse ().IsAny () ? route->GetGateway () : route->GetPrefixToUse ()));
+ rtentry->SetGateway (route->GetGateway ());
+ rtentry->SetOutputDevice (m_ipv6->GetNetDevice (interfaceIdx));
+ return rtentry;
+ }
+
+ /* beuh!!! not route at all */
+ return 0;
+}
+
+void Ipv6StaticRouting::DoDispose ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ for (HostRoutesI i = m_hostRoutes.begin () ; i != m_hostRoutes.end () ; i = m_hostRoutes.erase (i))
+ {
+ delete (*i);
+ }
+ m_hostRoutes.clear ();
+
+ for (NetworkRoutesI j = m_networkRoutes.begin () ; j != m_networkRoutes.end () ; j = m_networkRoutes.erase (j))
+ {
+ delete (*j);
+ }
+ m_networkRoutes.clear ();
+
+ if (m_defaultRoute != 0)
+ {
+ delete m_defaultRoute;
+ m_defaultRoute = 0;
+ }
+
+ for (MulticastRoutesI i = m_multicastRoutes.begin () ; i != m_multicastRoutes.end () ; i = m_multicastRoutes.erase (i))
+ {
+ delete (*i);
+ }
+ m_multicastRoutes.clear ();
+
+ m_ipv6 = 0;
+ Ipv6RoutingProtocol::DoDispose ();
+}
+
+Ptr<Ipv6MulticastRoute> Ipv6StaticRouting::LookupStatic (Ipv6Address origin, Ipv6Address group, uint32_t interface)
+{
+ NS_LOG_FUNCTION (this << origin << group << interface);
+ Ptr<Ipv6MulticastRoute> mrtentry = 0;
+
+ for (MulticastRoutesI i = m_multicastRoutes.begin () ; i != m_multicastRoutes.end () ; i++)
+ {
+ Ipv6MulticastRoutingTableEntry* route = *i;
+
+ /*
+ We've been passed an origin address, a multicast group address and an
+ interface index. We have to decide if the current route in the list is
+ a match.
+
+ The first case is the restrictive case where the origin, group and index
+ matches. This picks up exact routes during forwarded and exact routes from
+ the local node (in which case the ifIndex is a wildcard).
+ */
+
+ if (origin == route->GetOrigin () && group == route->GetGroup ())
+ {
+ /* skipping SSM case */
+ NS_LOG_LOGIC ("Find source specific multicast route" << *i);
+ }
+
+ if (group == route->GetGroup ())
+ {
+ if (interface == Ipv6::IF_ANY || interface == route->GetInputInterface ())
+ {
+ NS_LOG_LOGIC ("Found multicast route" << *i);
+ mrtentry = Create<Ipv6MulticastRoute>();
+ mrtentry->SetGroup (route->GetGroup ());
+ mrtentry->SetOrigin (route->GetOrigin ());
+ mrtentry->SetParent (route->GetInputInterface ());
+ for (uint32_t j = 0 ; j < route->GetNOutputInterfaces () ; j++)
+ {
+ if (route->GetOutputInterface (j))
+ {
+ NS_LOG_LOGIC ("Setting output interface index " << route->GetOutputInterface (j));
+ mrtentry->SetOutputTtl (route->GetOutputInterface (j), Ipv6MulticastRoute::MAX_TTL - 1);
+ }
+ }
+ return mrtentry;
+ }
+ }
+ }
+ return mrtentry;
+}
+
+uint32_t Ipv6StaticRouting::GetNRoutes ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ uint32_t n = 0;
+ if (m_defaultRoute != 0)
+ {
+ n++;
+ }
+ n += m_hostRoutes.size ();
+ n += m_networkRoutes.size ();
+ return n;
+}
+
+Ipv6RoutingTableEntry Ipv6StaticRouting::GetDefaultRoute ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ if (m_defaultRoute != 0)
+ {
+ return *m_defaultRoute;
+ }
+ else
+ {
+ return Ipv6RoutingTableEntry ();
+ }
+}
+
+Ipv6RoutingTableEntry Ipv6StaticRouting::GetRoute (uint32_t index)
+{
+ NS_LOG_FUNCTION (this << index);
+
+ if (index == 0 && m_defaultRoute != 0)
+ {
+ return *m_defaultRoute;
+ }
+
+ if (index > 0 && m_defaultRoute != 0)
+ {
+ index--;
+ }
+
+ if (index < m_hostRoutes.size ())
+ {
+ uint32_t tmp = 0;
+ for (HostRoutesCI i = m_hostRoutes.begin () ; i != m_hostRoutes.end () ; i++)
+ {
+ if (tmp == index)
+ {
+ return *i;
+ }
+ tmp++;
+ }
+ }
+
+ index -= m_hostRoutes.size ();
+ uint32_t tmp = 0;
+
+ for (NetworkRoutesI j = m_networkRoutes.begin () ; j != m_networkRoutes.end () ; j++)
+ {
+ if (tmp == index)
+ {
+ return *j;
+ }
+ tmp++;
+ }
+ NS_ASSERT (false);
+ // quiet compiler.
+ return 0;
+}
+
+void Ipv6StaticRouting::RemoveRoute (uint32_t index)
+{
+ NS_LOG_FUNCTION (this << index);
+ if (index == 0 && m_defaultRoute != 0)
+ {
+ delete m_defaultRoute;
+ m_defaultRoute = 0;
+ }
+
+ if (index > 0 && m_defaultRoute != 0)
+ {
+ index--;
+ }
+
+ if (index < m_hostRoutes.size ())
+ {
+ uint32_t tmp = 0;
+ for (HostRoutesI i = m_hostRoutes.begin () ; i != m_hostRoutes.end () ; i++)
+ {
+ if (tmp == index)
+ {
+ delete *i;
+ m_hostRoutes.erase (i);
+ return;
+ }
+ tmp++;
+ }
+ }
+ index -= m_hostRoutes.size ();
+ uint32_t tmp = 0;
+
+ for (NetworkRoutesI j = m_networkRoutes.begin () ; j != m_networkRoutes.end () ; j++)
+ {
+ if (tmp == index)
+ {
+ delete *j;
+ m_networkRoutes.erase (j);
+ return;
+ }
+ tmp++;
+ }
+ NS_ASSERT (false);
+}
+
+void Ipv6StaticRouting::RemoveRoute (Ipv6Address network, Ipv6Prefix prefix, uint32_t ifIndex)
+{
+ NS_LOG_FUNCTION (this << network << prefix << ifIndex);
+ for (NetworkRoutesI i = m_networkRoutes.begin () ; i != m_networkRoutes.end () ; i++)
+ {
+ if (network == (*i)->GetDest () and (*i)->GetInterface () == ifIndex)
+ {
+ delete *i;
+ m_networkRoutes.erase (i);
+ return;
+ }
+ }
+}
+
+Ptr<Ipv6Route> Ipv6StaticRouting::RouteOutput (Ptr<Packet> p, const Ipv6Header &header, uint32_t oif, Socket::SocketErrno &sockerr)
+{
+ NS_LOG_FUNCTION (this << header << oif);
+ Ipv6Address destination = header.GetDestinationAddress ();
+ Ptr<Ipv6Route> rtentry = 0;
+
+ if (destination.IsMulticast ())
+ {
+ // Note: Multicast routes for outbound packets are stored in the
+ // normal unicast table. An implication of this is that it is not
+ // possible to source multicast datagrams on multiple interfaces.
+ // This is a well-known property of sockets implementation on
+ // many Unix variants.
+ // So, we just log it and fall through to LookupStatic ()
+ NS_LOG_LOGIC ("RouteOutput ()::Multicast destination");
+ }
+
+ rtentry = LookupStatic (destination, oif);
+ if (rtentry)
+ {
+ sockerr = Socket::ERROR_NOTERROR;
+ }
+ else
+ {
+ sockerr = Socket::ERROR_NOROUTETOHOST;
+ }
+ return rtentry;
+}
+
+bool Ipv6StaticRouting::RouteInput (Ptr<const Packet> p, const Ipv6Header &ipHeader, Ptr<const NetDevice> idev,
+ UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+ LocalDeliverCallback lcb, ErrorCallback ecb)
+{
+ NS_LOG_FUNCTION (this << p << ipHeader << ipHeader.GetSourceAddress () << ipHeader.GetDestinationAddress () << idev);
+
+ if (ipHeader.GetDestinationAddress ().IsMulticast ())
+ {
+ NS_LOG_LOGIC ("Multicast destination");
+ Ptr<Ipv6MulticastRoute> mrtentry = LookupStatic (ipHeader.GetSourceAddress (),
+ ipHeader.GetDestinationAddress (), m_ipv6->GetInterfaceForDevice (idev));
+
+ if (mrtentry)
+ {
+ NS_LOG_LOGIC ("Multicast route found");
+ mcb (mrtentry, p, ipHeader); // multicast forwarding callback
+ return true;
+ }
+ else
+ {
+ NS_LOG_LOGIC ("Multicast route not found");
+ return false; // Let other routing protocols try to handle this
+ }
+ }
+//
+// This is a unicast packet. Check to see if we have a route for it.
+//
+ NS_LOG_LOGIC ("Unicast destination");
+ Ptr<Ipv6Route> rtentry = LookupStatic (ipHeader.GetDestinationAddress ());
+
+ if (rtentry != 0)
+ {
+ NS_LOG_LOGIC ("Found unicast destination- calling unicast callback");
+ ucb (rtentry, p, ipHeader); // unicast forwarding callback
+ return true;
+ }
+ else
+ {
+ NS_LOG_LOGIC ("Did not find unicast destination- returning false");
+ return false; // Let other routing protocols try to handle this
+ }
+}
+
+void Ipv6StaticRouting::NotifyInterfaceUp (uint32_t i)
+{
+ for (uint32_t j = 0 ; j < m_ipv6->GetNAddresses (i) ; j++)
+ {
+ if (m_ipv6->GetAddress (i, j).GetAddress () != Ipv6Address () &&
+ m_ipv6->GetAddress (i, j).GetPrefix () != Ipv6Prefix ())
+ {
+ if (m_ipv6->GetAddress (i, j).GetPrefix () == Ipv6Prefix (128))
+ {
+ /* host route */
+ AddHostRouteTo (m_ipv6->GetAddress (i, j).GetAddress (), i);
+ }
+ else
+ {
+ AddNetworkRouteTo (m_ipv6->GetAddress (i, j).GetAddress ().CombinePrefix (m_ipv6->GetAddress (i, j).GetPrefix ()),
+ m_ipv6->GetAddress (i, j).GetPrefix (), i);
+ }
+ }
+ }
+}
+
+void Ipv6StaticRouting::NotifyInterfaceDown (uint32_t i)
+{
+ /* remove all static routes that are going through this interface */
+ for (uint32_t j = 0 ; j < GetNRoutes () ; j++)
+ {
+ Ipv6RoutingTableEntry route = GetRoute (j);
+
+ if (route.GetInterface () == i)
+ {
+ RemoveRoute (j);
+ }
+ }
+}
+
+void Ipv6StaticRouting::NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address)
+{
+ if (!m_ipv6->IsUp (interface))
+ {
+ return;
+ }
+
+ Ipv6Address networkAddress = address.GetAddress ().CombinePrefix (address.GetPrefix ());
+ Ipv6Prefix networkMask = address.GetPrefix ();
+
+ if (address.GetAddress () != Ipv6Address () && address.GetPrefix () != Ipv6Prefix ())
+ {
+ AddNetworkRouteTo (networkAddress, networkMask, interface);
+ }
+}
+
+void Ipv6StaticRouting::NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address)
+{
+ if (!m_ipv6->IsUp (interface))
+ {
+ return;
+ }
+
+ Ipv6Address networkAddress = address.GetAddress ().CombinePrefix (address.GetPrefix ());
+ Ipv6Prefix networkMask = address.GetPrefix ();
+
+ // Remove all static routes that are going through this interface
+ // which reference this network
+ for (uint32_t j = 0 ; j < GetNRoutes () ; j++)
+ {
+ Ipv6RoutingTableEntry route = GetRoute (j);
+
+ if (route.GetInterface () == interface &&
+ route.IsNetwork () &&
+ route.GetDestNetwork () == networkAddress &&
+ route.GetDestNetworkPrefix () == networkMask)
+ {
+ RemoveRoute (j);
+ }
+ }
+}
+
+void Ipv6StaticRouting::NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
+{
+ NS_LOG_INFO (this << dst << mask << nextHop << interface << prefixToUse);
+ if (mask == Ipv6Prefix (128))
+ {
+ AddHostRouteTo (dst, nextHop, interface);
+ }
+ else if (dst != Ipv6Address::GetZero ())
+ {
+ AddNetworkRouteTo (dst, mask, nextHop, interface);
+ }
+ else /* default route */
+ {
+ /* this case is mainly used by configuring default route following RA processing,
+ * in case of multipe prefix in RA, the first will configured default route
+ */
+ if (!m_defaultRoute)
+ {
+ SetDefaultRoute (nextHop, interface, prefixToUse);
+ }
+ }
+}
+
+void Ipv6StaticRouting::NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface)
+{
+ NS_LOG_FUNCTION (this << dst << mask << nextHop << interface);
+ if (mask == Ipv6Prefix (128))
+ {
+ for (HostRoutesI j = m_hostRoutes.begin () ; j != m_hostRoutes.end () ; j++)
+ {
+ Ipv6Prefix prefix = (*j)->GetDestNetworkPrefix ();
+ Ipv6Address entry = (*j)->GetDestNetwork ();
+
+ if (dst == entry && prefix == mask && (*j)->GetInterface () == interface)
+ {
+ delete (*j);
+ m_hostRoutes.erase (j);
+ }
+ }
+ }
+ else if (dst != Ipv6Address::GetZero ())
+ {
+ for (NetworkRoutesI j = m_networkRoutes.begin () ; j != m_networkRoutes.end () ; j++)
+ {
+ Ipv6Prefix prefix = (*j)->GetDestNetworkPrefix ();
+ Ipv6Address entry = (*j)->GetDestNetwork ();
+
+ if (dst == entry && prefix == mask && (*j)->GetInterface () == interface)
+ {
+ delete (*j);
+ m_networkRoutes.erase (j);
+ }
+ }
+ }
+ else
+ {
+ /* default route case */
+ if (!m_defaultRoute)
+ {
+ return;
+ }
+
+ if (m_defaultRoute->GetInterface () == interface && m_defaultRoute->GetGateway () == nextHop)
+ {
+ NS_LOG_LOGIC ("Remove default route (maybe because autoconfigured address expired)");
+ delete m_defaultRoute;
+ m_defaultRoute = 0;
+ }
+ }
+}
+
+Ipv6Address Ipv6StaticRouting::SourceAddressSelection (uint32_t interface, Ipv6Address dest)
+{
+ NS_LOG_FUNCTION (this << interface << dest);
+ Ipv6Address ret;
+
+ /* first address of an IPv6 interface is link-local ones */
+ ret = m_ipv6->GetAddress (interface, 0).GetAddress ();
+
+ if (dest == Ipv6Address::GetAllNodesMulticast () || dest == Ipv6Address::GetAllRoutersMulticast () || dest == Ipv6Address::GetAllHostsMulticast ())
+ {
+ return ret;
+ }
+
+ /* useally IPv6 interfaces have one link-local address and one global address */
+
+ for (uint32_t i = 1 ; i < m_ipv6->GetNAddresses (interface) ; i++)
+ {
+ Ipv6InterfaceAddress test = m_ipv6->GetAddress (interface, i);
+
+ if (test.GetAddress ().CombinePrefix (test.GetPrefix ()) == dest.CombinePrefix (test.GetPrefix ()))
+ {
+ return test.GetAddress ();
+ }
+ }
+
+ return ret;
+}
+
+} /* namespace ns3 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/static-routing/ipv6-static-routing.h Wed Aug 26 15:29:03 2009 +0400
@@ -0,0 +1,303 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#ifndef IPV6_STATIC_ROUTING_H
+#define IPV6_STATIC_ROUTING_H
+
+#include <list>
+#include <stdint.h>
+
+#include "ns3/ptr.h"
+#include "ns3/ipv6-address.h"
+#include "ns3/ipv6.h"
+#include "ns3/ipv6-header.h"
+#include "ns3/ipv6-routing-protocol.h"
+
+namespace ns3
+{
+
+class Packet;
+class NetDevice;
+class Ipv6Interface;
+class Ipv6Route;
+class Node;
+class Ipv6RoutingTableEntry;
+class Ipv6MulticastRoutingTableEntry;
+
+/**
+ * \ingroup routing
+ * \defgroup ipv6StaticRouting Ipv6StaticRouting
+ * \class Ipv6StaticRouting
+ * \brief Static routing protocol for IP version 6 stack.
+ * \see Ipv6RoutingProtocol
+ * \see Ipv6ListRouting
+ */
+class Ipv6StaticRouting : public Ipv6RoutingProtocol
+{
+ public:
+ /**
+ * \brief The interface Id associated with this class.
+ * \return type identificator
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Constructor.
+ */
+ Ipv6StaticRouting ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Ipv6StaticRouting ();
+
+ /**
+ * \brief Add route to host.
+ * \param dest destination address
+ * \param nextHop next hop address to route the packet
+ * \param interface interface index
+ * \param prefixToUse prefix that should be used for source address for this destination
+ */
+ void AddHostRouteTo (Ipv6Address dest, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address ("::"));
+
+ /**
+ * \brief Add route to host.
+ * \param dest destination address.
+ * \param interface interface index
+ */
+ void AddHostRouteTo (Ipv6Address dest, uint32_t interface);
+
+ /**
+ * \brief Add route to network.
+ * \param network network address
+ * \param networkPrefix network prefix*
+ * \param nextHop next hop address to route the packet
+ * \param interface interface index
+ */
+ void AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface);
+
+ /**
+ * \brief Add route to network.
+ * \param network network address
+ * \param networkPrefix network prefix*
+ * \param nextHop next hop address to route the packet
+ * \param interface interface index
+ * \param prefixToUse prefix that should be used for source address for this destination
+ */
+ void AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse);
+
+ /**
+ * \brief Add route to network.
+ * \param network network address
+ * \param networkPrefix network prefix
+ * \param interface interface index
+ */
+ void AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface);
+
+ /**
+ * \brief Set the default route.
+ * \param nextHop next hop address to route the packet
+ * \param interface interface index
+ * \param prefixToUse prefix to use (i.e for multihoming)
+ */
+ void SetDefaultRoute (Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address ("::"));
+
+ /**
+ * \brief Remove the default route.
+ */
+ void RemoveDefaultRoute ();
+
+ /**
+ * \brief Get the number or entries in the routing table.
+ * \return number of entries
+ */
+ uint32_t GetNRoutes ();
+
+ /**
+ * \brief Get the default route.
+ * \return default Ipv6Route
+ */
+ Ipv6RoutingTableEntry GetDefaultRoute ();
+
+ /**
+ * \brief Get a specified route.
+ * \param i index
+ * \return the route whose index is i
+ */
+ Ipv6RoutingTableEntry GetRoute (uint32_t i);
+
+ /**
+ * \brief Remove a route from the routing table.
+ * \param i index
+ */
+ void RemoveRoute (uint32_t i);
+
+ /**
+ * \brief Remove a route from the routing table.
+ * \param network IPv6 network
+ * \param prefix IPv6 prefix
+ * \param ifIndex interface index
+ */
+ void RemoveRoute (Ipv6Address network, Ipv6Prefix prefix, uint32_t ifIndex);
+
+ /**
+ * \brief Add a multicast route for a given multicast source and group.
+ * \param origin IPv6 address of the source
+ * \param group the multicast group address.
+ * \param inputInterface the interface index
+ * \param outputInterfaces the list of output interface indices over which the packet
+ * should be sent (excluding the inputInterface).
+ */
+ void AddMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector<uint32_t> outputInterfaces);
+
+ /**
+ * \brief Set the default multicast route.
+ * \param outputInterface default output interface
+ */
+ void SetDefaultMulticastRoute (uint32_t outputInterface);
+
+ /**
+ * \brief Get the number of entries in the multicast routing table.
+ * \return number of entries
+ */
+ uint32_t GetNMulticastRoutes () const;
+
+ /**
+ * \brief Get the specified multicast route.
+ * \param i index
+ * \return the route whose index is i
+ */
+ Ipv6MulticastRoutingTableEntry GetMulticastRoute (uint32_t i) const;
+
+ /**
+ * \brief Get the default multicast IPv6 route.
+ * \return default Ipv6MulticastRoute
+ */
+ Ipv6MulticastRoutingTableEntry GetDefaultMulticastRoute () const;
+
+ /**
+ * \brief Remove a static multicast route.
+ * \param origin IPv6 address of the source
+ * \param group the multicast group address.
+ * \param inputInterface the input interface index
+ */
+ bool RemoveMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface);
+
+ /**
+ * \brief Remove a multicast route.
+ * \param i index of route to remove
+ */
+ void RemoveMulticastRoute (uint32_t i);
+
+ /**
+ * \brief If the destination is already present in network destination list.
+ * \param dest destination address
+ * \param interfaceIndex interface index
+ * \return true if dest is already in list, false otherwise
+ */
+ bool HasNetworkDest (Ipv6Address dest, uint32_t interfaceIndex);
+
+ virtual Ptr<Ipv6Route> RouteOutput (Ptr<Packet> p, const Ipv6Header &header, uint32_t oif, Socket::SocketErrno &sockerr);
+
+ virtual bool RouteInput (Ptr<const Packet> p, const Ipv6Header &header, Ptr<const NetDevice> idev,
+ UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+ LocalDeliverCallback lcb, ErrorCallback ecb);
+
+ virtual void NotifyInterfaceUp (uint32_t interface);
+ virtual void NotifyInterfaceDown (uint32_t interface);
+ virtual void NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address);
+ virtual void NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address);
+ virtual void NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ());
+ virtual void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface);
+ virtual void SetIpv6 (Ptr<Ipv6> ipv6);
+
+ protected:
+ /**
+ * \brief Dispose this object.
+ */
+ void DoDispose ();
+
+ private:
+ typedef std::list<Ipv6RoutingTableEntry *> HostRoutes;
+ typedef std::list<Ipv6RoutingTableEntry *>::const_iterator HostRoutesCI;
+ typedef std::list<Ipv6RoutingTableEntry *>::iterator HostRoutesI;
+ typedef std::list<Ipv6RoutingTableEntry *> NetworkRoutes;
+ typedef std::list<Ipv6RoutingTableEntry *>::const_iterator NetworkRoutesCI;
+ typedef std::list<Ipv6RoutingTableEntry *>::iterator NetworkRoutesI;
+
+ typedef std::list<Ipv6MulticastRoutingTableEntry *> MulticastRoutes;
+ typedef std::list<Ipv6MulticastRoutingTableEntry *>::const_iterator MulticastRoutesCI;
+ typedef std::list<Ipv6MulticastRoutingTableEntry *>::iterator MulticastRoutesI;
+
+ /**
+ * \brief Lookup in the forwarding table for destination.
+ * \param dest destination address
+ * \param interface output interface if any (put 0 otherwise)
+ * \return Ipv6Route to route the packet to reach dest address
+ */
+ Ptr<Ipv6Route> LookupStatic (Ipv6Address dest, uint32_t interface = 0);
+
+ /**
+ * \brief Lookup in the multicast forwarding table for destination.
+ * \param origin source address
+ * \param group group multicast address
+ * \param ifIndex interface index
+ * \return Ipv6MulticastRoute to route the packet to reach dest address
+ */
+ Ptr<Ipv6MulticastRoute> LookupStatic (Ipv6Address origin, Ipv6Address group, uint32_t ifIndex);
+
+ /**
+ * \brief Choose the source address to use with destination address.
+ * \param interface interface index
+ * \param dest IPv6 destination address
+ * \return IPv6 source address to use
+ */
+ Ipv6Address SourceAddressSelection (uint32_t interface, Ipv6Address dest);
+
+ /**
+ * \brief the forwarding table for hosts.
+ */
+ HostRoutes m_hostRoutes;
+
+ /**
+ * \brief the forwarding table for network.
+ */
+ NetworkRoutes m_networkRoutes;
+
+ /**
+ * \brief the default route.
+ */
+ Ipv6RoutingTableEntry *m_defaultRoute;
+
+ /**
+ * \brief the forwarding table for multicast.
+ */
+ MulticastRoutes m_multicastRoutes;
+
+ /**
+ * \brief Ipv6 reference.
+ */
+ Ptr<Ipv6> m_ipv6;
+};
+
+} /* namespace ns3 */
+
+#endif /* IPV6_STATIC_ROUTING_H */
+
--- a/src/routing/static-routing/wscript Tue Aug 25 20:12:53 2009 +0400
+++ b/src/routing/static-routing/wscript Wed Aug 26 15:29:03 2009 +0400
@@ -5,11 +5,15 @@
module.source = [
'ipv4-static-routing.cc',
'ipv4-routing-table-entry.cc',
+ 'ipv6-static-routing.cc',
+ 'ipv6-routing-table-entry.cc',
]
headers = bld.new_task_gen('ns3header')
headers.module = 'static-routing'
headers.source = [
'ipv4-static-routing.h',
'ipv4-routing-table-entry.h',
+ 'ipv6-static-routing.h',
+ 'ipv6-routing-table-entry.h',
]
--- a/src/wscript Tue Aug 25 20:12:53 2009 +0400
+++ b/src/wscript Wed Aug 26 15:29:03 2009 +0400
@@ -39,6 +39,8 @@
'devices/mesh',
'devices/mesh/dot11s',
'devices/mesh/flame',
+ 'applications/ping6',
+ 'applications/radvd',
)
def set_options(opt):