Move MakeMulticastAddress to NetDevice
authorCraig Dowell <craigdo@ee.washington.edu>
Wed, 29 Aug 2007 12:11:11 -0700
changeset 1443 580ed7a4dd1e
parent 1442 bb5cf98c0c64
child 1444 7c81b4e2617d
Move MakeMulticastAddress to NetDevice
src/devices/csma/csma-net-device.cc
src/devices/csma/csma-net-device.h
src/devices/point-to-point/point-to-point-net-device.cc
src/internet-node/arp-ipv4-interface.cc
src/internet-node/arp-ipv4-interface.h
src/internet-node/ipv4-l3-protocol.cc
src/node/net-device.cc
src/node/net-device.h
--- a/src/devices/csma/csma-net-device.cc	Mon Aug 27 23:46:14 2007 -0700
+++ b/src/devices/csma/csma-net-device.cc	Wed Aug 29 12:11:11 2007 -0700
@@ -19,8 +19,6 @@
  * Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
  */
 
-#include <iostream>
-#include <cassert>
 #include "ns3/debug.h"
 #include "ns3/queue.h"
 #include "ns3/simulator.h"
@@ -60,7 +58,6 @@
   return uid;
 }
 
-
 CsmaNetDevice::CsmaNetDevice (Ptr<Node> node)
   : NetDevice (node, Eui48Address::Allocate ()),
     m_bps (DataRate (0xffffffff))
@@ -71,7 +68,7 @@
 }
 
 CsmaNetDevice::CsmaNetDevice (Ptr<Node> node, Eui48Address addr, 
-                                  CsmaEncapsulationMode encapMode) 
+                              CsmaEncapsulationMode encapMode) 
   : NetDevice(node, addr), 
     m_bps (DataRate (0xffffffff))
 {
@@ -82,8 +79,8 @@
 }
 
 CsmaNetDevice::CsmaNetDevice (Ptr<Node> node, Eui48Address addr, 
-                                  CsmaEncapsulationMode encapMode,
-                                  bool sendEnable, bool receiveEnable) 
+                              CsmaEncapsulationMode encapMode,
+                              bool sendEnable, bool receiveEnable) 
   : NetDevice(node, addr), 
     m_bps (DataRate (0xffffffff))
 {
@@ -582,6 +579,61 @@
   return;
 }
 
