Fix PCAP tracing

This commit is contained in:
Tim Schubert 2020-08-03 21:11:53 +02:00
parent c1496e29f9
commit 096b48f005
6 changed files with 282 additions and 128 deletions

View file

@ -101,7 +101,7 @@ IslHelper::EnablePcapInternal (std::string prefix, Ptr<NetDevice> nd, bool promi
} }
Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, std::ios::out, Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, std::ios::out,
PcapHelper::DLT_PPP); PcapHelper::DLT_EN10MB);
pcapHelper.HookDefaultSink<MockNetDevice> (device, "PromiscSniffer", file); pcapHelper.HookDefaultSink<MockNetDevice> (device, "PromiscSniffer", file);
} }

View file

@ -114,7 +114,7 @@ LeoChannelHelper::EnablePcapInternal (std::string prefix, Ptr<NetDevice> nd, boo
} }
Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, std::ios::out, Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, std::ios::out,
PcapHelper::DLT_PPP); PcapHelper::DLT_EN10MB);
pcapHelper.HookDefaultSink<LeoMockNetDevice> (device, "PromiscSniffer", file); pcapHelper.HookDefaultSink<LeoMockNetDevice> (device, "PromiscSniffer", file);
} }

View file

@ -27,6 +27,7 @@
#include "ns3/pointer.h" #include "ns3/pointer.h"
#include "ns3/net-device-queue-interface.h" #include "ns3/net-device-queue-interface.h"
#include "ns3/ethernet-header.h" #include "ns3/ethernet-header.h"
#include "ns3/ethernet-trailer.h"
#include "mock-channel.h" #include "mock-channel.h"
#include "mock-net-device.h" #include "mock-net-device.h"
@ -191,11 +192,54 @@ MockNetDevice::AddHeader (Ptr<Packet> p,
uint16_t protocolNumber) uint16_t protocolNumber)
{ {
NS_LOG_FUNCTION (this << p << protocolNumber); NS_LOG_FUNCTION (this << p << protocolNumber);
EthernetHeader ethernet; EthernetHeader header (false);
ethernet.SetLengthType (protocolNumber); header.SetSource (Mac48Address::ConvertFrom (src));
ethernet.SetSource (Mac48Address::ConvertFrom (src)); header.SetDestination (Mac48Address::ConvertFrom (dst));
ethernet.SetDestination (Mac48Address::ConvertFrom (dst));
p->AddHeader (ethernet); EthernetTrailer trailer;
NS_LOG_LOGIC ("p->GetSize () = " << p->GetSize ());
NS_LOG_LOGIC ("m_mtu = " << m_mtu);
uint16_t lengthType = 0;
NS_LOG_LOGIC ("Encapsulating packet as LLC (length interpretation)");
LlcSnapHeader llc;
llc.SetType (protocolNumber);
p->AddHeader (llc);
//
// This corresponds to the length interpretation of the lengthType
// field but with an LLC/SNAP header added to the payload as in
// IEEE 802.2
//
lengthType = p->GetSize ();
//
// All Ethernet frames must carry a minimum payload of 46 bytes. The
// LLC SNAP header counts as part of this payload. We need to padd out
// if we don't have enough bytes. These must be real bytes since they
// will be written to pcap files and compared in regression trace files.
//
if (p->GetSize () < 46)
{
uint8_t buffer[46];
memset (buffer, 0, 46);
Ptr<Packet> padd = Create<Packet> (buffer, 46 - p->GetSize ());
p->AddAtEnd (padd);
}
NS_LOG_LOGIC ("header.SetLengthType (" << lengthType << ")");
header.SetLengthType (lengthType);
p->AddHeader (header);
if (Node::ChecksumEnabled ())
{
trailer.EnableFcs (true);
}
trailer.CalcFcs (p);
p->AddTrailer (trailer);
} }
void void
@ -364,6 +408,13 @@ MockNetDevice::Receive (Ptr<Packet> packet, Ptr<MockNetDevice> senderDevice)
{ {
NS_LOG_FUNCTION (this << packet << senderDevice); NS_LOG_FUNCTION (this << packet << senderDevice);
if (senderDevice == this)
{
return;
}
m_phyRxEndTrace (packet);
if (m_receiveErrorModel && m_receiveErrorModel->IsCorrupt (packet) ) if (m_receiveErrorModel && m_receiveErrorModel->IsCorrupt (packet) )
{ {
// //
@ -371,17 +422,9 @@ MockNetDevice::Receive (Ptr<Packet> packet, Ptr<MockNetDevice> senderDevice)
// corrupted packet, don't forward this packet up, let it go. // corrupted packet, don't forward this packet up, let it go.
// //
m_phyRxDropTrace (packet); m_phyRxDropTrace (packet);
return;
} }
else
{
//
// Hit the trace hooks. All of these hooks are in the same place in this
// device because it is so simple, but this is not usually the case in
// more complicated devices.
//
m_snifferTrace (packet);
m_promiscSnifferTrace (packet);
m_phyRxEndTrace (packet);
// //
// Trace sinks will expect complete packets, not packets without some of the // Trace sinks will expect complete packets, not packets without some of the
@ -389,9 +432,44 @@ MockNetDevice::Receive (Ptr<Packet> packet, Ptr<MockNetDevice> senderDevice)
// //
Ptr<Packet> originalPacket = packet->Copy (); Ptr<Packet> originalPacket = packet->Copy ();
EthernetTrailer trailer;
packet->RemoveTrailer (trailer);
if (Node::ChecksumEnabled ())
{
trailer.EnableFcs (true);
}
bool crcGood = trailer.CheckFcs (packet);
if (!crcGood)
{
NS_LOG_INFO ("CRC error on Packet " << packet);
m_phyRxDropTrace (packet);
return;
}
EthernetHeader header; EthernetHeader header;
packet->RemoveHeader (header); packet->RemoveHeader (header);
uint16_t protocol = header.GetLengthType ();
uint16_t protocol;
if (header.GetLengthType () <= 1500)
{
NS_ASSERT (packet->GetSize () >= header.GetLengthType ());
uint32_t padlen = packet->GetSize () - header.GetLengthType ();
NS_ASSERT (padlen <= 46);
if (padlen > 0)
{
packet->RemoveAtEnd (padlen);
}
LlcSnapHeader llc;
packet->RemoveHeader (llc);
protocol = llc.GetType ();
}
else
{
protocol = header.GetLengthType ();
}
PacketType packetType; PacketType packetType;
if (header.GetDestination ().IsBroadcast ()) if (header.GetDestination ().IsBroadcast ())
@ -411,19 +489,17 @@ MockNetDevice::Receive (Ptr<Packet> packet, Ptr<MockNetDevice> senderDevice)
packetType = PACKET_OTHERHOST; packetType = PACKET_OTHERHOST;
} }
// TODO sniffer trace m_promiscSnifferTrace (originalPacket);
Address remote = GetRemote (senderDevice);
if (!m_promiscCallback.IsNull ()) if (!m_promiscCallback.IsNull ())
{ {
m_macPromiscRxTrace (originalPacket); m_macPromiscRxTrace (originalPacket);
m_promiscCallback (this, packet, protocol, remote, GetAddress (), NetDevice::PACKET_HOST); m_promiscCallback (this, packet, protocol, header.GetSource (), header.GetDestination (), packetType);
} }
if (packetType != PACKET_OTHERHOST) { if (packetType != PACKET_OTHERHOST) {
NS_LOG_INFO ("[node " << m_node->GetId () << "] received packet on " << m_ifIndex << " from " << remote << " for " << header.GetDestination ()); NS_LOG_INFO ("[node " << m_node->GetId () << "] received packet on " << m_ifIndex << " from " << header.GetSource () << " for " << header.GetDestination ());
m_macRxTrace (originalPacket); m_macRxTrace (originalPacket);
m_rxCallback (this, packet, protocol, remote); m_rxCallback (this, packet, protocol, header.GetSource ());
}
} }
} }
@ -579,7 +655,9 @@ MockNetDevice::Send (Ptr<Packet> packet,
return false; return false;
} }
AddHeader (packet, m_address, dest, protocolNumber); Mac48Address destination = Mac48Address::ConvertFrom (dest);
Mac48Address source = Mac48Address::ConvertFrom (m_address);
AddHeader (packet, source, destination, protocolNumber);
m_macTxTrace (packet); m_macTxTrace (packet);
@ -594,10 +672,9 @@ MockNetDevice::Send (Ptr<Packet> packet,
if (m_txMachineState == READY) if (m_txMachineState == READY)
{ {
packet = m_queue->Dequeue (); packet = m_queue->Dequeue ();
m_snifferTrace (packet);
m_promiscSnifferTrace (packet); m_promiscSnifferTrace (packet);
bool ret = TransmitStart (packet, dest); m_snifferTrace (packet);
return ret; TransmitStart (packet, dest);
} }
return true; return true;
} }
@ -686,38 +763,10 @@ MockNetDevice::GetMtu (void) const
return m_mtu; return m_mtu;
} }
uint16_t
MockNetDevice::PppToEther (uint16_t proto)
{
NS_LOG_FUNCTION_NOARGS();
switch(proto)
{
case 0x0021: return 0x0800; //IPv4
case 0x0057: return 0x86DD; //IPv6
case 2054: return 0x0806; //ARP
default: NS_ASSERT_MSG (false, "PPP Protocol number not defined!");
}
return 0;
}
uint16_t
MockNetDevice::EtherToPpp (uint16_t proto)
{
NS_LOG_FUNCTION_NOARGS();
switch(proto)
{
case 0x0800: return 0x0021; //IPv4
case 0x86DD: return 0x0057; //IPv6
case 0x0806: return 2054; //ARP
default: NS_ASSERT_MSG (false, "PPP Protocol number not defined!");
}
return 0;
}
bool bool
MockNetDevice::IsPointToPoint() const MockNetDevice::IsPointToPoint() const
{ {
return true; return false;
} }
} // namespace ns3 } // namespace ns3

