src/devices/csma/csma-net-device.cc
changeset 1443 580ed7a4dd1e
parent 1442 bb5cf98c0c64
child 1449 df86e6b876ef
--- 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 
 {