--- a/bindings/python/ns3_module_core.py Mon Oct 27 23:05:57 2008 -0700
+++ b/bindings/python/ns3_module_core.py Wed Oct 29 11:49:21 2008 -0700
@@ -2025,6 +2025,10 @@
module.add_function('MakeStringChecker',
'ns3::Ptr< ns3::AttributeChecker const >',
[])
+ ## type-id.h: extern ns3::Ptr<ns3::AttributeChecker const> ns3::MakeTypeIdChecker() [free function]
+ module.add_function('MakeTypeIdChecker',
+ 'ns3::Ptr< ns3::AttributeChecker const >',
+ [])
## ptr.h: extern ns3::Ptr<ns3::PointerValue> ns3::Create() [free function]
module.add_function('Create',
'ns3::Ptr< ns3::PointerValue >',
@@ -2039,10 +2043,6 @@
module.add_function('LogComponentEnableAll',
'void',
[param('ns3::LogLevel', 'level')])
- ## type-id.h: extern ns3::Ptr<ns3::AttributeChecker const> ns3::MakeTypeIdChecker() [free function]
- module.add_function('MakeTypeIdChecker',
- 'ns3::Ptr< ns3::AttributeChecker const >',
- [])
## object-factory.h: extern ns3::Ptr<ns3::AttributeChecker const> ns3::MakeObjectFactoryChecker() [free function]
module.add_function('MakeObjectFactoryChecker',
'ns3::Ptr< ns3::AttributeChecker const >',
--- a/bindings/python/ns3_module_internet_stack.py Mon Oct 27 23:05:57 2008 -0700
+++ b/bindings/python/ns3_module_internet_stack.py Wed Oct 29 11:49:21 2008 -0700
@@ -3,6 +3,20 @@
def register_types(module):
root_module = module.get_root()
+ ## icmpv4.h: ns3::Icmpv4DestinationUnreachable [class]
+ module.add_class('Icmpv4DestinationUnreachable', parent=root_module['ns3::Header'])
+ ## icmpv4.h: ns3::Icmpv4DestinationUnreachable [enumeration]
+ module.add_enum('', ['NET_UNREACHABLE', 'HOST_UNREACHABLE', 'PROTOCOL_UNREACHABLE', 'PORT_UNREACHABLE', 'FRAG_NEEDED', 'SOURCE_ROUTE_FAILED'], outer_class=root_module['ns3::Icmpv4DestinationUnreachable'])
+ ## icmpv4.h: ns3::Icmpv4Echo [class]
+ module.add_class('Icmpv4Echo', parent=root_module['ns3::Header'])
+ ## icmpv4.h: ns3::Icmpv4Header [class]
+ module.add_class('Icmpv4Header', parent=root_module['ns3::Header'])
+ ## icmpv4.h: ns3::Icmpv4Header [enumeration]
+ module.add_enum('', ['ECHO_REPLY', 'DEST_UNREACH', 'ECHO', 'TIME_EXCEEDED'], outer_class=root_module['ns3::Icmpv4Header'])
+ ## icmpv4.h: ns3::Icmpv4TimeExceeded [class]
+ module.add_class('Icmpv4TimeExceeded', parent=root_module['ns3::Header'])
+ ## icmpv4.h: ns3::Icmpv4TimeExceeded [enumeration]
+ module.add_enum('', ['TIME_TO_LIVE', 'FRAGMENT_REASSEMBLY'], outer_class=root_module['ns3::Icmpv4TimeExceeded'])
## tcp-header.h: ns3::TcpHeader [class]
module.add_class('TcpHeader', parent=root_module['ns3::Header'])
## tcp-header.h: ns3::TcpHeader::Flags_t [enumeration]
@@ -57,6 +71,10 @@
def register_methods(root_module):
+ register_Ns3Icmpv4DestinationUnreachable_methods(root_module, root_module['ns3::Icmpv4DestinationUnreachable'])
+ register_Ns3Icmpv4Echo_methods(root_module, root_module['ns3::Icmpv4Echo'])
+ register_Ns3Icmpv4Header_methods(root_module, root_module['ns3::Icmpv4Header'])
+ register_Ns3Icmpv4TimeExceeded_methods(root_module, root_module['ns3::Icmpv4TimeExceeded'])
register_Ns3TcpHeader_methods(root_module, root_module['ns3::TcpHeader'])
register_Ns3UdpHeader_methods(root_module, root_module['ns3::UdpHeader'])
register_Ns3Ipv4Interface_methods(root_module, root_module['ns3::Ipv4Interface'])
@@ -64,6 +82,248 @@
register_Ns3Ipv4StaticRouting_methods(root_module, root_module['ns3::Ipv4StaticRouting'])
return
+def register_Ns3Icmpv4DestinationUnreachable_methods(root_module, cls):
+ ## icmpv4.h: ns3::Icmpv4DestinationUnreachable::Icmpv4DestinationUnreachable(ns3::Icmpv4DestinationUnreachable const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::Icmpv4DestinationUnreachable const &', 'arg0')])
+ ## icmpv4.h: static ns3::TypeId ns3::Icmpv4DestinationUnreachable::GetTypeId() [member function]
+ cls.add_method('GetTypeId',
+ 'ns3::TypeId',
+ [],
+ is_static=True)
+ ## icmpv4.h: ns3::Icmpv4DestinationUnreachable::Icmpv4DestinationUnreachable() [constructor]
+ cls.add_constructor([])
+ ## icmpv4.h: void ns3::Icmpv4DestinationUnreachable::SetNextHopMtu(uint16_t mtu) [member function]
+ cls.add_method('SetNextHopMtu',
+ 'void',
+ [param('uint16_t', 'mtu')])
+ ## icmpv4.h: uint16_t ns3::Icmpv4DestinationUnreachable::GetNextHopMtu() const [member function]
+ cls.add_method('GetNextHopMtu',
+ 'uint16_t',
+ [],
+ is_const=True)
+ ## icmpv4.h: void ns3::Icmpv4DestinationUnreachable::SetData(ns3::Ptr<const ns3::Packet> data) [member function]
+ cls.add_method('SetData',
+ 'void',
+ [param('ns3::Ptr< ns3::Packet const >', 'data')])
+ ## icmpv4.h: void ns3::Icmpv4DestinationUnreachable::SetHeader(ns3::Ipv4Header header) [member function]
+ cls.add_method('SetHeader',
+ 'void',
+ [param('ns3::Ipv4Header', 'header')])
+ ## icmpv4.h: void ns3::Icmpv4DestinationUnreachable::GetData(uint8_t * payload) const [member function]
+ cls.add_method('GetData',
+ 'void',
+ [param('uint8_t *', 'payload')],
+ is_const=True)
+ ## icmpv4.h: ns3::Ipv4Header ns3::Icmpv4DestinationUnreachable::GetHeader() const [member function]
+ cls.add_method('GetHeader',
+ 'ns3::Ipv4Header',
+ [],
+ is_const=True)
+ ## icmpv4.h: ns3::TypeId ns3::Icmpv4DestinationUnreachable::GetInstanceTypeId() const [member function]
+ cls.add_method('GetInstanceTypeId',
+ 'ns3::TypeId',
+ [],
+ is_const=True, visibility='private', is_virtual=True)
+ ## icmpv4.h: uint32_t ns3::Icmpv4DestinationUnreachable::GetSerializedSize() const [member function]
+ cls.add_method('GetSerializedSize',
+ 'uint32_t',
+ [],
+ is_const=True, visibility='private', is_virtual=True)
+ ## icmpv4.h: void ns3::Icmpv4DestinationUnreachable::Serialize(ns3::Buffer::Iterator start) const [member function]
+ cls.add_method('Serialize',
+ 'void',
+ [param('ns3::Buffer::Iterator', 'start')],
+ is_const=True, visibility='private', is_virtual=True)
+ ## icmpv4.h: uint32_t ns3::Icmpv4DestinationUnreachable::Deserialize(ns3::Buffer::Iterator start) [member function]
+ cls.add_method('Deserialize',
+ 'uint32_t',
+ [param('ns3::Buffer::Iterator', 'start')],
+ visibility='private', is_virtual=True)
+ ## icmpv4.h: void ns3::Icmpv4DestinationUnreachable::Print(std::ostream & os) const [member function]
+ cls.add_method('Print',
+ 'void',
+ [param('std::ostream &', 'os')],
+ is_const=True, visibility='private', is_virtual=True)
+ return
+
+def register_Ns3Icmpv4Echo_methods(root_module, cls):
+ ## icmpv4.h: ns3::Icmpv4Echo::Icmpv4Echo(ns3::Icmpv4Echo const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::Icmpv4Echo const &', 'arg0')])
+ ## icmpv4.h: void ns3::Icmpv4Echo::SetIdentifier(uint16_t id) [member function]
+ cls.add_method('SetIdentifier',
+ 'void',
+ [param('uint16_t', 'id')])
+ ## icmpv4.h: void ns3::Icmpv4Echo::SetSequenceNumber(uint16_t seq) [member function]
+ cls.add_method('SetSequenceNumber',
+ 'void',
+ [param('uint16_t', 'seq')])
+ ## icmpv4.h: void ns3::Icmpv4Echo::SetData(ns3::Ptr<const ns3::Packet> data) [member function]
+ cls.add_method('SetData',
+ 'void',
+ [param('ns3::Ptr< ns3::Packet const >', 'data')])
+ ## icmpv4.h: uint16_t ns3::Icmpv4Echo::GetIdentifier() const [member function]
+ cls.add_method('GetIdentifier',
+ 'uint16_t',
+ [],
+ is_const=True)
+ ## icmpv4.h: uint16_t ns3::Icmpv4Echo::GetSequenceNumber() const [member function]
+ cls.add_method('GetSequenceNumber',
+ 'uint16_t',
+ [],
+ is_const=True)
+ ## icmpv4.h: ns3::Ptr<const ns3::Packet> ns3::Icmpv4Echo::GetData() const [member function]
+ cls.add_method('GetData',
+ 'ns3::Ptr< ns3::Packet const >',
+ [],
+ is_const=True)
+ ## icmpv4.h: static ns3::TypeId ns3::Icmpv4Echo::GetTypeId() [member function]
+ cls.add_method('GetTypeId',
+ 'ns3::TypeId',
+ [],
+ is_static=True)
+ ## icmpv4.h: ns3::Icmpv4Echo::Icmpv4Echo() [constructor]
+ cls.add_constructor([])
+ ## icmpv4.h: ns3::TypeId ns3::Icmpv4Echo::GetInstanceTypeId() const [member function]
+ cls.add_method('GetInstanceTypeId',
+ 'ns3::TypeId',
+ [],
+ is_const=True, is_virtual=True)
+ ## icmpv4.h: uint32_t ns3::Icmpv4Echo::GetSerializedSize() const [member function]
+ cls.add_method('GetSerializedSize',
+ 'uint32_t',
+ [],
+ is_const=True, is_virtual=True)
+ ## icmpv4.h: void ns3::Icmpv4Echo::Serialize(ns3::Buffer::Iterator start) const [member function]
+ cls.add_method('Serialize',
+ 'void',
+ [param('ns3::Buffer::Iterator', 'start')],
+ is_const=True, is_virtual=True)
+ ## icmpv4.h: uint32_t ns3::Icmpv4Echo::Deserialize(ns3::Buffer::Iterator start) [member function]
+ cls.add_method('Deserialize',
+ 'uint32_t',
+ [param('ns3::Buffer::Iterator', 'start')],
+ is_virtual=True)
+ ## icmpv4.h: void ns3::Icmpv4Echo::Print(std::ostream & os) const [member function]
+ cls.add_method('Print',
+ 'void',
+ [param('std::ostream &', 'os')],
+ is_const=True, is_virtual=True)
+ return
+
+def register_Ns3Icmpv4Header_methods(root_module, cls):
+ ## icmpv4.h: ns3::Icmpv4Header::Icmpv4Header(ns3::Icmpv4Header const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::Icmpv4Header const &', 'arg0')])
+ ## icmpv4.h: void ns3::Icmpv4Header::EnableChecksum() [member function]
+ cls.add_method('EnableChecksum',
+ 'void',
+ [])
+ ## icmpv4.h: void ns3::Icmpv4Header::SetType(uint8_t type) [member function]
+ cls.add_method('SetType',
+ 'void',
+ [param('uint8_t', 'type')])
+ ## icmpv4.h: void ns3::Icmpv4Header::SetCode(uint8_t code) [member function]
+ cls.add_method('SetCode',
+ 'void',
+ [param('uint8_t', 'code')])
+ ## icmpv4.h: uint8_t ns3::Icmpv4Header::GetType() const [member function]
+ cls.add_method('GetType',
+ 'uint8_t',
+ [],
+ is_const=True)
+ ## icmpv4.h: uint8_t ns3::Icmpv4Header::GetCode() const [member function]
+ cls.add_method('GetCode',
+ 'uint8_t',
+ [],
+ is_const=True)
+ ## icmpv4.h: static ns3::TypeId ns3::Icmpv4Header::GetTypeId() [member function]
+ cls.add_method('GetTypeId',
+ 'ns3::TypeId',
+ [],
+ is_static=True)
+ ## icmpv4.h: ns3::Icmpv4Header::Icmpv4Header() [constructor]
+ cls.add_constructor([])
+ ## icmpv4.h: ns3::TypeId ns3::Icmpv4Header::GetInstanceTypeId() const [member function]
+ cls.add_method('GetInstanceTypeId',
+ 'ns3::TypeId',
+ [],
+ is_const=True, is_virtual=True)
+ ## icmpv4.h: uint32_t ns3::Icmpv4Header::GetSerializedSize() const [member function]
+ cls.add_method('GetSerializedSize',
+ 'uint32_t',
+ [],
+ is_const=True, is_virtual=True)
+ ## icmpv4.h: void ns3::Icmpv4Header::Serialize(ns3::Buffer::Iterator start) const [member function]
+ cls.add_method('Serialize',
+ 'void',
+ [param('ns3::Buffer::Iterator', 'start')],
+ is_const=True, is_virtual=True)
+ ## icmpv4.h: uint32_t ns3::Icmpv4Header::Deserialize(ns3::Buffer::Iterator start) [member function]
+ cls.add_method('Deserialize',
+ 'uint32_t',
+ [param('ns3::Buffer::Iterator', 'start')],
+ is_virtual=True)
+ ## icmpv4.h: void ns3::Icmpv4Header::Print(std::ostream & os) const [member function]
+ cls.add_method('Print',
+ 'void',
+ [param('std::ostream &', 'os')],
+ is_const=True, is_virtual=True)
+ return
+
+def register_Ns3Icmpv4TimeExceeded_methods(root_module, cls):
+ ## icmpv4.h: ns3::Icmpv4TimeExceeded::Icmpv4TimeExceeded(ns3::Icmpv4TimeExceeded const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::Icmpv4TimeExceeded const &', 'arg0')])
+ ## icmpv4.h: void ns3::Icmpv4TimeExceeded::SetData(ns3::Ptr<const ns3::Packet> data) [member function]
+ cls.add_method('SetData',
+ 'void',
+ [param('ns3::Ptr< ns3::Packet const >', 'data')])
+ ## icmpv4.h: void ns3::Icmpv4TimeExceeded::SetHeader(ns3::Ipv4Header header) [member function]
+ cls.add_method('SetHeader',
+ 'void',
+ [param('ns3::Ipv4Header', 'header')])
+ ## icmpv4.h: void ns3::Icmpv4TimeExceeded::GetData(uint8_t * payload) const [member function]
+ cls.add_method('GetData',
+ 'void',
+ [param('uint8_t *', 'payload')],
+ is_const=True)
+ ## icmpv4.h: ns3::Ipv4Header ns3::Icmpv4TimeExceeded::GetHeader() const [member function]
+ cls.add_method('GetHeader',
+ 'ns3::Ipv4Header',
+ [],
+ is_const=True)
+ ## icmpv4.h: static ns3::TypeId ns3::Icmpv4TimeExceeded::GetTypeId() [member function]
+ cls.add_method('GetTypeId',
+ 'ns3::TypeId',
+ [],
+ is_static=True)
+ ## icmpv4.h: ns3::Icmpv4TimeExceeded::Icmpv4TimeExceeded() [constructor]
+ cls.add_constructor([])
+ ## icmpv4.h: ns3::TypeId ns3::Icmpv4TimeExceeded::GetInstanceTypeId() const [member function]
+ cls.add_method('GetInstanceTypeId',
+ 'ns3::TypeId',
+ [],
+ is_const=True, is_virtual=True)
+ ## icmpv4.h: uint32_t ns3::Icmpv4TimeExceeded::GetSerializedSize() const [member function]
+ cls.add_method('GetSerializedSize',
+ 'uint32_t',
+ [],
+ is_const=True, is_virtual=True)
+ ## icmpv4.h: void ns3::Icmpv4TimeExceeded::Serialize(ns3::Buffer::Iterator start) const [member function]
+ cls.add_method('Serialize',
+ 'void',
+ [param('ns3::Buffer::Iterator', 'start')],
+ is_const=True, is_virtual=True)
+ ## icmpv4.h: uint32_t ns3::Icmpv4TimeExceeded::Deserialize(ns3::Buffer::Iterator start) [member function]
+ cls.add_method('Deserialize',
+ 'uint32_t',
+ [param('ns3::Buffer::Iterator', 'start')],
+ is_virtual=True)
+ ## icmpv4.h: void ns3::Icmpv4TimeExceeded::Print(std::ostream & os) const [member function]
+ cls.add_method('Print',
+ 'void',
+ [param('std::ostream &', 'os')],
+ is_const=True, is_virtual=True)
+ return
+
def register_Ns3TcpHeader_methods(root_module, cls):
## tcp-header.h: ns3::TcpHeader::TcpHeader(ns3::TcpHeader const & arg0) [copy constructor]
cls.add_constructor([param('ns3::TcpHeader const &', 'arg0')])
@@ -354,6 +614,14 @@
cls.add_method('SetNode',
'void',
[param('ns3::Ptr< ns3::Node >', 'node')])
+ ## ipv4-l3-protocol.h: ns3::Ptr<ns3::Socket> ns3::Ipv4L3Protocol::CreateRawSocket() [member function]
+ cls.add_method('CreateRawSocket',
+ 'ns3::Ptr< ns3::Socket >',
+ [])
+ ## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::DeleteRawSocket(ns3::Ptr<ns3::Socket> socket) [member function]
+ cls.add_method('DeleteRawSocket',
+ 'void',
+ [param('ns3::Ptr< ns3::Socket >', 'socket')])
## ipv4-l3-protocol.h: void ns3::Ipv4L3Protocol::Insert(ns3::Ptr<ns3::Ipv4L4Protocol> protocol) [member function]
cls.add_method('Insert',
'void',
--- a/bindings/python/ns3_module_node.py Mon Oct 27 23:05:57 2008 -0700
+++ b/bindings/python/ns3_module_node.py Wed Oct 29 11:49:21 2008 -0700
@@ -67,6 +67,8 @@
module.add_class('SocketFactory', parent=root_module['ns3::Object'])
## socket.h: ns3::SocketIpTtlTag [class]
module.add_class('SocketIpTtlTag', parent=root_module['ns3::Tag'])
+ ## socket.h: ns3::SocketSetDontFragmentTag [class]
+ module.add_class('SocketSetDontFragmentTag', parent=root_module['ns3::Tag'])
## tcp-socket.h: ns3::TcpSocket [class]
module.add_class('TcpSocket', parent=root_module['ns3::Socket'])
## tcp-socket-factory.h: ns3::TcpSocketFactory [class]
@@ -91,6 +93,8 @@
module.add_class('EthernetTrailer', parent=root_module['ns3::Trailer'])
## ipv4.h: ns3::Ipv4 [class]
module.add_class('Ipv4', parent=root_module['ns3::Object'])
+ ## ipv4-raw-socket-factory.h: ns3::Ipv4RawSocketFactory [class]
+ module.add_class('Ipv4RawSocketFactory', parent=root_module['ns3::SocketFactory'])
## ipv4.h: ns3::Ipv4RoutingProtocol [class]
module.add_class('Ipv4RoutingProtocol', parent=root_module['ns3::Object'])
## net-device.h: ns3::NetDevice [class]
@@ -172,6 +176,7 @@
register_Ns3SocketAddressTag_methods(root_module, root_module['ns3::SocketAddressTag'])
register_Ns3SocketFactory_methods(root_module, root_module['ns3::SocketFactory'])
register_Ns3SocketIpTtlTag_methods(root_module, root_module['ns3::SocketIpTtlTag'])
+ register_Ns3SocketSetDontFragmentTag_methods(root_module, root_module['ns3::SocketSetDontFragmentTag'])
register_Ns3TcpSocket_methods(root_module, root_module['ns3::TcpSocket'])
register_Ns3TcpSocketFactory_methods(root_module, root_module['ns3::TcpSocketFactory'])
register_Ns3UdpSocket_methods(root_module, root_module['ns3::UdpSocket'])
@@ -184,6 +189,7 @@
register_Ns3EthernetHeader_methods(root_module, root_module['ns3::EthernetHeader'])
register_Ns3EthernetTrailer_methods(root_module, root_module['ns3::EthernetTrailer'])
register_Ns3Ipv4_methods(root_module, root_module['ns3::Ipv4'])
+ register_Ns3Ipv4RawSocketFactory_methods(root_module, root_module['ns3::Ipv4RawSocketFactory'])
register_Ns3Ipv4RoutingProtocol_methods(root_module, root_module['ns3::Ipv4RoutingProtocol'])
register_Ns3NetDevice_methods(root_module, root_module['ns3::NetDevice'])
register_Ns3Node_methods(root_module, root_module['ns3::Node'])
@@ -1507,6 +1513,56 @@
is_const=True, is_virtual=True)
return
+def register_Ns3SocketSetDontFragmentTag_methods(root_module, cls):
+ ## socket.h: ns3::SocketSetDontFragmentTag::SocketSetDontFragmentTag(ns3::SocketSetDontFragmentTag const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::SocketSetDontFragmentTag const &', 'arg0')])
+ ## socket.h: ns3::SocketSetDontFragmentTag::SocketSetDontFragmentTag() [constructor]
+ cls.add_constructor([])
+ ## socket.h: void ns3::SocketSetDontFragmentTag::Enable() [member function]
+ cls.add_method('Enable',
+ 'void',
+ [])
+ ## socket.h: void ns3::SocketSetDontFragmentTag::Disable() [member function]
+ cls.add_method('Disable',
+ 'void',
+ [])
+ ## socket.h: bool ns3::SocketSetDontFragmentTag::IsEnabled() const [member function]
+ cls.add_method('IsEnabled',
+ 'bool',
+ [],
+ is_const=True)
+ ## socket.h: static ns3::TypeId ns3::SocketSetDontFragmentTag::GetTypeId() [member function]
+ cls.add_method('GetTypeId',
+ 'ns3::TypeId',
+ [],
+ is_static=True)
+ ## socket.h: ns3::TypeId ns3::SocketSetDontFragmentTag::GetInstanceTypeId() const [member function]
+ cls.add_method('GetInstanceTypeId',
+ 'ns3::TypeId',
+ [],
+ is_const=True, is_virtual=True)
+ ## socket.h: uint32_t ns3::SocketSetDontFragmentTag::GetSerializedSize() const [member function]
+ cls.add_method('GetSerializedSize',
+ 'uint32_t',
+ [],
+ is_const=True, is_virtual=True)
+ ## socket.h: void ns3::SocketSetDontFragmentTag::Serialize(ns3::TagBuffer i) const [member function]
+ cls.add_method('Serialize',
+ 'void',
+ [param('ns3::TagBuffer', 'i')],
+ is_const=True, is_virtual=True)
+ ## socket.h: void ns3::SocketSetDontFragmentTag::Deserialize(ns3::TagBuffer i) [member function]
+ cls.add_method('Deserialize',
+ 'void',
+ [param('ns3::TagBuffer', 'i')],
+ is_virtual=True)
+ ## socket.h: void ns3::SocketSetDontFragmentTag::Print(std::ostream & os) const [member function]
+ cls.add_method('Print',
+ 'void',
+ [param('std::ostream &', 'os')],
+ is_const=True, is_virtual=True)
+ return
+
def register_Ns3TcpSocket_methods(root_module, cls):
## tcp-socket.h: ns3::TcpSocket::TcpSocket(ns3::TcpSocket const & arg0) [copy constructor]
cls.add_constructor([param('ns3::TcpSocket const &', 'arg0')])
@@ -1661,6 +1717,16 @@
'uint32_t',
[],
is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True)
+ ## udp-socket.h: void ns3::UdpSocket::SetMtuDiscover(bool discover) [member function]
+ cls.add_method('SetMtuDiscover',
+ 'void',
+ [param('bool', 'discover')],
+ is_pure_virtual=True, visibility='private', is_virtual=True)
+ ## udp-socket.h: bool ns3::UdpSocket::GetMtuDiscover() const [member function]
+ cls.add_method('GetMtuDiscover',
+ 'bool',
+ [],
+ is_pure_virtual=True, is_const=True, visibility='private', is_virtual=True)
return
def register_Ns3UdpSocketFactory_methods(root_module, cls):
@@ -2167,6 +2233,18 @@
is_virtual=True)
return
+def register_Ns3Ipv4RawSocketFactory_methods(root_module, cls):
+ ## ipv4-raw-socket-factory.h: ns3::Ipv4RawSocketFactory::Ipv4RawSocketFactory(ns3::Ipv4RawSocketFactory const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::Ipv4RawSocketFactory const &', 'arg0')])
+ ## ipv4-raw-socket-factory.h: ns3::Ipv4RawSocketFactory::Ipv4RawSocketFactory() [constructor]
+ cls.add_constructor([])
+ ## ipv4-raw-socket-factory.h: static ns3::TypeId ns3::Ipv4RawSocketFactory::GetTypeId() [member function]
+ cls.add_method('GetTypeId',
+ 'ns3::TypeId',
+ [],
+ is_static=True)
+ return
+
def register_Ns3Ipv4RoutingProtocol_methods(root_module, cls):
## ipv4.h: ns3::Ipv4RoutingProtocol::IF_INDEX_ANY [variable]
cls.add_static_attribute('IF_INDEX_ANY', 'uint32_t const', is_const=True)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/csma-ping.cc Wed Oct 29 11:49:21 2008 -0700
@@ -0,0 +1,140 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * 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
+ */
+
+// Port of ns-2/tcl/ex/simple.tcl to ns-3
+//
+// Network topology
+//
+// n0 n1 n2 n3
+// | | | |
+// =====================
+//
+// - CBR/UDP flows from n0 to n1, and from n3 to n0
+// - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec.
+// (i.e., DataRate of 448,000 bps)
+// - DropTail queues
+// - Tracing of queues and packet receptions to file "csma-one-subnet.tr"
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <cassert>
+
+#include "ns3/core-module.h"
+#include "ns3/simulator-module.h"
+#include "ns3/node-module.h"
+#include "ns3/helper-module.h"
+#include "ns3/global-route-manager.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("CsmaPingExample");
+
+static void SinkRx (Ptr<const Packet> p, const Address &ad)
+{
+ //std::cout << *p << std::endl;
+}
+
+static void PingRtt (std::string context, Time rtt)
+{
+ //std::cout << context << " " << rtt << std::endl;
+}
+
+int
+main (int argc, char *argv[])
+{
+ //
+ // Make the random number generators generate reproducible results.
+ //
+ RandomVariable::UseGlobalSeed (1, 1, 2, 3, 5, 8);
+
+ CommandLine cmd;
+ cmd.Parse (argc, argv);
+
+ // Here, we will explicitly create four nodes.
+ NS_LOG_INFO ("Create nodes.");
+ NodeContainer c;
+ c.Create (4);
+
+ // connect all our nodes to a shared channel.
+ NS_LOG_INFO ("Build Topology.");
+ CsmaHelper csma;
+ csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate (5000000)));
+ csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
+ csma.SetDeviceAttribute ("EncapsulationMode", StringValue ("Llc"));
+ NetDeviceContainer devs = csma.Install (c);
+
+ // add an ip stack to all nodes.
+ NS_LOG_INFO ("Add ip stack.");
+ InternetStackHelper ipStack;
+ ipStack.Install (c);
+
+ // assign ip addresses
+ NS_LOG_INFO ("Assign ip addresses.");
+ Ipv4AddressHelper ip;
+ ip.SetBase ("192.168.1.0", "255.255.255.0");
+ Ipv4InterfaceContainer addresses = ip.Assign (devs);
+
+ // setup global router
+ GlobalRouteManager::PopulateRoutingTables ();
+ NS_LOG_INFO ("Create Source");
+ Config::SetDefault ("ns3::Ipv4RawSocketImpl::Protocol", StringValue ("2"));
+ InetSocketAddress dst = InetSocketAddress (addresses.GetAddress (3));
+ OnOffHelper onoff = OnOffHelper ("ns3::Ipv4RawSocketFactory", dst);
+ onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1.0)));
+ onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0.0)));
+ onoff.SetAttribute ("DataRate", DataRateValue (DataRate (15000)));
+ onoff.SetAttribute ("PacketSize", UintegerValue (1200));
+
+
+ ApplicationContainer apps = onoff.Install (c.Get (0));
+ apps.Start (Seconds (1.0));
+ apps.Stop (Seconds (10.0));
+
+ NS_LOG_INFO ("Create Sink.");
+ PacketSinkHelper sink = PacketSinkHelper ("ns3::Ipv4RawSocketFactory", dst);
+ apps = sink.Install (c.Get (3));
+ apps.Start (Seconds (0.0));
+ apps.Stop (Seconds (11.0));
+
+ NS_LOG_INFO ("Create pinger");
+ V4PingHelper ping = V4PingHelper (addresses.GetAddress (2));
+ NodeContainer pingers;
+ pingers.Add (c.Get (0));
+ pingers.Add (c.Get (1));
+ pingers.Add (c.Get (3));
+ apps = ping.Install (pingers);
+ apps.Start (Seconds (2.0));
+ apps.Stop (Seconds (5.0));
+
+ NS_LOG_INFO ("Configure Tracing.");
+ // first, pcap tracing.
+ csma.EnablePcapAll ("csma-ping");
+ // then, print what the packet sink receives.
+ Config::ConnectWithoutContext ("/NodeList/3/ApplicationList/0/$ns3::PacketSink/Rx",
+ MakeCallback (&SinkRx));
+ // finally, print the ping rtts.
+ Config::Connect ("/NodeList/*/ApplicationList/*/$ns3::V4Ping/Rtt",
+ MakeCallback (&PingRtt));
+
+ Packet::EnablePrinting ();
+
+
+ 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/csma-raw-ip-socket.cc Wed Oct 29 11:49:21 2008 -0700
@@ -0,0 +1,122 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * 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
+ */
+
+// Port of ns-2/tcl/ex/simple.tcl to ns-3
+//
+// Network topology
+//
+// n0 n1 n2 n3
+// | | | |
+// =====================
+//
+// - CBR/UDP flows from n0 to n1, and from n3 to n0
+// - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec.
+// (i.e., DataRate of 448,000 bps)
+// - DropTail queues
+// - Tracing of queues and packet receptions to file "csma-one-subnet.tr"
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <cassert>
+
+#include "ns3/core-module.h"
+#include "ns3/simulator-module.h"
+#include "ns3/node-module.h"
+#include "ns3/helper-module.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("CsmaPacketSocketExample");
+
+static void SinkRx (Ptr<const Packet> p, const Address &ad)
+{
+ //std::cout << *p << std::endl;
+}
+
+int
+main (int argc, char *argv[])
+{
+#if 0
+ LogComponentEnable ("CsmaPacketSocketExample", LOG_LEVEL_INFO);
+#endif
+
+ //
+ // Make the random number generators generate reproducible results.
+ //
+ RandomVariable::UseGlobalSeed (1, 1, 2, 3, 5, 8);
+
+ CommandLine cmd;
+ cmd.Parse (argc, argv);
+
+ // Here, we will explicitly create four nodes.
+ NS_LOG_INFO ("Create nodes.");
+ NodeContainer c;
+ c.Create (4);
+
+ // connect all our nodes to a shared channel.
+ NS_LOG_INFO ("Build Topology.");
+ CsmaHelper csma;
+ csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate (5000000)));
+ csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
+ csma.SetDeviceAttribute ("EncapsulationMode", StringValue ("Llc"));
+ NetDeviceContainer devs = csma.Install (c);
+
+ // add an ip stack to all nodes.
+ NS_LOG_INFO ("Add ip stack.");
+ InternetStackHelper ipStack;
+ ipStack.Install (c);
+
+ // assign ip addresses
+ NS_LOG_INFO ("Assign ip addresses.");
+ Ipv4AddressHelper ip;
+ ip.SetBase ("192.168.1.0", "255.255.255.0");
+ Ipv4InterfaceContainer addresses = ip.Assign (devs);
+
+ NS_LOG_INFO ("Create Source");
+ Config::SetDefault ("ns3::Ipv4RawSocketImpl::Protocol", StringValue ("2"));
+ InetSocketAddress dst = InetSocketAddress (addresses.GetAddress (3));
+ OnOffHelper onoff = OnOffHelper ("ns3::Ipv4RawSocketFactory", dst);
+ onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1.0)));
+ onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0.0)));
+ onoff.SetAttribute ("DataRate", DataRateValue (DataRate (6000)));
+ onoff.SetAttribute ("PacketSize", UintegerValue (1200));
+
+ ApplicationContainer apps = onoff.Install (c.Get (0));
+ apps.Start (Seconds (1.0));
+ apps.Stop (Seconds (10.0));
+
+ NS_LOG_INFO ("Create Sink.");
+ PacketSinkHelper sink = PacketSinkHelper ("ns3::Ipv4RawSocketFactory", dst);
+ apps = sink.Install (c.Get (3));
+ apps.Start (Seconds (0.0));
+ apps.Stop (Seconds (11.0));
+
+ NS_LOG_INFO ("Configure Tracing.");
+ // first, pcap tracing.
+ csma.EnablePcapAll ("csma-raw-ip-socket");
+ // then, print what the packet sink receives.
+ Config::ConnectWithoutContext ("/NodeList/3/ApplicationList/0/$ns3::PacketSink/Rx",
+ MakeCallback (&SinkRx));
+
+ Packet::EnablePrinting ();
+
+
+ NS_LOG_INFO ("Run Simulation.");
+ Simulator::Run ();
+ Simulator::Destroy ();
+ NS_LOG_INFO ("Done.");
+}
--- a/examples/wscript Mon Oct 27 23:05:57 2008 -0700
+++ b/examples/wscript Wed Oct 29 11:49:21 2008 -0700
@@ -94,3 +94,11 @@
['core', 'simulator', 'mobility', 'wifi',
'csma', 'helper', 'bridge'])
obj.source = 'wifi-wired-bridging.cc'
+
+ obj = bld.create_ns3_program('csma-raw-ip-socket',
+ ['csma', 'internet-stack'])
+ obj.source = 'csma-raw-ip-socket.cc'
+
+ obj = bld.create_ns3_program('csma-ping',
+ ['csma', 'internet-stack', 'v4ping'])
+ obj.source = 'csma-ping.cc'
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/regression/tests/test-csma-ping.py Wed Oct 29 11:49:21 2008 -0700
@@ -0,0 +1,12 @@
+#! /usr/bin/env python
+
+"""Generic trace-comparison-type regression test."""
+
+import os
+import shutil
+import tracediff
+
+def run(verbose, generate, refDirName):
+ """Execute a test."""
+
+ return tracediff.run_test(verbose, generate, refDirName, "csma-ping")
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/regression/tests/test-csma-raw-ip-socket.py Wed Oct 29 11:49:21 2008 -0700
@@ -0,0 +1,12 @@
+#! /usr/bin/env python
+
+"""Generic trace-comparison-type regression test."""
+
+import os
+import shutil
+import tracediff
+
+def run(verbose, generate, refDirName):
+ """Execute a test."""
+
+ return tracediff.run_test(verbose, generate, refDirName, "csma-raw-ip-socket")
--- a/src/applications/onoff/onoff-application.cc Mon Oct 27 23:05:57 2008 -0700
+++ b/src/applications/onoff/onoff-application.cc Wed Oct 29 11:49:21 2008 -0700
@@ -147,7 +147,14 @@
NS_LOG_FUNCTION_NOARGS ();
CancelEvents ();
- m_socket->Close ();
+ if(m_socket != 0)
+ {
+ m_socket->Close ();
+ }
+ else
+ {
+ NS_LOG_WARN("OnOffApplication found null socket to close in StopApplication");
+ }
}
void OnOffApplication::CancelEvents ()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/v4ping/v4ping.cc Wed Oct 29 11:49:21 2008 -0700
@@ -0,0 +1,155 @@
+#include "v4ping.h"
+#include "ns3/icmpv4.h"
+#include "ns3/assert.h"
+#include "ns3/log.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/socket.h"
+#include "ns3/uinteger.h"
+#include "ns3/inet-socket-address.h"
+#include "ns3/packet.h"
+#include "ns3/trace-source-accessor.h"
+#include "ns3/simulator.h"
+
+namespace ns3 {
+
+NS_LOG_COMPONENT_DEFINE ("V4Ping");
+NS_OBJECT_ENSURE_REGISTERED (V4Ping);
+
+TypeId
+V4Ping::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::V4Ping")
+ .SetParent<Application> ()
+ .AddConstructor<V4Ping> ()
+ .AddAttribute ("Remote",
+ "The address of the machine we want to ping.",
+ Ipv4AddressValue (),
+ MakeIpv4AddressAccessor (&V4Ping::m_remote),
+ MakeIpv4AddressChecker ())
+ .AddTraceSource ("Rtt",
+ "The rtt calculated by the ping.",
+ MakeTraceSourceAccessor (&V4Ping::m_traceRtt));
+ ;
+ return tid;
+}
+
+V4Ping::V4Ping ()
+ : m_socket (0),
+ m_seq (0)
+{}
+V4Ping::~V4Ping ()
+{}
+
+void
+V4Ping::DoDispose (void)
+{
+ NS_LOG_FUNCTION (this);
+ m_socket = 0;
+ Application::DoDispose ();
+}
+
+uint32_t
+V4Ping::GetApplicationId (void) const
+{
+ Ptr<Node> node = GetNode ();
+ for (uint32_t i = 0; i < node->GetNApplications (); ++i)
+ {
+ if (node->GetApplication (i) == this)
+ {
+ return i;
+ }
+ }
+ NS_ASSERT_MSG (false, "forgot to add application to node");
+ return 0; // quiet compiler
+}
+
+void
+V4Ping::Receive (Ptr<Socket> socket)
+{
+ NS_LOG_FUNCTION (this << socket);
+ while (m_socket->GetRxAvailable () > 0)
+ {
+ Address from;
+ Ptr<Packet> p = m_socket->RecvFrom (0xffffffff, 0, from);
+ NS_LOG_DEBUG ("recv " << p->GetSize () << " bytes");
+ NS_ASSERT (InetSocketAddress::IsMatchingType (from));
+ InetSocketAddress realFrom = InetSocketAddress::ConvertFrom (from);
+ NS_ASSERT (realFrom.GetPort () == 1); // protocol should be icmp.
+ Ipv4Header ipv4;
+ p->RemoveHeader (ipv4);
+ NS_ASSERT (ipv4.GetProtocol () == 1); // protocol should be icmp.
+ Icmpv4Header icmp;
+ p->RemoveHeader (icmp);
+ if (icmp.GetType () == Icmpv4Header::ECHO_REPLY)
+ {
+ Icmpv4Echo echo;
+ p->RemoveHeader (echo);
+ if (echo.GetSequenceNumber () == (m_seq - 1) &&
+ echo.GetIdentifier () == 0)
+ {
+ Ptr<const Packet> data = echo.GetData ();
+ if (data->GetSize () == 16)
+ {
+ uint32_t *buf = (uint32_t *)data->PeekData ();
+ if (buf[0] == GetNode ()->GetId () &&
+ buf[1] == GetApplicationId ())
+ {
+ int64_t ts = buf[3];
+ ts <<= 32;
+ ts |= buf[2];
+ Time sendTime = TimeStep (ts);
+ NS_ASSERT (Simulator::Now () > sendTime);
+ Time delta = Simulator::Now () - sendTime;
+ m_traceRtt (delta);
+ }
+ }
+ }
+ }
+ }
+}
+
+void
+V4Ping::StartApplication (void)
+{
+ NS_LOG_FUNCTION (this);
+ m_socket = Socket::CreateSocket (GetNode (), TypeId::LookupByName ("ns3::Ipv4RawSocketFactory"));
+ NS_ASSERT (m_socket != 0);
+ m_socket->SetAttribute ("Protocol", UintegerValue (1)); // icmp
+ m_socket->SetRecvCallback (MakeCallback (&V4Ping::Receive, this));
+ InetSocketAddress src = InetSocketAddress (Ipv4Address::GetAny (), 0);
+ int status;
+ status = m_socket->Bind (src);
+ NS_ASSERT (status != -1);
+ InetSocketAddress dst = InetSocketAddress (m_remote, 0);
+ status = m_socket->Connect (dst);
+ NS_ASSERT (status != -1);
+ Ptr<Packet> p = Create<Packet> ();
+ Icmpv4Echo echo;
+ echo.SetSequenceNumber (m_seq);
+ m_seq++;
+ echo.SetIdentifier (0);
+ uint32_t data[4];
+ data[0] = GetNode ()->GetId ();
+ data[1] = GetApplicationId ();
+ int64_t now = Simulator::Now ().GetTimeStep ();
+ data[2] = now & 0xffffffff;
+ now >>= 32;
+ data[3] = now & 0xffffffff;
+ Ptr<Packet> dataPacket = Create<Packet> ((uint8_t *) &data, 16);
+ echo.SetData (dataPacket);
+ p->AddHeader (echo);
+ Icmpv4Header header;
+ header.SetType (Icmpv4Header::ECHO);
+ header.SetCode (0);
+ p->AddHeader (header);
+ m_socket->Send (p, 0);
+
+}
+void
+V4Ping::StopApplication (void)
+{
+ NS_LOG_FUNCTION (this);
+}
+
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/v4ping/v4ping.h Wed Oct 29 11:49:21 2008 -0700
@@ -0,0 +1,36 @@
+#ifndef V4PING_H
+#define V4PING_H
+
+#include "ns3/application.h"
+#include "ns3/traced-callback.h"
+#include "ns3/nstime.h"
+
+namespace ns3 {
+
+class Socket;
+
+class V4Ping : public Application
+{
+public:
+ static TypeId GetTypeId (void);
+
+ V4Ping ();
+ virtual ~V4Ping ();
+
+private:
+ // inherited from Application base class.
+ virtual void StartApplication (void);
+ virtual void StopApplication (void);
+ virtual void DoDispose (void);
+ uint32_t GetApplicationId (void) const;
+ void Receive (Ptr<Socket> socket);
+
+ Ipv4Address m_remote;
+ Ptr<Socket> m_socket;
+ uint16_t m_seq;
+ TracedCallback<Time> m_traceRtt;
+};
+
+} // namespace ns3
+
+#endif /* V4PING_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/v4ping/wscript Wed Oct 29 11:49:21 2008 -0700
@@ -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('v4ping', ['node'])
+ module.source = [
+ 'v4ping.cc',
+ ]
+ headers = bld.create_obj('ns3header')
+ headers.module = 'v4ping'
+ headers.source = [
+ 'v4ping.h',
+ ]
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/v4ping-helper.cc Wed Oct 29 11:49:21 2008 -0700
@@ -0,0 +1,33 @@
+#include "v4ping-helper.h"
+#include "ns3/v4ping.h"
+
+namespace ns3 {
+
+V4PingHelper::V4PingHelper (Ipv4Address remote)
+{
+ m_factory.SetTypeId ("ns3::V4Ping");
+ m_factory.Set ("Remote", Ipv4AddressValue (remote));
+}
+
+void
+V4PingHelper::SetAttribute (std::string name, const AttributeValue &value)
+{
+ m_factory.Set (name, value);
+}
+
+ApplicationContainer
+V4PingHelper::Install (NodeContainer nodes)
+{
+ ApplicationContainer apps;
+ for (NodeContainer::Iterator i = nodes.Begin (); i != nodes.End (); ++i)
+ {
+ Ptr<Node> node = *i;
+ Ptr<V4Ping> ping = m_factory.Create<V4Ping> ();
+ node->AddApplication (ping);
+ apps.Add (ping);
+ }
+ return apps;
+}
+
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/v4ping-helper.h Wed Oct 29 11:49:21 2008 -0700
@@ -0,0 +1,25 @@
+#ifndef V4PING_HELPER_H
+#define V4PING_HELPER_H
+
+#include "node-container.h"
+#include "application-container.h"
+#include "ns3/object-factory.h"
+
+namespace ns3 {
+
+class V4PingHelper
+{
+public:
+ V4PingHelper (Ipv4Address remote);
+
+ void SetAttribute (std::string name, const AttributeValue &value);
+
+ ApplicationContainer Install (NodeContainer nodes);
+
+private:
+ ObjectFactory m_factory;
+};
+
+} // namespace ns3
+
+#endif /* V4PING_HELPER_H */
--- a/src/helper/wscript Mon Oct 27 23:05:57 2008 -0700
+++ b/src/helper/wscript Wed Oct 29 11:49:21 2008 -0700
@@ -23,6 +23,7 @@
'ipv4-interface-container.cc',
'udp-echo-helper.cc',
'bridge-helper.cc',
+ 'v4ping-helper.cc',
]
headers = bld.create_obj('ns3header')
@@ -48,4 +49,5 @@
'ipv4-interface-container.h',
'udp-echo-helper.h',
'bridge-helper.h',
+ 'v4ping-helper.h',
]
--- a/src/internet-stack/arp-ipv4-interface.cc Mon Oct 27 23:05:57 2008 -0700
+++ b/src/internet-stack/arp-ipv4-interface.cc Wed Oct 29 11:49:21 2008 -0700
@@ -65,7 +65,6 @@
ArpIpv4Interface::DoDispose (void)
{
NS_LOG_FUNCTION (this);
- m_node = 0;
m_device = 0;
m_cache = 0;
Ipv4Interface::DoDispose ();
@@ -107,6 +106,17 @@
NS_LOG_FUNCTION (this << p << dest);
NS_ASSERT (GetDevice () != 0);
+ if (dest == GetAddress ())
+ {
+ Ptr<Ipv4L3Protocol> ipv4 = m_node->GetObject<Ipv4L3Protocol> ();
+
+ ipv4->Receive (0, p, Ipv4L3Protocol::PROT_NUMBER,
+ GetDevice ()->GetBroadcast (),
+ GetDevice ()->GetBroadcast (),
+ NetDevice::PACKET_HOST // note: linux uses PACKET_LOOPBACK here
+ );
+ return;
+ }
if (m_device->NeedsArp ())
{
NS_LOG_LOGIC ("Needs ARP");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/icmpv4-l4-protocol.cc Wed Oct 29 11:49:21 2008 -0700
@@ -0,0 +1,223 @@
+#include "icmpv4-l4-protocol.h"
+#include "ipv4-interface.h"
+#include "ipv4-l3-protocol.h"
+#include "ns3/assert.h"
+#include "ns3/log.h"
+#include "ns3/node.h"
+#include "ns3/packet.h"
+#include "ns3/boolean.h"
+
+namespace ns3 {
+
+NS_LOG_COMPONENT_DEFINE ("Icmpv4L4Protocol");
+
+NS_OBJECT_ENSURE_REGISTERED (Icmpv4L4Protocol);
+
+ // see rfc 792
+enum {
+ ICMP_PROTOCOL = 1
+};
+
+TypeId
+Icmpv4L4Protocol::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::Icmpv4L4Protocol")
+ .SetParent<Ipv4L4Protocol> ()
+ .AddConstructor<Icmpv4L4Protocol> ()
+ .AddAttribute ("CalcChecksum",
+ "Control whether the icmp header checksum is calculated and stored in outgoing icmpv4 headers",
+ BooleanValue (false),
+ MakeBooleanAccessor (&Icmpv4L4Protocol::m_calcChecksum),
+ MakeBooleanChecker ())
+ ;
+ return tid;
+}
+
+Icmpv4L4Protocol::Icmpv4L4Protocol ()
+ : m_node (0)
+{}
+Icmpv4L4Protocol::~Icmpv4L4Protocol ()
+{
+ NS_ASSERT (m_node == 0);
+}
+
+void
+Icmpv4L4Protocol::SetNode (Ptr<Node> node)
+{
+ m_node = node;
+}
+
+uint16_t
+Icmpv4L4Protocol::GetStaticProtocolNumber (void)
+{
+ return ICMP_PROTOCOL;
+}
+
+int
+Icmpv4L4Protocol::GetProtocolNumber (void) const
+{
+ return ICMP_PROTOCOL;
+}
+void
+Icmpv4L4Protocol::SendMessage (Ptr<Packet> packet, Ipv4Address dest, uint8_t type, uint8_t code)
+{
+ Ptr<Ipv4L3Protocol> ipv4 = m_node->GetObject<Ipv4L3Protocol> ();
+ uint32_t i;
+ if (!ipv4->GetIfIndexForDestination (dest, i))
+ {
+ NS_LOG_WARN ("drop icmp message");
+ return;
+ }
+ Ipv4Address source = ipv4->GetAddress (i);
+ SendMessage (packet, source, dest, type, code);
+}
+
+void
+Icmpv4L4Protocol::SendMessage (Ptr<Packet> packet, Ipv4Address source, Ipv4Address dest, uint8_t type, uint8_t code)
+{
+ Ptr<Ipv4L3Protocol> ipv4 = m_node->GetObject<Ipv4L3Protocol> ();
+ Icmpv4Header icmp;
+ icmp.SetType (type);
+ icmp.SetCode (code);
+ if (m_calcChecksum)
+ {
+ icmp.EnableChecksum ();
+ }
+ packet->AddHeader (icmp);
+ ipv4->Send (packet, source, dest, ICMP_PROTOCOL);
+}
+void
+Icmpv4L4Protocol::SendDestUnreachFragNeeded (Ipv4Header header,
+ Ptr<const Packet> orgData,
+ uint16_t nextHopMtu)
+{
+ NS_LOG_FUNCTION (this << header << *orgData << nextHopMtu);
+ SendDestUnreach (header, orgData, Icmpv4DestinationUnreachable::FRAG_NEEDED, nextHopMtu);
+}
+void
+Icmpv4L4Protocol::SendDestUnreachPort (Ipv4Header header,
+ Ptr<const Packet> orgData)
+{
+ NS_LOG_FUNCTION (this << header << *orgData);
+ SendDestUnreach (header, orgData, Icmpv4DestinationUnreachable::PORT_UNREACHABLE, 0);
+}
+void
+Icmpv4L4Protocol::SendDestUnreach (Ipv4Header header, Ptr<const Packet> orgData,
+ uint8_t code, uint16_t nextHopMtu)
+{
+ NS_LOG_FUNCTION (this << header << *orgData << (uint32_t) code << nextHopMtu);
+ Ptr<Packet> p = Create<Packet> ();
+ Icmpv4DestinationUnreachable unreach;
+ unreach.SetNextHopMtu (nextHopMtu);
+ unreach.SetHeader (header);
+ unreach.SetData (orgData);
+ p->AddHeader (unreach);
+ SendMessage (p, header.GetSource (), Icmpv4Header::DEST_UNREACH, code);
+}
+
+void
+Icmpv4L4Protocol::SendTimeExceededTtl (Ipv4Header header, Ptr<const Packet> orgData)
+{
+ NS_LOG_FUNCTION (this << header << *orgData);
+ Ptr<Packet> p = Create<Packet> ();
+ Icmpv4TimeExceeded time;
+ time.SetHeader (header);
+ time.SetData (orgData);
+ p->AddHeader (time);
+ SendMessage (p, header.GetSource (), Icmpv4Header::TIME_EXCEEDED, Icmpv4TimeExceeded::TIME_TO_LIVE);
+}
+
+void
+Icmpv4L4Protocol::HandleEcho (Ptr<Packet> p,
+ Icmpv4Header header,
+ Ipv4Address source,
+ Ipv4Address destination)
+{
+ NS_LOG_FUNCTION (this << p << header << source << destination);
+
+ Ptr<Packet> reply = Create<Packet> ();
+ Icmpv4Echo echo;
+ p->RemoveHeader (echo);
+ reply->AddHeader (echo);
+ SendMessage (reply, destination, source, Icmpv4Header::ECHO_REPLY, 0);
+}
+void
+Icmpv4L4Protocol::Forward (Ipv4Address source, Icmpv4Header icmp,
+ uint32_t info, Ipv4Header ipHeader,
+ const uint8_t payload[8])
+{
+ Ptr<Ipv4L3Protocol> ipv4 = m_node->GetObject<Ipv4L3Protocol> ();
+ Ptr<Ipv4L4Protocol> l4 = ipv4->GetProtocol (ipHeader.GetProtocol ());
+ if (l4 != 0)
+ {
+ l4->ReceiveIcmp (source, ipHeader.GetTtl (), icmp.GetType (), icmp.GetCode (),
+ info, ipHeader.GetSource (), ipHeader.GetDestination (), payload);
+ }
+}
+void
+Icmpv4L4Protocol::HandleDestUnreach (Ptr<Packet> p,
+ Icmpv4Header icmp,
+ Ipv4Address source,
+ Ipv4Address destination)
+{
+ NS_LOG_FUNCTION (this << p << icmp << source << destination);
+
+ Icmpv4DestinationUnreachable unreach;
+ p->PeekHeader (unreach);
+ uint8_t payload[8];
+ unreach.GetData (payload);
+ Ipv4Header ipHeader = unreach.GetHeader ();
+ Forward (source, icmp, unreach.GetNextHopMtu (), ipHeader, payload);
+}
+void
+Icmpv4L4Protocol::HandleTimeExceeded (Ptr<Packet> p,
+ Icmpv4Header icmp,
+ Ipv4Address source,
+ Ipv4Address destination)
+{
+ NS_LOG_FUNCTION (this << p << icmp << source << destination);
+
+ Icmpv4TimeExceeded time;
+ p->PeekHeader (time);
+ uint8_t payload[8];
+ time.GetData (payload);
+ Ipv4Header ipHeader = time.GetHeader ();
+ // info field is zero for TimeExceeded on linux
+ Forward (source, icmp, 0, ipHeader, payload);
+}
+
+enum Ipv4L4Protocol::RxStatus
+Icmpv4L4Protocol::Receive(Ptr<Packet> p,
+ Ipv4Address const &source,
+ Ipv4Address const &destination,
+ Ptr<Ipv4Interface> incomingInterface)
+{
+ NS_LOG_FUNCTION (this << p << source << destination << incomingInterface);
+
+ Icmpv4Header icmp;
+ p->RemoveHeader (icmp);
+ switch (icmp.GetType ()) {
+ case Icmpv4Header::ECHO:
+ HandleEcho (p, icmp, source, destination);
+ break;
+ case Icmpv4Header::DEST_UNREACH:
+ HandleDestUnreach (p, icmp, source, destination);
+ break;
+ case Icmpv4Header::TIME_EXCEEDED:
+ HandleTimeExceeded (p, icmp, source, destination);
+ break;
+ default:
+ NS_LOG_DEBUG (icmp << " " << *p);
+ break;
+ }
+ return Ipv4L4Protocol::RX_OK;
+}
+void
+Icmpv4L4Protocol::DoDispose (void)
+{
+ NS_LOG_FUNCTION (this);
+ m_node = 0;
+ Ipv4L4Protocol::DoDispose ();
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/icmpv4-l4-protocol.h Wed Oct 29 11:49:21 2008 -0700
@@ -0,0 +1,62 @@
+#ifndef ICMPV4_L4_PROTOCOL_H
+#define ICMPV4_L4_PROTOCOL_H
+
+#include "ipv4-l4-protocol.h"
+#include "icmpv4.h"
+#include "ns3/ipv4-address.h"
+
+namespace ns3 {
+
+class Node;
+class Ipv4Interface;
+
+class Icmpv4L4Protocol : public Ipv4L4Protocol
+{
+public:
+ static TypeId GetTypeId (void);
+ Icmpv4L4Protocol ();
+ virtual ~Icmpv4L4Protocol ();
+
+ void SetNode (Ptr<Node> node);
+
+ static uint16_t GetStaticProtocolNumber (void);
+ virtual int GetProtocolNumber (void) const;
+ virtual enum Ipv4L4Protocol::RxStatus Receive(Ptr<Packet> p,
+ const Ipv4Address &source,
+ const Ipv4Address &destination,
+ Ptr<Ipv4Interface> incomingInterface);
+
+ void SendDestUnreachFragNeeded (Ipv4Header header, Ptr<const Packet> orgData, uint16_t nextHopMtu);
+ void SendTimeExceededTtl (Ipv4Header header, Ptr<const Packet> orgData);
+ void SendDestUnreachPort (Ipv4Header header, Ptr<const Packet> orgData);
+
+private:
+ void HandleEcho (Ptr<Packet> p,
+ Icmpv4Header header,
+ Ipv4Address source,
+ Ipv4Address destination);
+ void HandleDestUnreach (Ptr<Packet> p,
+ Icmpv4Header header,
+ Ipv4Address source,
+ Ipv4Address destination);
+ void HandleTimeExceeded (Ptr<Packet> p,
+ Icmpv4Header icmp,
+ Ipv4Address source,
+ Ipv4Address destination);
+ void SendDestUnreach (Ipv4Header header, Ptr<const Packet> orgData,
+ uint8_t code, uint16_t nextHopMtu);
+ void SendMessage (Ptr<Packet> packet, Ipv4Address dest, uint8_t type, uint8_t code);
+ void SendMessage (Ptr<Packet> packet, Ipv4Address source, Ipv4Address dest, uint8_t type, uint8_t code);
+ void Forward (Ipv4Address source, Icmpv4Header icmp,
+ uint32_t info, Ipv4Header ipHeader,
+ const uint8_t payload[8]);
+
+ virtual void DoDispose (void);
+
+ Ptr<Node> m_node;
+ bool m_calcChecksum;
+};
+
+} // namespace ns3
+
+#endif /* ICMPV4_L4_PROTOCOL_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/icmpv4.cc Wed Oct 29 11:49:21 2008 -0700
@@ -0,0 +1,387 @@
+#include "icmpv4.h"
+#include "ns3/packet.h"
+
+namespace ns3 {
+
+/********************************************************
+ * Icmpv4Header
+ ********************************************************/
+
+TypeId
+Icmpv4Header::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::Icmpv4Header")
+ .SetParent<Header> ()
+ .AddConstructor<Icmpv4Header> ()
+ ;
+ return tid;
+}
+Icmpv4Header::Icmpv4Header ()
+ : m_type (0),
+ m_code (0),
+ m_calcChecksum (false)
+{}
+Icmpv4Header::~Icmpv4Header ()
+{}
+void
+Icmpv4Header::EnableChecksum (void)
+{
+ m_calcChecksum = true;
+}
+TypeId
+Icmpv4Header::GetInstanceTypeId (void) const
+{
+ return GetTypeId ();
+}
+uint32_t
+Icmpv4Header::GetSerializedSize (void) const
+{
+ return 4;
+}
+void
+Icmpv4Header::Serialize (Buffer::Iterator start) const
+{
+ Buffer::Iterator i = start;
+ i.WriteU8 (m_type);
+ i.WriteU8 (m_code);
+ i.WriteHtonU16 (0);
+ if (m_calcChecksum)
+ {
+ i = start;
+ uint16_t checksum = i.CalculateIpChecksum (i.GetSize ());
+ i = start;
+ i.Next (2);
+ i.WriteU16 (checksum);
+ }
+
+}
+uint32_t
+Icmpv4Header::Deserialize (Buffer::Iterator start)
+{
+ m_type = start.ReadU8 ();
+ m_code = start.ReadU8 ();
+ uint16_t checksum;
+ checksum = start.ReadNtohU16 ();
+ return 4;
+}
+void
+Icmpv4Header::Print (std::ostream &os) const
+{
+ os << "type=" << (uint32_t)m_type << ", code=" << (uint32_t)m_code;
+}
+
+void
+Icmpv4Header::SetType (uint8_t type)
+{
+ m_type = type;
+}
+void
+Icmpv4Header::SetCode (uint8_t code)
+{
+ m_code = code;
+}
+uint8_t
+Icmpv4Header::GetType (void) const
+{
+ return m_type;
+}
+uint8_t
+Icmpv4Header::GetCode (void) const
+{
+ return m_code;
+}
+
+/********************************************************
+ * Icmpv4Echo
+ ********************************************************/
+
+void
+Icmpv4Echo::SetIdentifier (uint16_t id)
+{
+ m_identifier = id;
+}
+void
+Icmpv4Echo::SetSequenceNumber (uint16_t seq)
+{
+ m_sequence = seq;
+}
+void
+Icmpv4Echo::SetData (Ptr<const Packet> data)
+{
+ m_data = data->Copy ();
+}
+uint16_t
+Icmpv4Echo::GetIdentifier (void) const
+{
+ return m_identifier;
+}
+uint16_t
+Icmpv4Echo::GetSequenceNumber (void) const
+{
+ return m_sequence;
+}
+Ptr<const Packet>
+Icmpv4Echo::GetData (void) const
+{
+ return m_data->Copy ();
+}
+
+
+TypeId
+Icmpv4Echo::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::Icmpv4Echo")
+ .SetParent<Header> ()
+ .AddConstructor<Icmpv4Echo> ()
+ ;
+ return tid;
+}
+Icmpv4Echo::Icmpv4Echo ()
+ : m_identifier (0),
+ m_sequence (0),
+ m_data (0)
+{}
+Icmpv4Echo::~Icmpv4Echo ()
+{}
+TypeId
+Icmpv4Echo::GetInstanceTypeId (void) const
+{
+ return GetTypeId ();
+}
+uint32_t
+Icmpv4Echo::GetSerializedSize (void) const
+{
+ return 4 + m_data->GetSize ();
+}
+void
+Icmpv4Echo::Serialize (Buffer::Iterator start) const
+{
+ start.WriteHtonU16 (m_identifier);
+ start.WriteHtonU16 (m_sequence);
+ start.Write (m_data->PeekData (), m_data->GetSize ());
+}
+uint32_t
+Icmpv4Echo::Deserialize (Buffer::Iterator start)
+{
+ m_identifier = start.ReadNtohU16 ();
+ m_sequence = start.ReadNtohU16 ();
+ NS_ASSERT (start.GetSize () >= 4);
+ uint32_t size = start.GetSize () - 4;
+ uint8_t *buffer = new uint8_t[size] ();
+ start.Read (buffer, size);
+ m_data = Create<Packet> (buffer, size);
+ delete[] buffer;
+ return start.GetSize ();
+}
+void
+Icmpv4Echo::Print (std::ostream &os) const
+{
+ os << "identifier=" << m_identifier << ", sequence=" << m_sequence;
+}
+
+
+/********************************************************
+ * Icmpv4DestinationUnreachable
+ ********************************************************/
+
+TypeId
+Icmpv4DestinationUnreachable::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::Icmpv4DestinationUnreachable")
+ .SetParent<Header> ()
+ .AddConstructor<Icmpv4DestinationUnreachable> ()
+ ;
+ return tid;
+}
+Icmpv4DestinationUnreachable::Icmpv4DestinationUnreachable ()
+{
+ // make sure that thing is initialized to get initialized bytes
+ // when the ip payload's size is smaller than 8 bytes.
+ for (uint8_t j = 0; j < 8; j++)
+ {
+ m_data[j] = 0;
+ }
+}
+
+void
+Icmpv4DestinationUnreachable::SetNextHopMtu (uint16_t mtu)
+{
+ m_nextHopMtu = mtu;
+}
+uint16_t
+Icmpv4DestinationUnreachable::GetNextHopMtu (void) const
+{
+ return m_nextHopMtu;
+}
+
+void
+Icmpv4DestinationUnreachable::SetData (Ptr<const Packet> data)
+{
+ data->CopyData (m_data, 8);
+}
+void
+Icmpv4DestinationUnreachable::SetHeader (Ipv4Header header)
+{
+ m_header = header;
+}
+void
+Icmpv4DestinationUnreachable::GetData (uint8_t payload[8]) const
+{
+ memcpy (payload, m_data, 8);
+}
+Ipv4Header
+Icmpv4DestinationUnreachable::GetHeader (void) const
+{
+ return m_header;
+}
+
+
+Icmpv4DestinationUnreachable::~Icmpv4DestinationUnreachable ()
+{}
+TypeId
+Icmpv4DestinationUnreachable::GetInstanceTypeId (void) const
+{
+ return GetTypeId ();
+}
+uint32_t
+Icmpv4DestinationUnreachable::GetSerializedSize (void) const
+{
+ return 4 + m_header.GetSerializedSize () + 8;
+}
+void
+Icmpv4DestinationUnreachable::Serialize (Buffer::Iterator start) const
+{
+ start.WriteU16 (0);
+ start.WriteHtonU16 (m_nextHopMtu);
+ uint32_t size = m_header.GetSerializedSize ();
+ m_header.Serialize (start);
+ start.Next (size);
+ start.Write (m_data, 8);
+}
+
+uint32_t
+Icmpv4DestinationUnreachable::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+ i.Next (2);
+ m_nextHopMtu = i.ReadNtohU16 ();
+ uint32_t read = m_header.Deserialize (i);
+ i.Next (read);
+ for (uint8_t j = 0; j < 8; j++)
+ {
+ m_data[j] = i.ReadU8 ();
+ }
+ return i.GetDistanceFrom (start);
+}
+void
+Icmpv4DestinationUnreachable::Print (std::ostream &os) const
+{
+ m_header.Print (os);
+ os << " org data=";
+ for (uint8_t i = 0; i < 8; i++)
+ {
+ os << (uint32_t) m_data[i];
+ if (i != 8)
+ {
+ os << " ";
+ }
+ }
+}
+
+/********************************************************
+ * Icmpv4TimeExceeded
+ ********************************************************/
+
+TypeId
+Icmpv4TimeExceeded::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::Icmpv4TimeExceeded")
+ .SetParent<Header> ()
+ .AddConstructor<Icmpv4TimeExceeded> ()
+ ;
+ return tid;
+}
+Icmpv4TimeExceeded::Icmpv4TimeExceeded ()
+{
+ // make sure that thing is initialized to get initialized bytes
+ // when the ip payload's size is smaller than 8 bytes.
+ for (uint8_t j = 0; j < 8; j++)
+ {
+ m_data[j] = 0;
+ }
+}
+
+
+void
+Icmpv4TimeExceeded::SetData (Ptr<const Packet> data)
+{
+ data->CopyData (m_data, 8);
+}
+void
+Icmpv4TimeExceeded::SetHeader (Ipv4Header header)
+{
+ m_header = header;
+}
+void
+Icmpv4TimeExceeded::GetData (uint8_t payload[8]) const
+{
+ memcpy (payload, m_data, 8);
+}
+Ipv4Header
+Icmpv4TimeExceeded::GetHeader (void) const
+{
+ return m_header;
+}
+
+
+Icmpv4TimeExceeded::~Icmpv4TimeExceeded ()
+{}
+TypeId
+Icmpv4TimeExceeded::GetInstanceTypeId (void) const
+{
+ return GetTypeId ();
+}
+uint32_t
+Icmpv4TimeExceeded::GetSerializedSize (void) const
+{
+ return 4 + m_header.GetSerializedSize () + 8;
+}
+void
+Icmpv4TimeExceeded::Serialize (Buffer::Iterator start) const
+{
+ start.WriteU32 (0);
+ uint32_t size = m_header.GetSerializedSize ();
+ m_header.Serialize (start);
+ start.Next (size);
+ start.Write (m_data, 8);
+}
+
+uint32_t
+Icmpv4TimeExceeded::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+ i.Next (4);
+ uint32_t read = m_header.Deserialize (i);
+ i.Next (read);
+ for (uint8_t j = 0; j < 8; j++)
+ {
+ m_data[j] = i.ReadU8 ();
+ }
+ return i.GetDistanceFrom (start);
+}
+void
+Icmpv4TimeExceeded::Print (std::ostream &os) const
+{
+ m_header.Print (os);
+ os << " org data=";
+ for (uint8_t i = 0; i < 8; i++)
+ {
+ os << (uint32_t) m_data[i];
+ if (i != 8)
+ {
+ os << " ";
+ }
+ }
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/icmpv4.h Wed Oct 29 11:49:21 2008 -0700
@@ -0,0 +1,137 @@
+#ifndef ICMPV4_H
+#define ICMPV4_H
+
+#include "ns3/header.h"
+#include "ns3/ptr.h"
+#include "ns3/ipv4-header.h"
+#include <stdint.h>
+
+namespace ns3 {
+
+class Packet;
+
+class Icmpv4Header : public Header
+{
+public:
+ enum {
+ ECHO_REPLY = 0,
+ DEST_UNREACH = 3,
+ ECHO = 8,
+ TIME_EXCEEDED = 11
+ };
+
+ void EnableChecksum (void);
+ void SetType (uint8_t type);
+ void SetCode (uint8_t code);
+
+ uint8_t GetType (void) const;
+ uint8_t GetCode (void) const;
+
+ static TypeId GetTypeId (void);
+ Icmpv4Header ();
+ virtual ~Icmpv4Header ();
+ virtual TypeId GetInstanceTypeId (void) const;
+ virtual uint32_t GetSerializedSize (void) const;
+ virtual void Serialize (Buffer::Iterator start) const;
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+ virtual void Print (std::ostream &os) const;
+
+private:
+ uint8_t m_type;
+ uint8_t m_code;
+ bool m_calcChecksum;
+};
+
+class Icmpv4Echo : public Header
+{
+public:
+ void SetIdentifier (uint16_t id);
+ void SetSequenceNumber (uint16_t seq);
+ void SetData (Ptr<const Packet> data);
+ uint16_t GetIdentifier (void) const;
+ uint16_t GetSequenceNumber (void) const;
+ Ptr<const Packet> GetData (void) const;
+
+
+ static TypeId GetTypeId (void);
+ Icmpv4Echo ();
+ virtual ~Icmpv4Echo ();
+ virtual TypeId GetInstanceTypeId (void) const;
+ virtual uint32_t GetSerializedSize (void) const;
+ virtual void Serialize (Buffer::Iterator start) const;
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+ virtual void Print (std::ostream &os) const;
+private:
+ uint16_t m_identifier;
+ uint16_t m_sequence;
+ Ptr<Packet> m_data;
+};
+
+class Icmpv4DestinationUnreachable : public Header
+{
+public:
+ enum {
+ NET_UNREACHABLE = 0,
+ HOST_UNREACHABLE = 1,
+ PROTOCOL_UNREACHABLE = 2,
+ PORT_UNREACHABLE = 3,
+ FRAG_NEEDED = 4,
+ SOURCE_ROUTE_FAILED = 5
+ };
+ static TypeId GetTypeId (void);
+ Icmpv4DestinationUnreachable ();
+ virtual ~Icmpv4DestinationUnreachable ();
+
+ void SetNextHopMtu (uint16_t mtu);
+ uint16_t GetNextHopMtu (void) const;
+
+ void SetData (Ptr<const Packet> data);
+ void SetHeader (Ipv4Header header);
+
+ void GetData (uint8_t payload[8]) const;
+ Ipv4Header GetHeader (void) const;
+
+private:
+ virtual TypeId GetInstanceTypeId (void) const;
+ virtual uint32_t GetSerializedSize (void) const;
+ virtual void Serialize (Buffer::Iterator start) const;
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+ virtual void Print (std::ostream &os) const;
+private:
+ uint16_t m_nextHopMtu;
+ Ipv4Header m_header;
+ uint8_t m_data[8];
+};
+
+
+class Icmpv4TimeExceeded : public Header
+{
+public:
+ enum {
+ TIME_TO_LIVE = 0,
+ FRAGMENT_REASSEMBLY = 1
+ };
+
+ void SetData (Ptr<const Packet> data);
+ void SetHeader (Ipv4Header header);
+
+ void GetData (uint8_t payload[8]) const;
+ Ipv4Header GetHeader (void) const;
+
+ static TypeId GetTypeId (void);
+ Icmpv4TimeExceeded ();
+ virtual ~Icmpv4TimeExceeded ();
+ virtual TypeId GetInstanceTypeId (void) const;
+ virtual uint32_t GetSerializedSize (void) const;
+ virtual void Serialize (Buffer::Iterator start) const;
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+ virtual void Print (std::ostream &os) const;
+
+private:
+ Ipv4Header m_header;
+ uint8_t m_data[8];
+};
+
+} // namespace ns3
+
+#endif /* ICMPV4_H */
--- a/src/internet-stack/internet-stack.cc Mon Oct 27 23:05:57 2008 -0700
+++ b/src/internet-stack/internet-stack.cc Wed Oct 29 11:49:21 2008 -0700
@@ -30,6 +30,8 @@
#include "udp-socket-factory-impl.h"
#include "tcp-socket-factory-impl.h"
#include "ipv4-impl.h"
+#include "ipv4-raw-socket-factory-impl.h"
+#include "icmpv4-l4-protocol.h"
#ifdef NETWORK_SIMULATION_CRADLE
#include "nsc-tcp-socket-factory-impl.h"
#include "nsc-tcp-l4-protocol.h"
@@ -58,12 +60,25 @@
}
static void
+AddIcmpStack (Ptr<Node> node)
+{
+ Ptr<Ipv4L3Protocol> ipv4 = node->GetObject<Ipv4L3Protocol> ();
+ Ptr<Icmpv4L4Protocol> icmp = CreateObject<Icmpv4L4Protocol> ();
+ icmp->SetNode (node);
+ ipv4->Insert (icmp);
+ Ptr<Ipv4RawSocketFactoryImpl> rawFactory = CreateObject<Ipv4RawSocketFactoryImpl> ();
+ node->AggregateObject (rawFactory);
+}
+
+static void
AddTcpStack(Ptr<Node> node)
{
Ptr<Ipv4L3Protocol> ipv4 = node->GetObject<Ipv4L3Protocol> ();
Ptr<TcpL4Protocol> tcp = CreateObject<TcpL4Protocol> ();
tcp->SetNode (node);
+
ipv4->Insert (tcp);
+
Ptr<TcpSocketFactoryImpl> tcpFactory = CreateObject<TcpSocketFactoryImpl> ();
tcpFactory->SetTcp (tcp);
node->AggregateObject (tcpFactory);
@@ -85,6 +100,7 @@
{
AddArpStack (node);
AddIpv4Stack (node);
+ AddIcmpStack (node);
AddUdpStack (node);
AddTcpStack (node);
}
@@ -109,7 +125,7 @@
{
AddArpStack (node);
AddIpv4Stack (node);
-
+ AddIcmpStack (node);
AddUdpStack (node);
AddNscStack (node, soname);
}
--- a/src/internet-stack/ipv4-end-point-demux.cc Mon Oct 27 23:05:57 2008 -0700
+++ b/src/internet-stack/ipv4-end-point-demux.cc Wed Oct 29 11:49:21 2008 -0700
@@ -287,6 +287,47 @@
return retval1; // might be empty if no matches
}
+Ipv4EndPoint *
+Ipv4EndPointDemux::SimpleLookup (Ipv4Address daddr,
+ uint16_t dport,
+ Ipv4Address saddr,
+ uint16_t sport)
+{
+ // this code is a copy/paste version of an old BSD ip stack lookup
+ // function.
+ uint32_t genericity = 3;
+ Ipv4EndPoint *generic = 0;
+ for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
+ {
+ if ((*i)->GetLocalPort () != dport)
+ {
+ continue;
+ }
+ if ((*i)->GetLocalAddress () == daddr &&
+ (*i)->GetPeerPort () == sport &&
+ (*i)->GetPeerAddress () == saddr)
+ {
+ /* this is an exact match. */
+ return *i;
+ }
+ uint32_t tmp = 0;
+ if ((*i)->GetLocalAddress () == Ipv4Address::GetAny ())
+ {
+ tmp ++;
+ }
+ if ((*i)->GetPeerAddress () == Ipv4Address::GetAny ())
+ {
+ tmp ++;
+ }
+ if (tmp < genericity)
+ {
+ generic = (*i);
+ genericity = tmp;
+ }
+ }
+ return generic;
+}
+
uint16_t
Ipv4EndPointDemux::AllocateEphemeralPort (void)
{
--- a/src/internet-stack/ipv4-end-point-demux.h Mon Oct 27 23:05:57 2008 -0700
+++ b/src/internet-stack/ipv4-end-point-demux.h Wed Oct 29 11:49:21 2008 -0700
@@ -57,6 +57,11 @@
uint16_t sport,
Ptr<Ipv4Interface> incomingInterface);
+ Ipv4EndPoint *SimpleLookup (Ipv4Address daddr,
+ uint16_t dport,
+ Ipv4Address saddr,
+ uint16_t sport);
+
Ipv4EndPoint *Allocate (void);
Ipv4EndPoint *Allocate (Ipv4Address address);
Ipv4EndPoint *Allocate (uint16_t port);
--- a/src/internet-stack/ipv4-end-point.cc Mon Oct 27 23:05:57 2008 -0700
+++ b/src/internet-stack/ipv4-end-point.cc Wed Oct 29 11:49:21 2008 -0700
@@ -20,6 +20,9 @@
#include "ipv4-end-point.h"
#include "ns3/packet.h"
+#include "ns3/log.h"
+
+NS_LOG_COMPONENT_DEFINE ("Ipv4EndPoint");
namespace ns3 {
@@ -76,6 +79,11 @@
{
m_rxCallback = callback;
}
+void
+Ipv4EndPoint::SetIcmpCallback (Callback<void,Ipv4Address,uint8_t,uint8_t,uint8_t,uint32_t> callback)
+{
+ m_icmpCallback = callback;
+}
void
Ipv4EndPoint::SetDestroyCallback (Callback<void> callback)
@@ -92,6 +100,17 @@
}
}
-
+void
+Ipv4EndPoint::ForwardIcmp (Ipv4Address icmpSource, uint8_t icmpTtl,
+ uint8_t icmpType, uint8_t icmpCode,
+ uint32_t icmpInfo)
+{
+ NS_LOG_FUNCTION (this << icmpSource << (uint32_t)icmpTtl << (uint32_t)icmpType <<
+ (uint32_t)icmpCode << icmpInfo);
+ if (!m_icmpCallback.IsNull ())
+ {
+ m_icmpCallback (icmpSource,icmpTtl,icmpType,icmpCode,icmpInfo);
+ }
+}
}; // namespace ns3
--- a/src/internet-stack/ipv4-end-point.h Mon Oct 27 23:05:57 2008 -0700
+++ b/src/internet-stack/ipv4-end-point.h Wed Oct 29 11:49:21 2008 -0700
@@ -54,10 +54,19 @@
void SetPeer (Ipv4Address address, uint16_t port);
+ // Called from socket implementations to get notified about important events.
void SetRxCallback (Callback<void,Ptr<Packet>, Ipv4Address, uint16_t> callback);
+ void SetIcmpCallback (Callback<void,Ipv4Address,uint8_t,uint8_t,uint8_t,uint32_t> callback);
void SetDestroyCallback (Callback<void> callback);
+ // Called from an L4Protocol implementation to notify an endpoint of a
+ // packet reception.
void ForwardUp (Ptr<Packet> p, Ipv4Address saddr, uint16_t sport);
+ // Called from an L4Protocol implementation to notify an endpoint of
+ // an icmp message reception.
+ void ForwardIcmp (Ipv4Address icmpSource, uint8_t icmpTtl,
+ uint8_t icmpType, uint8_t icmpCode,
+ uint32_t icmpInfo);
private:
Ipv4Address m_localAddr;
@@ -65,6 +74,7 @@
Ipv4Address m_peerAddr;
uint16_t m_peerPort;
Callback<void,Ptr<Packet>, Ipv4Address, uint16_t> m_rxCallback;
+ Callback<void,Ipv4Address,uint8_t,uint8_t,uint8_t,uint32_t> m_icmpCallback;
Callback<void> m_destroyCallback;
};
--- a/src/internet-stack/ipv4-l3-protocol.cc Mon Oct 27 23:05:57 2008 -0700
+++ b/src/internet-stack/ipv4-l3-protocol.cc Wed Oct 29 11:49:21 2008 -0700
@@ -35,9 +35,11 @@
#include "ipv4-l3-protocol.h"
#include "ipv4-l4-protocol.h"
+#include "icmpv4-l4-protocol.h"
#include "ipv4-interface.h"
#include "ipv4-loopback-interface.h"
#include "arp-ipv4-interface.h"
+#include "ipv4-raw-socket-impl.h"
NS_LOG_COMPONENT_DEFINE ("Ipv4L3Protocol");
@@ -120,6 +122,30 @@
SetupLoopback ();
}
+Ptr<Socket>
+Ipv4L3Protocol::CreateRawSocket (void)
+{
+ NS_LOG_FUNCTION (this);
+ Ptr<Ipv4RawSocketImpl> socket = CreateObject<Ipv4RawSocketImpl> ();
+ socket->SetNode (m_node);
+ m_sockets.push_back (socket);
+ return socket;
+}
+void
+Ipv4L3Protocol::DeleteRawSocket (Ptr<Socket> socket)
+{
+ NS_LOG_FUNCTION (this << socket);
+ for (SocketList::iterator i = m_sockets.begin (); i != m_sockets.end (); ++i)
+ {
+ if ((*i) == socket)
+ {
+ m_sockets.erase (i);
+ return;
+ }
+ }
+ return;
+}
+
void
Ipv4L3Protocol::DoDispose (void)
{
@@ -514,6 +540,12 @@
return;
}
+ for (SocketList::iterator i = m_sockets.begin (); i != m_sockets.end (); ++i)
+ {
+ Ptr<Ipv4RawSocketImpl> socket = *i;
+ socket->ForwardUp (packet, ipHeader, device);
+ }
+
if (Forwarding (index, packet, ipHeader, device))
{
return;
@@ -522,6 +554,25 @@
ForwardUp (packet, ipHeader, ipv4Interface);
}
+Ptr<Icmpv4L4Protocol>
+Ipv4L3Protocol::GetIcmp (void) const
+{
+ Ptr<Ipv4L4Protocol> prot = GetProtocol (Icmpv4L4Protocol::GetStaticProtocolNumber ());
+ if (prot != 0)
+ {
+ return prot->GetObject<Icmpv4L4Protocol> ();
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+bool
+Ipv4L3Protocol::IsUnicast (Ipv4Address ad, Ipv4Mask interfaceMask) const
+{
+ return !ad.IsMulticast () && !ad.IsSubnetDirectedBroadcast (interfaceMask);
+}
void
Ipv4L3Protocol::Send (Ptr<Packet> packet,
@@ -542,16 +593,29 @@
ipHeader.SetDestination (destination);
ipHeader.SetProtocol (protocol);
ipHeader.SetPayloadSize (packet->GetSize ());
- ipHeader.SetTtl (m_defaultTtl);
- ipHeader.SetMayFragment ();
ipHeader.SetIdentification (m_identification);
m_identification ++;
+ SocketSetDontFragmentTag dfTag;
+ bool found = packet->FindFirstMatchingTag (dfTag);
+ if (found)
+ {
+ if (dfTag.IsEnabled ())
+ {
+ ipHeader.SetDontFragment ();
+ }
+ else
+ {
+ ipHeader.SetMayFragment ();
+ }
+ }
+
+
// Set TTL to 1 if it is a broadcast packet of any type. Otherwise,
// possibly override the default TTL if the packet is tagged
SocketIpTtlTag tag;
- bool found = packet->FindFirstMatchingTag (tag);
+ found = packet->FindFirstMatchingTag (tag);
if (destination.IsBroadcast ())
{
@@ -564,6 +628,7 @@
}
else
{
+ ipHeader.SetTtl (m_defaultTtl);
uint32_t ifaceIndex = 0;
for (Ipv4InterfaceList::iterator ifaceIter = m_interfaces.begin ();
ifaceIter != m_interfaces.end (); ifaceIter++, ifaceIndex++)
@@ -585,10 +650,28 @@
Ptr<Ipv4Interface> outInterface = *ifaceIter;
Ptr<Packet> packetCopy = packet->Copy ();
- NS_ASSERT (packetCopy->GetSize () <= outInterface->GetMtu ());
packetCopy->AddHeader (ipHeader);
- m_txTrace (packetCopy, ifaceIndex);
- outInterface->Send (packetCopy, destination);
+ if (packetCopy->GetSize () > outInterface->GetMtu () &&
+ ipHeader.IsDontFragment () &&
+ IsUnicast (ipHeader.GetDestination (), outInterface->GetNetworkMask ()))
+ {
+ Ptr<Icmpv4L4Protocol> icmp = GetIcmp ();
+ NS_ASSERT (icmp != 0);
+ icmp->SendDestUnreachFragNeeded (ipHeader, packet, outInterface->GetMtu ());
+ m_dropTrace (packetCopy);
+ }
+ else if (packet->GetSize () > outInterface->GetMtu () &&
+ !ipHeader.IsDontFragment ())
+ {
+ NS_LOG_LOGIC ("Too big: need fragmentation but no frag support.");
+ m_dropTrace (packet);
+ }
+ else
+ {
+ NS_ASSERT (packetCopy->GetSize () <= outInterface->GetMtu ());
+ m_txTrace (packetCopy, ifaceIndex);
+ outInterface->Send (packetCopy, destination);
+ }
}
}
else
@@ -625,17 +708,38 @@
NS_LOG_LOGIC ("Send via interface " << route.GetInterface ());
Ptr<Ipv4Interface> outInterface = GetInterface (route.GetInterface ());
- NS_ASSERT (packet->GetSize () <= outInterface->GetMtu ());
- m_txTrace (packet, route.GetInterface ());
- if (route.IsGateway ())
+ if (packet->GetSize () > outInterface->GetMtu () &&
+ ipHeader.IsDontFragment () &&
+ IsUnicast (ipHeader.GetDestination (), outInterface->GetNetworkMask ()))
+ {
+ NS_LOG_LOGIC ("Too big: need fragmentation but not allowed");
+ Ptr<Icmpv4L4Protocol> icmp = GetIcmp ();
+ NS_ASSERT (icmp != 0);
+ Ptr<Packet> copyNoHeader = packet->Copy ();
+ Ipv4Header tmp;
+ copyNoHeader->RemoveHeader (tmp);
+ icmp->SendDestUnreachFragNeeded (ipHeader, copyNoHeader, outInterface->GetMtu ());
+ m_dropTrace (packet);
+ }
+ else if (packet->GetSize () > outInterface->GetMtu () &&
+ !ipHeader.IsDontFragment ())
{
- NS_LOG_LOGIC ("Send to gateway " << route.GetGateway ());
- outInterface->Send (packet, route.GetGateway ());
- }
- else
+ NS_LOG_LOGIC ("Too big: need fragmentation but no frag support.");
+ m_dropTrace (packet);
+ }
+ else
{
- NS_LOG_LOGIC ("Send to destination " << ipHeader.GetDestination ());
- outInterface->Send (packet, ipHeader.GetDestination ());
+ m_txTrace (packet, route.GetInterface ());
+ if (route.IsGateway ())
+ {
+ NS_LOG_LOGIC ("Send to gateway " << route.GetGateway ());
+ outInterface->Send (packet, route.GetGateway ());
+ }
+ else
+ {
+ NS_LOG_LOGIC ("Send to destination " << ipHeader.GetDestination ());
+ outInterface->Send (packet, ipHeader.GetDestination ());
+ }
}
}
@@ -685,17 +789,6 @@
NS_LOG_LOGIC ("For me (Ipv4Addr any address)");
return false;
}
-
- if (ipHeader.GetTtl () == 1)
- {
- // Should send ttl expired here
- // XXX
- NS_LOG_LOGIC ("Not for me (TTL expired). Drop");
- m_dropTrace (packet);
- return true;
- }
- ipHeader.SetTtl (ipHeader.GetTtl () - 1);
-
//
// If this is a to a multicast address and this node is a member of the
// indicated group we need to return false so the multicast is forwarded up.
@@ -710,18 +803,39 @@
// We forward with a packet copy, since forwarding may change
// the packet, affecting our local delivery
NS_LOG_LOGIC ("Forwarding (multicast).");
- Lookup (ifIndex, ipHeader, packet->Copy (),
- MakeCallback (&Ipv4L3Protocol::SendRealOut, this));
+ DoForward (ifIndex, packet->Copy (), ipHeader);
return false;
}
- }
+ }
+
+ DoForward (ifIndex, packet, ipHeader);
+ return true;
+}
+
+void
+Ipv4L3Protocol::DoForward (uint32_t ifIndex,
+ Ptr<Packet> packet,
+ Ipv4Header ipHeader)
+{
+ NS_LOG_FUNCTION (this << ifIndex << packet << ipHeader);
+
+ ipHeader.SetTtl (ipHeader.GetTtl () - 1);
+ if (ipHeader.GetTtl () == 0)
+ {
+ if (IsUnicast (ipHeader.GetDestination (), GetInterface (ifIndex)->GetNetworkMask ()))
+ {
+ Ptr<Icmpv4L4Protocol> icmp = GetIcmp ();
+ icmp->SendTimeExceededTtl (ipHeader, packet);
+ }
+ m_dropTrace (packet);
+ return;
+ }
NS_LOG_LOGIC ("Not for me, forwarding.");
Lookup (ifIndex, ipHeader, packet,
- MakeCallback (&Ipv4L3Protocol::SendRealOut, this));
-
- return true;
+ MakeCallback (&Ipv4L3Protocol::SendRealOut, this));
}
+
void
Ipv4L3Protocol::ForwardUp (Ptr<Packet> p, Ipv4Header const&ip,
Ptr<Ipv4Interface> incomingInterface)
@@ -729,7 +843,26 @@
NS_LOG_FUNCTION (this << p << &ip);
Ptr<Ipv4L4Protocol> protocol = GetProtocol (ip.GetProtocol ());
- protocol->Receive (p, ip.GetSource (), ip.GetDestination (), incomingInterface);
+ if (protocol != 0)
+ {
+ // we need to make a copy in the unlikely event we hit the
+ // RX_ENDPOINT_UNREACH codepath
+ Ptr<Packet> copy = p->Copy ();
+ enum Ipv4L4Protocol::RxStatus status =
+ protocol->Receive (p, ip.GetSource (), ip.GetDestination (), incomingInterface);
+ switch (status) {
+ case Ipv4L4Protocol::RX_OK:
+ // fall through
+ case Ipv4L4Protocol::RX_CSUM_FAILED:
+ break;
+ case Ipv4L4Protocol::RX_ENDPOINT_UNREACH:
+ if (IsUnicast (ip.GetDestination (), incomingInterface->GetNetworkMask ()))
+ {
+ GetIcmp ()->SendDestUnreachPort (ip, copy);
+ }
+ break;
+ }
+ }
}
void
--- a/src/internet-stack/ipv4-l3-protocol.h Mon Oct 27 23:05:57 2008 -0700
+++ b/src/internet-stack/ipv4-l3-protocol.h Wed Oct 29 11:49:21 2008 -0700
@@ -40,7 +40,11 @@
class Ipv4Header;
class Ipv4Route;
class Node;
+class Socket;
+class Ipv4RawSocketImpl;
class Ipv4L4Protocol;
+class Ipv4L4Protocol;
+class Icmpv4L4Protocol;
/**
@@ -60,6 +64,9 @@
void SetNode (Ptr<Node> node);
+ Ptr<Socket> CreateRawSocket (void);
+ void DeleteRawSocket (Ptr<Socket> socket);
+
/**
* \param protocol a template for the protocol to add to this L4 Demux.
* \returns the L4Protocol effectively added.
@@ -201,6 +208,8 @@
virtual void DoDispose (void);
private:
+ Ipv4L3Protocol(const Ipv4L3Protocol &);
+ Ipv4L3Protocol &operator = (const Ipv4L3Protocol &);
void Lookup (uint32_t ifIndex,
Ipv4Header const &ipHeader,
Ptr<Packet> packet,
@@ -217,15 +226,19 @@
void ForwardUp (Ptr<Packet> p, Ipv4Header const&ip, Ptr<Ipv4Interface> incomingInterface);
uint32_t AddIpv4Interface (Ptr<Ipv4Interface> interface);
void SetupLoopback (void);
- Ipv4L3Protocol(const Ipv4L3Protocol &);
- Ipv4L3Protocol &operator = (const Ipv4L3Protocol &);
+ Ptr<Icmpv4L4Protocol> GetIcmp (void) const;
+ bool IsUnicast (Ipv4Address ad, Ipv4Mask interfaceMask) const;
+ void DoForward (uint32_t ifIndex,
+ Ptr<Packet> packet,
+ Ipv4Header ipHeader);
+
typedef std::list<Ptr<Ipv4Interface> > Ipv4InterfaceList;
- typedef std::list<std::pair<Ipv4Address, Ipv4Address> >
- Ipv4MulticastGroupList;
+ typedef std::list<std::pair<Ipv4Address, Ipv4Address> > Ipv4MulticastGroupList;
typedef std::list< std::pair< int, Ptr<Ipv4RoutingProtocol> > > Ipv4RoutingProtocolList;
+ typedef std::list<Ptr<Ipv4RawSocketImpl> > SocketList;
+ typedef std::list<Ptr<Ipv4L4Protocol> > L4List_t;
- typedef std::list<Ptr<Ipv4L4Protocol> > L4List_t;
L4List_t m_protocols;
Ipv4InterfaceList m_interfaces;
uint32_t m_nInterfaces;
@@ -241,6 +254,8 @@
Ptr<Ipv4StaticRouting> m_staticRouting;
Ipv4MulticastGroupList m_multicastGroups;
+
+ SocketList m_sockets;
};
} // Namespace ns3
--- a/src/internet-stack/ipv4-l4-protocol.cc Mon Oct 27 23:05:57 2008 -0700
+++ b/src/internet-stack/ipv4-l4-protocol.cc Wed Oct 29 11:49:21 2008 -0700
@@ -44,4 +44,11 @@
Ipv4L4Protocol::~Ipv4L4Protocol ()
{}
+void
+Ipv4L4Protocol::ReceiveIcmp (Ipv4Address icmpSource, uint8_t icmpTtl,
+ uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo,
+ Ipv4Address payloadSource,Ipv4Address payloadDestination,
+ const uint8_t payload[8])
+{}
+
}//namespace ns3
--- a/src/internet-stack/ipv4-l4-protocol.h Mon Oct 27 23:05:57 2008 -0700
+++ b/src/internet-stack/ipv4-l4-protocol.h Wed Oct 29 11:49:21 2008 -0700
@@ -25,12 +25,13 @@
#define IPV4_L4_PROTOCOL_H
#include "ns3/object.h"
-#include "ipv4-interface.h"
+#include "ns3/ipv4-header.h"
namespace ns3 {
class Packet;
class Ipv4Address;
+class Ipv4Interface;
/**
* \brief L4 Protocol abstract base class
@@ -41,6 +42,12 @@
class Ipv4L4Protocol : public Object
{
public:
+ enum RxStatus {
+ RX_OK,
+ RX_CSUM_FAILED,
+ RX_ENDPOINT_UNREACH
+ };
+
static TypeId GetTypeId (void);
virtual ~Ipv4L4Protocol ();
@@ -59,10 +66,29 @@
* Called from lower-level layers to send the packet up
* in the stack.
*/
- virtual void Receive(Ptr<Packet> p,
- Ipv4Address const &source,
- Ipv4Address const &destination,
- Ptr<Ipv4Interface> incomingInterface) = 0;
+ virtual enum RxStatus Receive(Ptr<Packet> p,
+ Ipv4Address const &source,
+ Ipv4Address const &destination,
+ Ptr<Ipv4Interface> incomingInterface) = 0;
+
+ /**
+ * \param icmpSouce the source address of the icmp message
+ * \param icmpTtl the ttl of the icmp message
+ * \param icmpType the 'type' field of the icmp message
+ * \param icmpCode the 'code' field of the icmp message
+ * \param icmpInfo extra information dependent on the icmp message
+ * generated by Icmpv4L4Protocol
+ * \param payloadSource the source address of the packet which triggered
+ * the icmp message
+ * \param payloadDestination the destination address of the packet which
+ * triggered the icmp message.
+ * \param payload the first 8 bytes of the udp header of the packet
+ * which triggered the icmp message.
+ */
+ virtual void ReceiveIcmp (Ipv4Address icmpSource, uint8_t icmpTtl,
+ uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo,
+ Ipv4Address payloadSource, Ipv4Address payloadDestination,
+ const uint8_t payload[8]);
};
} // Namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv4-raw-socket-factory-impl.cc Wed Oct 29 11:49:21 2008 -0700
@@ -0,0 +1,16 @@
+#include "ipv4-raw-socket-factory-impl.h"
+#include "ipv4-l3-protocol.h"
+#include "ns3/socket.h"
+
+namespace ns3 {
+
+
+Ptr<Socket>
+Ipv4RawSocketFactoryImpl::CreateSocket (void)
+{
+ Ptr<Ipv4L3Protocol> ipv4 = GetObject<Ipv4L3Protocol> ();
+ Ptr<Socket> socket = ipv4->CreateRawSocket ();
+ return socket;
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv4-raw-socket-factory-impl.h Wed Oct 29 11:49:21 2008 -0700
@@ -0,0 +1,17 @@
+#ifndef IPV4_RAW_SOCKET_FACTORY_IMPL_H
+#define IPV4_RAW_SOCKET_FACTORY_IMPL_H
+
+#include "ns3/ipv4-raw-socket-factory.h"
+
+namespace ns3 {
+
+class Ipv4RawSocketFactoryImpl : public Ipv4RawSocketFactory
+{
+public:
+ virtual Ptr<Socket> CreateSocket (void);
+};
+
+
+} // namespace ns3
+
+#endif /* IPV4_RAW_SOCKET_FACTORY_IMPL_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv4-raw-socket-impl.cc Wed Oct 29 11:49:21 2008 -0700
@@ -0,0 +1,269 @@
+#include "ipv4-raw-socket-impl.h"
+#include "ipv4-l3-protocol.h"
+#include "icmpv4.h"
+#include "ns3/inet-socket-address.h"
+#include "ns3/node.h"
+#include "ns3/packet.h"
+#include "ns3/uinteger.h"
+#include "ns3/log.h"
+
+NS_LOG_COMPONENT_DEFINE ("Ipv4RawSocketImpl");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv4RawSocketImpl);
+
+TypeId
+Ipv4RawSocketImpl::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::Ipv4RawSocketImpl")
+ .SetParent<Socket> ()
+ .AddAttribute ("Protocol", "Protocol number to match.",
+ UintegerValue (0),
+ MakeUintegerAccessor (&Ipv4RawSocketImpl::m_protocol),
+ MakeUintegerChecker<uint16_t> ())
+ .AddAttribute ("IcmpFilter",
+ "Any icmp header whose type field matches a bit in this filter is dropped.",
+ UintegerValue (0),
+ MakeUintegerAccessor (&Ipv4RawSocketImpl::m_icmpFilter),
+ MakeUintegerChecker<uint32_t> ())
+ ;
+ return tid;
+}
+
+Ipv4RawSocketImpl::Ipv4RawSocketImpl ()
+{
+ NS_LOG_FUNCTION (this);
+ m_err = Socket::ERROR_NOTERROR;
+ m_node = 0;
+ m_src = Ipv4Address::GetAny ();
+ m_dst = Ipv4Address::GetAny ();
+ m_protocol = 0;
+ m_shutdownSend = false;
+ m_shutdownRecv = false;
+}
+
+void
+Ipv4RawSocketImpl::SetNode (Ptr<Node> node)
+{
+ m_node = node;
+}
+
+void
+Ipv4RawSocketImpl::DoDispose (void)
+{
+ NS_LOG_FUNCTION (this);
+ m_node = 0;
+ Socket::DoDispose ();
+}
+
+enum Socket::SocketErrno
+Ipv4RawSocketImpl::GetErrno (void) const
+{
+ NS_LOG_FUNCTION (this);
+ return m_err;
+}
+Ptr<Node>
+Ipv4RawSocketImpl::GetNode (void) const
+{
+ NS_LOG_FUNCTION (this);
+ return m_node;
+}
+int
+Ipv4RawSocketImpl::Bind (const Address &address)
+{
+ NS_LOG_FUNCTION (this << address);
+ if (!InetSocketAddress::IsMatchingType (address))
+ {
+ m_err = Socket::ERROR_INVAL;
+ return -1;
+ }
+ InetSocketAddress ad = InetSocketAddress::ConvertFrom (address);
+ m_src = ad.GetIpv4 ();
+ return 0;
+}
+int
+Ipv4RawSocketImpl::Bind (void)
+{
+ NS_LOG_FUNCTION (this);
+ m_src = Ipv4Address::GetAny ();
+ return 0;
+}
+int
+Ipv4RawSocketImpl::GetSockName (Address &address) const
+{
+ address = InetSocketAddress (m_src, 0);
+ return 0;
+}
+int
+Ipv4RawSocketImpl::Close (void)
+{
+ NS_LOG_FUNCTION (this);
+ Ptr<Ipv4L3Protocol> ipv4 = m_node->GetObject<Ipv4L3Protocol> ();
+ if (ipv4 != 0)
+ {
+ ipv4->DeleteRawSocket (this);
+ }
+ return 0;
+}
+int
+Ipv4RawSocketImpl::ShutdownSend (void)
+{
+ NS_LOG_FUNCTION (this);
+ m_shutdownSend = true;
+ return 0;
+}
+int
+Ipv4RawSocketImpl::ShutdownRecv (void)
+{
+ NS_LOG_FUNCTION (this);
+ m_shutdownRecv = true;
+ return 0;
+}
+int
+Ipv4RawSocketImpl::Connect (const Address &address)
+{
+ NS_LOG_FUNCTION (this << address);
+ if (!InetSocketAddress::IsMatchingType (address))
+ {
+ m_err = Socket::ERROR_INVAL;
+ return -1;
+ }
+ InetSocketAddress ad = InetSocketAddress::ConvertFrom (address);
+ m_dst = ad.GetIpv4 ();
+ return 0;
+}
+int
+Ipv4RawSocketImpl::Listen (void)
+{
+ NS_LOG_FUNCTION (this);
+ m_err = Socket::ERROR_OPNOTSUPP;
+ return -1;
+}
+uint32_t
+Ipv4RawSocketImpl::GetTxAvailable (void) const
+{
+ NS_LOG_FUNCTION (this);
+ return 0xffffffff;
+}
+int
+Ipv4RawSocketImpl::Send (Ptr<Packet> p, uint32_t flags)
+{
+ NS_LOG_FUNCTION (this << p << flags);
+ InetSocketAddress to = InetSocketAddress (m_dst, m_protocol);
+ return SendTo (p, flags, to);
+}
+int
+Ipv4RawSocketImpl::SendTo (Ptr<Packet> p, uint32_t flags,
+ const Address &toAddress)
+{
+ NS_LOG_FUNCTION (this << p << flags << toAddress);
+ if (!InetSocketAddress::IsMatchingType (toAddress))
+ {
+ m_err = Socket::ERROR_INVAL;
+ return -1;
+ }
+ if (m_shutdownSend)
+ {
+ return 0;
+ }
+ InetSocketAddress ad = InetSocketAddress::ConvertFrom (toAddress);
+ Ptr<Ipv4L3Protocol> ipv4 = m_node->GetObject<Ipv4L3Protocol> ();
+ Ipv4Address dst = ad.GetIpv4 ();
+ uint32_t localIfIndex;
+ if (ipv4->GetIfIndexForDestination(dst, localIfIndex))
+ {
+ ipv4->Send (p, ipv4->GetAddress (localIfIndex), dst, m_protocol);
+ }
+ else
+ {
+ NS_LOG_DEBUG ("dropped because no outgoing route.");
+ }
+ return 0;
+}
+uint32_t
+Ipv4RawSocketImpl::GetRxAvailable (void) const
+{
+ NS_LOG_FUNCTION (this);
+ uint32_t rx = 0;
+ for (std::list<Data>::const_iterator i = m_recv.begin (); i != m_recv.end (); ++i)
+ {
+ rx += (i->packet)->GetSize ();
+ }
+ return rx;
+}
+Ptr<Packet>
+Ipv4RawSocketImpl::Recv (uint32_t maxSize, uint32_t flags)
+{
+ NS_LOG_FUNCTION (this << maxSize << flags);
+ Address tmp;
+ return RecvFrom (maxSize, flags, tmp);
+}
+Ptr<Packet>
+Ipv4RawSocketImpl::RecvFrom (uint32_t maxSize, uint32_t flags,
+ Address &fromAddress)
+{
+ NS_LOG_FUNCTION (this << maxSize << flags << fromAddress);
+ if (m_recv.empty ())
+ {
+ return 0;
+ }
+ struct Data data = m_recv.front ();
+ m_recv.pop_front ();
+ if (data.packet->GetSize () > maxSize)
+ {
+ Ptr<Packet> first = data.packet->CreateFragment (0, maxSize);
+ data.packet->RemoveAtStart (maxSize);
+ m_recv.push_front (data);
+ return first;
+ }
+ InetSocketAddress inet = InetSocketAddress (data.fromIp, data.fromProtocol);
+ fromAddress = inet;
+ return data.packet;
+}
+
+void
+Ipv4RawSocketImpl::SetProtocol (uint16_t protocol)
+{
+ NS_LOG_FUNCTION (this << protocol);
+ m_protocol = protocol;
+}
+
+bool
+Ipv4RawSocketImpl::ForwardUp (Ptr<const Packet> p, Ipv4Header ipHeader, Ptr<NetDevice> device)
+{
+ NS_LOG_FUNCTION (this << *p << ipHeader << device);
+ if (m_shutdownRecv)
+ {
+ return false;
+ }
+ if ((m_src == Ipv4Address::GetAny () || ipHeader.GetDestination () == m_src) &&
+ (m_dst == Ipv4Address::GetAny () || ipHeader.GetSource () == m_dst) &&
+ ipHeader.GetProtocol () == m_protocol)
+ {
+ Ptr<Packet> copy = p->Copy ();
+ if (m_protocol == 1)
+ {
+ Icmpv4Header icmpHeader;
+ copy->PeekHeader (icmpHeader);
+ uint8_t type = icmpHeader.GetType ();
+ if (type < 32 &&
+ ((1 << type) & m_icmpFilter))
+ {
+ // filter out icmp packet.
+ return false;
+ }
+ }
+ copy->AddHeader (ipHeader);
+ struct Data data;
+ data.packet = copy;
+ data.fromIp = ipHeader.GetSource ();
+ data.fromProtocol = ipHeader.GetProtocol ();
+ m_recv.push_back (data);
+ NotifyDataRecv ();
+ return true;
+ }
+ return false;
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv4-raw-socket-impl.h Wed Oct 29 11:49:21 2008 -0700
@@ -0,0 +1,65 @@
+#ifndef IPV4_RAW_SOCKET_IMPL_H
+#define IPV4_RAW_SOCKET_IMPL_H
+
+#include "ns3/socket.h"
+#include "ns3/ipv4-header.h"
+#include <list>
+
+namespace ns3 {
+
+class NetDevice;
+class Node;
+
+class Ipv4RawSocketImpl : public Socket
+{
+public:
+ static TypeId GetTypeId (void);
+
+ Ipv4RawSocketImpl ();
+
+ void SetNode (Ptr<Node> node);
+
+ virtual enum Socket::SocketErrno GetErrno (void) const;
+ virtual Ptr<Node> GetNode (void) const;
+ virtual int Bind (const Address &address);
+ virtual int Bind ();
+ virtual int GetSockName (Address &address) const;
+ virtual int Close (void);
+ virtual int ShutdownSend (void);
+ virtual int ShutdownRecv (void);
+ virtual int Connect (const Address &address);
+ virtual int Listen (void);
+ virtual uint32_t GetTxAvailable (void) const;
+ virtual int Send (Ptr<Packet> p, uint32_t flags);
+ virtual int SendTo (Ptr<Packet> p, uint32_t flags,
+ const Address &toAddress);
+ virtual uint32_t GetRxAvailable (void) const;
+ virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags);
+ virtual Ptr<Packet> RecvFrom (uint32_t maxSize, uint32_t flags,
+ Address &fromAddress);
+
+ void SetProtocol (uint16_t protocol);
+ bool ForwardUp (Ptr<const Packet> p, Ipv4Header ipHeader, Ptr<NetDevice> device);
+private:
+ virtual void DoDispose (void);
+
+ struct Data {
+ Ptr<Packet> packet;
+ Ipv4Address fromIp;
+ uint16_t fromProtocol;
+ };
+
+ enum Socket::SocketErrno m_err;
+ Ptr<Node> m_node;
+ Ipv4Address m_src;
+ Ipv4Address m_dst;
+ uint16_t m_protocol;
+ std::list<struct Data> m_recv;
+ bool m_shutdownSend;
+ bool m_shutdownRecv;
+ uint32_t m_icmpFilter;
+};
+
+} // namespace ns3
+
+#endif /* IPV4_RAW_SOCKET_IMPL_H */
--- a/src/internet-stack/nsc-tcp-l4-protocol.cc Mon Oct 27 23:05:57 2008 -0700
+++ b/src/internet-stack/nsc-tcp-l4-protocol.cc Wed Oct 29 11:49:21 2008 -0700
@@ -220,7 +220,7 @@
// NSC m_endPoints->DeAllocate (endPoint);
}
-void
+Ipv4L4Protocol::RxStatus
NscTcpL4Protocol::Receive (Ptr<Packet> packet,
Ipv4Address const &source,
Ipv4Address const &destination,
@@ -251,6 +251,7 @@
// deliver complete packet to the NSC network stack
m_nscStack->if_receive_packet(0, data, packetSize);
wakeup ();
+ return Ipv4L4Protocol::RX_OK;
}
void NscTcpL4Protocol::SoftInterrupt (void)
--- a/src/internet-stack/nsc-tcp-l4-protocol.h Mon Oct 27 23:05:57 2008 -0700
+++ b/src/internet-stack/nsc-tcp-l4-protocol.h Wed Oct 29 11:49:21 2008 -0700
@@ -80,10 +80,10 @@
* \param destination The destinations Ipv4Address
* \param incomingInterface The Ipv4Interface it was received on
*/
- virtual void Receive (Ptr<Packet> p,
- Ipv4Address const &source,
- Ipv4Address const &destination,
- Ptr<Ipv4Interface> incomingInterface);
+ virtual Ipv4L4Protocol::RxStatus Receive (Ptr<Packet> p,
+ Ipv4Address const &source,
+ Ipv4Address const &destination,
+ Ptr<Ipv4Interface> incomingInterface);
// NSC callbacks.
// NSC invokes these hooks to interact with the simulator.
--- a/src/internet-stack/tcp-l4-protocol.cc Mon Oct 27 23:05:57 2008 -0700
+++ b/src/internet-stack/tcp-l4-protocol.cc Wed Oct 29 11:49:21 2008 -0700
@@ -431,7 +431,7 @@
m_endPoints->DeAllocate (endPoint);
}
-void
+enum Ipv4L4Protocol::RxStatus
TcpL4Protocol::Receive (Ptr<Packet> packet,
Ipv4Address const &source,
Ipv4Address const &destination,
@@ -457,7 +457,7 @@
if(!tcpHeader.IsChecksumOk ())
{
NS_LOG_INFO("Bad checksum, dropping packet!");
- return;
+ return Ipv4L4Protocol::RX_CSUM_FAILED;
}
NS_LOG_LOGIC ("TcpL4Protocol "<<this<<" received a packet");
@@ -474,11 +474,12 @@
source.Print (oss);
oss<<" source port: "<<tcpHeader.GetSourcePort ();
NS_LOG_LOGIC (oss.str ());
- return;
+ return Ipv4L4Protocol::RX_ENDPOINT_UNREACH;
}
NS_ASSERT_MSG (endPoints.size() == 1 , "Demux returned more than one endpoint");
NS_LOG_LOGIC ("TcpL4Protocol "<<this<<" forwarding up to endpoint/socket");
(*endPoints.begin ())->ForwardUp (packet, source, tcpHeader.GetSourcePort ());
+ return Ipv4L4Protocol::RX_OK;
}
void
--- a/src/internet-stack/tcp-l4-protocol.h Mon Oct 27 23:05:57 2008 -0700
+++ b/src/internet-stack/tcp-l4-protocol.h Wed Oct 29 11:49:21 2008 -0700
@@ -101,10 +101,10 @@
* \param destination The destinations Ipv4Address
* \param incomingInterface The Ipv4Interface it was received on
*/
- virtual void Receive (Ptr<Packet> p,
- Ipv4Address const &source,
- Ipv4Address const &destination,
- Ptr<Ipv4Interface> incomingInterface);
+ virtual enum Ipv4L4Protocol::RxStatus Receive (Ptr<Packet> p,
+ Ipv4Address const &source,
+ Ipv4Address const &destination,
+ Ptr<Ipv4Interface> incomingInterface);
protected:
virtual void DoDispose (void);
--- a/src/internet-stack/tcp-socket-impl.cc Mon Oct 27 23:05:57 2008 -0700
+++ b/src/internet-stack/tcp-socket-impl.cc Wed Oct 29 11:49:21 2008 -0700
@@ -298,10 +298,6 @@
TcpSocketImpl::Close (void)
{
NS_LOG_FUNCTION_NOARGS ();
- if (m_state == CLOSED)
- {
- return -1;
- }
if (m_pendingData && m_pendingData->Size() != 0)
{ // App close with pending data must wait until all data transmitted
m_closeOnEmpty = true;
--- a/src/internet-stack/udp-l4-protocol.cc Mon Oct 27 23:05:57 2008 -0700
+++ b/src/internet-stack/udp-l4-protocol.cc Wed Oct 29 11:49:21 2008 -0700
@@ -146,6 +146,33 @@
}
void
+UdpL4Protocol::ReceiveIcmp (Ipv4Address icmpSource, uint8_t icmpTtl,
+ uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo,
+ Ipv4Address payloadSource,Ipv4Address payloadDestination,
+ const uint8_t payload[8])
+{
+ NS_LOG_FUNCTION (this << icmpSource << icmpTtl << icmpType << icmpCode << icmpInfo
+ << payloadSource << payloadDestination);
+ uint16_t src, dst;
+ src = payload[0] << 8;
+ src |= payload[1];
+ dst = payload[2] << 8;
+ dst |= payload[3];
+
+ Ipv4EndPoint *endPoint = m_endPoints->SimpleLookup (payloadSource, src, payloadDestination, dst);
+ if (endPoint != 0)
+ {
+ endPoint->ForwardIcmp (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
+ }
+ else
+ {
+ NS_LOG_DEBUG ("no endpoint found source=" << payloadSource <<
+ ", destination="<<payloadDestination<<
+ ", src=" << src << ", dst=" << dst);
+ }
+}
+
+enum Ipv4L4Protocol::RxStatus
UdpL4Protocol::Receive(Ptr<Packet> packet,
Ipv4Address const &source,
Ipv4Address const &destination,
@@ -165,17 +192,22 @@
if(!udpHeader.IsChecksumOk ())
{
NS_LOG_INFO("Bad checksum : dropping packet!");
- return;
+ return Ipv4L4Protocol::RX_CSUM_FAILED;
}
Ipv4EndPointDemux::EndPoints endPoints =
m_endPoints->Lookup (destination, udpHeader.GetDestinationPort (),
source, udpHeader.GetSourcePort (), interface);
+ if (endPoints.empty ())
+ {
+ return Ipv4L4Protocol::RX_ENDPOINT_UNREACH;
+ }
for (Ipv4EndPointDemux::EndPointsI endPoint = endPoints.begin ();
endPoint != endPoints.end (); endPoint++)
{
(*endPoint)->ForwardUp (packet->Copy (), source, udpHeader.GetSourcePort ());
}
+ return Ipv4L4Protocol::RX_OK;
}
void
--- a/src/internet-stack/udp-l4-protocol.h Mon Oct 27 23:05:57 2008 -0700
+++ b/src/internet-stack/udp-l4-protocol.h Wed Oct 29 11:49:21 2008 -0700
@@ -84,10 +84,15 @@
* \param interface the interface from which the packet is coming.
*/
// inherited from Ipv4L4Protocol
- virtual void Receive(Ptr<Packet> p,
- Ipv4Address const &source,
- Ipv4Address const &destination,
+ virtual enum Ipv4L4Protocol::RxStatus Receive(Ptr<Packet> p,
+ Ipv4Address const &source,
+ Ipv4Address const &destination,
Ptr<Ipv4Interface> interface);
+
+ virtual void ReceiveIcmp (Ipv4Address icmpSource, uint8_t icmpTtl,
+ uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo,
+ Ipv4Address payloadSource,Ipv4Address payloadDestination,
+ const uint8_t payload[8]);
protected:
virtual void DoDispose (void);
private:
--- a/src/internet-stack/udp-socket-impl.cc Mon Oct 27 23:05:57 2008 -0700
+++ b/src/internet-stack/udp-socket-impl.cc Wed Oct 29 11:49:21 2008 -0700
@@ -25,8 +25,6 @@
#include "ns3/ipv4.h"
#include "ns3/udp-socket-factory.h"
#include "ns3/trace-source-accessor.h"
-#include "ns3/uinteger.h"
-#include "ns3/boolean.h"
#include "udp-socket-impl.h"
#include "udp-l4-protocol.h"
#include "ipv4-end-point.h"
@@ -47,6 +45,10 @@
.AddConstructor<UdpSocketImpl> ()
.AddTraceSource ("Drop", "Drop UDP packet due to receive buffer overflow",
MakeTraceSourceAccessor (&UdpSocketImpl::m_dropTrace))
+ .AddAttribute ("IcmpCallback", "Callback invoked whenever an icmp error is received on this socket.",
+ CallbackValue (),
+ MakeCallbackAccessor (&UdpSocketImpl::m_icmpCallback),
+ MakeCallbackChecker ())
;
return tid;
}
@@ -134,6 +136,7 @@
return -1;
}
m_endPoint->SetRxCallback (MakeCallback (&UdpSocketImpl::ForwardUp, Ptr<UdpSocketImpl> (this)));
+ m_endPoint->SetIcmpCallback (MakeCallback (&UdpSocketImpl::ForwardIcmp, Ptr<UdpSocketImpl> (this)));
m_endPoint->SetDestroyCallback (MakeCallback (&UdpSocketImpl::Destroy, Ptr<UdpSocketImpl> (this)));
return 0;
}
@@ -328,6 +331,22 @@
tag.SetTtl (m_ipTtl);
p->AddTag (tag);
}
+ {
+ SocketSetDontFragmentTag tag;
+ bool found = p->FindFirstMatchingTag (tag);
+ if (!found)
+ {
+ if (m_mtuDiscover)
+ {
+ tag.Enable ();
+ }
+ else
+ {
+ tag.Disable ();
+ }
+ p->AddTag (tag);
+ }
+ }
//
// If dest is sent to the limited broadcast address (all ones),
// convert it to send a copy of the packet out of every interface
@@ -405,6 +424,7 @@
NS_LOG_FUNCTION (this << maxSize << flags);
if (m_deliveryQueue.empty() )
{
+ m_errno = ERROR_AGAIN;
return 0;
}
Ptr<Packet> p = m_deliveryQueue.front ();
@@ -483,6 +503,19 @@
}
}
+void
+UdpSocketImpl::ForwardIcmp (Ipv4Address icmpSource, uint8_t icmpTtl,
+ uint8_t icmpType, uint8_t icmpCode,
+ uint32_t icmpInfo)
+{
+ NS_LOG_FUNCTION (this << icmpSource << (uint32_t)icmpTtl << (uint32_t)icmpType <<
+ (uint32_t)icmpCode << icmpInfo);
+ if (!m_icmpCallback.IsNull ())
+ {
+ m_icmpCallback (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
+ }
+}
+
void
UdpSocketImpl::SetRcvBufSize (uint32_t size)
@@ -520,6 +553,18 @@
return m_ipMulticastTtl;
}
+void
+UdpSocketImpl::SetMtuDiscover (bool discover)
+{
+ m_mtuDiscover = discover;
+}
+bool
+UdpSocketImpl::GetMtuDiscover (void) const
+{
+ return m_mtuDiscover;
+}
+
+
} //namespace ns3
--- a/src/internet-stack/udp-socket-impl.h Mon Oct 27 23:05:57 2008 -0700
+++ b/src/internet-stack/udp-socket-impl.h Wed Oct 29 11:49:21 2008 -0700
@@ -28,6 +28,7 @@
#include "ns3/ptr.h"
#include "ns3/ipv4-address.h"
#include "ns3/udp-socket.h"
+#include "icmpv4.h"
namespace ns3 {
@@ -83,6 +84,9 @@
virtual uint32_t GetIpTtl (void) const;
virtual void SetIpMulticastTtl (uint32_t ipTtl);
virtual uint32_t GetIpMulticastTtl (void) const;
+ virtual void SetMtuDiscover (bool discover);
+ virtual bool GetMtuDiscover (void) const;
+
friend class UdpSocketFactory;
// invoked by Udp class
@@ -92,6 +96,9 @@
int DoSend (Ptr<Packet> p);
int DoSendTo (Ptr<Packet> p, const Address &daddr);
int DoSendTo (Ptr<Packet> p, Ipv4Address daddr, uint16_t dport);
+ void ForwardIcmp (Ipv4Address icmpSource, uint8_t icmpTtl,
+ uint8_t icmpType, uint8_t icmpCode,
+ uint32_t icmpInfo);
Ipv4EndPoint *m_endPoint;
Ptr<Node> m_node;
@@ -114,7 +121,8 @@
uint32_t m_rcvBufSize;
uint32_t m_ipTtl;
uint32_t m_ipMulticastTtl;
-
+ bool m_mtuDiscover;
+ Callback<void, Ipv4Address,uint8_t,uint8_t,uint8_t,uint32_t> m_icmpCallback;
};
}//namespace ns3
--- a/src/internet-stack/wscript Mon Oct 27 23:05:57 2008 -0700
+++ b/src/internet-stack/wscript Wed Oct 29 11:49:21 2008 -0700
@@ -148,6 +148,10 @@
'pending-data.cc',
'sequence-number.cc',
'rtt-estimator.cc',
+ 'ipv4-raw-socket-factory-impl.cc',
+ 'ipv4-raw-socket-impl.cc',
+ 'icmpv4.cc',
+ 'icmpv4-l4-protocol.cc',
]
headers = bld.create_obj('ns3header')
@@ -160,6 +164,7 @@
'ipv4-interface.h',
'ipv4-l3-protocol.h',
'ipv4-static-routing.h',
+ 'icmpv4.h',
]
if bld.env()['NSC_ENABLED']:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ipv4-raw-socket-factory.cc Wed Oct 29 11:49:21 2008 -0700
@@ -0,0 +1,35 @@
+/* -*- 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 <[email protected]>
+ */
+#include "ipv4-raw-socket-factory.h"
+#include "ns3/uinteger.h"
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv4RawSocketFactory);
+
+TypeId Ipv4RawSocketFactory::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::Ipv4RawSocketFactory")
+ .SetParent<SocketFactory> ()
+ ;
+ return tid;
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ipv4-raw-socket-factory.h Wed Oct 29 11:49:21 2008 -0700
@@ -0,0 +1,46 @@
+/* -*- 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 <[email protected]>
+ */
+#ifndef IPV4_RAW_SOCKET_FACTORY_H
+#define IPV4_RAW_SOCKET_FACTORY_H
+
+#include "socket-factory.h"
+
+namespace ns3 {
+
+class Socket;
+
+/**
+ * \ingroup socket
+ *
+ * \brief API to create RAW socket instances
+ *
+ * This abstract class defines the API for RAW socket factory.
+ *
+ */
+class Ipv4RawSocketFactory : public SocketFactory
+{
+public:
+ static TypeId GetTypeId (void);
+
+};
+
+} // namespace ns3
+
+#endif /* IPV4_RAW_SOCKET_FACTORY_H */
--- a/src/node/socket.cc Mon Oct 27 23:05:57 2008 -0700
+++ b/src/node/socket.cc Wed Oct 29 11:49:21 2008 -0700
@@ -362,4 +362,57 @@
}
+SocketSetDontFragmentTag::SocketSetDontFragmentTag ()
+{}
+void
+SocketSetDontFragmentTag::Enable (void)
+{
+ m_dontFragment = true;
+}
+void
+SocketSetDontFragmentTag::Disable (void)
+{
+ m_dontFragment = false;
+}
+bool
+SocketSetDontFragmentTag::IsEnabled (void) const
+{
+ return m_dontFragment;
+}
+
+TypeId
+SocketSetDontFragmentTag::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::SocketSetDontFragmentTag")
+ .SetParent<Tag> ()
+ .AddConstructor<SocketSetDontFragmentTag> ()
+ ;
+ return tid;
+}
+TypeId
+SocketSetDontFragmentTag::GetInstanceTypeId (void) const
+{
+ return GetTypeId ();
+}
+uint32_t
+SocketSetDontFragmentTag::GetSerializedSize (void) const
+{
+ return 1;
+}
+void
+SocketSetDontFragmentTag::Serialize (TagBuffer i) const
+{
+ i.WriteU8 (m_dontFragment?1:0);
+}
+void
+SocketSetDontFragmentTag::Deserialize (TagBuffer i)
+{
+ m_dontFragment = (i.ReadU8 () == 1)?true:false;
+}
+void
+SocketSetDontFragmentTag::Print (std::ostream &os) const
+{
+ os << (m_dontFragment?"true":"false");
+}
+
}//namespace ns3
--- a/src/node/socket.h Mon Oct 27 23:05:57 2008 -0700
+++ b/src/node/socket.h Wed Oct 29 11:49:21 2008 -0700
@@ -336,9 +336,9 @@
* not preserved.
*
* The flags argument is formed by or'ing one or more of the values:
- * MSG_OOB process out-of-band data
- * MSG_PEEK peek at incoming message
- * These flags are _unsupported_ as of ns-3.1.
+ * MSG_OOB process out-of-band data
+ * MSG_PEEK peek at incoming message
+ * None of these flags are supported for now.
*
* Some variants of Recv() are supported as additional API,
* including RecvFrom(), overloaded Recv() without arguments,
@@ -555,6 +555,29 @@
uint8_t m_ttl;
};
+
+/**
+ * \brief indicated whether packets should be sent out with
+ * the DF flag set.
+ */
+class SocketSetDontFragmentTag : public Tag
+{
+public:
+ SocketSetDontFragmentTag ();
+ void Enable (void);
+ void Disable (void);
+ bool IsEnabled (void) const;
+
+ static TypeId GetTypeId (void);
+ virtual TypeId GetInstanceTypeId (void) const;
+ virtual uint32_t GetSerializedSize (void) const;
+ virtual void Serialize (TagBuffer i) const;
+ virtual void Deserialize (TagBuffer i);
+ virtual void Print (std::ostream &os) const;
+private:
+ bool m_dontFragment;
+};
+
} //namespace ns3
#endif /* SOCKET_H */
--- a/src/node/udp-socket.cc Mon Oct 27 23:05:57 2008 -0700
+++ b/src/node/udp-socket.cc Wed Oct 29 11:49:21 2008 -0700
@@ -21,6 +21,7 @@
#include "ns3/object.h"
#include "ns3/log.h"
#include "ns3/uinteger.h"
+#include "ns3/boolean.h"
#include "ns3/trace-source-accessor.h"
#include "udp-socket.h"
@@ -53,6 +54,11 @@
MakeUintegerAccessor (&UdpSocket::GetIpMulticastTtl,
&UdpSocket::SetIpMulticastTtl),
MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("MtuDiscover", "If enabled, every outgoing ip packet will have the DF flag set.",
+ BooleanValue (false),
+ MakeBooleanAccessor (&UdpSocket::SetMtuDiscover,
+ &UdpSocket::GetMtuDiscover),
+ MakeBooleanChecker ())
;
return tid;
}
--- a/src/node/udp-socket.h Mon Oct 27 23:05:57 2008 -0700
+++ b/src/node/udp-socket.h Wed Oct 29 11:49:21 2008 -0700
@@ -58,7 +58,8 @@
virtual uint32_t GetIpTtl (void) const = 0;
virtual void SetIpMulticastTtl (uint32_t ipTtl) = 0;
virtual uint32_t GetIpMulticastTtl (void) const = 0;
-
+ virtual void SetMtuDiscover (bool discover) = 0;
+ virtual bool GetMtuDiscover (void) const = 0;
};
} //namespace ns3
--- a/src/node/wscript Mon Oct 27 23:05:57 2008 -0700
+++ b/src/node/wscript Wed Oct 29 11:49:21 2008 -0700
@@ -34,6 +34,7 @@
'application.cc',
'simple-channel.cc',
'simple-net-device.cc',
+ 'ipv4-raw-socket-factory.cc',
]
headers = bld.create_obj('ns3header')
@@ -69,4 +70,5 @@
'application.h',
'simple-channel.h',
'simple-net-device.h',
+ 'ipv4-raw-socket-factory.h',
]
--- a/src/wscript Mon Oct 27 23:05:57 2008 -0700
+++ b/src/wscript Wed Oct 29 11:49:21 2008 -0700
@@ -31,6 +31,7 @@
'devices/wifi',
'helper',
'contrib/stats',
+ 'applications/v4ping',
)
def set_options(opt):