merge
authorPavel Boyko <boyko@iitp.ru>
Tue, 21 Apr 2009 16:22:45 +0400
changeset 4969 106e7a5e4efc
parent 4968 ff5a2162d492 (current diff)
parent 4391 0868b79a6be4 (diff)
child 4971 06f549530ae2
merge
src/internet-stack/ipv4-impl.cc
src/internet-stack/ipv4-impl.h
src/internet-stack/ipv4-l3-protocol.cc
src/internet-stack/tcp-socket-impl.cc
src/internet-stack/udp-socket-impl.cc
src/node/wscript
src/wscript
--- a/CHANGES.html	Tue Apr 21 16:13:45 2009 +0400
+++ b/CHANGES.html	Tue Apr 21 16:22:45 2009 +0400
@@ -44,9 +44,78 @@
 us a note on ns-developers mailing list.  </p>
 
 <hr>
+<h1>Changes from ns-3.4 to ns-3.5</h1>
+
+<h2>Changes to build system:</h2>
+<ul>
+</ul>
+
+<h2>New API:</h2>
+<ul>
+</ul>
+
+<h2>Changes to existing API:</h2>
+<ul>
+<li> deconflict NetDevice::ifIndex and Ipv4::ifIndex (bug 85). All function parameters named "ifIndex" that refer 
+to an Ipv4 interface are instead named "interface".
+<pre>
+- static const uint32_t Ipv4RoutingProtocol::IF_INDEX_ANY = 0xffffffff;
++ static const uint32_t Ipv4RoutingProtocol::INTERFACE_ANY = 0xffffffff;
+
+- bool Ipv4RoutingProtocol::RequestIfIndex (Ipv4Address destination, uint32_t& ifIndex);
++ bool Ipv4RoutingProtocol::RequestInterface (Ipv4Address destination, uint32_t& interface);
+(N.B. this particular function is planned to be renamed to RouteOutput() in the
+proposed IPv4 routing refactoring)
+
+- uint32_t Ipv4::GetIfIndexByAddress (Ipv4Address addr, Ipv4Mask mask);
++ int_32t Ipv4::GetInterfaceForAddress (Ipv4Address address, Ipv4Mask mask) const;
+
+- bool Ipv4::GetIfIndexForDestination (Ipv4Address dest, uint32_t &ifIndex) const;
++ bool Ipv4::GetInterfaceForDestination (Ipv4Address dest, uint32_t &interface) const;
+(N.B. this function is not needed in the proposed Ipv4 routing refactoring)
+</pre>
+<li> allow multiple IPv4 addresses to be assigned to an interface (bug 188).  
+<ul>
+<li> Add class Ipv4InterfaceAddress:  
+This is a new class to resemble Linux's struct in_ifaddr.  It holds IP addressing information, including mask,
+broadcast address, scope, whether primary or secondary, etc.
+<pre>
++  virtual uint32_t AddAddress (uint32_t interface, Ipv4InterfaceAddress address) = 0;
++  virtual Ipv4InterfaceAddress GetAddress (uint32_t interface, uint32_t addressIndex) const = 0;
++  virtual uint32_t GetNAddresses (uint32_t interface) const = 0;
+</pre>
+<li>Regarding legacy API usage, typically where you once did the following,
+using the public Ipv4 class interface (e.g.):
+<pre>
+  ipv4A->SetAddress (ifIndexA, Ipv4Address ("172.16.1.1"));
+  ipv4A->SetNetworkMask (ifIndexA, Ipv4Mask ("255.255.255.255"));
+</pre>
+you now do:
+<pre>
+  Ipv4InterfaceAddress ipv4IfAddrA = Ipv4InterfaceAddress (Ipv4Address ("172.16.1.1"), Ipv4Mask ("255.255.255.255"));
+  ipv4A->AddAddress (ifIndexA, ipv4IfAddrA);
+</pre>
+<li> At the helper API level, one often gets an address from an interface
+container.  We preserve the legacy GetAddress (uint32_t i) but it
+is documented that this will return only the first (address index 0)
+address on the interface, if there are multiple such addresses. 
+We provide also an overloaded variant for the multi-address case: 
+
+<pre>
+Ipv4Address Ipv4InterfaceContainer::GetAddress (uint32_t i)
++ Ipv4Address Ipv4InterfaceContainer::GetAddress (uint32_t i, uint32_t j)
+</pre>
+</ul>
+</ul>
+
+<h2>Changed behavior:</h2>
+<ul>
+</ul>
+
+<hr>
 <h1>Changes from ns-3.3 to ns-3.4</h1>
 
-<h2>Changes to build system</h2>
+<h2>Changes to build system:</h2>
 <ul>
 <li>A major option regarding the downloading and building of ns-3 has been
 added for ns-3.4 -- the ns-3-allinone feature.  This allows a user to
--- a/bindings/python/ns3_module_core.py	Tue Apr 21 16:13:45 2009 +0400
+++ b/bindings/python/ns3_module_core.py	Tue Apr 21 16:22:45 2009 +0400
@@ -2028,7 +2028,7 @@
     cls.add_method('ConnectWithoutContext', 
                    'void', 
                    [param('ns3::CallbackBase const &', 'cb')])
-    ## traced-value.h: void ns3::TracedValue<unsigned int>::Connect(ns3::CallbackBase const & cb, std::string path) [member function]
+    ## traced-value.h: void ns3::TracedValue<unsigned int>::Connect(ns3::CallbackBase const & cb, std::basic_string<char,std::char_traits<char>,std::allocator<char> > path) [member function]
     cls.add_method('Connect', 
                    'void', 
                    [param('ns3::CallbackBase const &', 'cb'), param('std::string', 'path')])
@@ -2036,7 +2036,7 @@
     cls.add_method('DisconnectWithoutContext', 
                    'void', 
                    [param('ns3::CallbackBase const &', 'cb')])
-    ## traced-value.h: void ns3::TracedValue<unsigned int>::Disconnect(ns3::CallbackBase const & cb, std::string path) [member function]
+    ## traced-value.h: void ns3::TracedValue<unsigned int>::Disconnect(ns3::CallbackBase const & cb, std::basic_string<char,std::char_traits<char>,std::allocator<char> > path) [member function]
     cls.add_method('Disconnect', 
                    'void', 
                    [param('ns3::CallbackBase const &', 'cb'), param('std::string', 'path')])
@@ -2184,7 +2184,7 @@
     module.add_function('TypeNameGet', 
                         'std::string', 
                         [], 
-                        template_parameters=['long long'])
+                        template_parameters=['long'])
     ## type-name.h: extern std::string ns3::TypeNameGet() [free function]
     module.add_function('TypeNameGet', 
                         'std::string', 
@@ -2204,7 +2204,7 @@
     module.add_function('TypeNameGet', 
                         'std::string', 
                         [], 
-                        template_parameters=['unsigned long long'])
+                        template_parameters=['unsigned long'])
     ## type-name.h: extern std::string ns3::TypeNameGet() [free function]
     module.add_function('TypeNameGet', 
                         'std::string', 
--- a/bindings/python/ns3_module_helper.py	Tue Apr 21 16:13:45 2009 +0400
+++ b/bindings/python/ns3_module_helper.py	Tue Apr 21 16:22:45 2009 +0400
@@ -482,10 +482,10 @@
                    'uint32_t', 
                    [], 
                    is_const=True)
-    ## ipv4-interface-container.h: ns3::Ipv4Address ns3::Ipv4InterfaceContainer::GetAddress(uint32_t i) const [member function]
+    ## ipv4-interface-container.h: ns3::Ipv4Address ns3::Ipv4InterfaceContainer::GetAddress(uint32_t i, uint32_t j=0) const [member function]
     cls.add_method('GetAddress', 
                    'ns3::Ipv4Address', 
-                   [param('uint32_t', 'i')], 
+                   [param('uint32_t', 'i'), param('uint32_t', 'j', default_value='0')], 
                    is_const=True)
     ## ipv4-interface-container.h: void ns3::Ipv4InterfaceContainer::SetMetric(uint32_t i, uint16_t metric) [member function]
     cls.add_method('SetMetric', 
--- a/bindings/python/ns3_module_internet_stack.py	Tue Apr 21 16:13:45 2009 +0400
+++ b/bindings/python/ns3_module_internet_stack.py	Tue Apr 21 16:22:45 2009 +0400
@@ -518,15 +518,15 @@
                    is_static=True)
     ## ipv4-global-routing.h: ns3::Ipv4GlobalRouting::Ipv4GlobalRouting() [constructor]
     cls.add_constructor([])
-    ## ipv4-global-routing.h: bool ns3::Ipv4GlobalRouting::RequestRoute(uint32_t ifIndex, ns3::Ipv4Header const & ipHeader, ns3::Ptr<ns3::Packet> packet, ns3::Callback<void,bool,const ns3::Ipv4Route&,ns3::Ptr<ns3::Packet>,const ns3::Ipv4Header&,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty> routeReply) [member function]
+    ## ipv4-global-routing.h: bool ns3::Ipv4GlobalRouting::RequestRoute(uint32_t interface, ns3::Ipv4Header const & ipHeader, ns3::Ptr<ns3::Packet> packet, ns3::Callback<void,bool,const ns3::Ipv4Route&,ns3::Ptr<ns3::Packet>,const ns3::Ipv4Header&,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty> routeReply) [member function]
     cls.add_method('RequestRoute', 
                    'bool', 
-                   [param('uint32_t', 'ifIndex'), param('ns3::Ipv4Header const &', 'ipHeader'), param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Callback< void, bool, ns3::Ipv4Route const &, ns3::Ptr< ns3::Packet >, ns3::Ipv4Header const &, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'routeReply')], 
+                   [param('uint32_t', 'interface'), param('ns3::Ipv4Header const &', 'ipHeader'), param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Callback< void, bool, ns3::Ipv4Route const &, ns3::Ptr< ns3::Packet >, ns3::Ipv4Header const &, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'routeReply')], 
                    is_virtual=True)
-    ## ipv4-global-routing.h: bool ns3::Ipv4GlobalRouting::RequestIfIndex(ns3::Ipv4Address destination, uint32_t & ifIndex) [member function]
-    cls.add_method('RequestIfIndex', 
+    ## ipv4-global-routing.h: bool ns3::Ipv4GlobalRouting::RequestInterface(ns3::Ipv4Address destination, uint32_t & interface) [member function]
+    cls.add_method('RequestInterface', 
                    'bool', 
-                   [param('ns3::Ipv4Address', 'destination'), param('uint32_t &', 'ifIndex')], 
+                   [param('ns3::Ipv4Address', 'destination'), param('uint32_t &', 'interface')], 
                    is_virtual=True)
     ## ipv4-global-routing.h: void ns3::Ipv4GlobalRouting::AddHostRouteTo(ns3::Ipv4Address dest, ns3::Ipv4Address nextHop, uint32_t interface) [member function]
     cls.add_method('AddHostRouteTo', 
--- a/bindings/python/ns3_module_mobility.py	Tue Apr 21 16:13:45 2009 +0400
+++ b/bindings/python/ns3_module_mobility.py	Tue Apr 21 16:22:45 2009 +0400
@@ -707,6 +707,14 @@
                    'ns3::Ptr< ns3::MobilityModel >', 
                    [], 
                    is_const=True)
+    ## hierarchical-mobility-model.h: void ns3::HierarchicalMobilityModel::SetChild(ns3::Ptr<ns3::MobilityModel> model) [member function]
+    cls.add_method('SetChild', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::MobilityModel >', 'model')])
+    ## hierarchical-mobility-model.h: void ns3::HierarchicalMobilityModel::SetParent(ns3::Ptr<ns3::MobilityModel> model) [member function]
+    cls.add_method('SetParent', 
+                   'void', 
+                   [param('ns3::Ptr< ns3::MobilityModel >', 'model')])
     ## hierarchical-mobility-model.h: ns3::Vector ns3::HierarchicalMobilityModel::DoGetPosition() const [member function]
     cls.add_method('DoGetPosition', 
                    'ns3::Vector', 
--- a/bindings/python/ns3_module_node.py	Tue Apr 21 16:13:45 2009 +0400
+++ b/bindings/python/ns3_module_node.py	Tue Apr 21 16:22:45 2009 +0400
@@ -23,6 +23,10 @@
     root_module['ns3::Ipv4Address'].implicitly_converts_to(root_module['ns3::Address'])
     ## ipv4-address-generator.h: ns3::Ipv4AddressGenerator [class]
     module.add_class('Ipv4AddressGenerator')
+    ## ipv4-interface-address.h: ns3::Ipv4InterfaceAddress [class]
+    module.add_class('Ipv4InterfaceAddress')
+    ## ipv4-interface-address.h: ns3::Ipv4InterfaceAddress::InterfaceAddressScope_e [enumeration]
+    module.add_enum('InterfaceAddressScope_e', ['HOST', 'LINK', 'GLOBAL'], outer_class=root_module['ns3::Ipv4InterfaceAddress'])
     ## ipv4-address.h: ns3::Ipv4Mask [class]
     module.add_class('Ipv4Mask')
     ## ipv4-route.h: ns3::Ipv4MulticastRoute [class]
@@ -182,6 +186,7 @@
     register_Ns3InetSocketAddress_methods(root_module, root_module['ns3::InetSocketAddress'])
     register_Ns3Ipv4Address_methods(root_module, root_module['ns3::Ipv4Address'])
     register_Ns3Ipv4AddressGenerator_methods(root_module, root_module['ns3::Ipv4AddressGenerator'])
+    register_Ns3Ipv4InterfaceAddress_methods(root_module, root_module['ns3::Ipv4InterfaceAddress'])
     register_Ns3Ipv4Mask_methods(root_module, root_module['ns3::Ipv4Mask'])
     register_Ns3Ipv4MulticastRoute_methods(root_module, root_module['ns3::Ipv4MulticastRoute'])
     register_Ns3Ipv4Route_methods(root_module, root_module['ns3::Ipv4Route'])
@@ -542,6 +547,65 @@
                    is_static=True)
     return
 
+def register_Ns3Ipv4InterfaceAddress_methods(root_module, cls):
+    cls.add_output_stream_operator()
+    ## ipv4-interface-address.h: ns3::Ipv4InterfaceAddress::Ipv4InterfaceAddress() [constructor]
+    cls.add_constructor([])
+    ## ipv4-interface-address.h: ns3::Ipv4InterfaceAddress::Ipv4InterfaceAddress(ns3::Ipv4Address local, ns3::Ipv4Mask mask) [constructor]
+    cls.add_constructor([param('ns3::Ipv4Address', 'local'), param('ns3::Ipv4Mask', 'mask')])
+    ## ipv4-interface-address.h: ns3::Ipv4InterfaceAddress::Ipv4InterfaceAddress(ns3::Ipv4InterfaceAddress const & o) [copy constructor]
+    cls.add_constructor([param('ns3::Ipv4InterfaceAddress const &', 'o')])
+    ## ipv4-interface-address.h: ns3::Ipv4Address ns3::Ipv4InterfaceAddress::GetBroadcast() const [member function]
+    cls.add_method('GetBroadcast', 
+                   'ns3::Ipv4Address', 
+                   [], 
+                   is_const=True)
+    ## ipv4-interface-address.h: ns3::Ipv4Address ns3::Ipv4InterfaceAddress::GetLocal() const [member function]
+    cls.add_method('GetLocal', 
+                   'ns3::Ipv4Address', 
+                   [], 
+                   is_const=True)
+    ## ipv4-interface-address.h: ns3::Ipv4Mask ns3::Ipv4InterfaceAddress::GetMask() const [member function]
+    cls.add_method('GetMask', 
+                   'ns3::Ipv4Mask', 
+                   [], 
+                   is_const=True)
+    ## ipv4-interface-address.h: ns3::Ipv4InterfaceAddress::InterfaceAddressScope_e ns3::Ipv4InterfaceAddress::GetScope() const [member function]
+    cls.add_method('GetScope', 
+                   'ns3::Ipv4InterfaceAddress::InterfaceAddressScope_e', 
+                   [], 
+                   is_const=True)
+    ## ipv4-interface-address.h: bool ns3::Ipv4InterfaceAddress::IsSecondary() const [member function]
+    cls.add_method('IsSecondary', 
+                   'bool', 
+                   [], 
+                   is_const=True)
+    ## ipv4-interface-address.h: void ns3::Ipv4InterfaceAddress::SetBroadcast(ns3::Ipv4Address broadcast) [member function]
+    cls.add_method('SetBroadcast', 
+                   'void', 
+                   [param('ns3::Ipv4Address', 'broadcast')])
+    ## ipv4-interface-address.h: void ns3::Ipv4InterfaceAddress::SetLocal(ns3::Ipv4Address local) [member function]
+    cls.add_method('SetLocal', 
+                   'void', 
+                   [param('ns3::Ipv4Address', 'local')])
+    ## ipv4-interface-address.h: void ns3::Ipv4InterfaceAddress::SetMask(ns3::Ipv4Mask mask) [member function]
+    cls.add_method('SetMask', 
+                   'void', 
+                   [param('ns3::Ipv4Mask', 'mask')])
+    ## ipv4-interface-address.h: void ns3::Ipv4InterfaceAddress::SetPrimary() [member function]
+    cls.add_method('SetPrimary', 
+                   'void', 
+                   [])
+    ## ipv4-interface-address.h: void ns3::Ipv4InterfaceAddress::SetScope(ns3::Ipv4InterfaceAddress::InterfaceAddressScope_e scope) [member function]
+    cls.add_method('SetScope', 
+                   'void', 
+                   [param('ns3::Ipv4InterfaceAddress::InterfaceAddressScope_e', 'scope')])
+    ## ipv4-interface-address.h: void ns3::Ipv4InterfaceAddress::SetSecondary() [member function]
+    cls.add_method('SetSecondary', 
+                   'void', 
+                   [])
+    return
+
 def register_Ns3Ipv4Mask_methods(root_module, cls):
     cls.add_binary_comparison_operator('!=')
     cls.add_output_stream_operator()
@@ -1870,6 +1934,11 @@
                    'void', 
                    [], 
                    visibility='protected')
+    ## socket.h: void ns3::Socket::DoDispose() [member function]
+    cls.add_method('DoDispose', 
+                   'void', 
+                   [], 
+                   visibility='protected', is_virtual=True)
     return
 
 def register_Ns3SocketAddressTag_methods(root_module, cls):
@@ -2597,11 +2666,11 @@
                    'uint32_t', 
                    [param('ns3::Ptr< ns3::NetDevice >', 'device')], 
                    is_pure_virtual=True, is_virtual=True)
-    ## ipv4.h: uint32_t ns3::Ipv4::GetNInterfaces() [member function]
+    ## ipv4.h: uint32_t ns3::Ipv4::GetNInterfaces() const [member function]
     cls.add_method('GetNInterfaces', 
                    'uint32_t', 
                    [], 
-                   is_pure_virtual=True, is_virtual=True)
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
     ## ipv4.h: uint32_t ns3::Ipv4::FindInterfaceForAddr(ns3::Ipv4Address addr) const [member function]
     cls.add_method('FindInterfaceForAddr', 
                    'uint32_t', 
@@ -2632,20 +2701,20 @@
                    'void', 
                    [param('ns3::Ipv4Address', 'origin'), param('ns3::Ipv4Address', 'group')], 
                    is_pure_virtual=True, is_virtual=True)
