From 6e8b7012e7abbfc2e12e55dfaf4b607ba9b87e6d Mon Sep 17 00:00:00 2001 From: Craig Dowell Date: Tue, 23 Jun 2009 22:12:35 -0700 Subject: [PATCH] Finally make tap bridge work with VMs (bug 569) --- examples/tap-wifi-dumbbell.cc | 2 +- src/devices/bridge/bridge-net-device.cc | 7 ++ src/devices/bridge/bridge-net-device.h | 1 + src/devices/csma/csma-net-device.cc | 14 +-- src/devices/csma/csma-net-device.h | 8 +- src/devices/emu/emu-net-device.cc | 6 +- src/devices/emu/emu-net-device.h | 10 +- .../point-to-point-net-device.cc | 5 +- .../point-to-point-net-device.h | 10 +- src/devices/tap-bridge/tap-bridge.cc | 91 +++++++++---------- src/devices/tap-bridge/tap-bridge.h | 15 +-- .../virtual-net-device/virtual-net-device.h | 8 +- src/devices/wifi/wifi-net-device.cc | 5 + src/devices/wifi/wifi-net-device.h | 1 + src/internet-stack/loopback-net-device.cc | 6 ++ src/internet-stack/loopback-net-device.h | 1 + src/internet-stack/tcp-test.cc | 2 +- src/internet-stack/udp-test.cc | 8 +- src/node/net-device.h | 6 ++ src/node/node.cc | 15 +-- src/node/simple-net-device.cc | 14 +-- src/node/simple-net-device.h | 2 +- 22 files changed, 116 insertions(+), 121 deletions(-) diff --git a/examples/tap-wifi-dumbbell.cc b/examples/tap-wifi-dumbbell.cc index eda8adc72..8b8069cfa 100644 --- a/examples/tap-wifi-dumbbell.cc +++ b/examples/tap-wifi-dumbbell.cc @@ -227,7 +227,7 @@ main (int argc, char *argv[]) apps = sink.Install (nodesRight.Get (0)); apps.Start (Seconds (1.0)); - CsmaHelper::EnablePcapAll ("tap-dumbbell", false); + CsmaHelper::EnablePcapAll ("tap-wifi-dumbbell", false); GlobalRouteManager::PopulateRoutingTables (); Simulator::Stop (Seconds (60.)); diff --git a/src/devices/bridge/bridge-net-device.cc b/src/devices/bridge/bridge-net-device.cc index 03d7778eb..b22356f9e 100644 --- a/src/devices/bridge/bridge-net-device.cc +++ b/src/devices/bridge/bridge-net-device.cc @@ -278,6 +278,13 @@ BridgeNetDevice::GetChannel (void) const return m_channel; } +void +BridgeNetDevice::SetAddress (Address address) +{ + NS_LOG_FUNCTION_NOARGS (); + m_address = Mac48Address::ConvertFrom (address); +} + Address BridgeNetDevice::GetAddress (void) const { diff --git a/src/devices/bridge/bridge-net-device.h b/src/devices/bridge/bridge-net-device.h index 02be49f37..b7c2650a5 100644 --- a/src/devices/bridge/bridge-net-device.h +++ b/src/devices/bridge/bridge-net-device.h @@ -91,6 +91,7 @@ public: virtual void SetIfIndex(const uint32_t index); virtual uint32_t GetIfIndex(void) const; virtual Ptr GetChannel (void) const; + virtual void SetAddress (Address address); virtual Address GetAddress (void) const; virtual bool SetMtu (const uint16_t mtu); virtual uint16_t GetMtu (void) const; diff --git a/src/devices/csma/csma-net-device.cc b/src/devices/csma/csma-net-device.cc index 65534f1b5..e39052681 100644 --- a/src/devices/csma/csma-net-device.cc +++ b/src/devices/csma/csma-net-device.cc @@ -321,13 +321,6 @@ CsmaNetDevice::GetFrameSize (void) const return m_frameSize; } - void -CsmaNetDevice::SetAddress (Mac48Address self) -{ - NS_LOG_FUNCTION (self); - m_address = self; -} - void CsmaNetDevice::SetSendEnable (bool sendEnable) { @@ -875,6 +868,13 @@ CsmaNetDevice::GetChannel (void) const return m_channel; } + void +CsmaNetDevice::SetAddress (Address address) +{ + NS_LOG_FUNCTION_NOARGS (); + m_address = Mac48Address::ConvertFrom (address); +} + Address CsmaNetDevice::GetAddress (void) const { diff --git a/src/devices/csma/csma-net-device.h b/src/devices/csma/csma-net-device.h index 7dc1f9c55..1cff9f69b 100644 --- a/src/devices/csma/csma-net-device.h +++ b/src/devices/csma/csma-net-device.h @@ -182,13 +182,6 @@ public: */ void SetReceiveEnable (bool enable); - /** - * Set the MAC address of the the network device. - * - * \param addr The Mac48Address to use as the address of the device. - */ - void SetAddress (Mac48Address addr); - /** * Set The max frame size of packets sent over this device. * @@ -310,6 +303,7 @@ public: virtual Ptr GetChannel (void) const; virtual bool SetMtu (const uint16_t mtu); virtual uint16_t GetMtu (void) const; + virtual void SetAddress (Address address); virtual Address GetAddress (void) const; virtual bool IsLinkUp (void) const; virtual void SetLinkChangeCallback (Callback callback); diff --git a/src/devices/emu/emu-net-device.cc b/src/devices/emu/emu-net-device.cc index 94f452d24..3249daa7e 100644 --- a/src/devices/emu/emu-net-device.cc +++ b/src/devices/emu/emu-net-device.cc @@ -876,10 +876,10 @@ EmuNetDevice::GetChannel (void) const } void -EmuNetDevice::SetAddress (Mac48Address addr) +EmuNetDevice::SetAddress (Address address) { - NS_LOG_FUNCTION (addr); - m_address = addr; + NS_LOG_FUNCTION (address); + m_address = Mac48Address::ConvertFrom (address); } Address diff --git a/src/devices/emu/emu-net-device.h b/src/devices/emu/emu-net-device.h index ee00d05e6..10644d4d1 100644 --- a/src/devices/emu/emu-net-device.h +++ b/src/devices/emu/emu-net-device.h @@ -94,14 +94,6 @@ public: */ void SetQueue (Ptr queue); - /** - * Assign a MAC address to this device. - * - * @see Mac48Address - * @param addr The new address. - */ - void SetAddress (Mac48Address addr); - // // Pure virtual methods inherited from NetDevice we must implement. // @@ -109,6 +101,8 @@ public: virtual uint32_t GetIfIndex(void) const; virtual Ptr GetChannel (void) const; + + virtual void SetAddress (Address address); virtual Address GetAddress (void) const; virtual bool SetMtu (const uint16_t mtu); 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 609441cad..6ccda7ebc 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 @@ -395,10 +395,11 @@ PointToPointNetDevice::GetChannel (void) const // information. However, the base class NetDevice wants us to define the // methods to get and set the address. Rather than be rude and assert, we let // clients get and set the address, but simply ignore them. + void -PointToPointNetDevice::SetAddress (Mac48Address addr) +PointToPointNetDevice::SetAddress (Address address) { - m_address = addr; + m_address = Mac48Address::ConvertFrom (address); } Address diff --git a/src/devices/point-to-point/point-to-point-net-device.h b/src/devices/point-to-point/point-to-point-net-device.h index 956b6a356..efca761da 100644 --- a/src/devices/point-to-point/point-to-point-net-device.h +++ b/src/devices/point-to-point/point-to-point-net-device.h @@ -131,14 +131,6 @@ public: */ void Receive (Ptr p); - /** - * Assign a MAC address to this device. - * - * @see Mac48Address - * @param addr The new address. - */ - void SetAddress (Mac48Address addr); - /** * Set The max frame size of packets sent over this device. * @@ -230,6 +222,8 @@ public: virtual uint32_t GetIfIndex(void) const; virtual Ptr GetChannel (void) const; + + virtual void SetAddress (Address address); virtual Address GetAddress (void) const; virtual bool SetMtu (const uint16_t mtu); diff --git a/src/devices/tap-bridge/tap-bridge.cc b/src/devices/tap-bridge/tap-bridge.cc index df422d15c..bd238882d 100644 --- a/src/devices/tap-bridge/tap-bridge.cc +++ b/src/devices/tap-bridge/tap-bridge.cc @@ -131,7 +131,7 @@ TapBridge::TapBridge () m_startEvent (), m_stopEvent (), m_readThread (0), - m_learnedMac (Mac48Address ("ff:ff:ff:ff:ff:ff")) + m_ns3AddressRewritten (false) { NS_LOG_FUNCTION_NOARGS (); Start (m_tStart); @@ -641,7 +641,7 @@ TapBridge::ReadThread (void) return; } - NS_LOG_INFO ("TapBridge::ReadThread(): Received packet"); + NS_LOG_INFO ("TapBridge::ReadThread(): Received packet on node " << m_node->GetId ()); NS_LOG_INFO ("TapBridge::ReadThread(): Scheduling handler"); DynamicCast (Simulator::GetImplementation ())->ScheduleRealtimeNow ( MakeEvent (&TapBridge::ForwardToBridgedDevice, this, buf, len)); @@ -713,21 +713,21 @@ TapBridge::ForwardToBridgedDevice (uint8_t *buf, uint32_t len) // NS_ASSERT_MSG (Mac48Address::ConvertFrom (src) != Mac48Address ("ff:ff:ff:ff:ff:ff"), "TapBridge::ForwardToBridgedDevice: Source addr is broadcast"); - // - // Remember the Mac address since we are going to spoof it when we go - // the other way. - // - m_learnedMac = Mac48Address::ConvertFrom (src); - NS_LOG_LOGIC ("Learned MacAddr is " << m_learnedMac); - + if (m_ns3AddressRewritten == false) + { + // + // Set the ns-3 device's mac address to the overlying container's + // mac address + // + Mac48Address learnedMac = Mac48Address::ConvertFrom (src); + NS_LOG_LOGIC ("Learned MacAddr is " << learnedMac << ": setting ns-3 device to use this address"); + m_bridgedDevice->SetAddress (Mac48Address::ConvertFrom (learnedMac)); + m_ns3AddressRewritten = true; + } // // If we are operating in USE_LOCAL mode, we may be attached to an ns-3 // device that does not support bridging (SupportsSendFrom returns false). - // The whole point of this mode is really to support this case. We allow - // only packets from one source MAC to flow across the TapBridge in this - // mode and will spoof that address when packets flow the other way. - // Since we will be doing this spoofing, we can relax the normal bridged - // device requirement to support SendFrom and use Send. + // But, since the mac addresses are now aligned, we can call Send() // NS_LOG_LOGIC ("Forwarding packet to ns-3 device via Send()"); m_bridgedDevice->Send (packet, dst, type); @@ -864,20 +864,34 @@ TapBridge::SetBridgedNetDevice (Ptr bridgedDevice) } // - // Tell the bridged device to forward its received packets here. We use the - // promiscuous mode hook to get both the source and destination addresses. + // We need to disconnect the bridged device from the internet stack on our + // node to ensure that only one stack responds to packets inbound over the + // bridged device. That one stack lives outside ns-3 so we just blatantly + // steal the device callbacks. // - m_node->RegisterProtocolHandler (MakeCallback (&TapBridge::ReceiveFromBridgedDevice, this), 0, bridgedDevice, true); + // N.B This can be undone if someone does a RegisterProtocolHandler later + // on this node. + // + bridgedDevice->SetReceiveCallback (MakeCallback (&TapBridge::DiscardFromBridgedDevice, this)); + bridgedDevice->SetPromiscReceiveCallback (MakeCallback (&TapBridge::ReceiveFromBridgedDevice, this)); m_bridgedDevice = bridgedDevice; } -void +bool +TapBridge::DiscardFromBridgedDevice (Ptr device, Ptr packet, uint16_t protocol, const Address &src) +{ + NS_LOG_FUNCTION (device << packet << protocol << src); + NS_LOG_LOGIC ("Discarding packet stolen from bridged device " << device); + return true; +} + +bool TapBridge::ReceiveFromBridgedDevice ( Ptr device, Ptr packet, uint16_t protocol, - Address const &src, - Address const &dst, + const Address &src, + const Address &dst, PacketType packetType) { NS_LOG_FUNCTION (device << packet << protocol << src << dst << packetType); @@ -913,35 +927,11 @@ TapBridge::ReceiveFromBridgedDevice ( // we want to act like a bridge and forward these PACKET_OTHERHOST // packets. // - return; + return true; } - // - // We have received a packet from the ns-3 net device that has been associated - // with this bridge. We want to take these bits and send them off to the tap - // device on the Linux host. The only question we have to answer is, what - // should the destination address be? - // - // If we are in CONFIGURE_LOCAL mode, then the destination address is just - // left alone since it can only be the shared single MAC address, broadcast - // or multicast. - // - // If we are in USE_LOCAL mode, then we need to spoof the destination - // address with the one we saved. - // - // If we are in USE_BRIDGE mode, then we need to do the equvalent of a - // SendFrom and leave the source and destination alone. - // Mac48Address from = Mac48Address::ConvertFrom (src); - Mac48Address to; - if (m_mode == USE_LOCAL) - { - to = Mac48Address::ConvertFrom (m_learnedMac); - } - else - { - to = Mac48Address::ConvertFrom (dst); - } + Mac48Address to = Mac48Address::ConvertFrom (dst); Ptr p = packet->Copy (); EthernetHeader header = EthernetHeader (false); @@ -956,9 +946,11 @@ TapBridge::ReceiveFromBridgedDevice ( NS_LOG_LOGIC ("Pkt destination is " << header.GetDestination ()); NS_LOG_LOGIC ("Pkt LengthType is " << header.GetLengthType ()); NS_LOG_LOGIC ("Pkt size is " << p->GetSize ()); + NS_LOG_LOGIC ("End of receive packet handling on node " << m_node->GetId ()); uint32_t bytesWritten = write (m_sock, p->PeekData (), p->GetSize ()); NS_ABORT_MSG_IF (bytesWritten != p->GetSize (), "TapBridge::ReceiveFromBridgedDevice(): Write error."); + return true; } void @@ -982,6 +974,13 @@ TapBridge::GetChannel (void) const return 0; } +void +TapBridge::SetAddress (Address address) +{ + NS_LOG_FUNCTION (address); + m_address = Mac48Address::ConvertFrom (address); +} + Address TapBridge::GetAddress (void) const { diff --git a/src/devices/tap-bridge/tap-bridge.h b/src/devices/tap-bridge/tap-bridge.h index ac2fb2a2d..9654ebc6c 100644 --- a/src/devices/tap-bridge/tap-bridge.h +++ b/src/devices/tap-bridge/tap-bridge.h @@ -176,6 +176,7 @@ public: virtual void SetIfIndex(const uint32_t index); virtual uint32_t GetIfIndex(void) const; virtual Ptr GetChannel (void) const; + virtual void SetAddress (Address address); virtual Address GetAddress (void) const; virtual bool SetMtu (const uint16_t mtu); virtual uint16_t GetMtu (void) const; @@ -208,8 +209,11 @@ protected: */ virtual void DoDispose (void); - void ReceiveFromBridgedDevice (Ptr device, Ptr packet, uint16_t protocol, + bool ReceiveFromBridgedDevice (Ptr device, Ptr packet, uint16_t protocol, Address const &src, Address const &dst, PacketType packetType); + + bool DiscardFromBridgedDevice (Ptr device, Ptr packet, uint16_t protocol, Address const &src); + private: /** @@ -443,13 +447,10 @@ private: /** * \internal * - * The MAC address of the local tap device is stored in this variable. - * When in UseLocal mode, this address is added back to the destination - * Mac address for frames destined to the tap device. It is learned from - * the first frame sent from the host to the TapBridge device. In the - * other modes of this device, this value is unused. + * Whether the MAC address of the underlying ns-3 device has already been + * rewritten is stored in this variable (for UseLocal mode only). */ - Mac48Address m_learnedMac; + bool m_ns3AddressRewritten; }; diff --git a/src/devices/virtual-net-device/virtual-net-device.h b/src/devices/virtual-net-device/virtual-net-device.h index 0f34f494c..da84e8b9f 100644 --- a/src/devices/virtual-net-device/virtual-net-device.h +++ b/src/devices/virtual-net-device/virtual-net-device.h @@ -114,17 +114,11 @@ public: PacketType packetType); - /** - * Set the MAC address of the the network device. - * - * \param addr The Address to use as the address of the device. - */ - void SetAddress (Address addr); - // inherited from NetDevice base class. virtual void SetIfIndex(const uint32_t index); virtual uint32_t GetIfIndex(void) const; virtual Ptr GetChannel (void) const; + virtual void SetAddress (Address address); virtual Address GetAddress (void) const; virtual uint16_t GetMtu (void) const; virtual bool IsLinkUp (void) const; diff --git a/src/devices/wifi/wifi-net-device.cc b/src/devices/wifi/wifi-net-device.cc index 2abe6200d..c0ca4adab 100644 --- a/src/devices/wifi/wifi-net-device.cc +++ b/src/devices/wifi/wifi-net-device.cc @@ -157,6 +157,11 @@ WifiNetDevice::DoGetChannel (void) const { return m_phy->GetChannel (); } +void +WifiNetDevice::SetAddress (Address address) +{ + m_mac->SetAddress (Mac48Address::ConvertFrom (address)); +} Address WifiNetDevice::GetAddress (void) const { diff --git a/src/devices/wifi/wifi-net-device.h b/src/devices/wifi/wifi-net-device.h index d5aae5797..a395eeb14 100644 --- a/src/devices/wifi/wifi-net-device.h +++ b/src/devices/wifi/wifi-net-device.h @@ -78,6 +78,7 @@ public: virtual void SetIfIndex(const uint32_t index); virtual uint32_t GetIfIndex(void) const; virtual Ptr GetChannel (void) const; + virtual void SetAddress (Address address); virtual Address GetAddress (void) const; virtual bool SetMtu (const uint16_t mtu); virtual uint16_t GetMtu (void) const; diff --git a/src/internet-stack/loopback-net-device.cc b/src/internet-stack/loopback-net-device.cc index 8a06540a6..351b3431b 100644 --- a/src/internet-stack/loopback-net-device.cc +++ b/src/internet-stack/loopback-net-device.cc @@ -93,6 +93,12 @@ LoopbackNetDevice::GetChannel (void) const return 0; } +void +LoopbackNetDevice::SetAddress (Address address) +{ + m_address = Mac48Address::ConvertFrom (address); +} + Address LoopbackNetDevice::GetAddress (void) const { diff --git a/src/internet-stack/loopback-net-device.h b/src/internet-stack/loopback-net-device.h index de1af2874..105940bfa 100644 --- a/src/internet-stack/loopback-net-device.h +++ b/src/internet-stack/loopback-net-device.h @@ -45,6 +45,7 @@ public: virtual void SetIfIndex(const uint32_t index); virtual uint32_t GetIfIndex(void) const; virtual Ptr GetChannel (void) const; + virtual void SetAddress (Address address); virtual Address GetAddress (void) const; virtual bool SetMtu (const uint16_t mtu); virtual uint16_t GetMtu (void) const; diff --git a/src/internet-stack/tcp-test.cc b/src/internet-stack/tcp-test.cc index 12f2af89d..7bf53521a 100644 --- a/src/internet-stack/tcp-test.cc +++ b/src/internet-stack/tcp-test.cc @@ -300,7 +300,7 @@ Ptr TcpSocketImplTest::AddSimpleNetDevice (Ptr node, const char* ipaddr, const char* netmask) { Ptr dev = CreateObject (); - dev->SetAddress (Mac48Address::Allocate ()); + dev->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ())); node->AddDevice (dev); Ptr ipv4 = node->GetObject (); uint32_t ndid = ipv4->AddInterface (dev); diff --git a/src/internet-stack/udp-test.cc b/src/internet-stack/udp-test.cc index 36d514706..2d1ed13dd 100644 --- a/src/internet-stack/udp-test.cc +++ b/src/internet-stack/udp-test.cc @@ -134,7 +134,7 @@ UdpSocketImplTest::RunTests (void) Ptr rxDev1, rxDev2; { // first interface rxDev1 = CreateObject (); - rxDev1->SetAddress (Mac48Address::Allocate ()); + rxDev1->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ())); rxNode->AddDevice (rxDev1); Ptr ipv4 = rxNode->GetObject (); uint32_t netdev_idx = ipv4->AddInterface (rxDev1); @@ -145,7 +145,7 @@ UdpSocketImplTest::RunTests (void) { // second interface rxDev2 = CreateObject (); - rxDev2->SetAddress (Mac48Address::Allocate ()); + rxDev2->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ())); rxNode->AddDevice (rxDev2); Ptr ipv4 = rxNode->GetObject (); uint32_t netdev_idx = ipv4->AddInterface (rxDev2); @@ -160,7 +160,7 @@ UdpSocketImplTest::RunTests (void) Ptr txDev1; { txDev1 = CreateObject (); - txDev1->SetAddress (Mac48Address::Allocate ()); + txDev1->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ())); txNode->AddDevice (txDev1); Ptr ipv4 = txNode->GetObject (); uint32_t netdev_idx = ipv4->AddInterface (txDev1); @@ -171,7 +171,7 @@ UdpSocketImplTest::RunTests (void) Ptr txDev2; { txDev2 = CreateObject (); - txDev2->SetAddress (Mac48Address::Allocate ()); + txDev2->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ())); txNode->AddDevice (txDev2); Ptr ipv4 = txNode->GetObject (); uint32_t netdev_idx = ipv4->AddInterface (txDev2); diff --git a/src/node/net-device.h b/src/node/net-device.h index 201979528..3c065912f 100644 --- a/src/node/net-device.h +++ b/src/node/net-device.h @@ -97,10 +97,16 @@ public: */ virtual Ptr GetChannel (void) const = 0; + /** + * Set the address of this interface + */ + virtual void SetAddress (Address address) = 0; + /** * \return the current Address of this interface. */ virtual Address GetAddress (void) const = 0; + /** * \param mtu MTU value, in bytes, to set for the device * \return whether the MTU value was within legal bounds diff --git a/src/node/node.cc b/src/node/node.cc index 90922de60..180f7a060 100644 --- a/src/node/node.cc +++ b/src/node/node.cc @@ -192,23 +192,12 @@ Node::RegisterProtocolHandler (ProtocolHandler handler, i != m_devices.end (); i++) { Ptr dev = *i; - if (dev->SupportsSendFrom ()) - { - dev->SetPromiscReceiveCallback (MakeCallback (&Node::PromiscReceiveFromDevice, this)); - } + dev->SetPromiscReceiveCallback (MakeCallback (&Node::PromiscReceiveFromDevice, this)); } } else { - if (device->SupportsSendFrom ()) - { - device->SetPromiscReceiveCallback (MakeCallback (&Node::PromiscReceiveFromDevice, this)); - } - else - { - NS_LOG_WARN ("Protocol handler request promiscuous mode for a specific netdevice," - " but netdevice does not support promiscuous mode."); - } + device->SetPromiscReceiveCallback (MakeCallback (&Node::PromiscReceiveFromDevice, this)); } } diff --git a/src/node/simple-net-device.cc b/src/node/simple-net-device.cc index b72f28797..7e9ffae0d 100644 --- a/src/node/simple-net-device.cc +++ b/src/node/simple-net-device.cc @@ -76,12 +76,6 @@ SimpleNetDevice::SetChannel (Ptr channel) m_channel->Add (this); } -void -SimpleNetDevice::SetAddress (Mac48Address address) -{ - m_address = address; -} - void SimpleNetDevice::SetIfIndex(const uint32_t index) { @@ -97,9 +91,17 @@ SimpleNetDevice::GetChannel (void) const { return m_channel; } +void +SimpleNetDevice::SetAddress (Address address) +{ + m_address = Mac48Address::ConvertFrom(address); +} Address SimpleNetDevice::GetAddress (void) const { + // + // Implicit conversion from Mac48Address to Address + // return m_address; } bool diff --git a/src/node/simple-net-device.h b/src/node/simple-net-device.h index 7840887cf..5d98b7f6d 100644 --- a/src/node/simple-net-device.h +++ b/src/node/simple-net-device.h @@ -43,12 +43,12 @@ public: void Receive (Ptr packet, uint16_t protocol, Mac48Address to, Mac48Address from); void SetChannel (Ptr channel); - void SetAddress (Mac48Address address); // inherited from NetDevice base class. virtual void SetIfIndex(const uint32_t index); virtual uint32_t GetIfIndex(void) const; virtual Ptr GetChannel (void) const; + virtual void SetAddress (Address address); virtual Address GetAddress (void) const; virtual bool SetMtu (const uint16_t mtu); virtual uint16_t GetMtu (void) const;