turn on checksums in example csma-tap-bridge and tweaks to make ping demo work

This commit is contained in:
Craig Dowell
2009-01-30 15:47:38 -08:00
parent e104e03223
commit 885b97a6ec
6 changed files with 92 additions and 47 deletions

View File

@@ -71,8 +71,20 @@ main (int argc, char *argv[])
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).

View File

@@ -656,27 +656,22 @@ CsmaNetDevice::Receive (Ptr<Packet> packet, Ptr<CsmaNetDevice> senderDevice)
}
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)
{
LlcSnapHeader llc;
packet->RemoveHeader (llc);
protocol = llc.GetType ();
}
else
{
case DIX:
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;

View File

@@ -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 @@ TapBridge::Filter (Ptr<Packet> p, Address *src, Address *dst, uint16_t *type)
//
// 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 @@ TapBridge::Filter (Ptr<Packet> p, Address *src, Address *dst, uint16_t *type)
}
//
// 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 @@ TapBridge::SetBridgedNetDevice (Ptr<NetDevice> bridgedDevice)
}
//
// 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;
@@ -745,6 +735,18 @@ TapBridge::ReceiveFromBridgedDevice (
Mac48Address from = Mac48Address::ConvertFrom (src);
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
@@ -755,12 +757,20 @@ TapBridge::ReceiveFromBridgedDevice (
// 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 ());
}

View File

@@ -352,8 +352,6 @@ main (int argc, char *argv[])
opterr = 0;
gVerbose = true;
while ((c = getopt (argc, argv, "vd:g:i:m:n:p:")) != -1)
{
switch (c)

View File

@@ -143,18 +143,33 @@ ArpHeader::Serialize (Buffer::Iterator start) const
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 ();
}

View File

@@ -124,9 +124,24 @@ ArpL3Protocol::Receive(Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t prot
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 " <<