-    ## ipv4.h: void ns3::Ipv4::SetAddress(uint32_t i, ns3::Ipv4Address address) [member function]
-    cls.add_method('SetAddress', 
-                   'void', 
-                   [param('uint32_t', 'i'), param('ns3::Ipv4Address', 'address')], 
+    ## ipv4.h: uint32_t ns3::Ipv4::AddAddress(uint32_t interface, ns3::Ipv4InterfaceAddress address) [member function]
+    cls.add_method('AddAddress', 
+                   'uint32_t', 
+                   [param('uint32_t', 'interface'), param('ns3::Ipv4InterfaceAddress', 'address')], 
                    is_pure_virtual=True, is_virtual=True)
-    ## ipv4.h: void ns3::Ipv4::SetNetworkMask(uint32_t i, ns3::Ipv4Mask mask) [member function]
-    cls.add_method('SetNetworkMask', 
-                   'void', 
-                   [param('uint32_t', 'i'), param('ns3::Ipv4Mask', 'mask')], 
-                   is_pure_virtual=True, is_virtual=True)
-    ## ipv4.h: ns3::Ipv4Mask ns3::Ipv4::GetNetworkMask(uint32_t i) const [member function]
-    cls.add_method('GetNetworkMask', 
-                   'ns3::Ipv4Mask', 
-                   [param('uint32_t', 'i')], 
+    ## ipv4.h: uint32_t ns3::Ipv4::GetNAddresses(uint32_t interface) const [member function]
+    cls.add_method('GetNAddresses', 
+                   'uint32_t', 
+                   [param('uint32_t', 'interface')], 
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## ipv4.h: ns3::Ipv4InterfaceAddress ns3::Ipv4::GetAddress(uint32_t interface, uint32_t addressIndex) const [member function]
+    cls.add_method('GetAddress', 
+                   'ns3::Ipv4InterfaceAddress', 
+                   [param('uint32_t', 'interface'), param('uint32_t', 'addressIndex')], 
                    is_pure_virtual=True, is_const=True, is_virtual=True)
     ## ipv4.h: void ns3::Ipv4::SetMetric(uint32_t i, uint16_t metric) [member function]
     cls.add_method('SetMetric', 
@@ -2657,20 +2726,15 @@
                    'uint16_t', 
                    [param('uint32_t', 'i')], 
                    is_pure_virtual=True, is_const=True, is_virtual=True)
-    ## ipv4.h: ns3::Ipv4Address ns3::Ipv4::GetAddress(uint32_t i) const [member function]
-    cls.add_method('GetAddress', 
-                   'ns3::Ipv4Address', 
-                   [param('uint32_t', 'i')], 
-                   is_pure_virtual=True, is_const=True, is_virtual=True)
     ## ipv4.h: ns3::Ipv4Address ns3::Ipv4::GetSourceAddress(ns3::Ipv4Address destination) const [member function]
     cls.add_method('GetSourceAddress', 
                    'ns3::Ipv4Address', 
                    [param('ns3::Ipv4Address', 'destination')], 
                    is_pure_virtual=True, is_const=True, is_virtual=True)
-    ## ipv4.h: bool ns3::Ipv4::GetIfIndexForDestination(ns3::Ipv4Address dest, uint32_t & ifIndex) const [member function]
-    cls.add_method('GetIfIndexForDestination', 
+    ## ipv4.h: bool ns3::Ipv4::GetInterfaceForDestination(ns3::Ipv4Address dest, uint32_t & interface) const [member function]
+    cls.add_method('GetInterfaceForDestination', 
                    'bool', 
-                   [param('ns3::Ipv4Address', 'dest'), param('uint32_t &', 'ifIndex')], 
+                   [param('ns3::Ipv4Address', 'dest'), param('uint32_t &', 'interface')], 
                    is_pure_virtual=True, is_const=True, is_virtual=True)
     ## ipv4.h: uint16_t ns3::Ipv4::GetMtu(uint32_t i) const [member function]
     cls.add_method('GetMtu', 
@@ -2692,8 +2756,8 @@
                    'void', 
                    [param('uint32_t', 'i')], 
                    is_pure_virtual=True, is_virtual=True)
-    ## ipv4.h: uint32_t ns3::Ipv4::GetIfIndexByAddress(ns3::Ipv4Address addr, ns3::Ipv4Mask mask=ns3::Ipv4Mask(((const char*)"255.255.255.255"))) [member function]
-    cls.add_method('GetIfIndexByAddress', 
+    ## ipv4.h: uint32_t ns3::Ipv4::GetInterfaceByAddress(ns3::Ipv4Address addr, ns3::Ipv4Mask mask=ns3::Ipv4Mask(((const char*)"255.255.255.255"))) [member function]
+    cls.add_method('GetInterfaceByAddress', 
                    'uint32_t', 
                    [param('ns3::Ipv4Address', 'addr'), param('ns3::Ipv4Mask', 'mask', default_value='ns3::Ipv4Mask(((const char*)"255.255.255.255"))')], 
                    is_virtual=True)
@@ -2712,21 +2776,21 @@
     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)
+    ## ipv4.h: ns3::Ipv4RoutingProtocol::INTERFACE_ANY [variable]
+    cls.add_static_attribute('INTERFACE_ANY', 'uint32_t const', is_const=True)
     ## ipv4.h: ns3::Ipv4RoutingProtocol::Ipv4RoutingProtocol(ns3::Ipv4RoutingProtocol const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::Ipv4RoutingProtocol const &', 'arg0')])
     ## ipv4.h: ns3::Ipv4RoutingProtocol::Ipv4RoutingProtocol() [constructor]
     cls.add_constructor([])
-    ## ipv4.h: bool ns3::Ipv4RoutingProtocol::RequestRoute(uint32_t ifIndex, ns3::Ipv4Header const & ipHeader, ns3::Ptr<ns3::Packet> packet, ns3::Callback<void,bool,const ns3::Ipv4Route&,ns3::Ptr<ns3::Packet>,const ns3::Ipv4Header&,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty> routeReply) [member function]
+    ## ipv4.h: bool ns3::Ipv4RoutingProtocol::RequestRoute(uint32_t interface, ns3::Ipv4Header const & ipHeader, ns3::Ptr<ns3::Packet> packet, ns3::Callback<void,bool,const ns3::Ipv4Route&,ns3::Ptr<ns3::Packet>,const ns3::Ipv4Header&,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty> routeReply) [member function]
     cls.add_method('RequestRoute', 
                    'bool', 
-                   [param('uint32_t', 'ifIndex'), param('ns3::Ipv4Header const &', 'ipHeader'), param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Callback< void, bool, ns3::Ipv4Route const &, ns3::Ptr< ns3::Packet >, ns3::Ipv4Header const &, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'routeReply')], 
+                   [param('uint32_t', 'interface'), param('ns3::Ipv4Header const &', 'ipHeader'), param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Callback< void, bool, ns3::Ipv4Route const &, ns3::Ptr< ns3::Packet >, ns3::Ipv4Header const &, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'routeReply')], 
                    is_pure_virtual=True, is_virtual=True)
-    ## ipv4.h: bool ns3::Ipv4RoutingProtocol::RequestIfIndex(ns3::Ipv4Address destination, uint32_t & ifIndex) [member function]
-    cls.add_method('RequestIfIndex', 
+    ## ipv4.h: bool ns3::Ipv4RoutingProtocol::RequestInterface(ns3::Ipv4Address destination, uint32_t & interface) [member function]
+    cls.add_method('RequestInterface', 
                    'bool', 
-                   [param('ns3::Ipv4Address', 'destination'), param('uint32_t &', 'ifIndex')], 
+                   [param('ns3::Ipv4Address', 'destination'), param('uint32_t &', 'interface')], 
                    is_pure_virtual=True, is_virtual=True)
     return
 
--- a/bindings/python/ns3_module_olsr.py	Tue Apr 21 16:13:45 2009 +0400
+++ b/bindings/python/ns3_module_olsr.py	Tue Apr 21 16:22:45 2009 +0400
@@ -745,8 +745,8 @@
                    'bool', 
                    [param('uint32_t', 'ifIndex'), param('ns3::Ipv4Header const &', 'ipHeader'), param('ns3::Ptr< ns3::Packet >', 'packet'), param('ns3::Callback< void, bool, ns3::Ipv4Route const &, ns3::Ptr< ns3::Packet >, ns3::Ipv4Header const &, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'routeReply')], 
                    visibility='private', is_virtual=True)
-    ## olsr-routing-protocol.h: bool ns3::olsr::RoutingProtocol::RequestIfIndex(ns3::Ipv4Address destination, uint32_t & ifIndex) [member function]
-    cls.add_method('RequestIfIndex', 
+    ## olsr-routing-protocol.h: bool ns3::olsr::RoutingProtocol::RequestInterface(ns3::Ipv4Address destination, uint32_t & ifIndex) [member function]
+    cls.add_method('RequestInterface', 
                    'bool', 
                    [param('ns3::Ipv4Address', 'destination'), param('uint32_t &', 'ifIndex')], 
                    visibility='private', is_virtual=True)
--- a/bindings/python/ns3_module_wifi.py	Tue Apr 21 16:13:45 2009 +0400
+++ b/bindings/python/ns3_module_wifi.py	Tue Apr 21 16:22:45 2009 +0400
@@ -605,41 +605,6 @@
     cls.add_method('GetAckMode', 
                    'ns3::WifiMode', 
                    [param('ns3::WifiMode', 'dataMode')])
-    ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::DoReportRtsFailed() [member function]
-    cls.add_method('DoReportRtsFailed', 
-                   'void', 
-                   [], 
-                   is_pure_virtual=True, visibility='protected', is_virtual=True)
-    ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::DoReportDataFailed() [member function]
-    cls.add_method('DoReportDataFailed', 
-                   'void', 
-                   [], 
-                   is_pure_virtual=True, visibility='protected', is_virtual=True)
-    ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::DoReportRtsOk(double ctsSnr, ns3::WifiMode ctsMode, double rtsSnr) [member function]
-    cls.add_method('DoReportRtsOk', 
-                   'void', 
-                   [param('double', 'ctsSnr'), param('ns3::WifiMode', 'ctsMode'), param('double', 'rtsSnr')], 
-                   is_pure_virtual=True, visibility='protected', is_virtual=True)
-    ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::DoReportDataOk(double ackSnr, ns3::WifiMode ackMode, double dataSnr) [member function]
-    cls.add_method('DoReportDataOk', 
-                   'void', 
-                   [param('double', 'ackSnr'), param('ns3::WifiMode', 'ackMode'), param('double', 'dataSnr')], 
-                   is_pure_virtual=True, visibility='protected', is_virtual=True)
-    ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::DoReportFinalRtsFailed() [member function]
-    cls.add_method('DoReportFinalRtsFailed', 
-                   'void', 
-                   [], 
-                   is_pure_virtual=True, visibility='protected', is_virtual=True)
-    ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::DoReportFinalDataFailed() [member function]
-    cls.add_method('DoReportFinalDataFailed', 
-                   'void', 
-                   [], 
-                   is_pure_virtual=True, visibility='protected', is_virtual=True)
-    ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::DoReportRxOk(double rxSnr, ns3::WifiMode txMode) [member function]
-    cls.add_method('DoReportRxOk', 
-                   'void', 
-                   [param('double', 'rxSnr'), param('ns3::WifiMode', 'txMode')], 
-                   is_pure_virtual=True, visibility='protected', is_virtual=True)
     ## wifi-remote-station-manager.h: uint32_t ns3::WifiRemoteStation::GetNSupportedModes() const [member function]
     cls.add_method('GetNSupportedModes', 
                    'uint32_t', 
@@ -665,6 +630,41 @@
                    'ns3::WifiMode', 
                    [], 
                    is_pure_virtual=True, visibility='private', is_virtual=True)
+    ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::DoReportRtsFailed() [member function]
+    cls.add_method('DoReportRtsFailed', 
+                   'void', 
+                   [], 
+                   is_pure_virtual=True, visibility='private', is_virtual=True)
+    ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::DoReportDataFailed() [member function]
+    cls.add_method('DoReportDataFailed', 
+                   'void', 
+                   [], 
+                   is_pure_virtual=True, visibility='private', is_virtual=True)
+    ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::DoReportRtsOk(double ctsSnr, ns3::WifiMode ctsMode, double rtsSnr) [member function]
+    cls.add_method('DoReportRtsOk', 
+                   'void', 
+                   [param('double', 'ctsSnr'), param('ns3::WifiMode', 'ctsMode'), param('double', 'rtsSnr')], 
+                   is_pure_virtual=True, visibility='private', is_virtual=True)
+    ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::DoReportDataOk(double ackSnr, ns3::WifiMode ackMode, double dataSnr) [member function]
+    cls.add_method('DoReportDataOk', 
+                   'void', 
+                   [param('double', 'ackSnr'), param('ns3::WifiMode', 'ackMode'), param('double', 'dataSnr')], 
+                   is_pure_virtual=True, visibility='private', is_virtual=True)
+    ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::DoReportFinalRtsFailed() [member function]
+    cls.add_method('DoReportFinalRtsFailed', 
+                   'void', 
+                   [], 
+                   is_pure_virtual=True, visibility='private', is_virtual=True)
+    ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::DoReportFinalDataFailed() [member function]
+    cls.add_method('DoReportFinalDataFailed', 
+                   'void', 
+                   [], 
+                   is_pure_virtual=True, visibility='private', is_virtual=True)
+    ## wifi-remote-station-manager.h: void ns3::WifiRemoteStation::DoReportRxOk(double rxSnr, ns3::WifiMode txMode) [member function]
+    cls.add_method('DoReportRxOk', 
+                   'void', 
+                   [param('double', 'rxSnr'), param('ns3::WifiMode', 'txMode')], 
+                   is_pure_virtual=True, visibility='private', is_virtual=True)
     return
 
 def register_Ns3AmrrWifiRemoteStation_methods(root_module, cls):
--- a/doc/manual/routing.texi	Tue Apr 21 16:13:45 2009 +0400
+++ b/doc/manual/routing.texi	Tue Apr 21 16:22:45 2009 +0400
@@ -76,7 +76,7 @@
    * immediately after the IP header, although most routing do not
    * insert any extra header.
    */
-  virtual bool RequestRoute (uint32_t ifIndex,
+  virtual bool RequestRoute (uint32_t interface,
                              const Ipv4Header &ipHeader,
                              Ptr<Packet> packet,
                              RouteReplyCallback routeReply) = 0;
@@ -118,7 +118,7 @@
 The main function for obtaining a route is shown below:  
 @verbatim
 Ipv4L3Protocol::Lookup (
-  uint32_t ifIndex,
+  uint32_t interface,
   Ipv4Header const &ipHeader,
   Ptr<Packet> packet,
   Ipv4RoutingProtocol::RouteReplyCallback routeReply)
--- a/examples/global-routing-slash32.cc	Tue Apr 21 16:13:45 2009 +0400
+++ b/examples/global-routing-slash32.cc	Tue Apr 21 16:22:45 2009 +0400
@@ -87,13 +87,13 @@
   int32_t ifIndexA = ipv4A->AddInterface (deviceA);
   int32_t ifIndexC = ipv4C->AddInterface (deviceC);
     
-  ipv4A->SetAddress (ifIndexA, Ipv4Address ("172.16.1.1"));
-  ipv4A->SetNetworkMask (ifIndexA, Ipv4Mask ("255.255.255.255"));
+  Ipv4InterfaceAddress ifInAddrA = Ipv4InterfaceAddress (Ipv4Address ("172.16.1.1"), Ipv4Mask ("255.255.255.255"));
+  ipv4A->AddAddress (ifIndexA, ifInAddrA);
   ipv4A->SetMetric (ifIndexA, 1);
   ipv4A->SetUp (ifIndexA);
 
-  ipv4C->SetAddress (ifIndexC, Ipv4Address ("192.168.1.1"));
-  ipv4C->SetNetworkMask (ifIndexC, Ipv4Mask ("255.255.255.255"));
+  Ipv4InterfaceAddress ifInAddrC = Ipv4InterfaceAddress (Ipv4Address ("192.168.1.1"), Ipv4Mask ("255.255.255.255"));
+  ipv4C->AddAddress (ifIndexC, ifInAddrC);
   ipv4C->SetMetric (ifIndexC, 1);
   ipv4C->SetUp (ifIndexC);
  
@@ -105,7 +105,7 @@
   // 210 bytes at a rate of 448 Kb/s
   uint16_t port = 9;   // Discard port (RFC 863)
   OnOffHelper onoff ("ns3::UdpSocketFactory", 
-    Address (InetSocketAddress (Ipv4Address("192.168.1.1"), port)));
+    Address (InetSocketAddress (ifInAddrC.GetLocal(), port)));
   onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
   onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
   onoff.SetAttribute ("DataRate", DataRateValue (DataRate (6000)));
--- a/examples/mixed-wireless.cc	Tue Apr 21 16:13:45 2009 +0400
+++ b/examples/mixed-wireless.cc	Tue Apr 21 16:22:45 2009 +0400
@@ -353,7 +353,7 @@
   uint32_t lastNodeIndex = backboneNodes + backboneNodes*(lanNodes - 1) + backboneNodes*(infraNodes - 1) - 1;
   Ptr<Node> appSink = NodeList::GetNode (lastNodeIndex);  
   // Let's fetch the IP address of the last node, which is on Ipv4Interface 1
-  Ipv4Address remoteAddr = appSink->GetObject<Ipv4> ()->GetAddress(1);
+  Ipv4Address remoteAddr = appSink->GetObject<Ipv4> ()->GetAddress(1, 0).GetLocal ();
 
   OnOffHelper onoff ("ns3::UdpSocketFactory", 
                      Address (InetSocketAddress (remoteAddr, port)));
--- a/examples/static-routing-slash32.cc	Tue Apr 21 16:13:45 2009 +0400
+++ b/examples/static-routing-slash32.cc	Tue Apr 21 16:22:45 2009 +0400
@@ -87,13 +87,13 @@
   int32_t ifIndexA = ipv4A->AddInterface (deviceA);
   int32_t ifIndexC = ipv4C->AddInterface (deviceC);
     
-  ipv4A->SetAddress (ifIndexA, Ipv4Address ("172.16.1.1"));
-  ipv4A->SetNetworkMask (ifIndexA, Ipv4Mask ("255.255.255.255"));
+  Ipv4InterfaceAddress ifInAddrA = Ipv4InterfaceAddress (Ipv4Address ("172.16.1.1"), Ipv4Mask ("255.255.255.255"));
+  ipv4A->AddAddress (ifIndexA, ifInAddrA);
   ipv4A->SetMetric (ifIndexA, 1);
   ipv4A->SetUp (ifIndexA);
 
-  ipv4C->SetAddress (ifIndexC, Ipv4Address ("192.168.1.1"));
-  ipv4C->SetNetworkMask (ifIndexC, Ipv4Mask ("255.255.255.255"));
+  Ipv4InterfaceAddress ifInAddrC = Ipv4InterfaceAddress (Ipv4Address ("192.168.1.1"), Ipv4Mask ("255.255.255.255"));
+  ipv4C->AddAddress (ifIndexC, ifInAddrC);
   ipv4C->SetMetric (ifIndexC, 1);
   ipv4C->SetUp (ifIndexC);
  
@@ -107,7 +107,7 @@
   // 210 bytes at a rate of 448 Kb/s
   uint16_t port = 9;   // Discard port (RFC 863)
   OnOffHelper onoff ("ns3::UdpSocketFactory", 
-    Address (InetSocketAddress (Ipv4Address("192.168.1.1"), port)));
+    Address (InetSocketAddress (ifInAddrC.GetLocal (), port)));
   onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
   onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
   onoff.SetAttribute ("DataRate", DataRateValue (DataRate (6000)));
--- a/regression.py	Tue Apr 21 16:13:45 2009 +0400
+++ b/regression.py	Tue Apr 21 16:22:45 2009 +0400
@@ -159,7 +159,7 @@
             script = os.path.abspath(os.path.join('..', *os.path.split(program)))
             argv = [self.env['PYTHON'], script] + arguments
             try:
-                wutils.run_argv(argv, self.env, cwd=trace_output_path)
+                wutils.run_argv(argv, self.env, cwd=trace_output_path, force_no_valgrind=True)
             except Utils.WafError, ex:
                 print >> sys.stderr, ex
                 return 1
@@ -191,7 +191,7 @@
             script = os.path.abspath(os.path.join('..', *os.path.split(program)))
             argv = [self.env['PYTHON'], script] + arguments
             try:
-                retval = wutils.run_argv(argv, self.env, cwd=trace_output_path)
+                retval = wutils.run_argv(argv, self.env, cwd=trace_output_path, force_no_valgrind=True)
             except Utils.WafError, ex:
                 print >> sys.stderr, ex
                 return 1
--- a/src/contrib/wscript	Tue Apr 21 16:13:45 2009 +0400
+++ b/src/contrib/wscript	Tue Apr 21 16:22:45 2009 +0400
@@ -16,7 +16,7 @@
                                  "library 'libxml-2.0 >= 2.7' not found")
     conf.sub_config('stats')
 
-    conf.write_config_header('ns3/contrib-config.h')
+    conf.write_config_header('ns3/contrib-config.h', project_root_relative=True)
 
 def build(bld):
     module = bld.create_ns3_module('contrib', ['simulator', 'common'])
--- a/src/core/wscript	Tue Apr 21 16:13:45 2009 +0400
+++ b/src/core/wscript	Tue Apr 21 16:22:45 2009 +0400
@@ -41,7 +41,7 @@
                                  conf.env['ENABLE_THREADING'],
                                  "<pthread.h> include not detected")
 
-    conf.write_config_header('ns3/core-config.h')
+    conf.write_config_header('ns3/core-config.h', project_root_relative=True)
 
 def build(bld):
     core = bld.create_ns3_module('core')
--- a/src/devices/emu/emu-net-device.cc	Tue Apr 21 16:13:45 2009 +0400
+++ b/src/devices/emu/emu-net-device.cc	Tue Apr 21 16:22:45 2009 +0400
@@ -68,6 +68,11 @@
                    Mac48AddressValue (Mac48Address ("ff:ff:ff:ff:ff:ff")),
                    MakeMac48AddressAccessor (&EmuNetDevice::m_address),
                    MakeMac48AddressChecker ())
+    .AddAttribute ("DeviceName", 
+                   "The name of the underlying real device (e.g. eth1).",
+                   StringValue ("eth1"),
+                   MakeStringAccessor (&EmuNetDevice::m_deviceName),
+                   MakeStringChecker ())
     .AddAttribute ("Start", 
                    "The simulation time at which to spin up the device thread.",
                    TimeValue (Seconds (0.)),
--- a/src/devices/tap-bridge/tap-bridge.cc	Tue Apr 21 16:13:45 2009 +0400
+++ b/src/devices/tap-bridge/tap-bridge.cc	Tue Apr 21 16:22:45 2009 +0400
@@ -343,12 +343,16 @@
       Ptr<Node> n = nd->GetNode ();
       Ptr<Ipv4> ipv4 = n->GetObject<Ipv4> ();
       uint32_t index = ipv4->FindInterfaceForDevice (nd);
-      Ipv4Address ipv4Address = ipv4->GetAddress (index);
+      if (ipv4->GetNAddresses (index) > 1)
+        {
+          NS_LOG_WARN ("Underlying bridged NetDevice has multiple IP addresses; using first one.");
+        }
+      Ipv4Address ipv4Address = ipv4->GetAddress (index, 0).GetLocal ();
 
       //
       // The net mask is sitting right there next to the ipv4 address.
       //
-      Ipv4Mask ipv4Mask = ipv4->GetNetworkMask (index);
+      Ipv4Mask ipv4Mask = ipv4->GetAddress (index, 0).GetMask ();
 
       //
       // The MAC address should also already be assigned and waiting for us in
--- a/src/devices/tap-bridge/wscript	Tue Apr 21 16:13:45 2009 +0400
+++ b/src/devices/tap-bridge/wscript	Tue Apr 21 16:22:45 2009 +0400
@@ -27,7 +27,6 @@
         module.source.extend([
                 'tap-bridge.cc',
                 'tap-encode-decode.cc',
-                'tap-creator.cc',
                 ])
         headers.source.extend([
                 'tap-bridge.h',
--- a/src/helper/ipv4-address-helper.cc	Tue Apr 21 16:13:45 2009 +0400
+++ b/src/helper/ipv4-address-helper.cc	Tue Apr 21 16:22:45 2009 +0400
@@ -131,19 +131,19 @@
     Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
     NS_ASSERT_MSG (ipv4, "Ipv4AddressHelper::Allocate(): Bad ipv4");
 
-    int32_t ifIndex = ipv4->FindInterfaceForDevice (device);
-    if (ifIndex == -1)
+    int32_t interface = ipv4->FindInterfaceForDevice (device);
+    if (interface == -1)
       {
-        ifIndex = ipv4->AddInterface (device);
+        interface = ipv4->AddInterface (device);
       }
-    NS_ASSERT_MSG (ifIndex >= 0, "Ipv4AddressHelper::Allocate(): "
+    NS_ASSERT_MSG (interface >= 0, "Ipv4AddressHelper::Allocate(): "
       "Interface index not found");
 
-    ipv4->SetAddress (ifIndex, NewAddress ());
-    ipv4->SetNetworkMask (ifIndex, m_mask);
-    ipv4->SetMetric (ifIndex, 1);
-    ipv4->SetUp (ifIndex);
-    retval.Add (ipv4, ifIndex);
+    Ipv4InterfaceAddress ipv4Addr = Ipv4InterfaceAddress (NewAddress (), m_mask);
+    ipv4->AddAddress (interface, ipv4Addr);
+    ipv4->SetMetric (interface, 1);
+    ipv4->SetUp (interface);
+    retval.Add (ipv4, interface);
   }
   return retval;
 }
--- a/src/helper/ipv4-interface-container.cc	Tue Apr 21 16:13:45 2009 +0400
+++ b/src/helper/ipv4-interface-container.cc	Tue Apr 21 16:22:45 2009 +0400
@@ -23,12 +23,13 @@
 }
 
 Ipv4Address 
-Ipv4InterfaceContainer::GetAddress (uint32_t i) const
+Ipv4InterfaceContainer::GetAddress (uint32_t i, uint32_t j) const
 {
   Ptr<Ipv4> ipv4 = m_interfaces[i].first;
   uint32_t interface = m_interfaces[i].second;
-  return ipv4->GetAddress (interface);
+  return ipv4->GetAddress (interface, j).GetLocal ();
 }
+
 void 
 Ipv4InterfaceContainer::SetMetric (uint32_t i, uint16_t metric)
 {
--- a/src/helper/ipv4-interface-container.h	Tue Apr 21 16:13:45 2009 +0400
+++ b/src/helper/ipv4-interface-container.h	Tue Apr 21 16:22:45 2009 +0400
@@ -30,7 +30,16 @@
    */
   uint32_t GetN (void) const;
 
-  Ipv4Address GetAddress (uint32_t i) const;
+  /**
+   * \returns the IPv4 address of the j'th address of the interface
+   *  corresponding to index i.
+   * 
+   * If the second parameter is omitted, the zeroth indexed address of 
+   * the interface is returned.  Unless IP aliaising is being used on
+   * the interface, the second parameter may typically be omitted.
+   */
+  Ipv4Address GetAddress (uint32_t i, uint32_t j = 0) const;
+
   void SetMetric (uint32_t i, uint16_t metric);
 
   void Add (Ptr<Ipv4> ipv4, uint32_t interface);
--- a/src/helper/static-multicast-route-helper.cc	Tue Apr 21 16:13:45 2009 +0400
+++ b/src/helper/static-multicast-route-helper.cc	Tue Apr 21 16:22:45 2009 +0400
@@ -42,16 +42,16 @@
 {
   Ptr<Ipv4> ipv4 = n->GetObject<Ipv4> ();
 
-  // We need to convert the NetDeviceContainer to an array of ifIndex
+  // We need to convert the NetDeviceContainer to an array of interface
   std::vector<uint32_t> outputInterfaces;
   for (NetDeviceContainer::Iterator i = output.Begin (); i != output.End (); ++i)
     {
       Ptr<NetDevice> nd = *i;
-      uint32_t oifIndex = ipv4->FindInterfaceForDevice (nd);
-      outputInterfaces.push_back(oifIndex);
+      uint32_t ointerface = ipv4->FindInterfaceForDevice (nd);
+      outputInterfaces.push_back(ointerface);
     }
-  uint32_t iifIndex = ipv4->FindInterfaceForDevice (input);
-  ipv4->AddMulticastRoute (source, group, iifIndex, outputInterfaces);
+  uint32_t iinterface = ipv4->FindInterfaceForDevice (input);
+  ipv4->AddMulticastRoute (source, group, iinterface, outputInterfaces);
 }
 
 void  
@@ -97,8 +97,8 @@
   Ptr<NetDevice> nd)
 {
   Ptr<Ipv4> ipv4 = n->GetObject<Ipv4> ();
-  uint32_t ifIndexSrc = ipv4->FindInterfaceForDevice (nd);
-  ipv4->SetDefaultMulticastRoute (ifIndexSrc);
+  uint32_t interfaceSrc = ipv4->FindInterfaceForDevice (nd);
+  ipv4->SetDefaultMulticastRoute (interfaceSrc);
 }
 
 void
--- a/src/internet-stack/arp-ipv4-interface.cc	Tue Apr 21 16:13:45 2009 +0400
+++ b/src/internet-stack/arp-ipv4-interface.cc	Tue Apr 21 16:22:45 2009 +0400
@@ -106,7 +106,8 @@
   NS_LOG_FUNCTION (this << p << dest);
 
   NS_ASSERT (GetDevice () != 0);
-  if (dest == GetAddress ())
+  // XXX multi-address case
+  if (dest == GetAddress (0).GetLocal ())
     {
       Ptr<Ipv4L3Protocol> ipv4 = m_node->GetObject<Ipv4L3Protocol> ();
         
@@ -124,9 +125,9 @@
         m_node->GetObject<ArpL3Protocol> ();
       Address hardwareDestination;
       bool found;
-      
+      // XXX multi-address case
       if (dest.IsBroadcast () || 
-          dest.IsSubnetDirectedBroadcast (GetNetworkMask ()) )
+          dest.IsSubnetDirectedBroadcast (GetAddress (0).GetMask ()) )
         {
           NS_LOG_LOGIC ("IsBroadcast");
           hardwareDestination = GetDevice ()->GetBroadcast ();
--- a/src/internet-stack/arp-l3-protocol.cc	Tue Apr 21 16:13:45 2009 +0400
+++ b/src/internet-stack/arp-l3-protocol.cc	Tue Apr 21 16:22:45 2009 +0400
@@ -142,28 +142,29 @@
       NS_LOG_LOGIC ("ARP: Cannot remove ARP header");
       return;
     }
-  
+  // XXX multi-address case  
   NS_LOG_LOGIC ("ARP: received "<< (arp.IsRequest ()? "request" : "reply") <<
             " node="<<m_node->GetId ()<<", got request from " <<
             arp.GetSourceIpv4Address () << " for address " <<
             arp.GetDestinationIpv4Address () << "; we have address " <<
-            cache->GetInterface ()->GetAddress ());
+            cache->GetInterface ()->GetAddress (0).GetLocal ());
 
   /**
    * Note: we do not update the ARP cache when we receive an ARP request
    * from an unknown node. See bug #107
    */
-
+  // XXX multi-address case
   if (arp.IsRequest () && 
-      arp.GetDestinationIpv4Address () == cache->GetInterface ()->GetAddress ()) 
+      arp.GetDestinationIpv4Address () == cache->GetInterface ()->GetAddress (0).GetLocal ()) 
     {
       NS_LOG_LOGIC ("node="<<m_node->GetId () <<", got request from " << 
                 arp.GetSourceIpv4Address () << " -- send reply");
       SendArpReply (cache, arp.GetSourceIpv4Address (),
                     arp.GetSourceHardwareAddress ());
     } 
