---------------------------------------------------------------------------------------------
seem-manet-template.cc
---------------------------------------------------------------------------------------------
tapBridge.Install (adhocNodes.Get (0), adhocDevices.Get (0));
---------------------------------------------------------------------------------------------
tap-bridge-helper.cc
---------------------------------------------------------------------------------------------
Ptr<NetDevice>
TapBridgeHelper::Install (Ptr<Node> node, Ptr<NetDevice> nd)
{
NS_LOG_FUNCTION (node << nd);
NS_LOG_LOGIC ("Install TapBridge on node " << node->GetId () << " bridging net device " << nd);
Ptr<TapBridge> bridge = m_deviceFactory.Create<TapBridge> ();
node->AddDevice (bridge);
bridge->SetBridgedNetDevice (nd);
return bridge;
}
---------------------------------------------------------------------------------------------
tap-bridge.cc
---------------------------------------------------------------------------------------------
void
TapBridge::SetBridgedNetDevice (Ptr<NetDevice> bridgedDevice)
{
NS_LOG_FUNCTION (bridgedDevice);
NS_ASSERT_MSG (m_node != 0, "TapBridge::SetBridgedDevice: Bridge not installed in a node");
NS_ASSERT_MSG (bridgedDevice != this, "TapBridge::SetBridgedDevice: Cannot bridge to self");
NS_ASSERT_MSG (m_bridgedDevice == 0, "TapBridge::SetBridgedDevice: Already bridged");
if (!Mac48Address::IsMatchingType (bridgedDevice->GetAddress ()))
{
NS_FATAL_ERROR ("TapBridge::SetBridgedDevice: Device does not support eui 48 addresses: cannot be added to bridge.");
}
if (m_mode == USE_BRIDGE && !bridgedDevice->SupportsSendFrom ())
{
NS_FATAL_ERROR ("TapBridge::SetBridgedDevice: Device does not support SendFrom: cannot be added to bridge.");
}
//
// 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.
//
// 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;
}
bool
TapBridge::DiscardFromBridgedDevice (Ptr<NetDevice> device, Ptr<const Packet> 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<NetDevice> device,
Ptr<const Packet> packet,
uint16_t protocol,
const Address &src,
const Address &dst,
PacketType packetType)
{
NS_LOG_FUNCTION (device << packet << protocol << src << dst << packetType);
NS_ASSERT_MSG (device == m_bridgedDevice, "TapBridge::SetBridgedDevice: Received packet from unexpected device");
NS_LOG_DEBUG ("Packet UID is " << packet->GetUid ());
//
// There are three operating modes for the TapBridge
//
// CONFIGURE_LOCAL means that ns-3 will create and configure a tap device
// and we are expected to use it. The tap device and the ns-3 net device
// will have the same MAC address by definition.
//
// USE_LOCAL mode tells us that we have got to USE a pre-created tap device
// that will have a different MAC address from the ns-3 net device. In this
// case we will be spoofing the MAC address of a received packet to match
// the single allowed address on the Linux side.
//
// USE_BRIDGE mode tells us that we are logically extending a Linux bridge
// on which lies our tap device.
//
if (m_mode == CONFIGURE_LOCAL && packetType == PACKET_OTHERHOST)
{
//
// We hooked the promiscuous mode protocol handler so we could get the
// destination address of the actual packet. This means we will be
// getting PACKET_OTHERHOST packets (not broadcast, not multicast, not
// unicast to the ns-3 net device, but to some other address). In
// CONFIGURE_LOCAL mode we are not interested in these packets since they
// don't refer to the single MAC address shared by the ns-3 device and
// the TAP device. If, however, we are in USE_LOCAL or USE_BRIDGE mode,
// we want to act like a bridge and forward these PACKET_OTHERHOST
// packets.
//
return true;
}
Mac48Address from = Mac48Address::ConvertFrom (src);
Mac48Address to = Mac48Address::ConvertFrom (dst);
Ptr<Packet> p = packet->Copy ();
EthernetHeader header = EthernetHeader (false);
header.SetSource (from);
header.SetDestination (to);
header.SetLengthType (protocol);
p->AddHeader (header);
NS_LOG_LOGIC ("Writing packet to Linux host");
NS_LOG_LOGIC ("Pkt source is " << header.GetSource ());
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_ASSERT_MSG (p->GetSize () <= 65536, "TapBridge::ReceiveFromBridgedDevice: Packet too big " << p->GetSize ());
p->CopyData (m_packetBuffer, p->GetSize ());
uint32_t bytesWritten = write (m_sock, m_packetBuffer, p->GetSize ());
NS_ABORT_MSG_IF (bytesWritten != p->GetSize (), "TapBridge::ReceiveFromBridgedDevice(): Write error.");
NS_LOG_LOGIC ("End of receive packet handling on node " << m_node->GetId ());
return true;
}