View file

@ -16,8 +16,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#ifndef ISL_NET_DEVICE_H #ifndef MOCK_NET_DEVICE_H
#define ISL_NET_DEVICE_H #define MOCK_NET_DEVICE_H
#include <cstring> #include <cstring>
@ -40,28 +40,6 @@ class NetDeviceQueueInterface;
class MockChannel; class MockChannel;
class ErrorModel; class ErrorModel;
/**
* \defgroup point-to-point Point-To-Point Network Device
* This section documents the API of the ns-3 point-to-point module. For a
* functional description, please refer to the ns-3 manual here:
* http://www.nsnam.org/docs/models/html/point-to-point.html
*
* Be sure to read the manual BEFORE going down to the API.
*/
/**
* \ingroup point-to-point
* \class MockNetDevice
* \brief A Device for a Point to Point Network Link.
*
* This MockNetDevice class specializes the NetDevice abstract
* base class. Together with a MockChannel (and a peer
* MockNetDevice), the class models, with some level of
* abstraction, a generic point-to-point or serial link.
* Key parameters or objects that can be specified for this device
* include a queue, data rate, and interframe transmission gap (the
* propagation delay is set in the MockChannel).
*/
class MockNetDevice : public NetDevice class MockNetDevice : public NetDevice
{ {
public: public:
@ -476,20 +454,6 @@ private:
uint32_t m_channelDevId; uint32_t m_channelDevId;
Ptr<Packet> m_currentPkt; //!< Current packet processed Ptr<Packet> m_currentPkt; //!< Current packet processed
/**
* \brief PPP to Ethernet protocol number mapping
* \param protocol A PPP protocol number
* \return The corresponding Ethernet protocol number
*/
static uint16_t PppToEther (uint16_t protocol);
/**
* \brief Ethernet to PPP protocol number mapping
* \param protocol An Ethernet protocol number
* \return The corresponding PPP protocol number
*/
static uint16_t EtherToPpp (uint16_t protocol);
}; };
} // namespace ns3 } // namespace ns3

