--- a/examples/csma-tap-bridge.cc Thu Jan 29 16:16:10 2009 -0800
+++ b/examples/csma-tap-bridge.cc Fri Jan 30 15:47:38 2009 -0800
@@ -71,8 +71,20 @@
CommandLine cmd;
cmd.Parse (argc, argv);
- GlobalValue::Bind ("SimulatorImplementationType",
- StringValue ("ns3::RealtimeSimulatorImpl"));
+ //
+ // We need to enable the real-time simulator since we are going to be
+ // talking to the "real world."
+ GlobalValue::Bind ("SimulatorImplementationType", StringValue ("ns3::RealtimeSimulatorImpl"));
+
+ //
+ // Also, since the whole point of this exercise is to exchange packets
+ // with hosts running in the real world, we are going to need to enable
+ // checksums.
+ //
+ Config::SetDefault ("ns3::Ipv4L3Protocol::CalcChecksum", BooleanValue (true));
+ Config::SetDefault ("ns3::Icmpv4L4Protocol::CalcChecksum", BooleanValue (true));
+ Config::SetDefault ("ns3::TcpL4Protocol::CalcChecksum", BooleanValue (true));
+ Config::SetDefault ("ns3::UdpL4Protocol::CalcChecksum", BooleanValue (true));
//
// Create the nodes required by the topology (shown above).
--- a/src/devices/csma/csma-net-device.cc Thu Jan 29 16:16:10 2009 -0800
+++ b/src/devices/csma/csma-net-device.cc Fri Jan 30 15:47:38 2009 -0800
@@ -656,27 +656,22 @@
}
else
{
+ uint16_t protocol;
//
- // variable <protocol> must be initialized to avoid a compiler warning in the RAW case that breaks the optimized build.
+ // If the length/type is less than 1500, it corresponds to a length
+ // interpretation packet. In this case, it is an 802.3 packet and
+ // will also have an 802.2 LLC header. If greater than 1500, we
+ // find the protocol number (Ethernet type) directly.
//
- uint16_t protocol = 0;
-
- switch (m_encapMode)
+ if (header.GetLengthType () <= 1500)
{
- case DIX:
+ LlcSnapHeader llc;
+ packet->RemoveHeader (llc);
+ protocol = llc.GetType ();
+ }
+ else
+ {
protocol = header.GetLengthType ();
- break;
- case LLC:
- {
- LlcSnapHeader llc;
- packet->RemoveHeader (llc);
- protocol = llc.GetType ();
- }
- break;
- case ILLEGAL:
- default:
- NS_FATAL_ERROR ("CsmaNetDevice::Receive(): Unknown packet encapsulation mode");
- break;
}
PacketType packetType;
--- a/src/devices/tap-bridge/tap-bridge.cc Thu Jan 29 16:16:10 2009 -0800
+++ b/src/devices/tap-bridge/tap-bridge.cc Fri Jan 30 15:47:38 2009 -0800
@@ -23,7 +23,6 @@
#include "ns3/channel.h"
#include "ns3/packet.h"
#include "ns3/ethernet-header.h"
-#include "ns3/ethernet-trailer.h"
#include "ns3/llc-snap-header.h"
#include "ns3/log.h"
#include "ns3/boolean.h"
@@ -633,21 +632,10 @@
//
// We have a candidate packet for injection into ns-3. We expect that since
// it came over a socket that provides Ethernet packets, it sould be big
- // enough to hold an EthernetTrailer. If it can't, we signify the packet
+ // enough to hold an EthernetHeader. If it can't, we signify the packet
// should be filtered out by returning 0.
//
pktSize = p->GetSize ();
- EthernetTrailer trailer;
- if (pktSize < trailer.GetSerializedSize ())
- {
- return 0;
- }
- p->RemoveTrailer (trailer);
-
- //
- // We also expect that it will have an Ethernet header on it.
- //
- pktSize = p->GetSize ();
EthernetHeader header (false);
if (pktSize < header.GetSerializedSize ())
{
@@ -689,8 +677,9 @@
}
//
- // What we give back is a packet without the Ethernet header and trailer
- // on it, that is fit to give directly to the bridged net device.
+ // What we give back is a packet without the Ethernet header (nor the
+ // possible llc/snap header) on it. We think it is ready to send on
+ // out the bridged net device.
//
return p;
}
@@ -722,7 +711,8 @@
}
//
- // Tell the bridged device to forward its received packets here.
+ // Tell the bridged device to forward its received packets here. We use the
+ // promiscuous mode hook to get both the source and destination addresses.
//
m_node->RegisterProtocolHandler (MakeCallback (&TapBridge::ReceiveFromBridgedDevice, this), 0, bridgedDevice, true);
m_bridgedDevice = bridgedDevice;
@@ -746,6 +736,18 @@
Mac48Address to = Mac48Address::ConvertFrom (dst);
//
+ // 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
+ // this device, but to some other address). We don't want to forward those
+ // PACKET_OTHERHOST packets so just ignore them
+ //
+ if (packetType == PACKET_OTHERHOST)
+ {
+ return;
+ }
+
+ //
// 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. Once we do this, the bits in the packet will
@@ -755,12 +757,20 @@
// header, so we have to put one back on.
//
Ptr<Packet> p = packet->Copy ();
+
+
EthernetHeader header = EthernetHeader (false);
header.SetSource (from);
header.SetDestination (to);
- header.SetLengthType (0x800);
+ 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 ());
+
write (m_sock, p->PeekData (), p->GetSize ());
}
--- a/src/devices/tap-bridge/tap-creator.cc Thu Jan 29 16:16:10 2009 -0800
+++ b/src/devices/tap-bridge/tap-creator.cc Fri Jan 30 15:47:38 2009 -0800
@@ -352,8 +352,6 @@
opterr = 0;
- gVerbose = true;
-
while ((c = getopt (argc, argv, "vd:g:i:m:n:p:")) != -1)
{
switch (c)
--- a/src/internet-stack/arp-header.cc Thu Jan 29 16:16:10 2009 -0800
+++ b/src/internet-stack/arp-header.cc Fri Jan 30 15:47:38 2009 -0800
@@ -143,18 +143,33 @@
WriteTo (i, m_macDest);
WriteTo (i, m_ipv4Dest);
}
+
uint32_t
ArpHeader::Deserialize (Buffer::Iterator start)
{
Buffer::Iterator i = start;
- i.Next (2+2);
- uint32_t hardwareAddressLen = i.ReadU8 ();
- i.Next (1);
- m_type = i.ReadNtohU16 ();
- ReadFrom (i, m_macSource, hardwareAddressLen);
- ReadFrom (i, m_ipv4Source);
- ReadFrom (i, m_macDest, hardwareAddressLen);
- ReadFrom (i, m_ipv4Dest);
+ uint32_t hardwareType = i.ReadNtohU16 (); // Read HRD
+ uint32_t protocolType = i.ReadNtohU16 (); // Read PRO
+ uint32_t hardwareAddressLen = i.ReadU8 (); // Read HLN
+ uint32_t protocolAddressLen = i.ReadU8 (); // Read PLN
+
+ hardwareType = hardwareType;
+ //
+ // It is implicit here that we have a protocol type of 0x800 (IP).
+ // It is also implicit here that we are using Ipv4 (PLN == 4).
+ // If this isn't the case, we need to return an error since we don't want to
+ // be too fragile if we get connected to real networks.
+ //
+ if (protocolType != 0x800 || protocolAddressLen != 4)
+ {
+ return 0;
+ }
+
+ m_type = i.ReadNtohU16 (); // Read OP
+ ReadFrom (i, m_macSource, hardwareAddressLen); // Read SHA (size HLN)
+ ReadFrom (i, m_ipv4Source); // Read SPA (size PLN == 4)
+ ReadFrom (i, m_macDest, hardwareAddressLen); // Read THA (size HLN)
+ ReadFrom (i, m_ipv4Dest); // Read TPA (size PLN == 4)
return GetSerializedSize ();
}
--- a/src/internet-stack/arp-l3-protocol.cc Thu Jan 29 16:16:10 2009 -0800
+++ b/src/internet-stack/arp-l3-protocol.cc Fri Jan 30 15:47:38 2009 -0800
@@ -124,9 +124,24 @@
Ptr<Packet> packet = p->Copy ();
+ NS_LOG_LOGIC ("ARP: received packet of size "<< packet->GetSize ());
+
Ptr<ArpCache> cache = FindCache (device);
+
+ //
+ // If we're connected to a real world network, then some of the fields sizes
+ // in an ARP packet can vary in ways not seen in simulations. We need to be
+ // able to detect ARP packets with headers we don't recongnize and not process
+ // them instead of crashing. The ArpHeader will return 0 if it can't deal
+ // with the received header.
+ //
ArpHeader arp;
- packet->RemoveHeader (arp);
+ uint32_t size = packet->RemoveHeader (arp);
+ if (size == 0)
+ {
+ NS_LOG_LOGIC ("ARP: Cannot remove ARP header");
+ return;
+ }
NS_LOG_LOGIC ("ARP: received "<< (arp.IsRequest ()? "request" : "reply") <<
" node="<<m_node->GetId ()<<", got request from " <<