+  // XXX multi-address case
   else if (arp.IsReply () &&
-           arp.GetDestinationIpv4Address ().IsEqual (cache->GetInterface ()->GetAddress ()) &&
+           arp.GetDestinationIpv4Address ().IsEqual (cache->GetInterface ()->GetAddress (0).GetLocal ()) &&
            arp.GetDestinationHardwareAddress () == device->GetAddress ()) 
     {
       Ipv4Address from = arp.GetSourceIpv4Address ();
@@ -284,11 +285,12 @@
   ArpHeader arp;
   NS_LOG_LOGIC ("ARP: sending request from node "<<m_node->GetId ()<<
             " || src: " << cache->GetDevice ()->GetAddress () <<
-            " / " << cache->GetInterface ()->GetAddress () <<
+            " / " << cache->GetInterface ()->GetAddress (0).GetLocal () <<
             " || dst: " << cache->GetDevice ()->GetBroadcast () <<
             " / " << to);
+  // XXX multi-address case
   arp.SetRequest (cache->GetDevice ()->GetAddress (),
-		  cache->GetInterface ()->GetAddress (), 
+		  cache->GetInterface ()->GetAddress (0).GetLocal (), 
                   cache->GetDevice ()->GetBroadcast (),
                   to);
   Ptr<Packet> packet = Create<Packet> ();
@@ -303,10 +305,11 @@
   ArpHeader arp;
   NS_LOG_LOGIC ("ARP: sending reply from node "<<m_node->GetId ()<<
             "|| src: " << cache->GetDevice ()->GetAddress () << 
-            " / " << cache->GetInterface ()->GetAddress () <<
+            " / " << cache->GetInterface ()->GetAddress (0).GetLocal () <<
             " || dst: " << toMac << " / " << toIp);
+  // XXX multi-address case
   arp.SetReply (cache->GetDevice ()->GetAddress (),
-                cache->GetInterface ()->GetAddress (),
+                cache->GetInterface ()->GetAddress (0).GetLocal (),
                 toMac, toIp);
   Ptr<Packet> packet = Create<Packet> ();
   packet->AddHeader (arp);
--- a/src/internet-stack/icmpv4-l4-protocol.cc	Tue Apr 21 16:13:45 2009 +0400
+++ b/src/internet-stack/icmpv4-l4-protocol.cc	Tue Apr 21 16:22:45 2009 +0400
@@ -63,12 +63,13 @@
 {
   Ptr<Ipv4L3Protocol> ipv4 = m_node->GetObject<Ipv4L3Protocol> ();
   uint32_t i;
-  if (!ipv4->GetIfIndexForDestination (dest, i))
+  if (!ipv4->GetInterfaceForDestination (dest, i))
     {
       NS_LOG_WARN ("drop icmp message");
       return;
     }
-  Ipv4Address source = ipv4->GetAddress (i);
+  // XXX handle multi-address case
+  Ipv4Address source = ipv4->GetAddress (i, 0).GetLocal ();
   SendMessage (packet, source, dest, type, code);
 }
 
--- a/src/internet-stack/internet-stack.cc	Tue Apr 21 16:13:45 2009 +0400
+++ b/src/internet-stack/internet-stack.cc	Tue Apr 21 16:22:45 2009 +0400
@@ -29,7 +29,6 @@
 #include "arp-l3-protocol.h"
 #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
@@ -94,9 +93,6 @@
   Ptr<Ipv4L3Protocol> ipv4 = CreateObject<Ipv4L3Protocol> ();
   ipv4->SetNode (node);
   node->AggregateObject (ipv4);
-  Ptr<Ipv4Impl> ipv4Impl = CreateObject<Ipv4Impl> ();
-  ipv4Impl->SetIpv4 (ipv4);
-  node->AggregateObject (ipv4Impl);
 }
 
 void
--- a/src/internet-stack/ipv4-end-point-demux.cc	Tue Apr 21 16:13:45 2009 +0400
+++ b/src/internet-stack/ipv4-end-point-demux.cc	Tue Apr 21 16:22:45 2009 +0400
@@ -219,10 +219,11 @@
                         << " does not match packet dport " << dport);
           continue;
         }
+      // XXX handle multi-address case
       bool isBroadcast = (daddr.IsBroadcast () ||
          daddr.IsSubnetDirectedBroadcast (
-             incomingInterface->GetNetworkMask ()));
-      Ipv4Address incomingInterfaceAddr = incomingInterface->GetAddress ();
+             incomingInterface->GetAddress (0).GetMask ()));
+      Ipv4Address incomingInterfaceAddr = incomingInterface->GetAddress (0).GetLocal ();
       NS_LOG_DEBUG ("dest addr " << daddr << " broadcast? " << isBroadcast);
       bool localAddressMatchesWildCard = 
         endP->GetLocalAddress() == Ipv4Address::GetAny();
--- a/src/internet-stack/ipv4-global-routing.cc	Tue Apr 21 16:13:45 2009 +0400
+++ b/src/internet-stack/ipv4-global-routing.cc	Tue Apr 21 16:22:45 2009 +0400
@@ -209,12 +209,12 @@
 
 bool
 Ipv4GlobalRouting::RequestRoute (
-  uint32_t ifIndex,
+  uint32_t interface,
   Ipv4Header const &ipHeader,
   Ptr<Packet> packet,
   RouteReplyCallback routeReply)
 {
-  NS_LOG_FUNCTION (this << ifIndex << &ipHeader << packet << &routeReply);
+  NS_LOG_FUNCTION (this << interface << &ipHeader << packet << &routeReply);
 
   NS_LOG_LOGIC ("source = " << ipHeader.GetSource ());
 
@@ -243,9 +243,9 @@
 }
 
 bool
