src/devices/tap-bridge/tap-bridge.cc
changeset 4289 2f5b0ec50102
parent 4286 2cabb9cfae98
child 4290 af8a40d5c2cb
equal deleted inserted replaced
4288:8a999429091b 4289:2f5b0ec50102
    78                    "The name of the tap device to create.",
    78                    "The name of the tap device to create.",
    79                    StringValue (""),
    79                    StringValue (""),
    80                    MakeStringAccessor (&TapBridge::m_tapDeviceName),
    80                    MakeStringAccessor (&TapBridge::m_tapDeviceName),
    81                    MakeStringChecker ())
    81                    MakeStringChecker ())
    82     .AddAttribute ("Gateway", 
    82     .AddAttribute ("Gateway", 
    83                    "The IP address of the default gateway to assign to the tap device.",
    83                    "The IP address of the default gateway to assign to the host machine, when in ConfigureLocal mode.",
    84                    Ipv4AddressValue ("255.255.255.255"),
    84                    Ipv4AddressValue ("255.255.255.255"),
    85                    MakeIpv4AddressAccessor (&TapBridge::m_tapGateway),
    85                    MakeIpv4AddressAccessor (&TapBridge::m_tapGateway),
    86                    MakeIpv4AddressChecker ())
    86                    MakeIpv4AddressChecker ())
    87     .AddAttribute ("IpAddress", 
    87     .AddAttribute ("IpAddress", 
    88                    "The IP address to assign to the tap device.",
    88                    "The IP address to assign to the tap device, when in ConfigureLocal mode.",
    89                    Ipv4AddressValue ("255.255.255.255"),
    89                    Ipv4AddressValue ("255.255.255.255"),
    90                    MakeIpv4AddressAccessor (&TapBridge::m_tapIp),
    90                    MakeIpv4AddressAccessor (&TapBridge::m_tapIp),
    91                    MakeIpv4AddressChecker ())
    91                    MakeIpv4AddressChecker ())
    92     .AddAttribute ("MacAddress", 
    92     .AddAttribute ("MacAddress", 
    93                    "The MAC address to assign to the tap device.",
    93                    "The MAC address to assign to the tap device, when in ConfigureLocal mode.",
    94                    Mac48AddressValue (Mac48Address ("ff:ff:ff:ff:ff:ff")),
    94                    Mac48AddressValue (Mac48Address ("ff:ff:ff:ff:ff:ff")),
    95                    MakeMac48AddressAccessor (&TapBridge::m_tapMac),
    95                    MakeMac48AddressAccessor (&TapBridge::m_tapMac),
    96                    MakeMac48AddressChecker ())
    96                    MakeMac48AddressChecker ())
    97     .AddAttribute ("Netmask", 
    97     .AddAttribute ("Netmask", 
    98                    "The network mask to assign to the tap device.",
    98                    "The network mask to assign to the tap device, when in ConfigureLocal mode.",
    99                    Ipv4MaskValue ("255.255.255.255"),
    99                    Ipv4MaskValue ("255.255.255.255"),
   100                    MakeIpv4MaskAccessor (&TapBridge::m_tapNetmask),
   100                    MakeIpv4MaskAccessor (&TapBridge::m_tapNetmask),
   101                    MakeIpv4MaskChecker ())
   101                    MakeIpv4MaskChecker ())
   102     .AddAttribute ("Start", 
   102     .AddAttribute ("Start", 
   103                    "The simulation time at which to spin up the tap device read thread.",
   103                    "The simulation time at which to spin up the tap device read thread.",
   108                    "The simulation time at which to tear down the tap device read thread.",
   108                    "The simulation time at which to tear down the tap device read thread.",
   109                    TimeValue (Seconds (0.)),
   109                    TimeValue (Seconds (0.)),
   110                    MakeTimeAccessor (&TapBridge::m_tStop),
   110                    MakeTimeAccessor (&TapBridge::m_tStop),
   111                    MakeTimeChecker ())
   111                    MakeTimeChecker ())
   112     .AddAttribute ("Mode", 
   112     .AddAttribute ("Mode", 
   113                    "The operating and configuration mode (LocalDevice or BridgedDevice) to use.",
   113                    "The operating and configuration mode to use.",
   114                    EnumValue (LOCAL_DEVICE),
   114                    EnumValue (USE_LOCAL),
   115                    MakeEnumAccessor (&TapBridge::SetMode),
   115                    MakeEnumAccessor (&TapBridge::SetMode),
   116                    MakeEnumChecker (LOCAL_DEVICE, "LocalDevice",
   116                    MakeEnumChecker (CONFIGURE_LOCAL, "ConfigureLocal",
   117                                     BRIDGED_DEVICE, "BridgedDevice"))
   117                                     USE_LOCAL, "UseLocal",
       
   118                                     USE_BRIDGE, "UseBridge"))
   118     ;
   119     ;
   119   return tid;
   120   return tid;
   120 }
   121 }
   121 
   122 
   122 TapBridge::TapBridge ()
   123 TapBridge::TapBridge ()
   124   m_ifIndex (0),
   125   m_ifIndex (0),
   125   m_mtu (0),
   126   m_mtu (0),
   126   m_sock (-1),
   127   m_sock (-1),
   127   m_startEvent (),
   128   m_startEvent (),
   128   m_stopEvent (),
   129   m_stopEvent (),
   129   m_readThread (0)
   130   m_readThread (0),
       
   131   m_learnedMac (Mac48Address ("ff:ff:ff:ff:ff:ff"))
   130 {
   132 {
   131   NS_LOG_FUNCTION_NOARGS ();
   133   NS_LOG_FUNCTION_NOARGS ();
   132   Start (m_tStart);
   134   Start (m_tStart);
   133 }
   135 }
   134 
   136 
   220   NS_LOG_FUNCTION_NOARGS ();
   222   NS_LOG_FUNCTION_NOARGS ();
   221 
   223 
   222   // 
   224   // 
   223   // The TapBridge has two distinct operating modes.  The difference revolves
   225   // The TapBridge has two distinct operating modes.  The difference revolves
   224   // around who is responsible for creating and configuring the underlying 
   226   // around who is responsible for creating and configuring the underlying 
   225   // network tap that we use.  In LocalDevice mode, the TapBridge has the
   227   // network tap that we use.  In ConfigureLocal mode, the TapBridge has the
   226   // responsibility for creating and configuring the TAP.
   228   // responsibility for creating and configuring the TAP.
   227   //
   229   //
   228   // In BridgedDevice mode, the user will provide us a configuration and we have
   230   // In UseBridge mode, the user will provide us a configuration and we have
   229   // to adapt to it.  For example, the user will do something like:
   231   // to adapt to it.  For example, the user will do something like:
   230   //
   232   //
   231   //   sudo tunctl -t tap0
   233   //   sudo tunctl -t tap0
   232   //   sudo ifconfig tap0 hw ether 00:00:00:00:00:01
   234   //   sudo ifconfig tap0 hw ether 00:00:00:00:00:01
   233   //   sudo ifconfig tap0 10.1.1.1 netmask 255.255.255.0 up
   235   //   sudo ifconfig tap0 10.1.1.1 netmask 255.255.255.0 up
   234   //
   236   //
   235   // set the "Mode" Attribute to "BridgedDevice" and the "DeviceName" Attribute
   237   // set the "Mode" Attribute to "UseBridge" and the "DeviceName" Attribute
   236   // to "tap0" in this case.
   238   // to "tap0" in this case.
   237   //
   239   //
   238   // In LocalDevice mode, we will do the configuration and create a TAP with
   240   // In ConfigureLocal mode, we will do the configuration and create a TAP with
   239   // the provided "DeviceName" with which the user can later do what she wants.
   241   // the provided "DeviceName" with which the user can later do what she wants.
   240   //
   242   //
   241   // We want to either create or use a tap device on the host.  Unfortunately for
   243   // We want to either create or use a tap device on the host.  Unfortunately for
   242   // us you have to have root privileges to do that.  Instead of running the 
   244   // us you have to have root privileges to do that.  Instead of running the 
   243   // entire simulation as root, we decided to make a small program who's whole
   245   // entire simulation as root, we decided to make a small program who's whole
   294       // -d<device-name> The name of the tap device we want to create;
   296       // -d<device-name> The name of the tap device we want to create;
   295       // -g<gateway-address> The IP address to use as the default gateway;
   297       // -g<gateway-address> The IP address to use as the default gateway;
   296       // -i<IP-address> The IP address to assign to the new tap device;
   298       // -i<IP-address> The IP address to assign to the new tap device;
   297       // -m<MAC-address> The MAC-48 address to assign to the new tap device;
   299       // -m<MAC-address> The MAC-48 address to assign to the new tap device;
   298       // -n<network-mask> The network mask to assign to the new tap device;
   300       // -n<network-mask> The network mask to assign to the new tap device;
   299       // -o<operating mode> The operating mode of the bridge (1=LocalDevice, 2=BridgedDevice)
   301       // -o<operating mode> The operating mode of the bridge (1=ConfigureLocal, 2=UseLocal, 3=UseBridge)
   300       // -p<path> the path to the unix socket described above.
   302       // -p<path> the path to the unix socket described above.
   301       //
   303       //
   302       // Example tap-creator -dnewdev -g1.2.3.2 -i1.2.3.1 -m08:00:2e:00:01:23 -n255.255.255.0 -o1 -pblah
   304       // Example tap-creator -dnewdev -g1.2.3.2 -i1.2.3.1 -m08:00:2e:00:01:23 -n255.255.255.0 -o1 -pblah
   303       //
   305       //
   304       // We want to get as much of this stuff automagically as possible.
   306       // We want to get as much of this stuff automagically as possible.
   379           ossNetmask << "-n" << m_tapNetmask;
   381           ossNetmask << "-n" << m_tapNetmask;
   380         }
   382         }
   381 
   383 
   382       std::ostringstream ossMode;
   384       std::ostringstream ossMode;
   383       ossMode << "-o";
   385       ossMode << "-o";
   384       if (m_mode == LOCAL_DEVICE)
   386       if (m_mode == CONFIGURE_LOCAL)
   385         {
   387         {
   386           ossMode << "1";
   388           ossMode << "1";
   387         }
   389         }
       
   390       else if (m_mode == USE_LOCAL)
       
   391         {
       
   392           ossMode << "2";
       
   393         }
   388       else
   394       else
   389         {
   395         {
   390           ossMode << "2";
   396           ossMode << "3";
   391         }
   397         }
   392 
   398 
   393       std::ostringstream ossPath;
   399       std::ostringstream ossPath;
   394       ossPath << "-p" << path;
   400       ossPath << "-p" << path;
   395       //
   401       //
   588   for (;;) 
   594   for (;;) 
   589     {
   595     {
   590       uint32_t bufferSize = 65536;
   596       uint32_t bufferSize = 65536;
   591       uint8_t *buf = (uint8_t *)malloc (bufferSize);
   597       uint8_t *buf = (uint8_t *)malloc (bufferSize);
   592       NS_ABORT_MSG_IF (buf == 0, "TapBridge::ReadThread(): malloc packet buffer failed");
   598       NS_ABORT_MSG_IF (buf == 0, "TapBridge::ReadThread(): malloc packet buffer failed");
   593       NS_LOG_LOGIC ("Calling read on tap device socket fd");
   599       NS_LOG_LOGIC ("Calling read on tap device socket fd " << m_sock);
   594       len = read (m_sock, buf, bufferSize);
   600       len = read (m_sock, buf, bufferSize);
   595 
   601 
   596       if (len == -1)
   602       if (len == -1)
   597         {
   603         {
       
   604           NS_LOG_INFO ("TapBridge::ReadThread(): Returning");
   598           free (buf);
   605           free (buf);
   599           buf = 0;
   606           buf = 0;
   600           return;
   607           return;
   601         }
   608         }
   602 
   609 
   603       NS_LOG_INFO ("TapBridge::ReadThread(): Received packet");
   610       NS_LOG_INFO ("TapBridge::ReadThread(): Received packet");
   604       NS_LOG_INFO ("TapBridge::ReadThread(): Scheduling handler");
   611       NS_LOG_INFO ("TapBridge::ReadThread(): Scheduling handler");
   605       DynamicCast<RealtimeSimulatorImpl> (Simulator::GetImplementation ())->ScheduleRealtimeNow (
   612       DynamicCast<RealtimeSimulatorImpl> (Simulator::GetImplementation ())->ScheduleRealtimeNow (
   606         MakeEvent (&TapBridge::ForwardToBridgedDevice, this, buf, len));
   613         MakeEvent (&TapBridge::ForwardToSimDevice, this, buf, len));
   607       buf = 0;
   614       buf = 0;
   608     }
   615     }
   609 }
   616 }
   610 
   617 
   611 void
   618 void
   612 TapBridge::ForwardToBridgedDevice (uint8_t *buf, uint32_t len)
   619 TapBridge::ForwardToSimDevice (uint8_t *buf, uint32_t len)
   613 {
   620 {
   614   NS_LOG_FUNCTION (buf << len);
   621   NS_LOG_FUNCTION (buf << len);
   615 
   622 
   616   //
   623   //
   617   // Create a packet out of the buffer we received and free that buffer.
   624   // Create a packet out of the buffer we received and free that buffer.
   639     }
   646     }
   640 
   647 
   641   NS_LOG_LOGIC ("Pkt source is " << src);
   648   NS_LOG_LOGIC ("Pkt source is " << src);
   642   NS_LOG_LOGIC ("Pkt destination is " << dst);
   649   NS_LOG_LOGIC ("Pkt destination is " << dst);
   643   NS_LOG_LOGIC ("Pkt LengthType is " << type);
   650   NS_LOG_LOGIC ("Pkt LengthType is " << type);
   644 
   651   if (m_mode == USE_LOCAL)
   645   //
   652     {
   646   // If we are operating in BRIDGED_DEVICE mode, we have the situation described
   653       // Should not be a broadcast src
   647   // below:
   654       NS_ASSERT_MSG (Mac48Address::ConvertFrom (src) != Mac48Address ("ff:ff:ff:ff:ff:ff"), "TapBridge::ForwardToSimDevice:  Source addr is broadcast");
       
   655       m_learnedMac = Mac48Address::ConvertFrom (src);
       
   656       NS_LOG_LOGIC ("Learned MacAddr is " << m_learnedMac);
       
   657       // If we are operating in USE_LOCAL mode, we may be attached to an ns-3
       
   658       // bridging or non-bridging NetDevice.  We use the generic Send() method.
       
   659       NS_LOG_LOGIC ("Forwarding packet");
       
   660       m_bridgedDevice->Send (packet, dst, type);
       
   661       return;
       
   662     }
       
   663 
       
   664   //
       
   665   // If we are operating in USE_BRIDGE mode, we have the 
       
   666   // situation described below:
   648   //
   667   //
   649   //  Other Device  <-->  Tap Device  <--> ns3 device
   668   //  Other Device  <-->  Tap Device  <--> ns3 device
   650   //   Mac Addr A         Mac Addr B       Mac Addr C
   669   //   Mac Addr A         Mac Addr B       Mac Addr C
   651   //
   670   //
   652   // In Linux, "Other Device" and "Tap Device" are bridged together.  This
   671   // In Linux, "Other Device" and "Tap Device" are bridged together.  This
   655   // would call SendFrom on the "Tap Device" with the from address set to the 
   674   // would call SendFrom on the "Tap Device" with the from address set to the 
   656   // original "Other Device" address.   Packets received by "Tap Device" are 
   675   // original "Other Device" address.   Packets received by "Tap Device" are 
   657   // (modulo learning behavior) sent out to "Other Device."  This makes it 
   676   // (modulo learning behavior) sent out to "Other Device."  This makes it 
   658   // appear as if both devices are on a single subnet.
   677   // appear as if both devices are on a single subnet.
   659   //
   678   //
   660   // In BRIDGED_DEVICE mode, we want to logically extend this Linux behavior
   679   // In USE_BRIDGE mode, we want to logically extend this Linux behavior
   661   // to the ns3 device and make it appear as if it is connected to the Linux
   680   // to the ns3 device and make it appear as if it is connected to the Linux
   662   // subnet.  As you may expect, this means that we need to act like a real
   681   // subnet.  As you may expect, this means that we need to act like a real
   663   // bridge and do what is described above.  The code here will do the 
   682   // bridge and do what is described above.  The code here will do the 
   664   // equivalent of a SendFrom on "ns3 Device" of the bits received on
   683   // equivalent of a SendFrom on "ns3 Device" of the bits received on
   665   // "Tap Device"
   684   // "Tap Device"
   666   //
   685   //
   667   // If we are operating in LOCAL_DEVICE mode, we simply simply take all packets
   686   // If we are operating in CONFIGURE_LOCAL mode, we simply simply take all packets
   668   // that come from "Tap Device" and ask "ns3 Device" to send them down its 
   687   // that come from "Tap Device" and ask "ns3 Device" to send them down its 
   669   // directly connected network.  To to this, we just need to remove the
   688   // directly connected network.  To to this, we just need to remove the
   670   // Ethernet header (which was done for us by the Filter () method), and then 
   689   // Ethernet header (which was done for us by the Filter () method), and then 
   671   // just call SendFrom on the bridged device ("ns3 Device") to ship the packet
   690   // just call SendFrom on the bridged device ("ns3 Device") to ship the packet
   672   // out.  If you think about it, this is also a bridging operation, but the 
   691   // out.  If you think about it, this is also a bridging operation, but the 
   675   // The bottom line is that at this point, the code does exactly the same thing
   694   // The bottom line is that at this point, the code does exactly the same thing
   676   // even though they seem quite different at first glance.  The only issue is
   695   // even though they seem quite different at first glance.  The only issue is
   677   // what to do if the bridged device does not support SendFrom, which will be
   696   // what to do if the bridged device does not support SendFrom, which will be
   678   // the case for Wifi STA nodes.
   697   // the case for Wifi STA nodes.
   679   //
   698   //
   680 
       
   681   NS_LOG_LOGIC ("Forwarding packet");
   699   NS_LOG_LOGIC ("Forwarding packet");
   682 
   700 
   683   if (m_bridgedDevice->SupportsSendFrom ())
   701   if (m_mode == USE_BRIDGE)
   684     {
   702     {
   685       m_bridgedDevice->SendFrom (packet, src, dst, type);
   703       m_bridgedDevice->SendFrom (packet, src, dst, type);
   686     }
   704     }
   687   else
   705   else
   688     {
   706     {
   689       NS_FATAL_ERROR ("TapBridge::ForwardToBridgedDevice(): Bridged device does not support SendFrom");
   707       m_bridgedDevice->Send (packet, dst, type);
   690     }
   708     }
   691 }
   709 }
   692 
   710 
   693 Ptr<Packet>
   711 Ptr<Packet>
   694 TapBridge::Filter (Ptr<Packet> p, Address *src, Address *dst, uint16_t *type)
   712 TapBridge::Filter (Ptr<Packet> p, Address *src, Address *dst, uint16_t *type)
   696   NS_LOG_FUNCTION (p);
   714   NS_LOG_FUNCTION (p);
   697   uint32_t pktSize;
   715   uint32_t pktSize;
   698 
   716 
   699   //
   717   //
   700   // We have a candidate packet for injection into ns-3.  We expect that since
   718   // We have a candidate packet for injection into ns-3.  We expect that since
   701   // it came over a socket that provides Ethernet packets, it sould be big 
   719   // it came over a socket that provides Ethernet packets, it should be big 
   702   // enough to hold an EthernetHeader.  If it can't, we signify the packet 
   720   // enough to hold an EthernetHeader.  If it can't, we signify the packet 
   703   // should be filtered out by returning 0.
   721   // should be filtered out by returning 0.
   704   //
   722   //
   705   pktSize = p->GetSize ();
   723   pktSize = p->GetSize ();
   706   EthernetHeader header (false);
   724   EthernetHeader header (false);
   770   if (!Mac48Address::IsMatchingType (bridgedDevice->GetAddress ()))
   788   if (!Mac48Address::IsMatchingType (bridgedDevice->GetAddress ()))
   771     {
   789     {
   772       NS_FATAL_ERROR ("TapBridge::SetBridgedDevice: Device does not support eui 48 addresses: cannot be added to bridge.");
   790       NS_FATAL_ERROR ("TapBridge::SetBridgedDevice: Device does not support eui 48 addresses: cannot be added to bridge.");
   773     }
   791     }
   774   
   792   
   775   if (!bridgedDevice->SupportsSendFrom ())
   793   if (m_mode == USE_BRIDGE && !bridgedDevice->SupportsSendFrom ())
   776     {
   794     {
   777       NS_FATAL_ERROR ("TapBridge::SetBridgedDevice: Device does not support SendFrom: cannot be added to bridge.");
   795       NS_FATAL_ERROR ("TapBridge::SetBridgedDevice: Device does not support SendFrom: cannot be added to bridge.");
   778     }
   796     }
   779 
   797 
   780   //
   798   //
   781   // Tell the bridged device to forward its received packets here.  We use the 
   799   // Tell the bridged device to forward its received packets here.  We use the 
   782   // promiscuous mode hook to get both the source and destination addresses.
   800   // promiscuous mode hook to get both the source and destination addresses.
   783   //
   801   //
   784   m_node->RegisterProtocolHandler (MakeCallback (&TapBridge::ReceiveFromBridgedDevice, this), 0, bridgedDevice, true);
   802   m_node->RegisterProtocolHandler (MakeCallback (&TapBridge::ReceiveFromSimDevice, this), 0, bridgedDevice, true);
   785   m_bridgedDevice = bridgedDevice;
   803   m_bridgedDevice = bridgedDevice;
   786 }
   804 }
   787 
   805 
   788 void
   806 void
   789 TapBridge::ReceiveFromBridgedDevice (
   807 TapBridge::ReceiveFromSimDevice (
   790   Ptr<NetDevice> device, 
   808   Ptr<NetDevice> device, 
   791   Ptr<const Packet> packet, 
   809   Ptr<const Packet> packet, 
   792   uint16_t protocol,
   810   uint16_t protocol,
   793   Address const &src, 
   811   Address const &src, 
   794   Address const &dst, 
   812   Address const &dst, 
   797   NS_LOG_FUNCTION (device << packet << protocol << src << dst << packetType);
   815   NS_LOG_FUNCTION (device << packet << protocol << src << dst << packetType);
   798   NS_ASSERT_MSG (device == m_bridgedDevice, "TapBridge::SetBridgedDevice:  Received packet from unexpected device");
   816   NS_ASSERT_MSG (device == m_bridgedDevice, "TapBridge::SetBridgedDevice:  Received packet from unexpected device");
   799   
   817   
   800   NS_LOG_DEBUG ("Packet UID is " << packet->GetUid ());
   818   NS_LOG_DEBUG ("Packet UID is " << packet->GetUid ());
   801 
   819 
       
   820   if (m_mode == CONFIGURE_LOCAL && packetType == PACKET_OTHERHOST)
       
   821     {
       
   822       // We hooked the promiscuous mode protocol handler so we could get the 
       
   823       // destination address of the actual packet.  This means we will be 
       
   824       // getting PACKET_OTHERHOST packets (not broadcast, not multicast, not 
       
   825       // unicast to the ns-3 net device, but to some other address).  In 
       
   826       // CONFIGURE_LOCAL mode we are not interested in these packets since they 
       
   827       // don't refer to the single MAC address shared by the ns-3 device and 
       
   828       // the TAP device.  If, however, we are in USE_LOCAL or USE_BRIDGE mode, 
       
   829       // we want to act like a bridge and forward these 
       
   830       // PACKET_OTHERHOST packets.
       
   831       return;
       
   832     }
       
   833 
   802   Mac48Address from = Mac48Address::ConvertFrom (src);
   834   Mac48Address from = Mac48Address::ConvertFrom (src);
   803   Mac48Address to = Mac48Address::ConvertFrom (dst);
   835   Mac48Address to;
   804 
   836   if (m_mode == USE_LOCAL)
   805   //
   837     {
   806   // If we are operating in BRIDGED_DEVICE mode, we have the situation described
   838       to = Mac48Address::ConvertFrom (m_learnedMac);
       
   839     }
       
   840   else 
       
   841     {
       
   842       to = Mac48Address::ConvertFrom (dst);
       
   843     }
       
   844 
       
   845   //
       
   846   // If we are operating in USE_BRIDGE mode, we have the situation described
   807   // below:
   847   // below:
   808   //
   848   //
   809   //  Other Device  <-->  Tap Device  <--> ns3 device
   849   //  Other Device  <-->  Tap Device  <--> ns3 device
   810   //   Mac Addr A         Mac Addr B       Mac Addr C
   850   //   Mac Addr A         Mac Addr B       Mac Addr C
   811   //
   851   //
   815   // would call SendFrom on the "Tap Device" with the from address set to the 
   855   // would call SendFrom on the "Tap Device" with the from address set to the 
   816   // original "Other Device" address.   Packets received by "Tap Device" are 
   856   // original "Other Device" address.   Packets received by "Tap Device" are 
   817   // (modulo learning behavior) sent out to "Other Device."  This makes it 
   857   // (modulo learning behavior) sent out to "Other Device."  This makes it 
   818   // appear as if both devices are on a single subnet.
   858   // appear as if both devices are on a single subnet.
   819   //
   859   //
   820   // In BRIDGED_DEVICE mode, we want to logically extend this Linux behavior
   860   // In USE_BRIDGE mode, we want to logically extend this Linux behavior
   821   // to the ns3 device and make it appear as if it is connected to the Linux
   861   // to the ns3 device and make it appear as if it is connected to the Linux
   822   // subnet.  As you may expect, this means that we need to act like a real
   862   // subnet.  As you may expect, this means that we need to act like a real
   823   // bridge and do what is described above.  The code here will do the 
   863   // bridge and do what is described above.  The code here will do the 
   824   // equivalent of a SendFrom on the "Tap Device" of the bits received on the
   864   // equivalent of a SendFrom on the "Tap Device" of the bits received on the
   825   // ns-3 device.
   865   // ns-3 device.
   826   //
   866   //
   827   // If we are operating in LOCAL_DEVICE mode, we simply simply take all packets
   867   // If we are operating in CONFIGURE_LOCAL mode, we simply simply take all packets
   828   // that would normally be received by the device and forward them to the TAP
   868   // that would normally be received by the device and forward them to the TAP
   829   // device as if the ns-3 net device was never there.  To to this, we just need
   869   // device as if the ns-3 net device was never there.  To to this, we just need
   830   // to reconstruct an Ethernet header and add the original source and 
   870   // to reconstruct an Ethernet header and add the original source and 
   831   // destination MAC addresses.  If you think about it, this is also a bridging 
   871   // destination MAC addresses.  If you think about it, this is also a bridging 
   832   // operation, but the bridged devices happen to have the same MAC address.  
   872   // operation, but the bridged devices happen to have the same MAC address.  
   833   //
   873   //
   834   // The bottom line is that at this point, the code does exactly the same thing
   874   // The bottom line is that at this point, the code does exactly the same thing
   835   // even though they seem quite different at first glance.
   875   // even though they seem quite different at first glance.
   836   //
   876   //
   837 
   877 
   838   if (m_mode == LOCAL_DEVICE && packetType == PACKET_OTHERHOST)
       
   839     {
       
   840       // We hooked the promiscuous mode protocol handler so we could get the 
       
   841       // destination address of the actual packet.  This means we will be 
       
   842       // getting PACKET_OTHERHOST packets (not broadcast, not multicast, not 
       
   843       // unicast to the ns-3 net device, but to some other address).  In 
       
   844       // LOCAL_DEVICE mode we are not interested in these packets since they 
       
   845       // don't refer to the single MAC address shared by the ns-3 device and 
       
   846       // the TAP device.  If, however, we are in BRIDGED_DEVICE mode, we want
       
   847       // to act like a bridge and forward these PACKET_OTHERHOST packets.
       
   848       return;
       
   849     }
       
   850 
       
   851   //
   878   //
   852   // We have received a packet from the ns-3 net device that has been associated
   879   // We have received a packet from the ns-3 net device that has been associated
   853   // with this bridge.  We want to take these bits and send them off to the 
   880   // with this bridge.  We want to take these bits and send them off to the 
   854   // Tap device on the Linux host.  Once we do this, the bits in the packet will
   881   // Tap device on the Linux host.  Once we do this, the bits in the packet will
   855   // percolate up through the stack on the Linux host.
   882   // percolate up through the stack on the Linux host.
   871   NS_LOG_LOGIC ("Pkt destination is " << header.GetDestination ());
   898   NS_LOG_LOGIC ("Pkt destination is " << header.GetDestination ());
   872   NS_LOG_LOGIC ("Pkt LengthType is " << header.GetLengthType ());
   899   NS_LOG_LOGIC ("Pkt LengthType is " << header.GetLengthType ());
   873   NS_LOG_LOGIC ("Pkt size is " << p->GetSize ());
   900   NS_LOG_LOGIC ("Pkt size is " << p->GetSize ());
   874 
   901 
   875   uint32_t bytesWritten = write (m_sock, p->PeekData (), p->GetSize ());
   902   uint32_t bytesWritten = write (m_sock, p->PeekData (), p->GetSize ());
   876   NS_ABORT_MSG_IF (bytesWritten != p->GetSize (), "TapBridge::ReceiveFromBridgedDevice(): Write error.");
   903   NS_ABORT_MSG_IF (bytesWritten != p->GetSize (), "TapBridge::ReceiveFromSimDevice(): Write error.");
   877 }
   904 }
   878 
   905 
   879 void 
   906 void 
   880 TapBridge::SetName(const std::string name)
   907 TapBridge::SetName(const std::string name)
   881 {
   908 {