implementation and plumbing of Ipv4InterfaceAddress class
authorTom Henderson <tomh@tomh.org>
Wed, 08 Apr 2009 16:07:34 -0700
changeset 4373 e493e80274bd
parent 4372 d99061f1167c
child 4374 2aae35f2287f
implementation and plumbing of Ipv4InterfaceAddress class
src/internet-stack/ipv4-impl.cc
src/internet-stack/ipv4-impl.h
src/internet-stack/ipv4-interface.cc
src/internet-stack/ipv4-interface.h
src/internet-stack/ipv4-l3-protocol.cc
src/internet-stack/ipv4-l3-protocol.h
src/node/ipv4-interface-address.cc
src/node/ipv4-interface-address.h
src/node/ipv4.h
src/node/wscript
--- a/src/internet-stack/ipv4-impl.cc	Wed Apr 08 13:35:34 2009 -0700
+++ b/src/internet-stack/ipv4-impl.cc	Wed Apr 08 16:07:34 2009 -0700
@@ -189,6 +189,24 @@
   m_ipv4->LeaveMulticastGroup(origin, group);
 }
 
+uint32_t 
+Ipv4Impl::AddAddress (uint32_t i, Ipv4InterfaceAddress address)
+{
+  return m_ipv4->AddAddress (i, address);
+}
+
+Ipv4InterfaceAddress 
+Ipv4Impl::GetAddress (uint32_t interfaceIndex, uint32_t addressIndex) const
+{
+  return m_ipv4->GetAddress (interfaceIndex, addressIndex);
+}
+
+uint32_t 
+Ipv4Impl::GetNAddresses (uint32_t interface) const
+{
+  return m_ipv4->GetNAddresses (interface);
+}
+
 void 
 Ipv4Impl::SetAddress (uint32_t i, Ipv4Address address)
 {
--- a/src/internet-stack/ipv4-impl.h	Wed Apr 08 13:35:34 2009 -0700
+++ b/src/internet-stack/ipv4-impl.h	Wed Apr 08 16:07:34 2009 -0700
@@ -87,6 +87,10 @@
   virtual void JoinMulticastGroup (Ipv4Address origin, Ipv4Address group);
   virtual void LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group);
 
+  uint32_t AddAddress (uint32_t i, Ipv4InterfaceAddress address);
+  Ipv4InterfaceAddress GetAddress (uint32_t interfaceIndex, uint32_t addressIndex) const;
+  uint32_t GetNAddresses (uint32_t interface) const;
+
   virtual void SetAddress (uint32_t i, Ipv4Address address);
   virtual void SetNetworkMask (uint32_t i, Ipv4Mask mask);
   virtual Ipv4Mask GetNetworkMask (uint32_t t) const;
--- a/src/internet-stack/ipv4-interface.cc	Wed Apr 08 13:35:34 2009 -0700
+++ b/src/internet-stack/ipv4-interface.cc	Wed Apr 08 16:07:34 2009 -0700
@@ -170,5 +170,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	Wed Apr 08 13:35:34 2009 -0700
+++ b/src/internet-stack/ipv4-interface.h	Wed Apr 08 16:07:34 2009 -0700
@@ -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"
 
@@ -142,6 +143,28 @@
    */ 
   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:
@@ -150,6 +173,11 @@
   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	Wed Apr 08 13:35:34 2009 -0700
+++ b/src/internet-stack/ipv4-l3-protocol.cc	Wed Apr 08 16:07:34 2009 -0700
@@ -923,6 +923,30 @@
     }
 }
 
+uint32_t
+Ipv4L3Protocol::AddAddress (uint32_t i, Ipv4InterfaceAddress address)
+{
+  NS_LOG_FUNCTION (this << i << address);
+  Ptr<Ipv4Interface> interface = GetInterface (i);
+  return interface->AddAddress (address);
+}
+
+Ipv4InterfaceAddress
+Ipv4L3Protocol::GetAddress (uint32_t interfaceIndex, uint32_t addressIndex) const
+{
+  NS_LOG_FUNCTION (this << interfaceIndex << addressIndex);
+  Ptr<Ipv4Interface> interface = GetInterface (interfaceIndex);
+  return interface->GetAddress (addressIndex);
+}
+
+uint32_t
+Ipv4L3Protocol::GetNAddresses (uint32_t interface) const
+{
+  NS_LOG_FUNCTION (this << interface);
+  Ptr<Ipv4Interface> iface = GetInterface (interface);
+  return iface->GetNAddresses ();
+}
+
 void 
 Ipv4L3Protocol::SetAddress (uint32_t i, Ipv4Address address)
 {
--- a/src/internet-stack/ipv4-l3-protocol.h	Wed Apr 08 13:35:34 2009 -0700
+++ b/src/internet-stack/ipv4-l3-protocol.h	Wed Apr 08 16:07:34 2009 -0700
@@ -187,6 +187,10 @@
   void JoinMulticastGroup (Ipv4Address origin, Ipv4Address group);
   void LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group);
 
+  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 SetAddress (uint32_t i, Ipv4Address address);
   void SetNetworkMask (uint32_t i, Ipv4Mask mask);
   Ipv4Mask GetNetworkMask (uint32_t t) const;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ipv4-interface-address.cc	Wed Apr 08 16:07:34 2009 -0700
@@ -0,0 +1,156 @@
+/* -*-  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_peer (o.m_peer),
+    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::SetPeer (Ipv4Address peer)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_peer = peer;
+}
+
+Ipv4Address 
+Ipv4InterfaceAddress::GetPeer (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_peer;
+}
+
+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_peer=" << addr.GetPeer () << "; 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	Wed Apr 08 16:07:34 2009 -0700
@@ -0,0 +1,84 @@
+/* -*-  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 {
+
+/**
+ * \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 SetPeer (Ipv4Address peer);
+  Ipv4Address GetPeer (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
+  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.h	Wed Apr 08 13:35:34 2009 -0700
+++ b/src/node/ipv4.h	Wed Apr 08 16:07:34 2009 -0700
@@ -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"
@@ -391,6 +392,26 @@
   virtual void LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group) = 0;
 
   /**
+   * \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 uint32_t AddAddress (uint32_t interface, Ipv4InterfaceAddress address) = 0;
+
+  /**
+   * \param interface Interface number of an Ipv4 interface
+   * \returns the number of Ipv4InterfaceAddress entries for the interface.
+   */
+  virtual uint32_t GetNAddresses (uint32_t interface) const = 0;
+
+  /**
+   * \param interface Interface number of an Ipv4 interface
+   * \param addressIndex index of Ipv4InterfaceAddress
+   * \returns the Ipv4InterfaceAddress associated to the interface and addresIndex
+   */
+  virtual Ipv4InterfaceAddress GetAddress (uint32_t interface, uint32_t addressIndex) const = 0;
+
+  /**
    * \param i index of ipv4 interface
    * \param address address to associate to the underlying ipv4 interface
    */
--- a/src/node/wscript	Wed Apr 08 13:35:34 2009 -0700
+++ b/src/node/wscript	Wed Apr 08 16:07:34 2009 -0700
@@ -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',