View file

@ -0,0 +1,140 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/internet-module.h"
#include "ns3/applications-module.h"
#include "ns3/node-container.h"
#include "ns3/core-module.h"
#include "ns3/aodv-module.h"
#include "ns3/test.h"
#include "ns3/leo-module.h"
using namespace ns3;
class LeoTraceTestCase1 : public TestCase
{
public:
LeoTraceTestCase1 ();
virtual ~LeoTraceTestCase1 ();
private:
virtual void DoRun (void);
NodeContainer MakeSomeNodes (Vector position, size_t amount);
};
LeoTraceTestCase1::LeoTraceTestCase1 ()
: TestCase ("leo-trace-pcap-test")
{
}
LeoTraceTestCase1::~LeoTraceTestCase1 ()
{
}
NodeContainer
LeoTraceTestCase1::MakeSomeNodes (Vector position, size_t amount)
{
NodeContainer nodes;
for (uint32_t i = 0; i < amount; i ++)
{
Ptr<ConstantPositionMobilityModel> mob = CreateObject<ConstantPositionMobilityModel> ();
mob->SetPosition (Vector (i, 0, 0) + position);
Ptr<Node> node = CreateObject<Node> ();
node->AggregateObject (mob);
nodes.Add (node);
}
return nodes;
}
void
LeoTraceTestCase1::DoRun (void)
{
Time::SetResolution (Time::NS);
NodeContainer satellites = MakeSomeNodes (Vector (0, 0, 1), 2);
NodeContainer terminals = MakeSomeNodes (Vector (0, 0, 0), 2);
NetDeviceContainer islNet, utNet;
IslHelper islCh;
islCh.SetDeviceAttribute ("DataRate", StringValue ("10Mbps"));
islCh.SetDeviceAttribute ("ReceiveErrorModel", StringValue ("ns3::BurstErrorModel"));
islCh.SetChannelAttribute ("PropagationDelay", StringValue ("ns3::ConstantSpeedPropagationDelayModel"));
islCh.SetDeviceAttribute ("InterframeGap", TimeValue (Seconds (0.001)));
islCh.SetChannelAttribute ("PropagationLoss", StringValue ("ns3::IslPropagationLossModel"));
islNet = islCh.Install (satellites);
LeoChannelHelper utCh;
utCh.SetGndDeviceAttribute ("DataRate", StringValue ("10Mbps"));
utCh.SetGndDeviceAttribute ("ReceiveErrorModel", StringValue ("ns3::BurstErrorModel"));
utCh.SetSatDeviceAttribute ("DataRate", StringValue ("10Mbps"));
utCh.SetSatDeviceAttribute ("ReceiveErrorModel", StringValue ("ns3::BurstErrorModel"));
utCh.SetChannelAttribute ("PropagationDelay", StringValue ("ns3::ConstantSpeedPropagationDelayModel"));
utCh.SetSatDeviceAttribute ("InterframeGap", TimeValue (Seconds (0.001)));
utCh.SetGndDeviceAttribute ("InterframeGap", TimeValue (Seconds (0.001)));
utCh.SetChannelAttribute ("PropagationLoss", StringValue ("ns3::LeoPropagationLossModel"));
utCh.SetChannelAttribute ("PropagationDelay", StringValue ("ns3::ConstantSpeedPropagationDelayModel"));
utNet = utCh.Install (satellites, terminals);
// Install internet stack on nodes
InternetStackHelper stack;
AodvHelper aodv;
stack.SetRoutingHelper (aodv);
stack.Install (satellites);
stack.Install (terminals);
// Make all networks addressable for legacy protocol
Ipv4AddressHelper ipv4;
ipv4.SetBase ("10.1.0.0", "255.255.0.0");
Ipv4InterfaceContainer islIp = ipv4.Assign (islNet);
ipv4.SetBase ("10.3.0.0", "255.255.0.0");
Ipv4InterfaceContainer utIp = ipv4.Assign (utNet);
// we want to ping terminals
UdpEchoServerHelper echoServer (9);
ApplicationContainer serverApps = echoServer.Install (terminals.Get (1));
// install a client on one of the terminals
ApplicationContainer clientApps;
Address remote = utIp.GetAddress (3, 0);
UdpEchoClientHelper echoClient (remote, 9);
echoClient.SetAttribute ("MaxPackets", UintegerValue (10));
echoClient.SetAttribute ("Interval", TimeValue (Seconds (2.0)));
echoClient.SetAttribute ("PacketSize", UintegerValue (1024));
clientApps.Add (echoClient.Install (terminals.Get (0)));
serverApps.Start (Seconds (1.0));
clientApps.Start (Seconds (2.0));
clientApps.Stop (Seconds (60));
serverApps.Stop (Seconds (60));
utCh.EnablePcapAll ("leo-ut-trace");
islCh.EnablePcapAll ("leo-isl-trace");
Simulator::Stop (Seconds (60));
Simulator::Run ();
Simulator::Destroy ();
}
// The TestSuite class names the TestSuite, identifies what type of TestSuite,
// and enables the TestCases to be run. Typically, only the constructor for
// this class must be defined
//
class LeoTraceTestSuite : public TestSuite
{
public:
LeoTraceTestSuite ();
};
LeoTraceTestSuite::LeoTraceTestSuite ()
: TestSuite ("leo-trace", UNIT)
{
// TestDuration for TestCase can be QUICK, EXTENSIVE or TAKES_FOREVER
AddTestCase (new LeoTraceTestCase1, TestCase::EXTENSIVE);
}
// Do not forget to allocate an instance of this TestSuite
static LeoTraceTestSuite leoTraceTestSuite;

View file

@ -37,6 +37,7 @@ def build(bld):
'test/leo-mock-channel-test-suite.cc', 'test/leo-mock-channel-test-suite.cc',
'test/leo-propagation-test-suite.cc', 'test/leo-propagation-test-suite.cc',
'test/leo-test-suite.cc', 'test/leo-test-suite.cc',
'test/leo-trace-test-suite.cc',
'test/satellite-node-helper-test-suite.cc', 'test/satellite-node-helper-test-suite.cc',
] ]