diff --git a/helper/isl-helper.cc b/helper/isl-helper.cc index 26bd92e..c59b846 100644 --- a/helper/isl-helper.cc +++ b/helper/isl-helper.cc @@ -101,7 +101,7 @@ IslHelper::EnablePcapInternal (std::string prefix, Ptr nd, bool promi } Ptr file = pcapHelper.CreateFile (filename, std::ios::out, - PcapHelper::DLT_PPP); + PcapHelper::DLT_EN10MB); pcapHelper.HookDefaultSink (device, "PromiscSniffer", file); } diff --git a/helper/leo-channel-helper.cc b/helper/leo-channel-helper.cc index 70eaff4..e07bc1b 100644 --- a/helper/leo-channel-helper.cc +++ b/helper/leo-channel-helper.cc @@ -114,7 +114,7 @@ LeoChannelHelper::EnablePcapInternal (std::string prefix, Ptr nd, boo } Ptr file = pcapHelper.CreateFile (filename, std::ios::out, - PcapHelper::DLT_PPP); + PcapHelper::DLT_EN10MB); pcapHelper.HookDefaultSink (device, "PromiscSniffer", file); } diff --git a/model/mock-net-device.cc b/model/mock-net-device.cc index d182b03..fb9ea5b 100644 --- a/model/mock-net-device.cc +++ b/model/mock-net-device.cc @@ -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 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 padd = Create (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, Ptr 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, Ptr 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 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 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 > @@ -579,7 +655,9 @@ MockNetDevice::Send (Ptr 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, 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 diff --git a/model/mock-net-device.h b/model/mock-net-device.h index 3dd2282..7cb491d 100644 --- a/model/mock-net-device.h +++ b/model/mock-net-device.h @@ -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 @@ -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 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 diff --git a/test/leo-trace-test-suite.cc b/test/leo-trace-test-suite.cc new file mode 100644 index 0000000..4e54e7c --- /dev/null +++ b/test/leo-trace-test-suite.cc @@ -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 mob = CreateObject (); + mob->SetPosition (Vector (i, 0, 0) + position); + Ptr node = CreateObject (); + 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; diff --git a/wscript b/wscript index f122895..222cf3e 100644 --- a/wscript +++ b/wscript @@ -37,6 +37,7 @@ def build(bld): 'test/leo-mock-channel-test-suite.cc', 'test/leo-propagation-test-suite.cc', 'test/leo-test-suite.cc', + 'test/leo-trace-test-suite.cc', 'test/satellite-node-helper-test-suite.cc', ]