-Ipv4GlobalRouting::RequestIfIndex (Ipv4Address destination, uint32_t& ifIndex)
+Ipv4GlobalRouting::RequestInterface (Ipv4Address destination, uint32_t& interface)
 {
-  NS_LOG_FUNCTION (this << destination << &ifIndex);
+  NS_LOG_FUNCTION (this << destination << &interface);
 //
 // First, see if this is a multicast packet we have a route for.  If we
 // have a route, then send the packet down each of the specified interfaces.
@@ -262,7 +262,7 @@
   Ipv4Route *route = LookupGlobal (destination);
   if (route)
     {
-      ifIndex = route->GetInterface ();
+      interface = route->GetInterface ();
       return true;
     }
   else
--- a/src/internet-stack/ipv4-global-routing.h	Tue Apr 21 16:13:45 2009 +0400
+++ b/src/internet-stack/ipv4-global-routing.h	Tue Apr 21 16:22:45 2009 +0400
@@ -92,9 +92,9 @@
  * If the destination address is a multicast, then the method will return
  * false.
  *
- * @param ifIndex The network interface index over which the packed was 
- * received.  If the packet is from a local source, ifIndex will be set to
- * Ipv4RoutingProtocol::IF_INDEX_ANY.
+ * @param interface The network interface index over which the packed was 
+ * received.  If the packet is from a local source, interface will be set to
+ * Ipv4RoutingProtocol::INTERFACE_INDEX_ANY.
  * @param ipHeader the Ipv4Header containing the source and destination IP
  * addresses for the packet.
  * @param packet The packet to be sent if a route is found.
@@ -107,7 +107,7 @@
  * @see Ipv4GlobalRouting
  * @see Ipv4RoutingProtocol
  */
-  virtual bool RequestRoute (uint32_t ifIndex,
+  virtual bool RequestRoute (uint32_t interface,
                              Ipv4Header const &ipHeader,
                              Ptr<Packet> packet,
                              RouteReplyCallback routeReply);
@@ -126,14 +126,14 @@
  * given destination.
  *
  * If there are multiple paths out of the node, the resolution is performed
- * by Ipv4L3Protocol::GetIfIndexforDestination which has access to more 
+ * by Ipv4L3Protocol::GetInterfaceforDestination which has access to more 
  * contextual information that is useful for making a determination.
  *
  * This method will return false on a multicast address.
  *
  * @param destination The Ipv4Address if the destination of a hypothetical 
  * packet.  This may be a multicast group address.
- * @param ifIndex A reference to the interface index over which a packet
+ * @param interface A reference to the interface index over which a packet
  * sent to this destination would be sent.
  * @return Returns true if a route is found to the destination that involves
  * a single output interface index, otherwise returns false indicating that
@@ -143,7 +143,7 @@
  * @see Ipv4RoutingProtocol
  * @see Ipv4L3Protocol
  */
-  virtual bool RequestIfIndex (Ipv4Address destination, uint32_t& ifIndex);
+  virtual bool RequestInterface (Ipv4Address destination, uint32_t& interface);
 
 /**
  * @brief Add a host route to the global routing table.
--- a/src/internet-stack/ipv4-impl.cc	Tue Apr 21 16:13:45 2009 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,273 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#include "ipv4-impl.h"
-#include "ipv4-l3-protocol.h"
-#include "ipv4-interface.h"
-#include "ns3/assert.h"
-#include "ns3/net-device.h"
-
-namespace ns3 {
-
-Ipv4Impl::Ipv4Impl ()
-  : m_ipv4 (0)
-{}
-Ipv4Impl::~Ipv4Impl ()
-{
-  NS_ASSERT (m_ipv4 == 0);
-}
-void 
-Ipv4Impl::SetIpv4 (Ptr<Ipv4L3Protocol> ipv4)
-{
-  m_ipv4 = ipv4;
-}
-void 
-Ipv4Impl::DoDispose (void)
-{
-  m_ipv4 = 0;
-}
-
-void
-Ipv4Impl::AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
-                              int16_t priority)
-{
-  m_ipv4->AddRoutingProtocol (routingProtocol, priority);
-}
-
-void 
-Ipv4Impl::AddHostRouteTo (Ipv4Address dest, 
-			   Ipv4Address nextHop, 
-			   uint32_t interface)
-{
-  m_ipv4->AddHostRouteTo (dest, nextHop, interface);
-}
-void 
-Ipv4Impl::AddHostRouteTo (Ipv4Address dest, 
-			   uint32_t interface)
-{
-  m_ipv4->AddHostRouteTo (dest, interface);
-}
-void 
-Ipv4Impl::AddNetworkRouteTo (Ipv4Address network, 
-			      Ipv4Mask networkMask, 
-			      Ipv4Address nextHop, 
-			      uint32_t interface)
-{
-  m_ipv4->AddNetworkRouteTo (network, networkMask, nextHop, interface);
-}
-void 
-Ipv4Impl::AddNetworkRouteTo (Ipv4Address network, 
-			      Ipv4Mask networkMask, 
-			      uint32_t interface)
-{
-  m_ipv4->AddNetworkRouteTo (network, networkMask, interface);
-}
-void 
-Ipv4Impl::SetDefaultRoute (Ipv4Address nextHop, 
-			    uint32_t interface)
-{
-  m_ipv4->SetDefaultRoute (nextHop, interface);
-}
-uint32_t 
-Ipv4Impl::GetNRoutes (void)
-{
-  return m_ipv4->GetNRoutes ();
-}
-Ipv4Route 
-Ipv4Impl::GetRoute (uint32_t i)
-{
-  return *m_ipv4->GetRoute (i);
-}
-void 
-Ipv4Impl::RemoveRoute (uint32_t i)
-{
-  return m_ipv4->RemoveRoute (i);
-}
-
-void
-Ipv4Impl::AddMulticastRoute (Ipv4Address origin,
-                             Ipv4Address group,
-                             uint32_t inputInterface,
-                             std::vector<uint32_t> outputInterfaces)
-{
-  m_ipv4->AddMulticastRoute (origin, group, inputInterface, outputInterfaces);
-}
-
-void
-Ipv4Impl::SetDefaultMulticastRoute (uint32_t outputInterface)
-{
-  m_ipv4->SetDefaultMulticastRoute (outputInterface);
-}
-
-uint32_t 
-Ipv4Impl::GetNMulticastRoutes (void) const
-{
-  return m_ipv4->GetNMulticastRoutes ();
-}
-
-Ipv4MulticastRoute 
-Ipv4Impl::GetMulticastRoute (uint32_t i) const
-{
-  return *m_ipv4->GetMulticastRoute (i);
-}
-
-void
-Ipv4Impl::RemoveMulticastRoute (Ipv4Address origin,
-                                Ipv4Address group,
-                                uint32_t inputInterface)
-{
-  m_ipv4->RemoveMulticastRoute (origin, group, inputInterface);
-}
-
-void 
-Ipv4Impl::RemoveMulticastRoute (uint32_t i)
-{
-  return m_ipv4->RemoveMulticastRoute (i);
-}
-
-uint32_t 
-Ipv4Impl::AddInterface (Ptr<NetDevice> device)
-{
-  return m_ipv4->AddInterface (device);
-}
-
-uint32_t 
-Ipv4Impl::GetNInterfaces (void)
-{
-  return m_ipv4->GetNInterfaces ();
-}
-
-uint32_t 
-Ipv4Impl::FindInterfaceForAddr (Ipv4Address addr) const
-{
-  return m_ipv4->FindInterfaceForAddr (addr);
-}
-
-uint32_t 
-Ipv4Impl::FindInterfaceForAddr (Ipv4Address addr, Ipv4Mask mask) const
-{
-  return m_ipv4->FindInterfaceForAddr (addr, mask);
-}
-
-int32_t 
-Ipv4Impl::FindInterfaceForDevice (Ptr<NetDevice> device) const
-{
-  return m_ipv4->FindInterfaceIndexForDevice (device);
-}
-
-Ptr<NetDevice>
-Ipv4Impl::GetNetDevice (uint32_t i)
-{
-  return m_ipv4->GetInterface (i)-> GetDevice ();
-}
-
-void 
-Ipv4Impl::JoinMulticastGroup (Ipv4Address origin, Ipv4Address group)
-{
-  m_ipv4->JoinMulticastGroup(origin, group);
-}
-
-void
-Ipv4Impl::LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group)
-{
-  m_ipv4->LeaveMulticastGroup(origin, group);
-}
-
-void 
-Ipv4Impl::SetAddress (uint32_t i, Ipv4Address address)
-{
-  m_ipv4->SetAddress (i, address);
-}
-void 
-Ipv4Impl::SetNetworkMask (uint32_t i, Ipv4Mask mask)
-{
-  m_ipv4->SetNetworkMask (i, mask);
-}
-Ipv4Mask 
-Ipv4Impl::GetNetworkMask (uint32_t i) const
-{
-  return m_ipv4->GetNetworkMask (i);
-}
-
-Ipv4Address 
-Ipv4Impl::GetAddress (uint32_t i) const
-{
-  return m_ipv4->GetAddress (i);
-}
-
-void
-Ipv4Impl::SetMetric (uint32_t i, uint16_t metric) 
-{
-  m_ipv4->SetMetric (i, metric);
-}
-
-uint16_t
-Ipv4Impl::GetMetric (uint32_t i) const
-{
-  return m_ipv4->GetMetric (i);
-}
-
-bool
-Ipv4Impl::GetIfIndexForDestination (Ipv4Address dest, uint32_t &ifIndex) const
-{
-  return m_ipv4->GetIfIndexForDestination (dest, ifIndex);
-}
-
-Ipv4Address 
-Ipv4Impl::GetSourceAddress (Ipv4Address destination) const
-{
-  uint32_t ifIndex = 0xffffffff;
-
-  bool result = m_ipv4->GetIfIndexForDestination (destination, ifIndex);
-
-  if (result)
-    {
-      return m_ipv4->GetAddress (ifIndex);
-    }
-  else
-    {
-//
-// If we can't find any address, just leave it 0.0.0.0
-//
-      return Ipv4Address::GetAny ();
-    }
-}
-
-uint16_t 
-Ipv4Impl::GetMtu (uint32_t i) const
-{
-  return m_ipv4->GetMtu (i);
-}
-bool 
-Ipv4Impl::IsUp (uint32_t i) const
-{
-  return m_ipv4->IsUp (i);
-}
-void 
-Ipv4Impl::SetUp (uint32_t i)
-{
-  m_ipv4->SetUp (i);
-}
-void 
-Ipv4Impl::SetDown (uint32_t i)
-{
-  m_ipv4->SetDown (i);
-}
-
-}//namespace ns3
--- a/src/internet-stack/ipv4-impl.h	Tue Apr 21 16:13:45 2009 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,112 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef IPV4_IMPL_H
-#define IPV4_IMPL_H
-
-#include "ns3/ipv4.h"
-#include "ns3/ptr.h"
-
-namespace ns3 {
-
-class Ipv4L3Protocol;
-
-class Ipv4Impl : public Ipv4
-{
-public:
-  Ipv4Impl ();
-
-  virtual ~Ipv4Impl ();
-
-  void SetIpv4 (Ptr<Ipv4L3Protocol> ipv4);
-
-  virtual void AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
-                                   int16_t priority);
-
-  virtual void AddHostRouteTo (Ipv4Address dest, 
-			       Ipv4Address nextHop, 
-			       uint32_t interface);
-  virtual void AddHostRouteTo (Ipv4Address dest, 
-			       uint32_t interface);
-  virtual void AddNetworkRouteTo (Ipv4Address network, 
-				  Ipv4Mask networkMask, 
-				  Ipv4Address nextHop, 
-				  uint32_t interface);
-  virtual void AddNetworkRouteTo (Ipv4Address network, 
-				  Ipv4Mask networkMask, 
-				  uint32_t interface);
-  virtual void SetDefaultRoute (Ipv4Address nextHop, 
-				uint32_t interface);
-  virtual uint32_t GetNRoutes (void);
-  virtual Ipv4Route GetRoute (uint32_t i);
-  virtual void RemoveRoute (uint32_t i);
-
-
-  virtual void AddMulticastRoute (Ipv4Address origin,
-                                  Ipv4Address group,
-                                  uint32_t inputInterface,
-                                  std::vector<uint32_t> outputInterfaces);
-
-  virtual void SetDefaultMulticastRoute (uint32_t outputInterface);
-
-  virtual uint32_t GetNMulticastRoutes (void) const;
-  virtual Ipv4MulticastRoute GetMulticastRoute (uint32_t i) const;
-
-  virtual void RemoveMulticastRoute (Ipv4Address origin,
-                                     Ipv4Address group,
-                                     uint32_t inputInterface);
-  virtual void RemoveMulticastRoute (uint32_t i);
-
-  virtual uint32_t AddInterface (Ptr<NetDevice> device);
-  virtual uint32_t GetNInterfaces (void);  
-
-  virtual uint32_t FindInterfaceForAddr (Ipv4Address addr) const;
-  virtual uint32_t FindInterfaceForAddr (Ipv4Address addr, 
-    Ipv4Mask mask) const;
-
-  virtual int32_t FindInterfaceForDevice (Ptr<NetDevice> device) const;
-
-  virtual Ptr<NetDevice> GetNetDevice(uint32_t i);
-
-  virtual void JoinMulticastGroup (Ipv4Address origin, Ipv4Address group);
-  virtual void LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group);
-
-  virtual void SetAddress (uint32_t i, Ipv4Address address);
-  virtual void SetNetworkMask (uint32_t i, Ipv4Mask mask);
-  virtual Ipv4Mask GetNetworkMask (uint32_t t) const;
-  virtual Ipv4Address GetAddress (uint32_t i) const;
-  virtual void SetMetric (uint32_t i, uint16_t metric);
-  virtual uint16_t GetMetric (uint32_t i) const;
-  virtual Ipv4Address GetSourceAddress (Ipv4Address destination) const;
-  virtual bool GetIfIndexForDestination (Ipv4Address dest, 
-    uint32_t &ifIndex) const;
-
-  virtual uint16_t GetMtu (uint32_t i) const;
-  virtual bool IsUp (uint32_t i) const;
-  virtual void SetUp (uint32_t i);
-  virtual void SetDown (uint32_t i);
-protected:
-  virtual void DoDispose (void);
-private:
-  Ptr<Ipv4L3Protocol> m_ipv4;
-};
-
-} // namespace ns3
-
-#endif /* IPV4_IMPL_H */
--- a/src/internet-stack/ipv4-interface.cc	Tue Apr 21 16:13:45 2009 +0400
+++ b/src/internet-stack/ipv4-interface.cc	Tue Apr 21 16:22:45 2009 +0400
@@ -62,37 +62,6 @@
   Object::DoDispose ();
 }
 
-void 
-Ipv4Interface::SetAddress (Ipv4Address a)
-{
-  NS_LOG_FUNCTION (this << a);
-  m_address = a;
-}
-
-void 
-Ipv4Interface::SetNetworkMask (Ipv4Mask mask)
-{
-  NS_LOG_FUNCTION (this << mask);
-  m_netmask = mask;
-}
-
-Ipv4Address
-Ipv4Interface::GetBroadcast (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  uint32_t mask = m_netmask.Get ();
-  uint32_t address = m_address.Get ();
-  Ipv4Address broadcast = Ipv4Address (address | (~mask));
-  return broadcast;
-}
-
-Ipv4Mask 
-Ipv4Interface::GetNetworkMask (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_netmask;
-}
-
 void
 Ipv4Interface::SetMetric (uint16_t metric)
 {
@@ -107,13 +76,6 @@
   return m_metric;
 }
 
-Ipv4Address 
-Ipv4Interface::GetAddress (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_address;
-}
-
 uint16_t 
 Ipv4Interface::GetMtu (void) const
 {
@@ -170,5 +132,64 @@
   }
 }
 
+uint32_t
+Ipv4Interface::GetNAddresses (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_ifaddrs.size();
+}
+
+uint32_t
+Ipv4Interface::AddAddress (Ipv4InterfaceAddress addr)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  uint32_t index = m_ifaddrs.size ();
+  m_ifaddrs.push_back (addr);
+  return index;
+}
+
+Ipv4InterfaceAddress
+Ipv4Interface::GetAddress (uint32_t index) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  if (index < m_ifaddrs.size ())
+    {
+      uint32_t tmp = 0;
+      for (Ipv4InterfaceAddressListCI i = m_ifaddrs.begin (); i!= m_ifaddrs.end (); i++)
+        {
+          if (tmp  == index)
+            {
+              return *i;
+            }
+          ++tmp;
+        }
+    }
+  NS_ASSERT (false);  // Assert if not found
+  Ipv4InterfaceAddress addr;
+  return (addr);  // quiet compiler
+}
+
+void
+Ipv4Interface::RemoveAddress (uint32_t index)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  if (index >= m_ifaddrs.size ())
+    {
+      NS_ASSERT_MSG (false, "Bug in Ipv4Interface::RemoveAddress");
+    }
+  Ipv4InterfaceAddressListI i = m_ifaddrs.begin ();
+  uint32_t tmp = 0;
+  while (i != m_ifaddrs.end ())
+    {
+      if (tmp  == index)
+        {
+          m_ifaddrs.erase (i);
+          return;
+        }
+       ++tmp;
+    }
+  NS_ASSERT_MSG (false, "Address " << index << " not found");
+}
+
 }; // namespace ns3
 
--- a/src/internet-stack/ipv4-interface.h	Tue Apr 21 16:13:45 2009 +0400
+++ b/src/internet-stack/ipv4-interface.h	Tue Apr 21 16:22:45 2009 +0400
@@ -24,6 +24,7 @@
 
 #include <list>
 #include "ns3/ipv4-address.h"
+#include "ns3/ipv4-interface-address.h"
 #include "ns3/ptr.h"
 #include "ns3/object.h"
 
@@ -75,23 +76,6 @@
   virtual Ptr<NetDevice> GetDevice (void) const = 0;
 
   /**
-   * \param a set the ipv4 address of this interface.
-   */
-  void SetAddress (Ipv4Address a);
-  /**
-   * \param mask set the ipv4 netmask of this interface.
-   */
-  void SetNetworkMask (Ipv4Mask mask);
-
-  /**
-   * \returns the broadcast ipv4 address associated to this interface
-   */
-  Ipv4Address GetBroadcast (void) const;
-  /**
-   * \returns the ipv4 netmask of this interface
-   */
-  Ipv4Mask GetNetworkMask (void) const;
-  /**
    * \param metric configured routing metric (cost) of this interface
    */
   void SetMetric (uint16_t metric);
@@ -99,10 +83,6 @@
    * \returns configured routing metric (cost) of this interface
    */
   uint16_t GetMetric (void) const;
-  /**
-   * \returns the ipv4 address of this interface
-   */
-  Ipv4Address GetAddress (void) const;
 
   /**
    * This function a pass-through to NetDevice GetMtu, modulo
@@ -142,14 +122,39 @@
    */ 
   void Send(Ptr<Packet> p, Ipv4Address dest);
 
+  /**
+   * \param address The Ipv4InterfaceAddress to add to the interface
+   * \returns The index of the newly-added Ipv4InterfaceAddress
+   */
+  uint32_t AddAddress (Ipv4InterfaceAddress address);
+
+  /**
+   * \param i Index of Ipv4InterfaceAddress to return
+   * \returns The Ipv4InterfaceAddress address whose index is i
+   */
+  Ipv4InterfaceAddress GetAddress (uint32_t index) const;
+
+  /**
+   * \returns the number of Ipv4InterfaceAddresss stored on this interface
+   */
+  uint32_t GetNAddresses (void) const;
+
+  /**
+   * \param i index of Ipv4InterfaceAddress to remove from address list.
+   */
+  void RemoveAddress (uint32_t index);
+
 protected:
   virtual void DoDispose (void);
 private:
   virtual void SendTo (Ptr<Packet> p, Ipv4Address dest) = 0;
   bool m_ifup;
-  Ipv4Address m_address;
-  Ipv4Mask m_netmask;
   uint16_t m_metric;
+
+  typedef std::list<Ipv4InterfaceAddress> Ipv4InterfaceAddressList;
+  typedef std::list<Ipv4InterfaceAddress>::const_iterator Ipv4InterfaceAddressListCI;
+  typedef std::list<Ipv4InterfaceAddress>::iterator Ipv4InterfaceAddressListI;
+  Ipv4InterfaceAddressList m_ifaddrs;
 };
 
 }; // namespace ns3
