turn on checksums in example csma-tap-bridge and tweaks to make ping demo work
This commit is contained in:
@@ -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).
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 ());
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 ();
|
||||
}
|
||||
|
||||
|
||||
@@ -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 " <<
|
||||
|
||||
Reference in New Issue
Block a user