Mac16Address added, Mac64Address refactored, and Mac[16,64]Address can be used in IPv6
authorTommaso Pecorella <tommaso.pecorella@unifi.it>
Sat, 13 Jul 2013 12:35:55 +0200
changeset 9946 df4a7e93c13d
parent 9945 9a867fd76097
child 9947 0763593e84ad
Mac16Address added, Mac64Address refactored, and Mac[16,64]Address can be used in IPv6
CHANGES.html
RELEASE_NOTES
src/internet/helper/ipv6-address-helper.cc
src/internet/model/ipv6-interface.cc
src/internet/model/ipv6-l3-protocol.cc
src/network/utils/address-utils.cc
src/network/utils/address-utils.h
src/network/utils/ipv6-address.cc
src/network/utils/ipv6-address.h
src/network/utils/mac16-address.cc
src/network/utils/mac16-address.h
src/network/utils/mac64-address.cc
src/network/utils/mac64-address.h
src/network/wscript
--- a/CHANGES.html	Thu Jul 11 17:20:11 2013 -0700
+++ b/CHANGES.html	Sat Jul 13 12:35:55 2013 +0200
@@ -60,6 +60,10 @@
   <li>New generic hash function interface.  Two hash functions are provided:
       murmur3 (default), and the venerable FNV1a.  See the Hash Functions
       section in the Manual.</li>
+  <li>New Mac16Address has been added. It can be used with IPv6 to make
+      an Autoconfigured address.</li>
+  <li>Mac64Address support has been extended. It can now be used with 
+      IPv6 to make an Autoconfigured address.</li>
 </ul>
 
 <h2>Changes to existing API:</h2>
--- a/RELEASE_NOTES	Thu Jul 11 17:20:11 2013 -0700
+++ b/RELEASE_NOTES	Sat Jul 13 12:35:55 2013 +0200
@@ -27,6 +27,8 @@
 - New generic hash function interface.  Two hash functions are provided:
   murmur3 (default), and the venerable FNV1a.  See the Hash Functions
   section in the Manual.
+- New Mac16Address has been added, Mac64Address is now in-line with 
+  Mac48Address and all the three can be used in IPv6 autoconfigure. 
 
 Bugs fixed
 ----------
--- a/src/internet/helper/ipv6-address-helper.cc	Thu Jul 11 17:20:11 2013 -0700
+++ b/src/internet/helper/ipv6-address-helper.cc	Sat Jul 13 12:35:55 2013 +0200
@@ -23,7 +23,9 @@
 #include "ns3/ptr.h"
 #include "ns3/node.h"
 #include "ns3/net-device.h"
+#include "ns3/mac16-address.h"
 #include "ns3/mac48-address.h"
+#include "ns3/mac64-address.h"
 #include "ns3/ipv6.h"
 #include "ns3/ipv6-address-generator.h"
 
@@ -60,16 +62,30 @@
 Ipv6Address Ipv6AddressHelper::NewAddress (Address addr)
 {
   NS_LOG_FUNCTION (this << addr);
-  if (Mac48Address::IsMatchingType (addr))
+  if (Mac16Address::IsMatchingType (addr))
+    {
+      Ipv6Address network = Ipv6AddressGenerator::GetNetwork (Ipv6Prefix (64));
+      Ipv6Address address = Ipv6Address::MakeAutoconfiguredAddress (Mac16Address::ConvertFrom (addr), network);
+      Ipv6AddressGenerator::AddAllocated (address);
+      return address;
+    }
+  else if (Mac48Address::IsMatchingType (addr))
     {
       Ipv6Address network = Ipv6AddressGenerator::GetNetwork (Ipv6Prefix (64));
       Ipv6Address address = Ipv6Address::MakeAutoconfiguredAddress (Mac48Address::ConvertFrom (addr), network);
       Ipv6AddressGenerator::AddAllocated (address);
       return address;
-    } 
+    }
+  else if (Mac64Address::IsMatchingType (addr))
+    {
+      Ipv6Address network = Ipv6AddressGenerator::GetNetwork (Ipv6Prefix (64));
+      Ipv6Address address = Ipv6Address::MakeAutoconfiguredAddress (Mac64Address::ConvertFrom (addr), network);
+      Ipv6AddressGenerator::AddAllocated (address);
+      return address;
+    }
   else
     {
-      NS_FATAL_ERROR ("Did not pass in a Mac48Address");
+      NS_FATAL_ERROR ("Did not pass in a valid Mac Address (16, 48 or 64 bits)");
     }
   /* never reached */
   return Ipv6Address ("::");