--- a/src/internet-stack/ipv4-l3-protocol.cc	Tue Apr 21 16:13:45 2009 +0400
+++ b/src/internet-stack/ipv4-l3-protocol.cc	Tue Apr 21 16:22:45 2009 +0400
@@ -53,7 +53,7 @@
 Ipv4L3Protocol::GetTypeId (void)
 {
   static TypeId tid = TypeId ("ns3::Ipv4L3Protocol")
-    .SetParent<Object> ()
+    .SetParent<Ipv4> ()
     .AddConstructor<Ipv4L3Protocol> ()
     .AddAttribute ("DefaultTtl", "The TTL value set by default on all outgoing packets generated on this node.",
                    UintegerValue (64),
@@ -181,8 +181,8 @@
 
   Ptr<Ipv4LoopbackInterface> interface = CreateObject<Ipv4LoopbackInterface> ();
   interface->SetNode (m_node);
-  interface->SetAddress (Ipv4Address::GetLoopback ());
-  interface->SetNetworkMask (Ipv4Mask::GetLoopback ());
+  Ipv4InterfaceAddress ifaceAddr = Ipv4InterfaceAddress (Ipv4Address::GetLoopback (), Ipv4Mask::GetLoopback ());
+  interface->AddAddress (ifaceAddr);
   uint32_t index = AddIpv4Interface (interface);
   AddHostRouteTo (Ipv4Address::GetLoopback (), index);
   interface->SetUp ();
@@ -248,17 +248,17 @@
 {
   NS_LOG_FUNCTION (this << &ipHeader << packet << &routeReply);
 
-  Lookup (Ipv4RoutingProtocol::IF_INDEX_ANY, ipHeader, packet, routeReply);
+  Lookup (Ipv4RoutingProtocol::INTERFACE_ANY, ipHeader, packet, routeReply);
 }
 
 void
 Ipv4L3Protocol::Lookup (
-  uint32_t ifIndex,
+  uint32_t interface,
   Ipv4Header const &ipHeader,
   Ptr<Packet> packet,
   Ipv4RoutingProtocol::RouteReplyCallback routeReply)
 {
-  NS_LOG_FUNCTION (this << ifIndex << &ipHeader << packet << &routeReply);
+  NS_LOG_FUNCTION (this << interface << &ipHeader << packet << &routeReply);
 
   for (Ipv4RoutingProtocolList::const_iterator rprotoIter = 
          m_routingProtocols.begin ();
@@ -266,13 +266,13 @@
        rprotoIter++)
     {
       NS_LOG_LOGIC ("Requesting route");
-      if ((*rprotoIter).second->RequestRoute (ifIndex, ipHeader, packet, 
+      if ((*rprotoIter).second->RequestRoute (interface, ipHeader, packet, 
                                               routeReply))
         return;
     }
 
   if (ipHeader.GetDestination ().IsMulticast () && 
-      ifIndex == Ipv4RoutingProtocol::IF_INDEX_ANY)
+      interface == Ipv4RoutingProtocol::INTERFACE_ANY)
     {
       NS_LOG_LOGIC ("Multicast destination with local source");
 //
@@ -304,7 +304,7 @@
 
 void
 Ipv4L3Protocol::AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
-                                    int priority)
+                                    int16_t priority)
 {
   NS_LOG_FUNCTION (this << &routingProtocol << priority);
   m_routingProtocols.push_back
@@ -319,11 +319,11 @@
   return m_staticRouting->GetNRoutes ();
 }
 
-Ipv4Route *
+Ipv4Route 
 Ipv4L3Protocol::GetRoute (uint32_t index)
 {
   NS_LOG_FUNCTION_NOARGS ();
-  return m_staticRouting->GetRoute (index);
+  return *m_staticRouting->GetRoute (index);
 }
 
 void 
@@ -360,11 +360,11 @@
   return m_staticRouting->GetNMulticastRoutes ();
 }
 
-Ipv4MulticastRoute *
+Ipv4MulticastRoute 
 Ipv4L3Protocol::GetMulticastRoute (uint32_t index) const
 {
   NS_LOG_FUNCTION (this << index);
-  return m_staticRouting->GetMulticastRoute (index);
+  return *m_staticRouting->GetMulticastRoute (index);
 }
 
 void 
@@ -438,14 +438,17 @@
 {
   NS_LOG_FUNCTION (this << addr);
 
-  uint32_t ifIndex = 0;
+  uint32_t interface = 0;
   for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); 
        i != m_interfaces.end (); 
-       i++, ifIndex++)
+       i++, interface++)
     {
-      if ((*i)->GetAddress () == addr)
+      for (uint32_t j = 0; j < (*i)->GetNAddresses (); j++) 
         {
-          return ifIndex;
+          if ((*i)->GetAddress (j).GetLocal () == addr)
+            {
+              return interface;
+            }
         }
     }
 
@@ -459,14 +462,17 @@
 {
   NS_LOG_FUNCTION (this << addr << mask);
 
-  uint32_t ifIndex = 0;
+  uint32_t interface = 0;
   for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); 
        i != m_interfaces.end (); 
-       i++, ifIndex++)
+       i++, interface++)
     {
-      if ((*i)->GetAddress ().CombineMask (mask) == addr.CombineMask (mask))
+      for (uint32_t j = 0; j < (*i)->GetNAddresses (); j++)
         {
-          return ifIndex;
+          if ((*i)->GetAddress (j).GetLocal ().CombineMask (mask) == addr.CombineMask (mask))
+            {
+              return interface;
+            }
         }
     }
 
@@ -476,18 +482,18 @@
 }
 
 int32_t 
-Ipv4L3Protocol::FindInterfaceIndexForDevice (Ptr<NetDevice> device) const
+Ipv4L3Protocol::FindInterfaceForDevice (Ptr<NetDevice> device) const
 {
   NS_LOG_FUNCTION (this << device);
 
-  uint32_t ifIndex = 0;
+  uint32_t interface = 0;
   for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); 
        i != m_interfaces.end (); 
-       i++, ifIndex++)
+       i++, interface++)
     {
       if ((*i)->GetDevice () == device)
         {
-          return ifIndex;
+          return interface;
         }
     }
 
@@ -647,11 +653,15 @@
            ifaceIter != m_interfaces.end (); ifaceIter++, ifaceIndex++)
         {
           Ptr<Ipv4Interface> outInterface = *ifaceIter;
-          if (destination.IsSubnetDirectedBroadcast (
-                outInterface->GetNetworkMask ()))
-          {
-            ipHeader.SetTtl (1);
-          }
+          // XXX this logic might not be completely correct for multi-addressed interface
+          for (uint32_t j = 0; j < outInterface->GetNAddresses(); j++)
+            {
+              if (destination.IsSubnetDirectedBroadcast (
+                outInterface->GetAddress (j).GetMask ()))
+                {
+                  ipHeader.SetTtl (1);
+                }
+            }
         }
     }
   if (destination.IsBroadcast ())
@@ -664,9 +674,10 @@
           Ptr<Packet> packetCopy = packet->Copy ();
 
           packetCopy->AddHeader (ipHeader);
+          // XXX Handle multiple address on interface
           if (packetCopy->GetSize () > outInterface->GetMtu () &&
               ipHeader.IsDontFragment () &&
-              IsUnicast (ipHeader.GetDestination (), outInterface->GetNetworkMask ()))
+              IsUnicast (ipHeader.GetDestination (), outInterface->GetAddress (0).GetMask ()))
             {
               Ptr<Icmpv4L4Protocol> icmp = GetIcmp ();
               NS_ASSERT (icmp != 0);
@@ -728,9 +739,10 @@
   NS_LOG_LOGIC ("Send via interface " << route.GetInterface ());
 
   Ptr<Ipv4Interface> outInterface = GetInterface (route.GetInterface ());
+  // XXX handle multiple address on interface
   if (packet->GetSize () > outInterface->GetMtu () &&
       ipHeader.IsDontFragment () &&
-      IsUnicast (ipHeader.GetDestination (), outInterface->GetNetworkMask ()))
+      IsUnicast (ipHeader.GetDestination (), outInterface->GetAddress (0).GetMask ()))
     {
       NS_LOG_LOGIC ("Too big: need fragmentation but not allowed");
       Ptr<Icmpv4L4Protocol> icmp = GetIcmp ();
@@ -782,21 +794,24 @@
 
 bool
 Ipv4L3Protocol::Forwarding (
-  uint32_t ifIndex, 
+  uint32_t interface, 
   Ptr<Packet> packet, 
   Ipv4Header &ipHeader, 
   Ptr<NetDevice> device)
 {
-  NS_LOG_FUNCTION (ifIndex << packet << &ipHeader<< device);
+  NS_LOG_FUNCTION (interface << packet << &ipHeader<< device);
   NS_LOG_LOGIC ("Forwarding logic for node: " << m_node->GetId ());
 
   for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
        i != m_interfaces.end (); i++) 
     {
-      if ((*i)->GetAddress ().IsEqual (ipHeader.GetDestination ())) 
+      for (uint32_t j = 0; j < (*i)->GetNAddresses (); j++)
         {
-          NS_LOG_LOGIC ("For me (destination match)");
-          return false;
+          if ((*i)->GetAddress (j).GetLocal ().IsEqual (ipHeader.GetDestination ())) 
+            {
+              NS_LOG_LOGIC ("For me (destination match)");
+              return false;
+            }
         }
     }
   
@@ -806,7 +821,8 @@
       Ptr<Ipv4Interface> interface = *i;
       if (interface->GetDevice () == device)
 	{
-	  if (ipHeader.GetDestination ().IsEqual (interface->GetBroadcast ())) 
+          // XXX multi-address case
+	  if (ipHeader.GetDestination ().IsEqual (interface->GetAddress (0).GetBroadcast ())) 
 	    {
               NS_LOG_LOGIC ("For me (interface broadcast address)");
 	      return false;
@@ -840,26 +856,27 @@
           // We forward with a packet copy, since forwarding may change
           // the packet, affecting our local delivery
           NS_LOG_LOGIC ("Forwarding (multicast).");
-          DoForward (ifIndex, packet->Copy (), ipHeader);
+          DoForward (interface, packet->Copy (), ipHeader);
           return false;
         }   
     }
 
-  DoForward (ifIndex, packet, ipHeader);
+  DoForward (interface, packet, ipHeader);
   return true;
 }
 
 void
-Ipv4L3Protocol::DoForward (uint32_t ifIndex, 
+Ipv4L3Protocol::DoForward (uint32_t interface, 
                            Ptr<Packet> packet, 
                            Ipv4Header ipHeader)
 {
-  NS_LOG_FUNCTION (this << ifIndex << packet << ipHeader);
+  NS_LOG_FUNCTION (this << interface << packet << ipHeader);
 
   ipHeader.SetTtl (ipHeader.GetTtl () - 1);
+  // XXX handle multi-interfaces
   if (ipHeader.GetTtl () == 0)
     {
-      if (IsUnicast (ipHeader.GetDestination (), GetInterface (ifIndex)->GetNetworkMask ()))
+      if (IsUnicast (ipHeader.GetDestination (), GetInterface (interface)->GetAddress (0).GetMask ()))
         {
           Ptr<Icmpv4L4Protocol> icmp = GetIcmp ();
           icmp->SendTimeExceededTtl (ipHeader, packet);
@@ -869,7 +886,7 @@
       return;
     }  
   NS_LOG_LOGIC ("Not for me, forwarding.");
-  Lookup (ifIndex, ipHeader, packet,
+  Lookup (interface, ipHeader, packet,
           MakeCallback (&Ipv4L3Protocol::SendRealOut, this));
 }
 
@@ -894,7 +911,8 @@
       case Ipv4L4Protocol::RX_CSUM_FAILED:
         break;
       case Ipv4L4Protocol::RX_ENDPOINT_UNREACH:
-        if (IsUnicast (ip.GetDestination (), incomingInterface->GetNetworkMask ()))
+        // XXX handle multi-interface case
+        if (IsUnicast (ip.GetDestination (), incomingInterface->GetAddress (0).GetMask ()))
           {
             GetIcmp ()->SendDestUnreachPort (ip, copy);
           }
@@ -928,36 +946,28 @@
     }
 }
 
-void 
-Ipv4L3Protocol::SetAddress (uint32_t i, Ipv4Address address)
+uint32_t
+Ipv4L3Protocol::AddAddress (uint32_t i, Ipv4InterfaceAddress address)
 {
   NS_LOG_FUNCTION (this << i << address);
   Ptr<Ipv4Interface> interface = GetInterface (i);
-  interface->SetAddress (address);
-}
-
-void 
-Ipv4L3Protocol::SetNetworkMask (uint32_t i, Ipv4Mask mask)
-{
-  NS_LOG_FUNCTION (this << i << mask);
-  Ptr<Ipv4Interface> interface = GetInterface (i);
-  interface->SetNetworkMask (mask);
+  return interface->AddAddress (address);
 }
 
-Ipv4Mask 
-Ipv4L3Protocol::GetNetworkMask (uint32_t i) const
+Ipv4InterfaceAddress
+Ipv4L3Protocol::GetAddress (uint32_t interfaceIndex, uint32_t addressIndex) const
 {
-  NS_LOG_FUNCTION (this << i);
-  Ptr<Ipv4Interface> interface = GetInterface (i);
-  return interface->GetNetworkMask ();
+  NS_LOG_FUNCTION (this << interfaceIndex << addressIndex);
+  Ptr<Ipv4Interface> interface = GetInterface (interfaceIndex);
+  return interface->GetAddress (addressIndex);
 }
 
-Ipv4Address 
-Ipv4L3Protocol::GetAddress (uint32_t i) const
+uint32_t
+Ipv4L3Protocol::GetNAddresses (uint32_t interface) const
 {
-  NS_LOG_FUNCTION (this << i);
-  Ptr<Ipv4Interface> interface = GetInterface (i);
-  return interface->GetAddress ();
+  NS_LOG_FUNCTION (this << interface);
+  Ptr<Ipv4Interface> iface = GetInterface (interface);
+  return iface->GetNAddresses ();
 }
 
 void 
@@ -977,10 +987,10 @@
 }
 
 bool
-Ipv4L3Protocol::GetIfIndexForDestination (
-  Ipv4Address destination, uint32_t& ifIndex) const
+Ipv4L3Protocol::GetInterfaceForDestination (
+  Ipv4Address destination, uint32_t& interface) const
 {
-  NS_LOG_FUNCTION (this << destination << &ifIndex);
+  NS_LOG_FUNCTION (this << destination << &interface);
 //
 // The first thing we do in trying to determine a source address is to 
 // consult the routing protocols.  These will also check for a default route
@@ -991,12 +1001,12 @@
        i++)
     {
       NS_LOG_LOGIC ("Requesting Source Address");
-      uint32_t ifIndexTmp;
+      uint32_t interfaceTmp;
 
-      if ((*i).second->RequestIfIndex (destination, ifIndexTmp))
+      if ((*i).second->RequestInterface (destination, interfaceTmp))
         {
-          NS_LOG_LOGIC ("Found ifIndex " << ifIndexTmp);
-          ifIndex = ifIndexTmp;
+          NS_LOG_LOGIC ("Found interface " << interfaceTmp);
+          interface = interfaceTmp;
           return true;
         }
     }
@@ -1012,7 +1022,7 @@
   if (GetNInterfaces () == 2)
     {
       NS_LOG_LOGIC ("One Interface.  Using interface 1.");
-      ifIndex = 1;
+      interface = 1;
       return true;
     }
 //
@@ -1035,14 +1045,14 @@
 
   if (route == NULL)
     {
-      NS_LOG_LOGIC ("Ipv4L3Protocol::GetIfIndexForDestination (): "
+      NS_LOG_LOGIC ("Ipv4L3Protocol::GetInterfaceForDestination (): "
                     "Unable to determine outbound interface.  No default route set");
       return false;
     }
 
-  ifIndex = route->GetInterface ();
+  interface = route->GetInterface ();
 
-  NS_LOG_LOGIC ("Default route specifies interface " << ifIndex);
+  NS_LOG_LOGIC ("Default route specifies interface " << interface);
   return true;
 }
 
@@ -1072,11 +1082,13 @@
   // If interface address and network mask have been set, add a route
   // to the network of the interface (like e.g. ifconfig does on a
   // Linux box)
-  if (((interface->GetAddress ()) != (Ipv4Address ()))
-      && (interface->GetNetworkMask ()) != (Ipv4Mask ()))
+  for (uint32_t j = 0; j < interface->GetNAddresses (); j++)
     {
-      AddNetworkRouteTo (interface->GetAddress ().CombineMask (interface->GetNetworkMask ()),
-                         interface->GetNetworkMask (), i);
+      if (((interface->GetAddress (j).GetLocal ()) != (Ipv4Address ()))
+          && (interface->GetAddress (j).GetMask ()) != (Ipv4Mask ()))
+        {
+          AddNetworkRouteTo (interface->GetAddress (j).GetLocal ().CombineMask (interface->GetAddress (j).GetMask ()), interface->GetAddress (j).GetMask (), i);
+        }
     }
 }
 
@@ -1094,8 +1106,8 @@
       modified = false;
       for (uint32_t i = 0; i < GetNRoutes (); i++)
         {
-          Ipv4Route *route = GetRoute (i);
-          if (route->GetInterface () == ifaceIndex)
+          Ipv4Route route = GetRoute (i);
+          if (route.GetInterface () == ifaceIndex)
             {
               RemoveRoute (i);
               modified = true;
@@ -1105,4 +1117,43 @@
     }
 }
 
+// Note:  This method will be removed in Ipv4 routing work
+Ipv4Address
+Ipv4L3Protocol::GetSourceAddress (Ipv4Address destination) const
+{
+  uint32_t interface = 0xffffffff;
+
+  bool result = GetInterfaceForDestination (destination, interface);
+
+  if (result)
+    {
+      // if multiple addresses exist, search for the first one on the same subnet
+      for (uint32_t i = 0; i < GetNAddresses (interface); i++)
+        {
+          Ipv4InterfaceAddress ipv4InAddr = GetAddress (interface, i);
+          if (ipv4InAddr.GetLocal().CombineMask(ipv4InAddr.GetMask ()) == destination.CombineMask (ipv4InAddr.GetMask ()))
+            {
+              return ipv4InAddr.GetLocal ();
+            }
+        }
+      // Destination is off-link, so return first address.
+      return GetAddress (interface, 0).GetLocal ();
+    }
+  else
+    {
+//
+// If we can't find any address, just leave it 0.0.0.0
+//
+      return Ipv4Address::GetAny ();
+    }
+}
+
+Ptr<NetDevice>
+Ipv4L3Protocol::GetNetDevice (uint32_t i)
+{
+  return GetInterface (i)-> GetDevice ();
+}
+
+
+
 }//namespace ns3
--- a/src/internet-stack/ipv4-l3-protocol.h	Tue Apr 21 16:13:45 2009 +0400
+++ b/src/internet-stack/ipv4-l3-protocol.h	Tue Apr 21 16:22:45 2009 +0400
@@ -53,7 +53,7 @@
  * This is the actual implementation of IP.  It contains APIs to send and
  * receive packets at the IP layer, as well as APIs for IP routing.
  */
-class Ipv4L3Protocol : public Object
+class Ipv4L3Protocol : public Ipv4
 {
 public:
   static TypeId GetTypeId (void);
@@ -158,7 +158,7 @@
                Ipv4RoutingProtocol::RouteReplyCallback routeReply);
 
   uint32_t GetNRoutes (void);