+Address
+CsmaNetDevice::MakeMulticastAddress(Ipv4Address multicastGroup) const
+{
+  NS_DEBUG ("CsmaNetDevice::MakeMulticastAddress (" << multicastGroup <<
+    ")");
+//
+// First, get the generic multicast address.
+//
+  Address hardwareDestination = GetMulticast ();
+
+  NS_DEBUG ("CsmaNetDevice::MakeMulticastAddress (): "
+    "Device multicast address: " << hardwareDestination);
+//
+// It's our address, and we know we're playing with an EUI-48 address here
+// primarily since we know that by construction, but also since the parameter
+// is an Ipv4Address.
+//
+  Eui48Address etherAddr = Eui48Address::ConvertFrom (hardwareDestination);
+//
+// We now have the multicast address in an abstract 48-bit container.  We 
+// need to pull it out so we can play with it.  When we're done, we have the 
+// high order bits in etherBuffer[0], etc.
+//
+  uint8_t etherBuffer[6];
+  etherAddr.CopyTo (etherBuffer);
+//
+// Now we need to pull the raw bits out of the Ipv4 destination address.
+//
+  uint8_t ipBuffer[4];
+  multicastGroup.Serialize (ipBuffer);
+//
+// RFC 1112 says that an Ipv4 host group address is mapped to an EUI-48
+// multicast address by placing the low-order 23-bits of the IP address into 
+// the low-order 23 bits of the Ethernet multicast address 
+// 01-00-5E-00-00-00 (hex). 
+//
+  etherBuffer[3] |= ipBuffer[1] & 0x7f;
+  etherBuffer[4] = ipBuffer[2];
+  etherBuffer[5] = ipBuffer[3];
+//
+// Now, etherBuffer has the desired ethernet multicast address.  We have to
+// suck these bits back into the Eui48Address,
+//
+  etherAddr.CopyFrom (etherBuffer);
+//
+// Implicit conversion (operator Address ()) is defined for Eui48Address, so
+// use it by just returning the EUI-48 address which is automagically converted
+// to an Address.
+//
+  NS_DEBUG ("CsmaNetDevice::MakeMulticastAddress (): "
+    "multicast address is " << etherAddr);
+
+  return etherAddr;
+}
+
 Ptr<Queue>
 CsmaNetDevice::GetQueue(void) const 
 { 
--- a/src/devices/csma/csma-net-device.h	Mon Aug 27 23:46:14 2007 -0700
+++ b/src/devices/csma/csma-net-device.h	Wed Aug 29 12:11:11 2007 -0700
@@ -197,6 +197,37 @@
    */
   void Receive (const Packet& p);
 
+  /**
+   * @brief Make and return a MAC multicast address using the provided
+   *        multicast group
+   *
+   * RFC 1112 says that an Ipv4 host group address is mapped to an Ethernet 
+   * multicast address by placing the low-order 23-bits of the IP address into 
+   * the low-order 23 bits of the Ethernet multicast address 
+   * 01-00-5E-00-00-00 (hex).
+   *
+   * This method performs the multicast address creation function appropriate
+   * to an EUI-48-based CSMA device.  This MAC address is encapsulated in an
+   *  abstract Address to avoid dependencies on the exact address format.
+   *
+   * A default imlementation of MakeMulticastAddress is provided, but this
+   * method simply NS_ASSERTS.  In the case of net devices that do not support
+   * multicast, clients are expected to test NetDevice::IsMulticast and avoid
+   * attempting to map multicast packets.  Subclasses of NetDevice that do
+   * support multicasting are expected to override this method and provide an
+   * implementation appropriate to the particular device.
+   *
+   * @param multicastGroup The IP address for the multicast group destination
+   * of the packet.
+   * @return The MAC multicast Address used to send packets to the provided
+   * multicast group.
+   *
+   * @see Ipv4Address
+   * @see Eui48Address
+   * @see Address
+   */
+  Address MakeMulticastAddress (Ipv4Address multicastGroup) const;
+
   bool IsSendEnabled (void);
   bool IsReceiveEnabled (void);
 
--- a/src/devices/point-to-point/point-to-point-net-device.cc	Mon Aug 27 23:46:14 2007 -0700
+++ b/src/devices/point-to-point/point-to-point-net-device.cc	Wed Aug 29 12:11:11 2007 -0700
@@ -20,8 +20,6 @@
  * Revised: George Riley <riley@ece.gatech.edu>
  */
 
-#include <iostream>
-#include <cassert>
 #include "ns3/debug.h"
 #include "ns3/queue.h"
 #include "ns3/simulator.h"
@@ -73,7 +71,7 @@
 // You _must_ support broadcast to get any sort of packet from the ARP layer.
   EnableBroadcast (Eui48Address ("ff:ff:ff:ff:ff:ff"));
 //
-// Randomly pick the ethernet multicast address base
+// We want to allow multicast packets to flow across this link
 //
   EnableMulticast (Eui48Address ("01:00:5e:00:00:00"));
   EnablePointToPoint();
@@ -214,6 +212,8 @@
   m_bps = m_channel->GetDataRate ();
   // GFR Comment.  Below is definitely wrong.  Interframe gap
   // is unrelated to channel delay.
+  // -- unlesss you want to introduce a default gap which is there to avoid
+  // parts of multiple packets flowing on the "wire" at the same time.
   //m_tInterframeGap = m_channel->GetDelay ();
 
   /* 
--- a/src/internet-node/arp-ipv4-interface.cc	Mon Aug 27 23:46:14 2007 -0700
+++ b/src/internet-node/arp-ipv4-interface.cc	Wed Aug 29 12:11:11 2007 -0700
@@ -61,74 +61,6 @@
   return resolver;
 }
 
-//
-// RFC 1112 says that an IP host group address is mapped to an Ethernet 
-// multicast address by placing the low-order 23-bits of the IP address into 
-// the low-order 23 bits of the Ethernet multicast address 01-00-5E-00-00-00 
-// (hex).  These are completely different animals and they're encapsulated
-// very nicely.  Translation: This isn't going to be very pretty.
-//
-Address
-ArpIpv4Interface::MakeMulticastAddress(Ipv4Address multicastGroup)
-{
-  NS_DEBUG ("ArpIpv4Interface::MakeMulticastAddress (" << multicastGroup <<
-    ")");
-//
-// First, get the generic multicast address from the device.  Since it is 
-// connected to this object, and this object is an IPV4 stack, we hope that
-// it is really an Eui48Address.  If it's not, then we don't know what to do.
-//
-  Address hardwareDestination = GetDevice ()->GetMulticast ();
-
-  NS_DEBUG ("ArpIpv4Interface::MakeMulticastAddress (): "
-    "Device multicast address: " << hardwareDestination);
-
-  Eui48Address etherAddr = Eui48Address::ConvertFrom (hardwareDestination);
-//
-// We now have the multicast address in an abstract 48-bit container.  We 
-// need to pull it out so we can play with it.  When we're done, we have the 
-// high order bits in etherBuffer[0], etc.
-//
-  uint8_t etherBuffer[6];
-  etherAddr.CopyTo (etherBuffer);
-//
-// If the device is playing the game correctly, the low order 23 bits of the
-// multicast base address will be zero.
-//
-  NS_ASSERT_MSG((etherBuffer[4] & 0x7f) == 0,
-    "ArpIpv4Interface::SendTo ():  Expected low order bits zeroed");
-  NS_ASSERT_MSG(etherBuffer[5] == 0, 
-    "ArpIpv4Interface::SendTo ():  Expected low order bits zeroed");
-  NS_ASSERT_MSG(etherBuffer[6] == 0, 
-    "ArpIpv4Interface::SendTo ():  Expected low order bits zeroed");
-//
-// Now we need to pull the raw bits out of the Ipv4 destination address.
-//
-  uint8_t ipBuffer[4];
-  multicastGroup.Serialize (ipBuffer);
-//
-// We need to place the low order 23 bits of the IP address into the low order
-// 23 bits of the ethernet address.
-//
-  etherBuffer[3] |= ipBuffer[1] & 0x7f;
-  etherBuffer[4] = ipBuffer[2];
-  etherBuffer[5] = ipBuffer[3];
-//
-// Now, etherBuffer has the desired ethernet multicast address.  We have to
-// suck these bits back into the Eui48Address; and then suck those bits back
-// into the abstract hardwareAddress.
-//
-  etherAddr.CopyFrom (etherBuffer);
-//
-// Implicit conversion (operator Address ()) is defined for Eui48Address, so
-// use it.
-//
-  NS_DEBUG ("ArpIpv4Interface::MakeMulticastAddress (): "
-    "multicast address is " << etherAddr);
-
-  return etherAddr;
-}
-
 void 
 ArpIpv4Interface::SendTo (Packet p, Ipv4Address dest)
 {
@@ -156,7 +88,7 @@
             "ArpIpv4Interface::SendTo (): Sending multicast packet over "
             "non-multicast device");
 
-          hardwareDestination = MakeMulticastAddress(dest);
+          hardwareDestination = GetDevice ()->MakeMulticastAddress(dest);
           found = true;
         }
       else
--- a/src/internet-node/arp-ipv4-interface.h	Mon Aug 27 23:46:14 2007 -0700
+++ b/src/internet-node/arp-ipv4-interface.h	Wed Aug 29 12:11:11 2007 -0700
@@ -47,7 +47,6 @@
   virtual void SendTo (Packet p, Ipv4Address dest);
   virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
   Ptr<Node> m_node;
-  Address MakeMulticastAddress (Ipv4Address multicastGroup);
 };
 
 }//namespace ns3
--- a/src/internet-node/ipv4-l3-protocol.cc	Mon Aug 27 23:46:14 2007 -0700
+++ b/src/internet-node/ipv4-l3-protocol.cc	Wed Aug 29 12:11:11 2007 -0700
@@ -504,6 +504,8 @@
   NS_DEBUG("Ipv4L3Protocol::Receive (" << &device << ", " << &p << ", " <<
     protocol << ", " << from << ")");
 
+  NS_DEBUG("Ipv4L3Protocol::Receive (): Packet from " << from);
+
   uint32_t index = 0;
   for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); 
        i != m_interfaces.end (); 
--- a/src/node/net-device.cc	Mon Aug 27 23:46:14 2007 -0700
+++ b/src/node/net-device.cc	Wed Aug 29 12:11:11 2007 -0700
@@ -140,10 +140,19 @@
   return m_isMulticast;
 }
 
-Address const &
+Address 
 NetDevice::GetMulticast (void) const
 {
-  NS_ASSERT (m_isMulticast);
+  NS_ASSERT_MSG (m_isMulticast, "NetDevice::GetMulticast (): "
+    "Invalid operation when not IsMulticast ()");
+  return m_multicast;
+}
+
+Address
+NetDevice::MakeMulticastAddress(Ipv4Address multicastGroup) const
+{
+  NS_ASSERT_MSG (m_isMulticast, "NetDevice::GetMulticast (): "
+    "Invalid operation when not IsMulticast ()");
   return m_multicast;
 }
 
--- a/src/node/net-device.h	Mon Aug 27 23:46:14 2007 -0700
+++ b/src/node/net-device.h	Wed Aug 29 12:11:11 2007 -0700
@@ -29,6 +29,7 @@
 #include "ns3/object.h"
 #include "ns3/ptr.h"
 #include "address.h"
+#include "ipv4-address.h"
 
 namespace ns3 {
 
@@ -145,13 +146,61 @@
   bool IsMulticast (void) const;
 
   /**
-   * \return the multicast address supported by
-   *         this netdevice.
+   * \brief Return the MAC multicast base address used when mapping multicast
+   * groups to MAC multicast addresses.
+   *
+   * Typically when one constructs a multicast MAC addresses, some bits from
+   * the IP multicast group are copied into a corresponding MAC multicast 
+   * group.  In EUI-48, for example, the low order 23 bits of the multicast
+   * group are copied to the MAC multicast group base address.
+   *
+   * This method allows access to the underlying MAC multicast group base 
+   * address.  It is expected that in most cases, a net device client will
+   * allow the net device to perform the actual construction of the multicast
+   * address.  Use of this method is discouraged unless you have a good reason
+   * to perform a custom mapping.  You should prefer 
+   * NetDevice::MakeMulticastAddress which will do the RFC-specified mapping
+   * for the net device in question.
+   *
+   * \return The multicast address supported by this net device.
+   *
+   * \warning Calling this method is invalid if IsMulticast returns not true.
+   * The method NS_ASSERTs if the device is not a multicast device.
+   * \see NetDevice::MakeMulticastAddress
+   */
+  Address GetMulticast (void) const;
+
+  /**
+   * \brief Make and return a MAC multicast address using the provided
+   *        multicast group
    *
-   * Calling this method is invalid if IsMulticast returns
-   * not true.
+   * RFC 1112 says that an Ipv4 host group address is mapped to an Ethernet 
+   * multicast address by placing the low-order 23-bits of the IP address into 
+   * the low-order 23 bits of the Ethernet multicast address 
+   * 01-00-5E-00-00-00 (hex).  Similar RFCs exist for Ipv6 and Eui64 mappings.
+   * This method performs the multicast address creation function appropriate
+   * to the underlying MAC address of the device.  This MAC address is
+   * encapsulated in an abstract Address to avoid dependencies on the exact
+   * MAC address format.
+   *
+   * A default imlementation of MakeMulticastAddress is provided, but this
+   * method simply NS_ASSERTS.  In the case of net devices that do not support
+   * multicast, clients are expected to test NetDevice::IsMulticast and avoid
+   * attempting to map multicast packets.  Subclasses of NetDevice that do
+   * support multicasting are expected to override this method and provide an
+   * implementation appropriate to the particular device.
+   *
+   * \param multicastGroup The IP address for the multicast group destination
+   * of the packet.
+   * \return The MAC multicast Address used to send packets to the provided
+   * multicast group.
+   *
+   * \warning Calling this method is invalid if IsMulticast returns not true.
+   * \see Ipv4Address
+   * \see Address
+   * \see NetDevice::IsMulticast
    */
-  Address const &GetMulticast (void) const;
+  virtual Address MakeMulticastAddress (Ipv4Address multicastGroup) const;
 
   /**
    * \return value of m_isPointToPoint flag