--- a/src/internet/model/ipv6-interface.cc	Thu Jul 11 17:20:11 2013 -0700
+++ b/src/internet/model/ipv6-interface.cc	Sat Jul 13 12:35:55 2013 +0200
@@ -25,6 +25,8 @@
 #include "ipv6-interface.h"
 #include "ns3/net-device.h"
 #include "loopback-net-device.h"
+#include "ns3/mac16-address.h"
+#include "ns3/mac64-address.h"
 #include "ipv6-l3-protocol.h"
 #include "icmpv6-l4-protocol.h"
 #include "ndisc-cache.h"
@@ -87,11 +89,21 @@
     {
       Address addr = GetDevice ()->GetAddress ();
 
-      if (Mac48Address::IsMatchingType (addr))
+      if (Mac16Address::IsMatchingType (addr))
+        {
+          Ipv6InterfaceAddress ifaddr = Ipv6InterfaceAddress (Ipv6Address::MakeAutoconfiguredLinkLocalAddress (Mac16Address::ConvertFrom (addr)), Ipv6Prefix (64));
+          AddAddress (ifaddr);
+        }
+      else if (Mac48Address::IsMatchingType (addr))
         {
           Ipv6InterfaceAddress ifaddr = Ipv6InterfaceAddress (Ipv6Address::MakeAutoconfiguredLinkLocalAddress (Mac48Address::ConvertFrom (addr)), Ipv6Prefix (64));
           AddAddress (ifaddr);
         }
+      else if (Mac64Address::IsMatchingType (addr))
+        {
+          Ipv6InterfaceAddress ifaddr = Ipv6InterfaceAddress (Ipv6Address::MakeAutoconfiguredLinkLocalAddress (Mac64Address::ConvertFrom (addr)), Ipv6Prefix (64));
+          AddAddress (ifaddr);
+        }
       else
         {
           NS_ASSERT_MSG (false, "IPv6 autoconf for this kind of address not implemented.");
--- a/src/internet/model/ipv6-l3-protocol.cc	Thu Jul 11 17:20:11 2013 -0700
+++ b/src/internet/model/ipv6-l3-protocol.cc	Sat Jul 13 12:35:55 2013 +0200
@@ -28,6 +28,8 @@
 #include "ns3/object-vector.h"
 #include "ns3/ipv6-routing-protocol.h"
 #include "ns3/ipv6-route.h"
+#include "ns3/mac16-address.h"
+#include "ns3/mac64-address.h"
 
 #include "loopback-net-device.h"
 #include "ipv6-l3-protocol.h"
@@ -263,11 +265,19 @@
 
   if (flags & (1 << 6)) /* auto flag */
     {
-      /** \todo add other L2 address case */
-      if (Mac48Address::IsMatchingType (addr))
+      // In case of new MacAddress types, remember to change Ipv6L3Protocol::RemoveAutoconfiguredAddress as well
+      if (Mac16Address::IsMatchingType (addr))
+        {
+          address = Ipv6InterfaceAddress (Ipv6Address::MakeAutoconfiguredAddress (Mac16Address::ConvertFrom (addr), network));
+        }
+      else if (Mac48Address::IsMatchingType (addr))
         {
           address = Ipv6InterfaceAddress (Ipv6Address::MakeAutoconfiguredAddress (Mac48Address::ConvertFrom (addr), network));
         }
+      else if (Mac64Address::IsMatchingType (addr))
+        {
+          address = Ipv6InterfaceAddress (Ipv6Address::MakeAutoconfiguredAddress (Mac64Address::ConvertFrom (addr), network));
+        }
       else
         {
           NS_FATAL_ERROR ("Unknown method to make autoconfigured address for this kind of device.");
@@ -312,7 +322,25 @@
   Address addr = iface->GetDevice ()->GetAddress ();
   uint32_t max = iface->GetNAddresses ();
   uint32_t i = 0;
-  Ipv6Address toFound = Ipv6Address::MakeAutoconfiguredAddress (Mac48Address::ConvertFrom (addr), network);
+  Ipv6Address toFound;
+
+  if (Mac16Address::IsMatchingType (addr))
+    {
+      toFound = Ipv6Address::MakeAutoconfiguredAddress (Mac16Address::ConvertFrom (addr), network);
+    }
+  else if (Mac48Address::IsMatchingType (addr))
+    {
+      toFound = Ipv6Address::MakeAutoconfiguredAddress (Mac48Address::ConvertFrom (addr), network);
+    }
+  else if (Mac64Address::IsMatchingType (addr))
+    {
+      toFound = Ipv6Address::MakeAutoconfiguredAddress (Mac64Address::ConvertFrom (addr), network);
+    }
+  else
+    {
+      NS_FATAL_ERROR ("Unknown method to make autoconfigured address for this kind of device.");
+      return;
+    }
 
   for (i = 0; i < max; i++)
     {
--- a/src/network/utils/address-utils.cc	Thu Jul 11 17:20:11 2013 -0700
+++ b/src/network/utils/address-utils.cc	Sat Jul 13 12:35:55 2013 +0200
@@ -44,6 +44,13 @@
   ad.CopyTo (mac);
   i.Write (mac, ad.GetLength ());
 }
+void WriteTo (Buffer::Iterator &i, Mac64Address ad)
+{
+  NS_LOG_FUNCTION (&i << &ad);
+  uint8_t mac[8];
+  ad.CopyTo (mac);
+  i.Write (mac, 8);
+}
 void WriteTo (Buffer::Iterator &i, Mac48Address ad)
 {
   NS_LOG_FUNCTION (&i << &ad);
@@ -51,6 +58,14 @@
   ad.CopyTo (mac);
   i.Write (mac, 6);
 }
+void WriteTo (Buffer::Iterator &i, Mac16Address ad)
+{
+  NS_LOG_FUNCTION (&i << &ad);
+  uint8_t mac[2];
+  ad.CopyTo (mac);
+  i.Write (mac+1, 1);
+  i.Write (mac, 1);
+}
 
 void ReadFrom (Buffer::Iterator &i, Ipv4Address &ad)
 {
@@ -71,6 +86,13 @@
   i.Read (mac, len);
   ad.CopyFrom (mac, len);
 }
+void ReadFrom (Buffer::Iterator &i, Mac64Address &ad)
+{
+  NS_LOG_FUNCTION (&i << &ad);
+  uint8_t mac[8];
+  i.Read (mac, 8);
+  ad.CopyFrom (mac);
+}
 void ReadFrom (Buffer::Iterator &i, Mac48Address &ad)
 {
   NS_LOG_FUNCTION (&i << &ad);
@@ -78,6 +100,14 @@
   i.Read (mac, 6);
   ad.CopyFrom (mac);
 }
+void ReadFrom (Buffer::Iterator &i, Mac16Address &ad)
+{
+  NS_LOG_FUNCTION (&i << &ad);
+  uint8_t mac[2];
+  i.Read (mac+1, 1);
+  i.Read (mac, 1);
+  ad.CopyFrom (mac);
+}
 
 namespace addressUtils {
 
--- a/src/network/utils/address-utils.h	Thu Jul 11 17:20:11 2013 -0700
+++ b/src/network/utils/address-utils.h	Sat Jul 13 12:35:55 2013 +0200
@@ -24,19 +24,25 @@
 #include "ipv4-address.h"
 #include "ipv6-address.h"
 #include "ns3/address.h"
+#include "mac64-address.h"
 #include "mac48-address.h"
+#include "mac16-address.h"
 
 namespace ns3 {
 
 void WriteTo (Buffer::Iterator &i, Ipv4Address ad);
 void WriteTo (Buffer::Iterator &i, Ipv6Address ad);
 void WriteTo (Buffer::Iterator &i, const Address &ad);
+void WriteTo (Buffer::Iterator &i, Mac64Address ad);
 void WriteTo (Buffer::Iterator &i, Mac48Address ad);
+void WriteTo (Buffer::Iterator &i, Mac16Address ad);
 
 void ReadFrom (Buffer::Iterator &i, Ipv4Address &ad);
 void ReadFrom (Buffer::Iterator &i, Ipv6Address &ad);
 void ReadFrom (Buffer::Iterator &i, Address &ad, uint32_t len);
+void ReadFrom (Buffer::Iterator &i, Mac64Address &ad);
 void ReadFrom (Buffer::Iterator &i, Mac48Address &ad);
+void ReadFrom (Buffer::Iterator &i, Mac16Address &ad);
 
 namespace addressUtils {
 
--- a/src/network/utils/ipv6-address.cc	Thu Jul 11 17:20:11 2013 -0700
+++ b/src/network/utils/ipv6-address.cc	Sat Jul 13 12:35:55 2013 +0200
@@ -24,7 +24,9 @@
 #include "ns3/log.h"
 #include "ns3/assert.h"
 
+#include "mac16-address.h"
 #include "mac48-address.h"
+#include "mac64-address.h"
 #include "ipv6-address.h"
 
 NS_LOG_COMPONENT_DEFINE ("Ipv6Address");
@@ -332,6 +334,24 @@
     return (v4Addr);
 }
 
+Ipv6Address Ipv6Address::MakeAutoconfiguredAddress (Mac16Address addr, Ipv6Address prefix)
+{
+  NS_LOG_FUNCTION (addr << prefix);
+  Ipv6Address ret;
+  uint8_t buf[2];
+  uint8_t buf2[16];
+
+  addr.CopyTo (buf);
+  prefix.GetBytes (buf2);
+
+  memcpy (buf2 + 14, buf, 2);
+  buf2[11] = 0xff;
+  buf2[12] = 0xfe;
+
+  ret.Set (buf2);
+  return ret;
+}
+
 Ipv6Address Ipv6Address::MakeAutoconfiguredAddress (Mac48Address addr, Ipv6Address prefix)
 {
   NS_LOG_FUNCTION (addr << prefix);
@@ -352,6 +372,42 @@
   return ret;
 }
 
+Ipv6Address Ipv6Address::MakeAutoconfiguredAddress (Mac64Address addr, Ipv6Address prefix)
+{
+  NS_LOG_FUNCTION (addr << prefix);
+  Ipv6Address ret;
+  uint8_t buf[8];
+  uint8_t buf2[16];
+
+  addr.CopyTo (buf);
+  prefix.GetBytes (buf2);
+
+  memcpy (buf2 + 8, buf, 8);
+
+  ret.Set (buf2);
+  return ret;
+}
+
+Ipv6Address Ipv6Address::MakeAutoconfiguredLinkLocalAddress (Mac16Address addr)
+{
+  NS_LOG_FUNCTION (addr);
+  Ipv6Address ret;
+  uint8_t buf[2];
+  uint8_t buf2[16];
+
+  addr.CopyTo (buf);
+
+  memset (buf2, 0x00, sizeof (buf2));
+  buf2[0] = 0xfe;
+  buf2[1] = 0x80;
+  memcpy (buf2 + 14, buf, 2);
+  buf2[11] = 0xff;
+  buf2[12] = 0xfe;
+
+  ret.Set (buf2);
+  return ret;
+}
+
 Ipv6Address Ipv6Address::MakeAutoconfiguredLinkLocalAddress (Mac48Address addr)
 {
   NS_LOG_FUNCTION (addr);
@@ -374,6 +430,24 @@
   return ret;
 }
 
+Ipv6Address Ipv6Address::MakeAutoconfiguredLinkLocalAddress (Mac64Address addr)
+{
+  NS_LOG_FUNCTION (addr);
+  Ipv6Address ret;
+  uint8_t buf[8];
+  uint8_t buf2[16];
+
+  addr.CopyTo (buf);
+
+  memset (buf2, 0x00, sizeof (buf2));
+  buf2[0] = 0xfe;
+  buf2[1] = 0x80;
+  memcpy (buf2 + 8, buf, 8);
+
+  ret.Set (buf2);
+  return ret;
+}
+
 Ipv6Address Ipv6Address::MakeSolicitedAddress (Ipv6Address addr)
 {
   NS_LOG_FUNCTION (addr);
--- a/src/network/utils/ipv6-address.h	Thu Jul 11 17:20:11 2013 -0700
+++ b/src/network/utils/ipv6-address.h	Sat Jul 13 12:35:55 2013 +0200
@@ -33,7 +33,9 @@
 namespace ns3 { 
 
 class Ipv6Prefix;
+class Mac16Address;
 class Mac48Address;
+class Mac64Address;
 
 /**
  * \ingroup address
@@ -136,6 +138,14 @@
   Ipv4Address GetIpv4MappedAddress () const;
 
   /**
+   * \brief Make the autoconfigured IPv6 address with Mac16Address.
+   * \param addr the MAC address (16 bits).
+   * \param prefix the IPv6 prefix
+   * \return autoconfigured IPv6 address
+   */
+  static Ipv6Address MakeAutoconfiguredAddress (Mac16Address addr, Ipv6Address prefix);
+
+  /**
    * \brief Make the autoconfigured IPv6 address with Mac48Address.
    * \param addr the MAC address (48 bits).
    * \param prefix the IPv6 prefix
@@ -144,6 +154,21 @@
   static Ipv6Address MakeAutoconfiguredAddress (Mac48Address addr, Ipv6Address prefix);
 
   /**
+   * \brief Make the autoconfigured IPv6 address with Mac48Address.
+   * \param addr the MAC address (64 bits).
+   * \param prefix the IPv6 prefix
+   * \return autoconfigured IPv6 address
+   */
+  static Ipv6Address MakeAutoconfiguredAddress (Mac64Address addr, Ipv6Address prefix);
+
+  /**
+   * \brief Make the autoconfigured link-local IPv6 address with Mac16Address.
+   * \param mac the MAC address (16 bits).
+   * \return autoconfigured link-local IPv6 address
+   */
+  static Ipv6Address MakeAutoconfiguredLinkLocalAddress (Mac16Address mac);
+
+  /**
    * \brief Make the autoconfigured link-local IPv6 address with Mac48Address.
    * \param mac the MAC address (48 bits).
    * \return autoconfigured link-local IPv6 address
@@ -151,6 +176,13 @@
   static Ipv6Address MakeAutoconfiguredLinkLocalAddress (Mac48Address mac);
 
   /**
+   * \brief Make the autoconfigured link-local IPv6 address with Mac48Address.
+   * \param mac the MAC address (64 bits).
+   * \return autoconfigured link-local IPv6 address
+   */
+  static Ipv6Address MakeAutoconfiguredLinkLocalAddress (Mac64Address mac);
+
+  /**
    * \brief Print this address to the given output stream.
    *
    * The print format is in the typical "2001:660:4701::1".
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/network/utils/mac16-address.cc	Sat Jul 13 12:35:55 2013 +0200
@@ -0,0 +1,210 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * Copyright (c) 2011 The Boeing Company
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include "mac16-address.h"
+#include "ns3/address.h"
+#include "ns3/assert.h"
+#include "ns3/log.h"
+#include <iomanip>
+#include <iostream>
+#include <cstring>
+
+NS_LOG_COMPONENT_DEFINE ("Mac16Address");
+
+namespace ns3 {
+
+ATTRIBUTE_HELPER_CPP (Mac16Address);
+
+#define ASCII_a (0x41)
+#define ASCII_z (0x5a)
+#define ASCII_A (0x61)
+#define ASCII_Z (0x7a)
+#define ASCII_COLON (0x3a)
+#define ASCII_ZERO (0x30)
+
+static char
+AsciiToLowCase (char c)
+{
+  if (c >= ASCII_a && c <= ASCII_z) {
+      return c;
+    } else if (c >= ASCII_A && c <= ASCII_Z) {
+      return c + (ASCII_a - ASCII_A);
+    } else {
+      return c;
+    }
+}
+
+
+Mac16Address::Mac16Address ()
+{
+  NS_LOG_FUNCTION (this);
+  memset (m_address, 0, 2);
+}
+
+Mac16Address::Mac16Address (const char *str)
+{
+  NS_LOG_FUNCTION (this << str);
+  int i = 0;
+  while (*str != 0 && i < 2)
+    {
+      uint8_t byte = 0;
+      while (*str != ASCII_COLON && *str != 0)
+        {
+          byte <<= 4;
+          char low = AsciiToLowCase (*str);
+          if (low >= ASCII_a)
+            {
+              byte |= low - ASCII_a + 10;
+            }
+          else
+            {
+              byte |= low - ASCII_ZERO;
+            }
+          str++;
+        }
+      m_address[i] = byte;
+      i++;
+      if (*str == 0)
+        {
+          break;
+        }
+      str++;
+    }
+  NS_ASSERT (i == 2);
+}
+
+void
+Mac16Address::CopyFrom (const uint8_t buffer[2])
+{
+  NS_LOG_FUNCTION (this << &buffer);
+  memcpy (m_address, buffer, 2);
+}
+void
+Mac16Address::CopyTo (uint8_t buffer[2]) const
+{
+  NS_LOG_FUNCTION (this << &buffer);
+  memcpy (buffer, m_address, 2);
+}
+
+bool
+Mac16Address::IsMatchingType (const Address &address)
+{
+  NS_LOG_FUNCTION (&address);
+  return address.CheckCompatible (GetType (), 2);
+}
+
+Mac16Address::operator Address () const
+{
+  return ConvertTo ();
+}
+
+Mac16Address
+Mac16Address::ConvertFrom (const Address &address)
+{
+  NS_LOG_FUNCTION (address);
+  NS_ASSERT (address.CheckCompatible (GetType (), 2));
+  Mac16Address retval;
+  address.CopyTo (retval.m_address);
+  return retval;
+}
+Address
+Mac16Address::ConvertTo (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return Address (GetType (), m_address, 2);
+}
+
+Mac16Address
+Mac16Address::Allocate (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  static uint64_t id = 0;
+  id++;
+  Mac16Address address;
+  address.m_address[0] = (id >> 8) & 0xff;
+  address.m_address[1] = (id >> 0) & 0xff;
+  return address;
+}
+
+uint8_t
+Mac16Address::GetType (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  static uint8_t type = Address::Register ();
+  return type;
+}
+
+std::ostream & operator<< (std::ostream& os, const Mac16Address & address)
+{
+  uint8_t ad[2];
+  address.CopyTo (ad);
+
+  os.setf (std::ios::hex, std::ios::basefield);
+  os.fill ('0');
+  for (uint8_t i = 0; i < 1; i++)
+    {
+      os << std::setw (2) << (uint32_t)ad[i] << ":";
+    }
+  // Final byte not suffixed by ":"
+  os << std::setw (2) << (uint32_t)ad[1];
+  os.setf (std::ios::dec, std::ios::basefield);
+  os.fill (' ');
+  return os;
+}
+
+static uint8_t
+AsInt (std::string v)
+{
+  NS_LOG_FUNCTION (v);
+  std::istringstream iss;
+  iss.str (v);
+  uint32_t retval;
+  iss >> std::hex >> retval >> std::dec;
+  return retval;
+}
+
+std::istream& operator>> (std::istream& is, Mac16Address & address)
+{
+  std::string v;
+  is >> v;
+
+  std::string::size_type col = 0;
+  for (uint8_t i = 0; i < 2; ++i)
+    {
+      std::string tmp;
+      std::string::size_type next;
+      next = v.find (":", col);
+      if (next == std::string::npos)
+        {
+          tmp = v.substr (col, v.size ()-col);
+          address.m_address[i] = AsInt (tmp);
+          break;
+        }
+      else
+        {
+          tmp = v.substr (col, next-col);
+          address.m_address[i] = AsInt (tmp);
+          col = next + 1;
+        }
+    }
+  return is;
+}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/network/utils/mac16-address.h	Sat Jul 13 12:35:55 2013 +0200
@@ -0,0 +1,127 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * Copyright (c) 2011 The Boeing Company
+ *
+ * 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 MAC16_ADDRESS_H
+#define MAC16_ADDRESS_H
+
+#include <stdint.h>
+#include <ostream>
+#include "ns3/attribute.h"
+#include "ns3/attribute-helper.h"
+#include "ipv4-address.h"
+#include "ipv6-address.h"
+
+namespace ns3 {
+
+class Address;
+
+/**
+ * \ingroup address
+ *
+ * This class can contain 16 bit addresses.
+ */
+class Mac16Address
+{
+public:
+  Mac16Address ();
+  /**
+   * \param str a string representing the new Mac16Address
+   *
+  */
+  Mac16Address (const char *str);
+
+  /**
+   * \param buffer address in network order
+   *
+   * Copy the input address to our internal buffer.
+   */
+  void CopyFrom (const uint8_t buffer[2]);
+  /**
+   * \param buffer address in network order
+   *
+   * Copy the internal address to the input buffer.
+   */
+  void CopyTo (uint8_t buffer[2]) const;
+  /**
+   * \returns a new Address instance
+   *
+   * Convert an instance of this class to a polymorphic Address instance.
+   */
+  operator Address () const;
+  /**
+   * \param address a polymorphic address
+   * \returns a new Mac16Address from the polymorphic address
+   *
+   * This function performs a type check and asserts if the
+   * type of the input address is not compatible with an
+   * Mac16Address.
+   */
+  static Mac16Address ConvertFrom (const Address &address);
+  /**
+   * \param address address to test
+   * \returns true if the address matches, false otherwise.
+   */
+  static bool IsMatchingType (const Address &address);
+  /**
+   * Allocate a new Mac16Address.
+   */
+  static Mac16Address Allocate (void);
+
+private:
+  /**
+   * \returns a new Address instance
+   *
+   * Convert an instance of this class to a polymorphic Address instance.
+   */
+  Address ConvertTo (void) const;
+  static uint8_t GetType (void);
+  friend bool operator < (const Mac16Address &a, const Mac16Address &b);
+  friend bool operator == (const Mac16Address &a, const Mac16Address &b);
+  friend bool operator != (const Mac16Address &a, const Mac16Address &b);
+  friend std::istream& operator>> (std::istream& is, Mac16Address & address);
+
+  uint8_t m_address[2];
+};
+
+/**
+ * \class ns3::Mac16AddressValue
+ * \brief hold objects of type ns3::Mac16Address
+ */
+
+ATTRIBUTE_HELPER_HEADER (Mac16Address);
+
+inline bool operator == (const Mac16Address &a, const Mac16Address &b)
+{
+  return memcmp (a.m_address, b.m_address, 2) == 0;
+}
+inline bool operator != (const Mac16Address &a, const Mac16Address &b)
+{
+  return memcmp (a.m_address, b.m_address, 2) != 0;
+}
+inline bool operator < (const Mac16Address &a, const Mac16Address &b)
+{
+  return memcmp (a.m_address, b.m_address, 2) < 0;
+}
+
+std::ostream& operator<< (std::ostream& os, const Mac16Address & address);
+std::istream& operator>> (std::istream& is, Mac16Address & address);
+
+} // namespace ns3
+
+#endif /* MAC16_ADDRESS_H */
--- a/src/network/utils/mac64-address.cc	Thu Jul 11 17:20:11 2013 -0700
+++ b/src/network/utils/mac64-address.cc	Sat Jul 13 12:35:55 2013 +0200
@@ -29,6 +29,8 @@
 
 namespace ns3 {
 
+ATTRIBUTE_HELPER_CPP (Mac64Address);
+
 #define ASCII_a (0x41)
 #define ASCII_z (0x5a)
 #define ASCII_A (0x61)
@@ -84,7 +86,7 @@
         }
       str++;
     }
-  NS_ASSERT (i == 6);
+  NS_ASSERT (i == 8);
 }
 void 
 Mac64Address::CopyFrom (const uint8_t buffer[8])
@@ -151,19 +153,6 @@
   return type;
 }
 
-bool operator == (const Mac64Address &a, const Mac64Address &b)
-{
-  uint8_t ada[8];
-  uint8_t adb[8];
-  a.CopyTo (ada);
-  b.CopyTo (adb);
-  return std::memcmp (ada, adb, 8) == 0;
-}
-bool operator != (const Mac64Address &a, const Mac64Address &b)
-{
-  return !(a == b);
-}
-
 std::ostream& operator<< (std::ostream& os, const Mac64Address & address)
 {
   uint8_t ad[8];
@@ -182,5 +171,42 @@
   return os;
 }
 
+static uint8_t
+AsInt (std::string v)
+{
+  NS_LOG_FUNCTION (v);
+  std::istringstream iss;
+  iss.str (v);
+  uint32_t retval;
+  iss >> std::hex >> retval >> std::dec;
+  return retval;
+}
+
+std::istream& operator>> (std::istream& is, Mac64Address & address)
+{
+  std::string v;
+  is >> v;
+
+  std::string::size_type col = 0;
+  for (uint8_t i = 0; i < 8; ++i)
+    {
+      std::string tmp;
+      std::string::size_type next;
+      next = v.find (":", col);
+      if (next == std::string::npos)
+        {
+          tmp = v.substr (col, v.size ()-col);
+          address.m_address[i] = AsInt (tmp);
+          break;
+        }
+      else
+        {
+          tmp = v.substr (col, next-col);
+          address.m_address[i] = AsInt (tmp);
+          col = next + 1;
+        }
+    }
+  return is;
+}
 
 } // namespace ns3
--- a/src/network/utils/mac64-address.h	Thu Jul 11 17:20:11 2013 -0700
+++ b/src/network/utils/mac64-address.h	Sat Jul 13 12:35:55 2013 +0200
@@ -22,6 +22,10 @@
 
 #include <stdint.h>
 #include <ostream>
+#include "ns3/attribute.h"
+#include "ns3/attribute-helper.h"
+#include "ipv4-address.h"
+#include "ipv6-address.h"
 
 namespace ns3 {
 
@@ -89,12 +93,36 @@
    */
   Address ConvertTo (void) const;
   static uint8_t GetType (void);
+  friend bool operator < (const Mac64Address &a, const Mac64Address &b);
+  friend bool operator == (const Mac64Address &a, const Mac64Address &b);
+  friend bool operator != (const Mac64Address &a, const Mac64Address &b);
+  friend std::istream& operator>> (std::istream& is, Mac64Address & address);
+
   uint8_t m_address[8];
 };
 
-bool operator == (const Mac64Address &a, const Mac64Address &b);
-bool operator != (const Mac64Address &a, const Mac64Address &b);
+/**
+ * \class ns3::Mac64AddressValue
+ * \brief hold objects of type ns3::Mac64Address
+ */
+
+ATTRIBUTE_HELPER_HEADER (Mac64Address);
+
+inline bool operator == (const Mac64Address &a, const Mac64Address &b)
+{
+  return memcmp (a.m_address, b.m_address, 8) == 0;
+}
+inline bool operator != (const Mac64Address &a, const Mac64Address &b)
+{
+  return memcmp (a.m_address, b.m_address, 8) != 0;
+}
+inline bool operator < (const Mac64Address &a, const Mac64Address &b)
+{
+  return memcmp (a.m_address, b.m_address, 8) < 0;
+}
+
 std::ostream& operator<< (std::ostream& os, const Mac64Address & address);
+std::istream& operator>> (std::istream& is, Mac64Address & address);
 
 } // namespace ns3
 
--- a/src/network/wscript	Thu Jul 11 17:20:11 2013 -0700
+++ b/src/network/wscript	Sat Jul 13 12:35:55 2013 +0200
@@ -35,6 +35,7 @@
         'utils/inet6-socket-address.cc',
         'utils/ipv4-address.cc',
         'utils/ipv6-address.cc',
+        'utils/mac16-address.cc',
         'utils/mac48-address.cc',
         'utils/mac64-address.cc',
         'utils/llc-snap-header.cc',
@@ -109,6 +110,7 @@
         'utils/ipv4-address.h',
         'utils/ipv6-address.h',
         'utils/llc-snap-header.h',
+        'utils/mac16-address.h',
         'utils/mac48-address.h',
         'utils/mac64-address.h',
         'utils/output-stream-wrapper.h',