-  Ipv4Route *GetRoute (uint32_t i);
+  Ipv4Route GetRoute (uint32_t i);
   void RemoveRoute (uint32_t i);
 
   void AddMulticastRoute (Ipv4Address origin,
@@ -169,7 +169,7 @@
   void SetDefaultMulticastRoute (uint32_t onputInterface);
 
   uint32_t GetNMulticastRoutes (void) const;
-  Ipv4MulticastRoute *GetMulticastRoute (uint32_t i) const;
+  Ipv4MulticastRoute GetMulticastRoute (uint32_t i) const;
 
   void RemoveMulticastRoute (Ipv4Address origin,
                              Ipv4Address group,
@@ -182,26 +182,29 @@
 
   uint32_t FindInterfaceForAddr (Ipv4Address addr) const;
   uint32_t FindInterfaceForAddr (Ipv4Address addr, Ipv4Mask mask) const;
-  int32_t FindInterfaceIndexForDevice (Ptr<NetDevice> device) const;
+  int32_t FindInterfaceForDevice (Ptr<NetDevice> device) const;
   
   void JoinMulticastGroup (Ipv4Address origin, Ipv4Address group);
   void LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group);
 
-  void SetAddress (uint32_t i, Ipv4Address address);
-  void SetNetworkMask (uint32_t i, Ipv4Mask mask);
-  Ipv4Mask GetNetworkMask (uint32_t t) const;
-  Ipv4Address GetAddress (uint32_t i) const;
+  uint32_t AddAddress (uint32_t i, Ipv4InterfaceAddress address);
+  Ipv4InterfaceAddress GetAddress (uint32_t interfaceIndex, uint32_t addressIndex) const;
+  uint32_t GetNAddresses (uint32_t interface) const;
+
   void SetMetric (uint32_t i, uint16_t metric);
   uint16_t GetMetric (uint32_t i) const;
-  bool GetIfIndexForDestination (Ipv4Address destination, 
-                                 uint32_t& ifIndex) const;
+  Ipv4Address GetSourceAddress (Ipv4Address destination) const;
+  bool GetInterfaceForDestination (Ipv4Address destination, 
+                                 uint32_t& interface) const;
   uint16_t GetMtu (uint32_t i) const;
   bool IsUp (uint32_t i) const;
   void SetUp (uint32_t i);
   void SetDown (uint32_t i);
 
+  Ptr<NetDevice> GetNetDevice (uint32_t i);
+
   void AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
-                           int priority);
+                           int16_t priority);
 
 protected:
 
@@ -210,7 +213,7 @@
 private:
   Ipv4L3Protocol(const Ipv4L3Protocol &);
   Ipv4L3Protocol &operator = (const Ipv4L3Protocol &);
-  void Lookup (uint32_t ifIndex,
+  void Lookup (uint32_t interface,
                Ipv4Header const &ipHeader,
                Ptr<Packet> packet,
                Ipv4RoutingProtocol::RouteReplyCallback routeReply);
@@ -219,7 +222,7 @@
                     Ipv4Route const &route,
                     Ptr<Packet> packet,
                     Ipv4Header const &ipHeader);
