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

@ -27,6 +27,7 @@
#include "ns3/pointer.h"
#include "ns3/net-device-queue-interface.h"
#include "ns3/ethernet-header.h"
#include "ns3/ethernet-trailer.h"
#include "mock-channel.h"
#include "mock-net-device.h"
@ -191,11 +192,54 @@ MockNetDevice::AddHeader (Ptr<Packet> p,
uint16_t protocolNumber)
{
NS_LOG_FUNCTION (this << p << protocolNumber);
EthernetHeader ethernet;
ethernet.SetLengthType (protocolNumber);
ethernet.SetSource (Mac48Address::ConvertFrom (src));
ethernet.SetDestination (Mac48Address::ConvertFrom (dst));
p->AddHeader (ethernet);
EthernetHeader header (false);
header.SetSource (Mac48Address::ConvertFrom (src));
header.SetDestination (Mac48Address::ConvertFrom (dst));
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
@ -364,6 +408,13 @@ MockNetDevice::Receive (Ptr<Packet> packet, Ptr<MockNetDevice> senderDevice)
{
NS_LOG_FUNCTION (this << packet << senderDevice);
if (senderDevice == this)
{
return;
}
m_phyRxEndTrace (packet);
if (m_receiveErrorModel && m_receiveErrorModel->IsCorrupt (packet) )
{
//
@ -371,60 +422,85 @@ MockNetDevice::Receive (Ptr<Packet> packet, Ptr<MockNetDevice> senderDevice)
// corrupted packet, don't forward this packet up, let it go.
//
m_phyRxDropTrace (packet);
return;
}
//
// Trace sinks will expect complete packets, not packets without some of the
// headers.
//
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;
packet->RemoveHeader (header);
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
{
//
// 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
// headers.
//
Ptr<Packet> originalPacket = packet->Copy ();
EthernetHeader header;
packet->RemoveHeader (header);
uint16_t protocol = header.GetLengthType ();
PacketType packetType;
if (header.GetDestination ().IsBroadcast ())
{
packetType = PACKET_BROADCAST;
}
else if (header.GetDestination () == m_address)
{
packetType = PACKET_HOST;
}
else if (header.GetDestination ().IsGroup ())
{
packetType = PACKET_MULTICAST;
}
else
{
packetType = PACKET_OTHERHOST;
}
// TODO sniffer trace
Address remote = GetRemote (senderDevice);
if (!m_promiscCallback.IsNull ())
{
m_macPromiscRxTrace (originalPacket);
m_promiscCallback (this, packet, protocol, remote, GetAddress (), NetDevice::PACKET_HOST);
}
if (packetType != PACKET_OTHERHOST) {
NS_LOG_INFO ("[node " << m_node->GetId () << "] received packet on " << m_ifIndex << " from " << remote << " for " << header.GetDestination ());
m_macRxTrace (originalPacket);
m_rxCallback (this, packet, protocol, remote);
}
protocol = header.GetLengthType ();
}
PacketType packetType;
if (header.GetDestination ().IsBroadcast ())
{
packetType = PACKET_BROADCAST;
}
else if (header.GetDestination () == m_address)
{
packetType = PACKET_HOST;
}
else if (header.GetDestination ().IsGroup ())
{
packetType = PACKET_MULTICAST;
}
else
{
packetType = PACKET_OTHERHOST;
}
m_promiscSnifferTrace (originalPacket);
if (!m_promiscCallback.IsNull ())
{
m_macPromiscRxTrace (originalPacket);
m_promiscCallback (this, packet, protocol, header.GetSource (), header.GetDestination (), packetType);
}
if (packetType != PACKET_OTHERHOST) {
NS_LOG_INFO ("[node " << m_node->GetId () << "] received packet on " << m_ifIndex << " from " << header.GetSource () << " for " << header.GetDestination ());
m_macRxTrace (originalPacket);
m_rxCallback (this, packet, protocol, header.GetSource ());
}
}
Ptr<Queue<Packet> >
@ -579,7 +655,9 @@ MockNetDevice::Send (Ptr<Packet> packet,
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);
@ -594,10 +672,9 @@ MockNetDevice::Send (Ptr<Packet> packet,
if (m_txMachineState == READY)
{
packet = m_queue->Dequeue ();
m_snifferTrace (packet);
m_promiscSnifferTrace (packet);
bool ret = TransmitStart (packet, dest);
return ret;
m_snifferTrace (packet);
TransmitStart (packet, dest);
}
return true;
}
@ -686,38 +763,10 @@ MockNetDevice::GetMtu (void) const
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
MockNetDevice::IsPointToPoint() const
{
return true;
return false;
}
} // namespace ns3

View file

@ -16,8 +16,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef ISL_NET_DEVICE_H
#define ISL_NET_DEVICE_H
#ifndef MOCK_NET_DEVICE_H
#define MOCK_NET_DEVICE_H
#include <cstring>
@ -40,28 +40,6 @@ class NetDeviceQueueInterface;
class MockChannel;
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
{
public:
@ -476,20 +454,6 @@ private:
uint32_t m_channelDevId;
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