From 2d73bd99275da4420132d475ff390634fd741ea7 Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Wed, 29 Aug 2007 12:11:11 -0700 Subject: [PATCH] Move MakeMulticastAddress to NetDevice --- src/devices/csma/csma-net-device.cc | 64 +++++++++++++++-- src/devices/csma/csma-net-device.h | 31 ++++++++ .../point-to-point-net-device.cc | 6 +- src/internet-node/arp-ipv4-interface.cc | 70 +------------------ src/internet-node/arp-ipv4-interface.h | 1 - src/internet-node/ipv4-l3-protocol.cc | 2 + src/node/net-device.cc | 13 +++- src/node/net-device.h | 59 ++++++++++++++-- 8 files changed, 160 insertions(+), 86 deletions(-) diff --git a/src/devices/csma/csma-net-device.cc b/src/devices/csma/csma-net-device.cc index ca6a693a5..7cdcd455c 100644 --- a/src/devices/csma/csma-net-device.cc +++ b/src/devices/csma/csma-net-device.cc @@ -19,8 +19,6 @@ * Author: Emmanuelle Laprise */ -#include -#include #include "ns3/debug.h" #include "ns3/queue.h" #include "ns3/simulator.h" @@ -60,7 +58,6 @@ CsmaTraceType::GetUid (void) return uid; } - CsmaNetDevice::CsmaNetDevice (Ptr node) : NetDevice (node, Eui48Address::Allocate ()), m_bps (DataRate (0xffffffff)) @@ -71,7 +68,7 @@ CsmaNetDevice::CsmaNetDevice (Ptr node) } CsmaNetDevice::CsmaNetDevice (Ptr node, Eui48Address addr, - CsmaEncapsulationMode encapMode) + CsmaEncapsulationMode encapMode) : NetDevice(node, addr), m_bps (DataRate (0xffffffff)) { @@ -82,8 +79,8 @@ CsmaNetDevice::CsmaNetDevice (Ptr node, Eui48Address addr, } CsmaNetDevice::CsmaNetDevice (Ptr 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 @@ CsmaNetDevice::Receive (const Packet& packet) 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 CsmaNetDevice::GetQueue(void) const { diff --git a/src/devices/csma/csma-net-device.h b/src/devices/csma/csma-net-device.h index 441ea04cd..b0442ac94 100644 --- a/src/devices/csma/csma-net-device.h +++ b/src/devices/csma/csma-net-device.h @@ -197,6 +197,37 @@ enum CsmaEncapsulationMode { */ 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); diff --git a/src/devices/point-to-point/point-to-point-net-device.cc b/src/devices/point-to-point/point-to-point-net-device.cc index ada429621..ae4da905b 100644 --- a/src/devices/point-to-point/point-to-point-net-device.cc +++ b/src/devices/point-to-point/point-to-point-net-device.cc @@ -20,8 +20,6 @@ * Revised: George Riley */ -#include -#include #include "ns3/debug.h" #include "ns3/queue.h" #include "ns3/simulator.h" @@ -73,7 +71,7 @@ PointToPointNetDevice::PointToPointNetDevice (Ptr node, // 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 @@ bool PointToPointNetDevice::Attach (Ptr ch) 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 (); /* diff --git a/src/internet-node/arp-ipv4-interface.cc b/src/internet-node/arp-ipv4-interface.cc index 29ccb19f2..63533ff58 100644 --- a/src/internet-node/arp-ipv4-interface.cc +++ b/src/internet-node/arp-ipv4-interface.cc @@ -61,74 +61,6 @@ ArpIpv4Interface::DoCreateTraceResolver (TraceContext const &context) 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 (Packet p, Ipv4Address dest) "ArpIpv4Interface::SendTo (): Sending multicast packet over " "non-multicast device"); - hardwareDestination = MakeMulticastAddress(dest); + hardwareDestination = GetDevice ()->MakeMulticastAddress(dest); found = true; } else diff --git a/src/internet-node/arp-ipv4-interface.h b/src/internet-node/arp-ipv4-interface.h index dd73ff2b0..130a52256 100644 --- a/src/internet-node/arp-ipv4-interface.h +++ b/src/internet-node/arp-ipv4-interface.h @@ -47,7 +47,6 @@ class ArpIpv4Interface : public Ipv4Interface virtual void SendTo (Packet p, Ipv4Address dest); virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context); Ptr m_node; - Address MakeMulticastAddress (Ipv4Address multicastGroup); }; }//namespace ns3 diff --git a/src/internet-node/ipv4-l3-protocol.cc b/src/internet-node/ipv4-l3-protocol.cc index b5faf663b..b45046783 100644 --- a/src/internet-node/ipv4-l3-protocol.cc +++ b/src/internet-node/ipv4-l3-protocol.cc @@ -504,6 +504,8 @@ Ipv4L3Protocol::Receive( Ptr device, const Packet& p, uint16_t protoc 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 (); diff --git a/src/node/net-device.cc b/src/node/net-device.cc index 72d610924..4e6710758 100644 --- a/src/node/net-device.cc +++ b/src/node/net-device.cc @@ -140,10 +140,19 @@ NetDevice::IsMulticast (void) const 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; } diff --git a/src/node/net-device.h b/src/node/net-device.h index 98c527e4b..dd622ae90 100644 --- a/src/node/net-device.h +++ b/src/node/net-device.h @@ -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 @@ public: 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. * - * Calling this method is invalid if IsMulticast returns - * not true. + * 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 const &GetMulticast (void) const; + Address GetMulticast (void) const; + + /** + * \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). 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 + */ + virtual Address MakeMulticastAddress (Ipv4Address multicastGroup) const; /** * \return value of m_isPointToPoint flag