-  bool Forwarding (uint32_t ifIndex, 
+  bool Forwarding (uint32_t interface, 
                    Ptr<Packet> packet, 
                    Ipv4Header &ipHeader, 
                    Ptr<NetDevice> device);
@@ -228,7 +231,7 @@
   void SetupLoopback (void);
   Ptr<Icmpv4L4Protocol> GetIcmp (void) const;
   bool IsUnicast (Ipv4Address ad, Ipv4Mask interfaceMask) const;
-  void DoForward (uint32_t ifIndex, 
+  void DoForward (uint32_t interface, 
                   Ptr<Packet> packet, 
                   Ipv4Header ipHeader);
 
--- a/src/internet-stack/ipv4-raw-socket-impl.cc	Tue Apr 21 16:13:45 2009 +0400
+++ b/src/internet-stack/ipv4-raw-socket-impl.cc	Tue Apr 21 16:22:45 2009 +0400
@@ -170,10 +170,10 @@
   InetSocketAddress ad = InetSocketAddress::ConvertFrom (toAddress);
   Ptr<Ipv4L3Protocol> ipv4 = m_node->GetObject<Ipv4L3Protocol> ();
   Ipv4Address dst = ad.GetIpv4 ();
-  uint32_t localIfIndex;
-  if (ipv4->GetIfIndexForDestination(dst, localIfIndex))
+  uint32_t localInterface;
+  if (ipv4->GetInterfaceForDestination(dst, localInterface))
     {
-      ipv4->Send (p, ipv4->GetAddress (localIfIndex), dst, m_protocol);
+      ipv4->Send (p, ipv4->GetSourceAddress (dst), dst, m_protocol);
     }
   else
     {
--- a/src/internet-stack/ipv4-static-routing.cc	Tue Apr 21 16:13:45 2009 +0400
+++ b/src/internet-stack/ipv4-static-routing.cc	Tue Apr 21 16:22:45 2009 +0400
@@ -111,7 +111,7 @@
   NS_LOG_FUNCTION_NOARGS ();
   Ipv4Address origin = Ipv4Address::GetAny ();
   Ipv4Address group = Ipv4Address::GetAny ();
-  uint32_t inputInterface = Ipv4RoutingProtocol::IF_INDEX_ANY;
+  uint32_t inputInterface = Ipv4RoutingProtocol::INTERFACE_ANY;
 
   std::vector<uint32_t> outputInterfaces (1);
   outputInterfaces[0] = outputInterface;
@@ -296,7 +296,7 @@
 Ipv4StaticRouting::LookupStatic (
   Ipv4Address origin, 
   Ipv4Address group,
-  uint32_t    ifIndex)
+  uint32_t    interface)
 {
   NS_LOG_FUNCTION_NOARGS ();
 //
@@ -317,12 +317,12 @@
 //
 // The first case is the restrictive case where the origin, group and index
 // matches.  This picks up exact routes during forwarded and exact routes from
-// the local node (in which case the ifIndex is a wildcard).
+// the local node (in which case the interface is a wildcard).
 //
       if (origin == route->GetOrigin () && group == route->GetGroup ())
         {
-          if (ifIndex == Ipv4RoutingProtocol::IF_INDEX_ANY || 
-              ifIndex == route->GetInputInterface ())
+          if (interface == Ipv4RoutingProtocol::INTERFACE_ANY || 
+              interface == route->GetInputInterface ())
             {
               return *i;
             }
@@ -334,7 +334,7 @@
 // just happily forward packets we don't really know what to do with.  
 // Multicast storms are not generally considered a good thing.
 //
-  if (ifIndex != Ipv4RoutingProtocol::IF_INDEX_ANY)
+  if (interface != Ipv4RoutingProtocol::INTERFACE_ANY)
     {
       return 0;
     }
@@ -515,12 +515,12 @@
 
 bool
 Ipv4StaticRouting::RequestRoute (
-  uint32_t ifIndex,
+  uint32_t interface,
   Ipv4Header const &ipHeader,
   Ptr<Packet> packet,
   RouteReplyCallback routeReply)
 {
-  NS_LOG_FUNCTION (this << ifIndex << &ipHeader << packet << &routeReply);
+  NS_LOG_FUNCTION (this << interface << &ipHeader << packet << &routeReply);
 
   NS_LOG_LOGIC ("source = " << ipHeader.GetSource ());
 
@@ -531,7 +531,7 @@
       NS_LOG_LOGIC ("Multicast destination");
 
       Ipv4MulticastRoute *mRoute = LookupStatic(ipHeader.GetSource (),
-        ipHeader.GetDestination (), ifIndex);
+        ipHeader.GetDestination (), interface);
 
       if (mRoute)
         {
@@ -570,9 +570,9 @@
 }
 
 bool
-Ipv4StaticRouting::RequestIfIndex (Ipv4Address destination, uint32_t& ifIndex)
+Ipv4StaticRouting::RequestInterface (Ipv4Address destination, uint32_t& interface)
 {
-  NS_LOG_FUNCTION (this << destination << &ifIndex);
+  NS_LOG_FUNCTION (this << destination << &interface);
 //
 // First, see if this is a multicast packet we have a route for.  If we
 // have a route, then send the packet down each of the specified interfaces.
@@ -582,7 +582,7 @@
       NS_LOG_LOGIC ("Multicast destination");
 
       Ipv4MulticastRoute *mRoute = LookupStatic(Ipv4Address::GetAny (),
-        destination, Ipv4RoutingProtocol::IF_INDEX_ANY);
+        destination, Ipv4RoutingProtocol::INTERFACE_ANY);
 
       if (mRoute)
         {
@@ -594,8 +594,8 @@
               return false;
             }
 
-          ifIndex = mRoute->GetOutputInterface(0);
-          NS_LOG_LOGIC ("Found ifIndex " << ifIndex);
+          interface = mRoute->GetOutputInterface(0);
+          NS_LOG_LOGIC ("Found interface " << interface);
           return true;
         }
       return false; // Let other routing protocols try to handle this
@@ -607,7 +607,7 @@
   Ipv4Route *route = LookupStatic (destination);
   if (route)
     {
-      ifIndex = route->GetInterface ();
+      interface = route->GetInterface ();
       return true;
     }
   else
--- a/src/internet-stack/ipv4-static-routing.h	Tue Apr 21 16:13:45 2009 +0400
+++ b/src/internet-stack/ipv4-static-routing.h	Tue Apr 21 16:22:45 2009 +0400
@@ -102,10 +102,10 @@
  * 
  * If the destination address is a multicast, then the exact processing steps
  * depend on whether or not the packet has been sourced locally.  This is 
- * determined by the parameter ifIndex.  This is the interface index over which
+ * determined by the parameter interface.  This is the interface index over which
  * this packet was received.  If the packet has not been received over a
  * network interface, this index will be set to 
- * Ipv4RoutingProtocol::IF_INDEX_ANY (a very large number).  In that case, 
+ * Ipv4RoutingProtocol::INTERFACE_INDEX_ANY (a very large number).  In that case, 
  * we want to avoid the requirement that an explicit route out of each node 
  * must be set, so we don't do anything here.
  * 
@@ -118,9 +118,9 @@
  * packet out of as many interfaces as required using the provided callback
  * (think of it as a pre-packaged send call).
  *
- * @param ifIndex The network interface index over which the packed was 
- * received.  If the packet is from a local source, ifIndex will be set to
- * Ipv4RoutingProtocol::IF_INDEX_ANY.
+ * @param interface The network interface index over which the packed was 
+ * received.  If the packet is from a local source, interface will be set to
+ * Ipv4RoutingProtocol::INTERFACE_ANY.
  * @param ipHeader the Ipv4Header containing the source and destination IP
  * addresses for the packet.
  * @param packet The packet to be sent if a route is found.
@@ -134,7 +134,7 @@
  * @see Ipv4StaticRouting
  * @see Ipv4RoutingProtocol
  */
-  virtual bool RequestRoute (uint32_t ifIndex,
+  virtual bool RequestRoute (uint32_t interface,
                              Ipv4Header const &ipHeader,
                              Ptr<Packet> packet,
                              RouteReplyCallback routeReply);
@@ -157,12 +157,12 @@
  * that includeds multiple output interfaces, that route cannot be used.
  * 
  * If there are multiple paths out of the node, the resolution is performed
- * by Ipv4L3Protocol::GetIfIndexforDestination which has access to more 
+ * by Ipv4L3Protocol::GetInterfaceforDestination which has access to more 
  * contextual information that is useful for making a determination.
  *
  * @param destination The Ipv4Address if the destination of a hypothetical 
  * packet.  This may be a multicast group address.
- * @param ifIndex A reference to the interface index over which a packet
+ * @param interface A reference to the interface index over which a packet
  * sent to this destination would be sent.
  * @return Returns true if a route is found to the destination that involves
  * a single output interface index, otherwise returns false indicating that
@@ -173,7 +173,7 @@
  * @see Ipv4RoutingProtocol
  * @see Ipv4L3Protocol
  */
-  virtual bool RequestIfIndex (Ipv4Address destination, uint32_t& ifIndex);
+  virtual bool RequestInterface (Ipv4Address destination, uint32_t& interface);
 
 /**
  * @brief Add a host route to the static routing table.
@@ -323,7 +323,7 @@
  * of a local node.  The difference is in the input interface.  Routes for
  * forwarding will always have an explicit input interface specified.  Routes
  * off of a node will always set the input interface to a wildcard specified
- * by the index Ipv4RoutingProtocol::IF_INDEX_ANY.
+ * by the index Ipv4RoutingProtocol::INTERFACE_ANY.
  *
  * For routes off of a local node wildcards may be used in the origin and
  * multicast group addresses.  The wildcard used for Ipv4Adresses is that 
@@ -346,7 +346,7 @@
  * @param group The Ipv4Address of the multicast group or this route.
  * @param inputInterface The input network interface index over which to 
  * expect packets destined for this route.  May be
- * Ipv4RoutingProtocol::IF_INDEX_ANY for packets of local origin.
+ * Ipv4RoutingProtocol::INTERFACE_ANY for packets of local origin.
  * @param outputInterfaces A vector of network interface indices used to specify
  * how to send packets to the destination(s).
  *
@@ -492,7 +492,7 @@
 
   Ipv4Route *LookupStatic (Ipv4Address dest);
   Ipv4MulticastRoute *LookupStatic (Ipv4Address origin, Ipv4Address group,
-                                    uint32_t ifIndex);
+                                    uint32_t interface);
 
   HostRoutes m_hostRoutes;
   NetworkRoutes m_networkRoutes;
--- a/src/internet-stack/nsc-tcp-l4-protocol.cc	Tue Apr 21 16:13:45 2009 +0400
+++ b/src/internet-stack/nsc-tcp-l4-protocol.cc	Tue Apr 21 16:22:45 2009 +0400
@@ -344,8 +344,9 @@
   // how things _should_ be (once nsc can deal with multiple interfaces...)
   for (uint32_t i = 1; i < nInterfaces; i++)
     {
-      Ipv4Address addr = ip->GetAddress(i);
-      Ipv4Mask mask = ip->GetNetworkMask(i);
+      Ipv4InterfaceAddress ifAddr = ip->GetAddress (i, 0);
+      Ipv4Address addr = ifAddr.GetLocal ();
+      Ipv4Mask mask = ifAddr.GetMask ();
       uint16_t mtu = ip->GetMtu (i);
 
       std::ostringstream addrOss, maskOss;
--- a/src/internet-stack/tcp-socket-impl.cc	Tue Apr 21 16:13:45 2009 +0400
+++ b/src/internet-stack/tcp-socket-impl.cc	Tue Apr 21 16:22:45 2009 +0400
@@ -340,12 +340,12 @@
   m_remoteAddress = transport.GetIpv4 ();
   m_remotePort = transport.GetPort ();
   
-  uint32_t localIfIndex;
+  uint32_t localInterface;
   Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
 
-  if (ipv4->GetIfIndexForDestination (m_remoteAddress, localIfIndex))
+  if (ipv4->GetInterfaceForDestination (m_remoteAddress, localInterface))
     {
-      m_endPoint->SetLocalAddress (ipv4->GetAddress (localIfIndex));
+      m_endPoint->SetLocalAddress (ipv4->GetSourceAddress (m_remoteAddress));
     }
   else
     {
@@ -797,7 +797,7 @@
                                      const Address& fromAddress)
 {
   NS_LOG_FUNCTION (this << a << p  << fromAddress);
-  uint32_t localIfIndex;
+  uint32_t localInterface;
   Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
   switch (a)
   {
@@ -812,9 +812,9 @@
       NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action SYN_ACK_TX");
 //      m_remotePort = InetSocketAddress::ConvertFrom (fromAddress).GetPort ();
 //      m_remoteAddress = InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 ();
-//       if (ipv4->GetIfIndexForDestination (m_remoteAddress, localIfIndex))
+//       if (ipv4->GetInterfaceForDestination (m_remoteAddress, localInterface))
 //         {
-//           m_localAddress = ipv4->GetAddress (localIfIndex);
+//           m_localAddress = ipv4->GetAddress (localInterface);
 //         }
       if (m_state == LISTEN) //this means we should fork a new TcpSocketImpl
         {
@@ -833,9 +833,9 @@
       // This is the cloned endpoint
       NS_ASSERT (m_state == SYN_RCVD);
       m_endPoint->SetPeer (m_remoteAddress, m_remotePort);
-      if (ipv4->GetIfIndexForDestination (m_remoteAddress, localIfIndex))
+      if (ipv4->GetInterfaceForDestination (m_remoteAddress, localInterface))
         {
-          m_localAddress = ipv4->GetAddress (localIfIndex);
+          m_localAddress = ipv4->GetSourceAddress (m_remoteAddress);
           m_endPoint->SetLocalAddress (m_localAddress);
           // Leave local addr in the portmap to any, as the path from
           // remote can change and packets can arrive on different interfaces
@@ -1924,8 +1924,8 @@
   node->AddDevice (dev);
   Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
   uint32_t ndid = ipv4->AddInterface (dev);
-  ipv4->SetAddress (ndid, Ipv4Address (ipaddr));
-  ipv4->SetNetworkMask (ndid, Ipv4Mask (netmask));
+  Ipv4InterfaceAddress ipv4Addr = Ipv4InterfaceAddress (Ipv4Address (ipaddr), Ipv4Mask (netmask));
+  ipv4->AddAddress (ndid, ipv4Addr);
   ipv4->SetUp (ndid);
   return dev;
 }
--- a/src/internet-stack/udp-socket-impl.cc	Tue Apr 21 16:13:45 2009 +0400
+++ b/src/internet-stack/udp-socket-impl.cc	Tue Apr 21 16:22:45 2009 +0400
@@ -308,7 +308,7 @@
       return -1;
     }
 
-  uint32_t localIfIndex;
+  uint32_t localInterface;
   Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
 
   // Locally override the IP TTL for this socket
@@ -362,8 +362,10 @@
       NS_LOG_LOGIC ("Limited broadcast start.");
       for (uint32_t i = 0; i < ipv4->GetNInterfaces (); i++ )
         {
-          Ipv4Address addri = ipv4->GetAddress (i);
-          Ipv4Mask maski = ipv4->GetNetworkMask (i);
+          // Get the primary address
+          Ipv4InterfaceAddress iaddr = ipv4->GetAddress (i, 0);
+          Ipv4Address addri = iaddr.GetLocal ();
+          Ipv4Mask maski = iaddr.GetMask ();
           if (maski == Ipv4Mask::GetOnes ())
             {
               // if the network mask is 255.255.255.255, do not convert dest
@@ -389,10 +391,10 @@
       NS_LOG_LOGIC ("Limited broadcast end.");
       return p->GetSize();
     }
-  else if (ipv4->GetIfIndexForDestination(dest, localIfIndex))
+  else if (ipv4->GetInterfaceForDestination(dest, localInterface))
     {
       NS_LOG_LOGIC ("Route exists");
-      m_udp->Send (p->Copy (), ipv4->GetAddress (localIfIndex), dest,
+      m_udp->Send (p->Copy (), ipv4->GetSourceAddress (dest), dest,
 		   m_endPoint->GetLocalPort (), port);
       NotifyDataSent (p->GetSize ());
       NotifySend (GetTxAvailable ());
@@ -666,8 +668,8 @@
     rxNode->AddDevice (rxDev1);
     Ptr<Ipv4> ipv4 = rxNode->GetObject<Ipv4> ();
     uint32_t netdev_idx = ipv4->AddInterface (rxDev1);
-    ipv4->SetAddress (netdev_idx, Ipv4Address ("10.0.0.1"));
-    ipv4->SetNetworkMask (netdev_idx, Ipv4Mask (0xffff0000U));
+    Ipv4InterfaceAddress ipv4Addr = Ipv4InterfaceAddress (Ipv4Address ("10.0.0.1"), Ipv4Mask (0xffff0000U));
+    ipv4->AddAddress (netdev_idx, ipv4Addr);
     ipv4->SetUp (netdev_idx);
   }
 
@@ -677,8 +679,8 @@
     rxNode->AddDevice (rxDev2);
     Ptr<Ipv4> ipv4 = rxNode->GetObject<Ipv4> ();
     uint32_t netdev_idx = ipv4->AddInterface (rxDev2);
-    ipv4->SetAddress (netdev_idx, Ipv4Address ("10.0.1.1"));
-    ipv4->SetNetworkMask (netdev_idx, Ipv4Mask (0xffff0000U));
+    Ipv4InterfaceAddress ipv4Addr = Ipv4InterfaceAddress (Ipv4Address ("10.0.1.1"), Ipv4Mask (0xffff0000U));
+    ipv4->AddAddress (netdev_idx, ipv4Addr);
     ipv4->SetUp (netdev_idx);
   }
   
@@ -692,8 +694,8 @@
     txNode->AddDevice (txDev1);
     Ptr<Ipv4> ipv4 = txNode->GetObject<Ipv4> ();
     uint32_t netdev_idx = ipv4->AddInterface (txDev1);
-    ipv4->SetAddress (netdev_idx, Ipv4Address ("10.0.0.2"));
-    ipv4->SetNetworkMask (netdev_idx, Ipv4Mask (0xffff0000U));
+    Ipv4InterfaceAddress ipv4Addr = Ipv4InterfaceAddress (Ipv4Address ("10.0.0.2"), Ipv4Mask (0xffff0000U));
+    ipv4->AddAddress (netdev_idx, ipv4Addr);
     ipv4->SetUp (netdev_idx);
   }
   Ptr<SimpleNetDevice> txDev2;
@@ -703,8 +705,8 @@
     txNode->AddDevice (txDev2);
     Ptr<Ipv4> ipv4 = txNode->GetObject<Ipv4> ();
     uint32_t netdev_idx = ipv4->AddInterface (txDev2);
-    ipv4->SetAddress (netdev_idx, Ipv4Address ("10.0.1.2"));
-    ipv4->SetNetworkMask (netdev_idx, Ipv4Mask (0xffff0000U));
+    Ipv4InterfaceAddress ipv4Addr = Ipv4InterfaceAddress (Ipv4Address ("10.0.1.2"), Ipv4Mask (0xffff0000U));
+    ipv4->AddAddress (netdev_idx, ipv4Addr);
     ipv4->SetUp (netdev_idx);
   }
 
--- a/src/internet-stack/wscript	Tue Apr 21 16:13:45 2009 +0400
+++ b/src/internet-stack/wscript	Tue Apr 21 16:22:45 2009 +0400
@@ -92,7 +92,6 @@
         'udp-socket-impl.cc',
         'tcp-socket-impl.cc',
         'ipv4-end-point-demux.cc',
-        'ipv4-impl.cc',
         'udp-socket-factory-impl.cc',
         'tcp-socket-factory-impl.cc',
         'pending-data.cc',
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ipv4-interface-address.cc	Tue Apr 21 16:22:45 2009 +0400
@@ -0,0 +1,141 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#include "ns3/log.h"
+#include "ns3/assert.h"
+#include "ipv4-interface-address.h"
+
+NS_LOG_COMPONENT_DEFINE("Ipv4InterfaceAddress");
+
+namespace ns3 {
+
+Ipv4InterfaceAddress::Ipv4InterfaceAddress ()
+  : m_scope (GLOBAL), 
+    m_secondary (false)
+{
+  NS_LOG_FUNCTION (this);
+}
+
+Ipv4InterfaceAddress::Ipv4InterfaceAddress (Ipv4Address local, Ipv4Mask mask)
+  : m_scope (GLOBAL), 
+    m_secondary (false)
+{
+  NS_LOG_FUNCTION (this);
+  m_local = local;
+  m_mask = mask;
+  m_broadcast = Ipv4Address (local.Get () | (~mask.Get ()));
+}
+
+Ipv4InterfaceAddress::Ipv4InterfaceAddress (const Ipv4InterfaceAddress &o)
+  : m_local (o.m_local),
+    m_mask (o.m_mask),
+    m_broadcast (o.m_broadcast),
+    m_scope (o.m_scope),
+    m_secondary (o.m_secondary)
+{
+  NS_LOG_FUNCTION (this);
+}
+
+void 
+Ipv4InterfaceAddress::SetLocal (Ipv4Address local)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_local = local;
+}
+
+Ipv4Address 
+Ipv4InterfaceAddress::GetLocal (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_local; 
+}
+
+void 
+Ipv4InterfaceAddress::SetMask (Ipv4Mask mask) 
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_mask = mask;
+}
+
+Ipv4Mask 
+Ipv4InterfaceAddress::GetMask (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_mask;
+}
+
+void 
+Ipv4InterfaceAddress::SetBroadcast (Ipv4Address broadcast)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_broadcast = broadcast;
+}
+
+Ipv4Address 
+Ipv4InterfaceAddress::GetBroadcast (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_broadcast;
+}
+
+void 
+Ipv4InterfaceAddress::SetScope (Ipv4InterfaceAddress::InterfaceAddressScope_e scope)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_scope = scope;
+}
+
+Ipv4InterfaceAddress::InterfaceAddressScope_e 
+Ipv4InterfaceAddress::GetScope (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_scope;
+}
+
+bool 
+Ipv4InterfaceAddress::IsSecondary (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_secondary;
+}
+
+void 
+Ipv4InterfaceAddress::SetSecondary (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_secondary = true;
+}
+
+void 
+Ipv4InterfaceAddress::SetPrimary (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_secondary = false;
+}
+
+std::ostream& operator<< (std::ostream& os, const Ipv4InterfaceAddress &addr)
+{ 
+  os << "m_local=" << addr.GetLocal () << "; m_mask=" <<
+    addr.GetMask () << "; m_broadcast=" << addr.GetBroadcast () << "; m_scope=" << addr.GetScope() <<
+    "; m_secondary=" << addr.IsSecondary ();
+  return os;
+} 
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ipv4-interface-address.h	Tue Apr 21 16:22:45 2009 +0400
@@ -0,0 +1,86 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef IPV4_INTERFACE_ADDRESS_H
+#define IPV4_INTERFACE_ADDRESS_H
+
+#include <stdint.h>
+#include <ostream>
+#include "ipv4-address.h"
+
+namespace ns3 {
+
+/**
+ * \ingroup address
+ *
+ * \brief a class to store IPv4 address information on an interface
+ *
+ * Corresponds to Linux struct in_ifaddr.  A list of these addresses
+ * is stored in Ipv4Interface.  This class is modelled after how current
+ * Linux handles IP aliasing for IPv4.  Notably, aliasing of IPv4 
+ * interfaces (e.g., "eth0:1") is not used, and instead an interface
+ * is assigned possibly multiple addresses, with each address being
+ * classified as being primary and secondary.  See the iproute2 
+ * documentation for this distinction.
+ */
+class Ipv4InterfaceAddress 
+{
+public:
+  enum InterfaceAddressScope_e {
+    HOST,
+    LINK,
+    GLOBAL
+  };
+
+  Ipv4InterfaceAddress ();
+  // Configure m_local, m_mask, and m_broadcast from the below constructor
+  Ipv4InterfaceAddress (Ipv4Address local, Ipv4Mask mask);
+  Ipv4InterfaceAddress (const Ipv4InterfaceAddress &o);
+
+  void SetLocal (Ipv4Address local);
+  Ipv4Address GetLocal (void) const;
+  void SetMask (Ipv4Mask mask);
+  Ipv4Mask GetMask (void) const;
+  void SetBroadcast (Ipv4Address broadcast);
+  Ipv4Address GetBroadcast (void) const;
+ 
+  void SetScope (Ipv4InterfaceAddress::InterfaceAddressScope_e scope);
+  Ipv4InterfaceAddress::InterfaceAddressScope_e GetScope (void) const;
+  
+  bool IsSecondary (void) const;
+  void SetSecondary (void);
+  void SetPrimary (void);
+  
+private:
+
+  Ipv4Address m_local;     // Interface address
+  // Note:  m_peer may be added in future when necessary
+  // Ipv4Address m_peer;      // Peer destination address (in Linux:  m_address)
+  Ipv4Mask m_mask;         // Network mask
+  Ipv4Address m_broadcast; // Broadcast address
+
+  InterfaceAddressScope_e m_scope;   
+  bool m_secondary;        // For use in multihoming
+};
+
+std::ostream& operator<< (std::ostream& os, const Ipv4InterfaceAddress &addr);
+
+} // namespace ns3
+
+#endif /* IPV4_ADDRESS_H */
--- a/src/node/ipv4.cc	Tue Apr 21 16:13:45 2009 +0400
+++ b/src/node/ipv4.cc	Tue Apr 21 16:22:45 2009 +0400
@@ -41,17 +41,21 @@
 {}
 
 uint32_t 
-Ipv4::GetIfIndexByAddress (Ipv4Address addr, Ipv4Mask mask)
+Ipv4::GetInterfaceByAddress (Ipv4Address addr, Ipv4Mask mask)
 {
   for (uint32_t i = 0; i < GetNInterfaces (); i++)
     {
-      if (GetAddress (i).CombineMask(mask) == addr.CombineMask(mask) )
+      for (uint32_t j = 0; j < GetNAddresses (i); j++)
         {
-          return i;
+          Ipv4InterfaceAddress ipv4InAddr = GetAddress (i, j);
+          if (ipv4InAddr.GetLocal ().CombineMask(mask) == addr.CombineMask(mask) )
+            {
+              return i;
+            }
         }
     }
   // Mapping not found
-  NS_ASSERT_MSG (false, "Ipv4::GetIfIndexByAddress failed");
+  NS_ASSERT_MSG (false, "Ipv4::GetInterfaceByAddress failed");
   return 0;
 }
 
--- a/src/node/ipv4.h	Tue Apr 21 16:13:45 2009 +0400
+++ b/src/node/ipv4.h	Tue Apr 21 16:22:45 2009 +0400
@@ -22,6 +22,7 @@
 
 #include <stdint.h>
 #include "ns3/ipv4-address.h"
+#include "ns3/ipv4-interface-address.h"
 #include "ns3/object.h"
 #include "ns3/callback.h"
 #include "ipv4-route.h"
@@ -76,7 +77,7 @@
   /**
    * \brief Request that a packet be routed.
    *
-   * \param ifIndex The interface index on which the packet was received.
+   * \param interface The interface index on which the packet was received.
    * \param ipHeader IP header of the packet
    * \param packet packet that is being sent or forwarded
    * \param routeReply callback that will receive the route reply
@@ -111,7 +112,7 @@
    * destination will be serviced by cloning the packet and calling the 
    * route reply callback once for each outgoing interface in the route.
    */
-  virtual bool RequestRoute (uint32_t ifIndex,
+  virtual bool RequestRoute (uint32_t interface,
                              const Ipv4Header &ipHeader,
                              Ptr<Packet> packet,
                              RouteReplyCallback routeReply) = 0;
@@ -134,12 +135,12 @@
  * that includeds multiple output interfaces, that route cannot be used.
  * 
  * If there are multiple paths out of the node, the resolution is performed
- * by Ipv4L3Protocol::GetIfIndexforDestination which has access to more 
+ * by Ipv4L3Protocol::GetInterfaceforDestination which has access to more 
  * contextual information that is useful for making a determination.
  *
  * \param destination The Ipv4Address if the destination of a hypothetical 
  * packet.  This may be a multicast group address.
- * \param ifIndex A reference to the interface index over which a packet
+ * \param interface A reference to the interface index over which a packet
  * sent to this destination would be sent.
  * \return Returns true if a route is found to the destination that involves
  * a single output interface index, otherwise false.
@@ -148,10 +149,10 @@
  * \see Ipv4RoutingProtocol
  * \see Ipv4L3Protocol
  */
-  virtual bool RequestIfIndex (Ipv4Address destination, 
-                              uint32_t& ifIndex) = 0;
+  virtual bool RequestInterface (Ipv4Address destination, 
+                              uint32_t& interface) = 0;
 
-  static const uint32_t IF_INDEX_ANY = 0xffffffff;
+  static const uint32_t INTERFACE_ANY = 0xffffffff;
 };
 
 /**
@@ -319,7 +320,7 @@
   /**
    * \returns the number of interfaces added by the user.
    */
-  virtual uint32_t GetNInterfaces (void) = 0;  
+  virtual uint32_t GetNInterfaces (void) const = 0;  
 
   /**
    * \brief Find and return the interface ID of the interface that has been
@@ -391,22 +392,24 @@
   virtual void LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group) = 0;
 
   /**
-   * \param i index of ipv4 interface
-   * \param address address to associate to the underlying ipv4 interface
+   * \param interface Interface number of an Ipv4 interface
+   * \param address Ipv4InterfaceAddress address to associate with the underlying Ipv4 interface
+   * \returns The address index of the newly-added address
    */
-  virtual void SetAddress (uint32_t i, Ipv4Address address) = 0;
+  virtual uint32_t AddAddress (uint32_t interface, Ipv4InterfaceAddress address) = 0;
 
   /**
-   * \param i index of ipv4 interface
-   * \param mask mask to associate to the underlying ipv4 interface
+   * \param interface Interface number of an Ipv4 interface
+   * \returns the number of Ipv4InterfaceAddress entries for the interface.
    */
-  virtual void SetNetworkMask (uint32_t i, Ipv4Mask mask) = 0;
+  virtual uint32_t GetNAddresses (uint32_t interface) const = 0;
 
   /**
-   * \param i index of ipv4 interface
-   * \returns the mask associated to the underlying ipv4 interface
+   * \param interface Interface number of an Ipv4 interface
+   * \param addressIndex index of Ipv4InterfaceAddress
+   * \returns the Ipv4InterfaceAddress associated to the interface and addresIndex
    */
-  virtual Ipv4Mask GetNetworkMask (uint32_t i) const = 0;
+  virtual Ipv4InterfaceAddress GetAddress (uint32_t interface, uint32_t addressIndex) const = 0;
 
   /**
    * \param i index of ipv4 interface
@@ -423,17 +426,6 @@
   virtual uint16_t GetMetric (uint32_t i) const = 0;
 
   /**
-   * \param i index of ipv4 interface
-   * \returns the address associated to the underlying ipv4 interface
-   *
-   * Note that the broadcast address for this interface may be fetched
-   * from the Ipv4Address object returned here using
-   * Ipv4Address::GetSubnetDirectedBroadcast(mask), where the mask for
-   * the interface may be retrived using Ipv4::GetNetworkMask(i).
-   */
-  virtual Ipv4Address GetAddress (uint32_t i) const = 0;
-
-  /**
    * \param destination The IP address of a hypothetical destination.
    * \returns The IP address assigned to the interface that will be used
    * if we were to send a packet to destination.
@@ -447,12 +439,12 @@
 
   /**
    * \param dest The IP address of a hypothetical destination.
-   * \param ifIndex filled in with the interface index that will be used to
+   * \param interface filled in with the interface index that will be used to
    *        send a packet to the hypothetical destination.
    * \returns true if a single interface can be identified, false otherwise.
    */
-  virtual bool GetIfIndexForDestination (Ipv4Address dest,
-                                         uint32_t &ifIndex) const = 0;
+  virtual bool GetInterfaceForDestination (Ipv4Address dest,
+                                         uint32_t &interface) const = 0;
 
   /**
    * \param i index of ipv4 interface
@@ -485,14 +477,14 @@
   virtual void SetDown (uint32_t i) = 0;
 
   /**
-   * \brief Convenience function to return the ifIndex corresponding
+   * \brief Convenience function to return the interface corresponding
    * to the Ipv4Address provided
    *
    * \param addr Ipv4Address
    * \param mask corresponding Ipv4Mask
-   * \returns ifIndex corresponding to a/amask
+   * \returns interface corresponding to a/amask
    */
-  virtual uint32_t GetIfIndexByAddress (Ipv4Address addr, 
+  virtual uint32_t GetInterfaceByAddress (Ipv4Address addr, 
     Ipv4Mask mask = Ipv4Mask("255.255.255.255"));
 };
 
--- a/src/node/wscript	Tue Apr 21 16:13:45 2009 +0400
+++ b/src/node/wscript	Tue Apr 21 16:22:45 2009 +0400
@@ -10,6 +10,7 @@
         'packet-socket-address.cc',
         'node.cc',
         'ipv4-address.cc',
+        'ipv4-interface-address.cc',
         'ipv4-address-generator.cc',
         'ipv4-header.cc',
         'net-device.cc',
@@ -47,6 +48,7 @@
         'mac48-address.h',
         'mac64-address.h',
         'inet-socket-address.h',
+        'ipv4-interface-address.h',
         'packet-socket-address.h',
         'node.h',
         'ipv4-address.h',
--- a/src/routing/global-routing/global-route-manager-impl.cc	Tue Apr 21 16:13:45 2009 +0400
+++ b/src/routing/global-routing/global-route-manager-impl.cc	Tue Apr 21 16:22:45 2009 +0400
@@ -1352,7 +1352,7 @@
 
 //
 // Return the interface index corresponding to a given IP address
-// This is a wrapper around GetIfIndexByIpv4Address(), but we first
+// This is a wrapper around GetInterfaceByIpv4Address(), but we first
 // have to find the right node pointer to pass to that function.
 //
   uint32_t
@@ -1406,7 +1406,7 @@
 // we're looking for.  If we find one, return the corresponding interface
 // index.
 //
-          return (ipv4->GetIfIndexByAddress (a, amask) );
+          return (ipv4->GetInterfaceByAddress (a, amask) );
         }
     }
 //
--- a/src/routing/global-routing/global-router-interface.cc	Tue Apr 21 16:13:45 2009 +0400
+++ b/src/routing/global-routing/global-router-interface.cc	Tue Apr 21 16:22:45 2009 +0400
@@ -594,8 +594,8 @@
       //
       if (NetDeviceIsBridged (ndLocal))
         {
-          uint32_t ifIndexBridge;
-          bool rc = FindIfIndexForDevice(node, ndLocal, ifIndexBridge);
+          uint32_t interfaceBridge;
+          bool rc = FindInterfaceForDevice(node, ndLocal, interfaceBridge);
           NS_ABORT_MSG_IF (rc, "GlobalRouter::DiscoverLSAs(): Bridge ports must not have an IPv4 interface index");
         }
 
@@ -697,17 +697,21 @@
   //
   Ptr<Node> node = nd->GetNode ();
 
-  uint32_t ifIndexLocal;
-  bool rc = FindIfIndexForDevice(node, nd, ifIndexLocal);
+  uint32_t interfaceLocal;
+  bool rc = FindInterfaceForDevice(node, nd, interfaceLocal);
   NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessSingleBroadcastLink(): No interface index associated with device");
 
   Ptr<Ipv4> ipv4Local = node->GetObject<Ipv4> ();
   NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessSingleBroadcastLink (): GetObject for <Ipv4> interface failed");
 
-  Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal);
-  Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal);
+  if (ipv4Local->GetNAddresses (interfaceLocal) > 1)
+    {
+      NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
+    }
+  Ipv4Address addrLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetLocal ();
+  Ipv4Mask maskLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetMask ();
   NS_LOG_LOGIC ("Working with local address " << addrLocal);
-  uint16_t metricLocal = ipv4Local->GetMetric (ifIndexLocal);
+  uint16_t metricLocal = ipv4Local->GetMetric (interfaceLocal);
 
   //
   // Check to see if the net device is connected to a channel/network that has
@@ -813,17 +817,21 @@
   //
   Ptr<Node> node = nd->GetNode ();
 
-  uint32_t ifIndexLocal;
-  bool rc = FindIfIndexForDevice(node, nd, ifIndexLocal);
+  uint32_t interfaceLocal;
+  bool rc = FindInterfaceForDevice(node, nd, interfaceLocal);
   NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessBridgedBroadcastLink(): No interface index associated with device");
 
   Ptr<Ipv4> ipv4Local = node->GetObject<Ipv4> ();
   NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessBridgedBroadcastLink (): GetObject for <Ipv4> interface failed");
 
-  Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal);
-  Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal);
+  if (ipv4Local->GetNAddresses (interfaceLocal) > 1)
+    {
+      NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
+    }
+  Ipv4Address addrLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetLocal ();
+  Ipv4Mask maskLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetMask ();;
   NS_LOG_LOGIC ("Working with local address " << addrLocal);
-  uint16_t metricLocal = ipv4Local->GetMetric (ifIndexLocal);
+  uint16_t metricLocal = ipv4Local->GetMetric (interfaceLocal);
 
   //
   // We need to handle a bridge on the router.  This means that we have been 
@@ -955,17 +963,21 @@
   //
   Ptr<Node> nodeLocal = ndLocal->GetNode ();
 
-  uint32_t ifIndexLocal;
-  bool rc = FindIfIndexForDevice(nodeLocal, ndLocal, ifIndexLocal);
+  uint32_t interfaceLocal;
+  bool rc = FindInterfaceForDevice(nodeLocal, ndLocal, interfaceLocal);
   NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessPointToPointLink (): No interface index associated with device");
 
   Ptr<Ipv4> ipv4Local = nodeLocal->GetObject<Ipv4> ();
   NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessPointToPointLink (): GetObject for <Ipv4> interface failed");
 
-  Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal);
-  Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal);
+  if (ipv4Local->GetNAddresses (interfaceLocal) > 1)
+    {
+      NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
+    }
+  Ipv4Address addrLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetLocal ();
+  Ipv4Mask maskLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetMask ();
   NS_LOG_LOGIC ("Working with local address " << addrLocal);
-  uint16_t metricLocal = ipv4Local->GetMetric (ifIndexLocal);
+  uint16_t metricLocal = ipv4Local->GetMetric (interfaceLocal);
 
   //
   // Now, we're going to walk over to the remote net device on the other end of 
@@ -1010,16 +1022,20 @@
   // Now, just like we did above, we need to get the IP interface index for the 
   // net device on the other end of the point-to-point channel.
   //
-  uint32_t ifIndexRemote;
-  rc = FindIfIndexForDevice(nodeRemote, ndRemote, ifIndexRemote);
+  uint32_t interfaceRemote;
+  rc = FindInterfaceForDevice(nodeRemote, ndRemote, interfaceRemote);
   NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessPointToPointLinks(): No interface index associated with remote device");
 
   //
   // Now that we have the Ipv4 interface, we can get the (remote) address and
   // mask we need.
   //
-  Ipv4Address addrRemote = ipv4Remote->GetAddress(ifIndexRemote);
-  Ipv4Mask maskRemote = ipv4Remote->GetNetworkMask(ifIndexRemote);
+  if (ipv4Remote->GetNAddresses (interfaceRemote) > 1)
+    {
+      NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
+    }
+  Ipv4Address addrRemote = ipv4Remote->GetAddress (interfaceRemote, 0).GetLocal ();
+  Ipv4Mask maskRemote = ipv4Remote->GetAddress (interfaceRemote, 0).GetMask ();
   NS_LOG_LOGIC ("Working with remote address " << addrRemote);
 
   //
@@ -1028,9 +1044,9 @@
   // the second is a stub network record with the network number.
   //
   GlobalRoutingLinkRecord *plr;
-  if (ipv4Remote->IsUp (ifIndexRemote))
+  if (ipv4Remote->IsUp (interfaceRemote))
     {
-      NS_LOG_LOGIC ("Remote side interface " << ifIndexRemote << " is up-- add a type 1 link");
+      NS_LOG_LOGIC ("Remote side interface " << interfaceRemote << " is up-- add a type 1 link");
  
       plr  = new GlobalRoutingLinkRecord;
       NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessPointToPointLink(): Can't alloc link record");
@@ -1069,15 +1085,19 @@
       Ptr<NetDevice> ndLocal = c.Get (i);
       Ptr<Node> node = ndLocal->GetNode ();
 
-      uint32_t ifIndexLocal;
-      bool rc = FindIfIndexForDevice(node, ndLocal, ifIndexLocal);
+      uint32_t interfaceLocal;
+      bool rc = FindInterfaceForDevice(node, ndLocal, interfaceLocal);
       NS_ABORT_MSG_IF (rc == false, "GlobalRouter::BuildNetworkLSAs (): No interface index associated with device");
 
       Ptr<Ipv4> ipv4Local = node->GetObject<Ipv4> ();
       NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessPointToPointLink (): GetObject for <Ipv4> interface failed");
 
-      Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal);
-      Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal);
+      if (ipv4Local->GetNAddresses (interfaceLocal) > 1)
+        {
+          NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
+        }
+      Ipv4Address addrLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetLocal ();
+      Ipv4Mask maskLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetMask ();
 
       GlobalRoutingLSA *pLSA = new GlobalRoutingLSA;
       NS_ABORT_MSG_IF (pLSA == 0, "GlobalRouter::BuildNetworkLSAs(): Can't alloc link record");
@@ -1117,18 +1137,22 @@
           // Does the attached node have an ipv4 interface for the device we're probing?
           // If not, it can't play router.
           //
-          uint32_t tempIfIndex;
-          if (FindIfIndexForDevice (tempNode, tempNd, tempIfIndex))
+          uint32_t tempInterface;
+          if (FindInterfaceForDevice (tempNode, tempNd, tempInterface))
             {
               Ptr<Ipv4> tempIpv4 = tempNode->GetObject<Ipv4> ();
               NS_ASSERT (tempIpv4);
-              if (!tempIpv4->IsUp (tempIfIndex))
+              if (!tempIpv4->IsUp (tempInterface))
                 {
-                  NS_LOG_LOGIC ("Remote side interface " << tempIfIndex << " not up");
+                  NS_LOG_LOGIC ("Remote side interface " << tempInterface << " not up");
                 }
               else 
                 {
-                  Ipv4Address tempAddr = tempIpv4->GetAddress(tempIfIndex);
+                  if (tempIpv4->GetNAddresses (tempInterface) > 1)
+                    {
+                      NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
+                    }
+                  Ipv4Address tempAddr = tempIpv4->GetAddress(tempInterface, 0).GetLocal ();
                   pLSA->AddAttachedRouter (tempAddr);
                 }
             }
@@ -1197,16 +1221,20 @@
           Ptr<Ipv4> ipv4 = nodeOther->GetObject<Ipv4> ();
           if (rtr && ipv4)
             {
-              uint32_t ifIndexOther;
-              if (FindIfIndexForDevice(nodeOther, bnd, ifIndexOther))
+              uint32_t interfaceOther;
+              if (FindInterfaceForDevice(nodeOther, bnd, interfaceOther))
                 {
                   NS_LOG_LOGIC ("Found router on bridge net device " << bnd);
-                  if (!ipv4->IsUp (ifIndexOther))
+                  if (!ipv4->IsUp (interfaceOther))
                     {
-                      NS_LOG_LOGIC ("Remote side interface " << ifIndexOther << " not up");
+                      NS_LOG_LOGIC ("Remote side interface " << interfaceOther << " not up");
                       continue;
                     }
-                  Ipv4Address addrOther = ipv4->GetAddress (ifIndexOther);
+                  if (ipv4->GetNAddresses (interfaceOther) > 1)
+                    {
+                      NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
+                    }
+                  Ipv4Address addrOther = ipv4->GetAddress (interfaceOther, 0).GetLocal ();
                   desigRtr = addrOther < desigRtr ? addrOther : desigRtr;
                   NS_LOG_LOGIC ("designated router now " << desigRtr);
                 }
@@ -1246,16 +1274,20 @@
           Ptr<Ipv4> ipv4 = nodeOther->GetObject<Ipv4> ();
           if (rtr && ipv4)
             {
-              uint32_t ifIndexOther;
-              if (FindIfIndexForDevice(nodeOther, ndOther, ifIndexOther))
+              uint32_t interfaceOther;
+              if (FindInterfaceForDevice(nodeOther, ndOther, interfaceOther))
                 {
-                  if (!ipv4->IsUp (ifIndexOther))
+                  if (!ipv4->IsUp (interfaceOther))
                     {
-                      NS_LOG_LOGIC ("Remote side interface " << ifIndexOther << " not up");
+                      NS_LOG_LOGIC ("Remote side interface " << interfaceOther << " not up");
                       continue;
                     }
                   NS_LOG_LOGIC ("Found router on net device " << ndOther);
-                  Ipv4Address addrOther = ipv4->GetAddress (ifIndexOther);
+                  if (ipv4->GetNAddresses (interfaceOther) > 1)
+                    {
+                      NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
+                    }
+                  Ipv4Address addrOther = ipv4->GetAddress (interfaceOther, 0).GetLocal ();
                   desigRtr = addrOther < desigRtr ? addrOther : desigRtr;
                   NS_LOG_LOGIC ("designated router now " << desigRtr);
                 }
@@ -1441,7 +1473,7 @@
 // is bridged, there will not be an interface associated directly with the device.
 //
   bool
-GlobalRouter::FindIfIndexForDevice (Ptr<Node> node, Ptr<NetDevice> nd, uint32_t &index) const
+GlobalRouter::FindInterfaceForDevice (Ptr<Node> node, Ptr<NetDevice> nd, uint32_t &index) const
 {
   NS_LOG_FUNCTION_NOARGS ();
   NS_LOG_LOGIC("For node " << node->GetId () << " for net device " << nd );
--- a/src/routing/global-routing/global-router-interface.h	Tue Apr 21 16:13:45 2009 +0400
+++ b/src/routing/global-routing/global-router-interface.h	Tue Apr 21 16:22:45 2009 +0400
@@ -644,7 +644,7 @@
   void ClearLSAs (void);
 
   Ptr<NetDevice> GetAdjacent(Ptr<NetDevice> nd, Ptr<Channel> ch) const;
-  bool FindIfIndexForDevice(Ptr<Node> node, Ptr<NetDevice> nd, uint32_t &index) const;
+  bool FindInterfaceForDevice(Ptr<Node> node, Ptr<NetDevice> nd, uint32_t &index) const;
   Ipv4Address FindDesignatedRouterForLink (Ptr<NetDevice> ndLocal, bool allowRecursion) const;
   bool AnotherRouterOnLink (Ptr<NetDevice> nd, bool allowRecursion) const;
   void ProcessBroadcastLink (Ptr<NetDevice> nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c);
--- a/src/routing/olsr/olsr-routing-protocol.cc	Tue Apr 21 16:13:45 2009 +0400
+++ b/src/routing/olsr/olsr-routing-protocol.cc	Tue Apr 21 16:22:45 2009 +0400
@@ -232,7 +232,8 @@
       Ipv4Address loopback ("127.0.0.1");
       for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
         {
-          Ipv4Address addr = m_ipv4->GetAddress (i);
+          // Use primary address, if multiple
+          Ipv4Address addr = m_ipv4->GetAddress (i, 0).GetLocal ();
           if (addr != loopback)
             {
               m_mainAddress = addr;
@@ -248,7 +249,7 @@
   Ipv4Address loopback ("127.0.0.1");
   for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
     {
-      Ipv4Address addr = m_ipv4->GetAddress (i);
+      Ipv4Address addr = m_ipv4->GetAddress (i, 0).GetLocal ();
       if (addr == loopback)
         continue;
 
@@ -285,7 +286,7 @@
 
 void RoutingProtocol::SetMainInterface (uint32_t interface)
 {
-  m_mainAddress = m_ipv4->GetAddress (interface);
+  m_mainAddress = m_ipv4->GetAddress (interface, 0).GetLocal ();
 }
 
 
@@ -1544,7 +1545,7 @@
   Ipv4Address loopback ("127.0.0.1");
   for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
     {
-      Ipv4Address addr = m_ipv4->GetAddress (i);
+      Ipv4Address addr = m_ipv4->GetAddress (i, 0).GetLocal ();
       if (addr != m_mainAddress && addr != loopback)
         mid.interfaceAddresses.push_back (addr);
     }
@@ -2590,7 +2591,7 @@
 }
 
 bool
-RoutingProtocol::RequestIfIndex (Ipv4Address destination,
+RoutingProtocol::RequestInterface (Ipv4Address destination,
                               uint32_t& ifIndex)
 {
   RoutingTableEntry entry1, entry2;
@@ -2652,10 +2653,13 @@
   RoutingTableEntry entry;
   for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
     {
-      if (m_ipv4->GetAddress (i) == interfaceAddress)
+      for (uint32_t j = 0; j < m_ipv4->GetNAddresses (i); j++)
         {
-          AddEntry (dest, next, i, distance);
-          return;
+          if (m_ipv4->GetAddress (i,j).GetLocal () == interfaceAddress)
+            {
+              AddEntry (dest, next, i, distance);
+              return;
+            }
         }
     }
   NS_ASSERT (false); // should not be reached
--- a/src/routing/olsr/olsr-routing-protocol.h	Tue Apr 21 16:13:45 2009 +0400
+++ b/src/routing/olsr/olsr-routing-protocol.h	Tue Apr 21 16:22:45 2009 +0400
@@ -125,7 +125,7 @@
                              const Ipv4Header &ipHeader,
                              Ptr<Packet> packet,
                              RouteReplyCallback routeReply);
-  virtual bool RequestIfIndex (Ipv4Address destination, 
+  virtual bool RequestInterface (Ipv4Address destination, 
                                uint32_t& ifIndex);
 
 
--- a/src/simulator/wscript	Tue Apr 21 16:13:45 2009 +0400
+++ b/src/simulator/wscript	Tue Apr 21 16:22:45 2009 +0400
@@ -31,7 +31,7 @@
 
     conf.check(header_name='sys/inttypes.h', define_name='HAVE_SYS_INT_TYPES_H')
 
-    conf.write_config_header('ns3/simulator-config.h')
+    conf.write_config_header('ns3/simulator-config.h', project_root_relative=True)
 
     if not conf.check(lib='rt', uselib='RT', define_name='HAVE_RT'):
         conf.report_optional_feature("RealTime", "Real Time Simulator",
--- a/src/wscript	Tue Apr 21 16:13:45 2009 +0400
+++ b/src/wscript	Tue Apr 21 16:22:45 2009 +0400
@@ -69,7 +69,7 @@
 
 
 def create_ns3_module(bld, name, dependencies=()):
-    module = bld.new_task_gen('cxx', 'objects')
+    module = bld.new_task_gen('cxx')
     module.name = 'ns3-' + name
     module.target = module.name
     module.add_objects = ['ns3-' + dep for dep in dependencies]
@@ -84,10 +84,6 @@
     return bld.new_task_gen(*args)
 
 def build(bld):
-    #Object.register('ns3header', Ns3Header)
-    #Action.Action('ns3header', func=_ns3_headers_inst, color='BLUE')
-    #Object.register('ns3-module-header', Ns3ModuleHeader)
-    #Action.Action('gen-ns3-module-header', func=gen_ns3_module_header, color='BLUE')
     bld.create_ns3_module = types.MethodType(create_ns3_module, bld)
     bld.create_obj = types.MethodType(create_obj, bld)
     
Binary file waf has changed
--- a/wscript	Tue Apr 21 16:13:45 2009 +0400
+++ b/wscript	Tue Apr 21 16:22:45 2009 +0400
@@ -174,7 +174,7 @@
     try:
         retval = conf.run_c_code(code='#include <stdio.h>\nint main() { return 0; }\n',
                                  env=env, compile_filename='test.cc',
-                                 compile_mode='cxx',type='program', execute=False)
+                                 compile_mode='cxx',type='cprogram', execute=False)
     except Configure.ConfigurationError:
         ok = False
     else:
@@ -251,6 +251,12 @@
             env.append_value("LINKFLAGS", "-Wl,--enable-runtime-pseudo-reloc")
         elif sys.platform == 'cygwin':
             env.append_value("LINKFLAGS", "-Wl,--enable-auto-import")
+        cxx, = env['CXX']
+        p = subprocess.Popen([cxx, '-print-file-name=libstdc++.so'], stdout=subprocess.PIPE)
+        libstdcxx_location = os.path.dirname(p.stdout.read().strip())
+        p.wait()
+        if libstdcxx_location:
+            conf.env.append_value('NS3_MODULE_PATH', libstdcxx_location)
 
     conf.sub_config('src')
     conf.sub_config('utils')
@@ -296,10 +302,11 @@
     after = 'cxx_link cc_link'
     maxjobs = 1
     def __init__(self, bld, program):
+        self.bld = bld
         self.m_display = 'build-suid'
         self.__program = program
         self.__env = bld.env.copy ()
-        super(SuidBuildTask, self).__init__()
+        super(SuidBuildTask, self).__init__(generator=self)
         try:
             program_obj = wutils.find_program(self.__program.target, self.__env)
         except ValueError, ex:
@@ -498,7 +505,7 @@
     "run the NS-3 unit tests"
     Scripting.build(bld)
     ## generate the trace sources list docs
-    env = bld.env
+    env = wutils.bld.env
     proc_env = wutils.get_proc_env()
     try:
         program_obj = wutils.find_program('print-introspected-doxygen', env)
@@ -514,11 +521,12 @@
         out.close()
 
     print "-- Running NS-3 C++ core unit tests..."
-    wutils.run_program('run-tests', wutils.get_command_template(env))
+    wutils.run_program('run-tests', env, wutils.get_command_template(env))
 
     if env['ENABLE_PYTHON_BINDINGS']:
         print "-- Running NS-3 Python bindings unit tests..."
-        wutils.run_argv([env['PYTHON'], os.path.join("utils", "python-unit-tests.py")], env, proc_env)
+        wutils.run_argv([env['PYTHON'], os.path.join("utils", "python-unit-tests.py")],
+                        env, proc_env, force_no_valgrind=True)
     else:
         print "-- Skipping NS-3 Python bindings unit tests: Python bindings not enabled."
 
--- a/wutils.py	Tue Apr 21 16:13:45 2009 +0400
+++ b/wutils.py	Tue Apr 21 16:22:45 2009 +0400
@@ -114,9 +114,9 @@
 
     return proc_env
 
-def run_argv(argv, env, os_env=None, cwd=None):
+def run_argv(argv, env, os_env=None, cwd=None, force_no_valgrind=False):
     proc_env = get_proc_env(os_env)
-    if Options.options.valgrind:
+    if Options.options.valgrind and not force_no_valgrind:
         if Options.options.command_template:
             raise Utils.WafError("Options --command-template and --valgrind are conflicting")
         if not env['VALGRIND']: