A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
point-to-point-net-device.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2007, 2008 University of Washington
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 */
6
8
10#include "ppp-header.h"
11
12#include "ns3/error-model.h"
13#include "ns3/llc-snap-header.h"
14#include "ns3/log.h"
15#include "ns3/mac48-address.h"
16#include "ns3/pointer.h"
17#include "ns3/queue.h"
18#include "ns3/simulator.h"
19#include "ns3/trace-source-accessor.h"
20#include "ns3/uinteger.h"
21
22namespace ns3
23{
24
25NS_LOG_COMPONENT_DEFINE("PointToPointNetDevice");
26
27NS_OBJECT_ENSURE_REGISTERED(PointToPointNetDevice);
28
29TypeId
31{
32 static TypeId tid =
33 TypeId("ns3::PointToPointNetDevice")
35 .SetGroupName("PointToPoint")
36 .AddConstructor<PointToPointNetDevice>()
37 .AddAttribute("Mtu",
38 "The MAC-level Maximum Transmission Unit",
43 .AddAttribute("Address",
44 "The MAC address of this device.",
45 Mac48AddressValue(Mac48Address("ff:ff:ff:ff:ff:ff")),
48 .AddAttribute("DataRate",
49 "The default data rate for point to point links",
50 DataRateValue(DataRate("32768b/s")),
53 .AddAttribute("ReceiveErrorModel",
54 "The receiver error model used to simulate packet loss",
58 .AddAttribute("InterframeGap",
59 "The time to wait between packet (frame) transmissions",
60 TimeValue(Seconds(0.0)),
63
64 //
65 // Transmit queueing discipline for the device which includes its own set
66 // of trace hooks.
67 //
68 .AddAttribute("TxQueue",
69 "A queue to use as the transmit queue in the device.",
73
74 //
75 // Trace sources at the "top" of the net device, where packets transition
76 // to/from higher layers.
77 //
78 .AddTraceSource("MacTx",
79 "Trace source indicating a packet has arrived "
80 "for transmission by this device",
82 "ns3::Packet::TracedCallback")
83 .AddTraceSource("MacTxDrop",
84 "Trace source indicating a packet has been dropped "
85 "by the device before transmission",
87 "ns3::Packet::TracedCallback")
88 .AddTraceSource("MacPromiscRx",
89 "A packet has been received by this device, "
90 "has been passed up from the physical layer "
91 "and is being forwarded up the local protocol stack. "
92 "This is a promiscuous trace,",
94 "ns3::Packet::TracedCallback")
95 .AddTraceSource("MacRx",
96 "A packet has been received by this device, "
97 "has been passed up from the physical layer "
98 "and is being forwarded up the local protocol stack. "
99 "This is a non-promiscuous trace,",
101 "ns3::Packet::TracedCallback")
102#if 0
103 // Not currently implemented for this device
104 .AddTraceSource ("MacRxDrop",
105 "Trace source indicating a packet was dropped "
106 "before being forwarded up the stack",
108 "ns3::Packet::TracedCallback")
109#endif
110 //
111 // Trace sources at the "bottom" of the net device, where packets transition
112 // to/from the channel.
113 //
114 .AddTraceSource("PhyTxBegin",
115 "Trace source indicating a packet has begun "
116 "transmitting over the channel",
118 "ns3::Packet::TracedCallback")
119 .AddTraceSource("PhyTxEnd",
120 "Trace source indicating a packet has been "
121 "completely transmitted over the channel",
123 "ns3::Packet::TracedCallback")
124 .AddTraceSource("PhyTxDrop",
125 "Trace source indicating a packet has been "
126 "dropped by the device during transmission",
128 "ns3::Packet::TracedCallback")
129#if 0
130 // Not currently implemented for this device
131 .AddTraceSource ("PhyRxBegin",
132 "Trace source indicating a packet has begun "
133 "being received by the device",
135 "ns3::Packet::TracedCallback")
136#endif
137 .AddTraceSource("PhyRxEnd",
138 "Trace source indicating a packet has been "
139 "completely received by the device",
141 "ns3::Packet::TracedCallback")
142 .AddTraceSource("PhyRxDrop",
143 "Trace source indicating a packet has been "
144 "dropped by the device during reception",
146 "ns3::Packet::TracedCallback")
147
148 //
149 // Trace sources designed to simulate a packet sniffer facility (tcpdump).
150 // Note that there is really no difference between promiscuous and
151 // non-promiscuous traces in a point-to-point link.
152 //
153 .AddTraceSource("Sniffer",
154 "Trace source simulating a non-promiscuous packet sniffer "
155 "attached to the device",
157 "ns3::Packet::TracedCallback")
158 .AddTraceSource("PromiscSniffer",
159 "Trace source simulating a promiscuous packet sniffer "
160 "attached to the device",
162 "ns3::Packet::TracedCallback");
163 return tid;
164}
165
167 : m_txMachineState(READY),
168 m_channel(nullptr),
169 m_linkUp(false),
170 m_currentPkt(nullptr)
171{
172 NS_LOG_FUNCTION(this);
173}
174
179
180void
182{
183 NS_LOG_FUNCTION(this << p << protocolNumber);
184 PppHeader ppp;
185 ppp.SetProtocol(EtherToPpp(protocolNumber));
186 p->AddHeader(ppp);
187}
188
189bool
191{
192 NS_LOG_FUNCTION(this << p << param);
193 PppHeader ppp;
194 p->RemoveHeader(ppp);
195 param = PppToEther(ppp.GetProtocol());
196 return true;
197}
198
199void
201{
202 NS_LOG_FUNCTION(this);
203 m_node = nullptr;
204 m_channel = nullptr;
205 m_receiveErrorModel = nullptr;
206 m_currentPkt = nullptr;
207 m_queue = nullptr;
209}
210
211void
217
218void
224
225bool
227{
228 NS_LOG_FUNCTION(this << p);
229 NS_LOG_LOGIC("UID is " << p->GetUid() << ")");
230
231 //
232 // This function is called to start the process of transmitting a packet.
233 // We need to tell the channel that we've started wiggling the wire and
234 // schedule an event that will be executed when the transmission is complete.
235 //
236 NS_ASSERT_MSG(m_txMachineState == READY, "Must be READY to transmit");
238 m_currentPkt = p;
240
241 Time txTime = m_bps.CalculateBytesTxTime(p->GetSize());
242 Time txCompleteTime = txTime + m_tInterframeGap;
243
244 NS_LOG_LOGIC("Schedule TransmitCompleteEvent in " << txCompleteTime.As(Time::S));
246
247 bool result = m_channel->TransmitStart(p, this, txTime);
248 if (!result)
249 {
251 }
252 return result;
253}
254
255void
257{
258 NS_LOG_FUNCTION(this);
259
260 //
261 // This function is called to when we're all done transmitting a packet.
262 // We try and pull another packet off of the transmit queue. If the queue
263 // is empty, we are done, otherwise we need to start transmitting the
264 // next packet.
265 //
266 NS_ASSERT_MSG(m_txMachineState == BUSY, "Must be BUSY if transmitting");
268
269 NS_ASSERT_MSG(m_currentPkt, "PointToPointNetDevice::TransmitComplete(): m_currentPkt zero");
270
272 m_currentPkt = nullptr;
273
274 Ptr<Packet> p = m_queue->Dequeue();
275 if (!p)
276 {
277 NS_LOG_LOGIC("No pending packets in device queue after tx complete");
278 return;
279 }
280
281 //
282 // Got another packet off of the queue, so start the transmit process again.
283 //
286 TransmitStart(p);
287}
288
289bool
291{
292 NS_LOG_FUNCTION(this << &ch);
293
294 m_channel = ch;
295
296 m_channel->Attach(this);
297
298 //
299 // This device is up whenever it is attached to a channel. A better plan
300 // would be to have the link come up when both devices are attached, but this
301 // is not done for now.
302 //
303 NotifyLinkUp();
304 return true;
305}
306
307void
313
314void
320
321void
323{
324 NS_LOG_FUNCTION(this << packet);
325 uint16_t protocol = 0;
326
327 if (m_receiveErrorModel && m_receiveErrorModel->IsCorrupt(packet))
328 {
329 //
330 // If we have an error model and it indicates that it is time to lose a
331 // corrupted packet, don't forward this packet up, let it go.
332 //
333 m_phyRxDropTrace(packet);
334 }
335 else
336 {
337 //
338 // Hit the trace hooks. All of these hooks are in the same place in this
339 // device because it is so simple, but this is not usually the case in
340 // more complicated devices.
341 //
342 m_snifferTrace(packet);
343 m_promiscSnifferTrace(packet);
344 m_phyRxEndTrace(packet);
345
346 //
347 // Trace sinks will expect complete packets, not packets without some of the
348 // headers.
349 //
350 Ptr<Packet> originalPacket = packet->Copy();
351
352 //
353 // Strip off the point-to-point protocol header and forward this packet
354 // up the protocol stack. Since this is a simple point-to-point link,
355 // there is no difference in what the promisc callback sees and what the
356 // normal receive callback sees.
357 //
358 ProcessHeader(packet, protocol);
359
361 {
362 m_macPromiscRxTrace(originalPacket);
364 packet,
365 protocol,
366 GetRemote(),
367 GetAddress(),
369 }
370
371 m_macRxTrace(originalPacket);
372 m_rxCallback(this, packet, protocol, GetRemote());
373 }
374}
375
378{
379 NS_LOG_FUNCTION(this);
380 return m_queue;
381}
382
383void
390
391void
393{
394 NS_LOG_FUNCTION(this);
395 m_ifIndex = index;
396}
397
400{
401 return m_ifIndex;
402}
403
406{
407 return m_channel;
408}
409
410//
411// This is a point-to-point device, so we really don't need any kind of address
412// information. However, the base class NetDevice wants us to define the
413// methods to get and set the address. Rather than be rude and assert, we let
414// clients get and set the address, but simply ignore them.
415
416void
418{
419 NS_LOG_FUNCTION(this << address);
421}
422
425{
426 return m_address;
427}
428
429bool
431{
432 NS_LOG_FUNCTION(this);
433 return m_linkUp;
434}
435
436void
442
443//
444// This is a point-to-point device, so every transmission is a broadcast to
445// all of the devices on the network.
446//
447bool
449{
450 NS_LOG_FUNCTION(this);
451 return true;
452}
453
454//
455// We don't really need any addressing information since this is a
456// point-to-point device. The base class NetDevice wants us to return a
457// broadcast address, so we make up something reasonable.
458//
465
466bool
468{
469 NS_LOG_FUNCTION(this);
470 return true;
471}
472
475{
476 NS_LOG_FUNCTION(this);
477 return Mac48Address("01:00:5e:00:00:00");
478}
479
482{
483 NS_LOG_FUNCTION(this << addr);
484 return Mac48Address("33:33:00:00:00:00");
485}
486
487bool
489{
490 NS_LOG_FUNCTION(this);
491 return true;
492}
493
494bool
496{
497 NS_LOG_FUNCTION(this);
498 return false;
499}
500
501bool
502PointToPointNetDevice::Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
503{
504 NS_LOG_FUNCTION(this << packet << dest << protocolNumber);
505 NS_LOG_LOGIC("p=" << packet << ", dest=" << &dest);
506 NS_LOG_LOGIC("UID is " << packet->GetUid());
507
508 //
509 // If IsLinkUp() is false it means there is no channel to send any packet
510 // over so we just hit the drop trace on the packet and return an error.
511 //
512 if (!IsLinkUp())
513 {
514 m_macTxDropTrace(packet);
515 return false;
516 }
517
518 //
519 // Stick a point to point protocol header on the packet in preparation for
520 // shoving it out the door.
521 //
522 AddHeader(packet, protocolNumber);
523
524 m_macTxTrace(packet);
525
526 //
527 // We should enqueue and dequeue the packet to hit the tracing hooks.
528 //
529 if (m_queue->Enqueue(packet))
530 {
531 //
532 // If the channel is ready for transition we send the packet right now
533 //
534 if (m_txMachineState == READY)
535 {
536 packet = m_queue->Dequeue();
537 m_snifferTrace(packet);
538 m_promiscSnifferTrace(packet);
539 bool ret = TransmitStart(packet);
540 return ret;
541 }
542 return true;
543 }
544
545 // Enqueue may fail (overflow)
546
547 m_macTxDropTrace(packet);
548 return false;
549}
550
551bool
553 const Address& source,
554 const Address& dest,
555 uint16_t protocolNumber)
556{
557 NS_LOG_FUNCTION(this << packet << source << dest << protocolNumber);
558 return false;
559}
560
563{
564 return m_node;
565}
566
567void
569{
570 NS_LOG_FUNCTION(this);
571 m_node = node;
572}
573
574bool
576{
577 NS_LOG_FUNCTION(this);
578 return false;
579}
580
581void
586
587void
592
593bool
595{
596 NS_LOG_FUNCTION(this);
597 return false;
598}
599
600void
606
609{
610 NS_LOG_FUNCTION(this);
611 NS_ASSERT(m_channel->GetNDevices() == 2);
612 for (std::size_t i = 0; i < m_channel->GetNDevices(); ++i)
613 {
614 Ptr<NetDevice> tmp = m_channel->GetDevice(i);
615 if (tmp != this)
616 {
617 return tmp->GetAddress();
618 }
619 }
620 NS_ASSERT(false);
621 // quiet compiler.
622 return Address();
623}
624
625bool
627{
628 NS_LOG_FUNCTION(this << mtu);
629 m_mtu = mtu;
630 return true;
631}
632
633uint16_t
635{
636 NS_LOG_FUNCTION(this);
637 return m_mtu;
638}
639
640uint16_t
642{
644 switch (proto)
645 {
646 case 0x0021:
647 return 0x0800; // IPv4
648 case 0x0057:
649 return 0x86DD; // IPv6
650 default:
651 NS_ASSERT_MSG(false, "PPP Protocol number not defined!");
652 }
653 return 0;
654}
655
656uint16_t
658{
660 switch (proto)
661 {
662 case 0x0800:
663 return 0x0021; // IPv4
664 case 0x86DD:
665 return 0x0057; // IPv6
666 default:
667 NS_ASSERT_MSG(false, "PPP Protocol number not defined!");
668 }
669 return 0;
670}
671
672} // namespace ns3
a polymophic address class
Definition address.h:90
Callback template class.
Definition callback.h:422
bool IsNull() const
Check for null implementation.
Definition callback.h:555
Class for representing data rates.
Definition data-rate.h:78
Time CalculateBytesTxTime(uint32_t bytes) const
Calculate transmission time.
Definition data-rate.cc:220
Ipv4 addresses are stored in host order in this class.
Describes an IPv6 address.
an EUI-48 address
static Mac48Address ConvertFrom(const Address &address)
static Mac48Address GetBroadcast()
Network layer to device interface.
Definition net-device.h:87
@ PACKET_HOST
Packet addressed to us.
Definition net-device.h:290
virtual void DoDispose()
Destructor implementation.
Definition object.cc:433
A Device for a Point to Point Network Link.
void AddHeader(Ptr< Packet > p, uint16_t protocolNumber)
Adds the necessary headers and trailers to a packet of data in order to respect the protocol implemen...
static const uint16_t DEFAULT_MTU
Default MTU.
Ptr< Node > GetNode() const override
TracedCallback< Ptr< const Packet > > m_phyRxEndTrace
The trace source fired when a packet ends the reception process from the medium.
Address GetMulticast(Ipv4Address multicastGroup) const override
Make and return a MAC multicast address using the provided multicast group.
Address GetBroadcast() const override
TracedCallback< Ptr< const Packet > > m_macPromiscRxTrace
The trace source fired for packets successfully received by the device immediately before being forwa...
PointToPointNetDevice()
Construct a PointToPointNetDevice.
Ptr< PointToPointChannel > m_channel
The PointToPointChannel to which this PointToPointNetDevice has been attached.
DataRate m_bps
The data rate that the Net Device uses to simulate packet transmission timing.
bool TransmitStart(Ptr< Packet > p)
Start Sending a Packet Down the Wire.
TracedCallback< Ptr< const Packet > > m_macRxTrace
The trace source fired for packets successfully received by the device immediately before being forwa...
TracedCallback< Ptr< const Packet > > m_macRxDropTrace
The trace source fired for packets successfully received by the device but are dropped before being f...
TracedCallback m_linkChangeCallbacks
Callback for the link change event.
TracedCallback< Ptr< const Packet > > m_macTxTrace
The trace source fired when packets come into the "top" of the device at the L3/L2 transition,...
bool SendFrom(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber) override
void SetNode(Ptr< Node > node) override
void SetQueue(Ptr< Queue< Packet > > queue)
Attach a queue to the PointToPointNetDevice.
void SetIfIndex(const uint32_t index) override
void AddLinkChangeCallback(Callback< void > callback) override
bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber) override
bool IsPointToPoint() const override
Return true if the net device is on a point-to-point link.
bool Attach(Ptr< PointToPointChannel > ch)
Attach the device to a channel.
static uint16_t EtherToPpp(uint16_t protocol)
Ethernet to PPP protocol number mapping.
void SetReceiveErrorModel(Ptr< ErrorModel > em)
Attach a receive ErrorModel to the PointToPointNetDevice.
TracedCallback< Ptr< const Packet > > m_phyTxDropTrace
The trace source fired when the phy layer drops a packet before it tries to transmit it.
Ptr< ErrorModel > m_receiveErrorModel
Error model for receive packet events.
void SetInterframeGap(Time t)
Set the interframe gap used to separate packets.
void SetReceiveCallback(NetDevice::ReceiveCallback cb) override
bool m_linkUp
Identify if the link is up or not.
TracedCallback< Ptr< const Packet > > m_phyRxDropTrace
The trace source fired when the phy layer drops a packet it has received.
void NotifyLinkUp()
Make the link up and running.
Ptr< Queue< Packet > > GetQueue() const
Get a copy of the attached Queue.
@ READY
The transmitter is ready to begin transmission of a packet.
@ BUSY
The transmitter is busy transmitting a packet.
static uint16_t PppToEther(uint16_t protocol)
PPP to Ethernet protocol number mapping.
bool IsBridge() const override
Return true if the net device is acting as a bridge.
Ptr< Channel > GetChannel() const override
TracedCallback< Ptr< const Packet > > m_phyTxBeginTrace
The trace source fired when a packet begins the transmission process on the medium.
void DoDispose() override
Dispose of the object.
void SetAddress(Address address) override
Set the address of this interface.
void TransmitComplete()
Stop Sending a Packet Down the Wire and Begin the Interframe Gap.
~PointToPointNetDevice() override
Destroy a PointToPointNetDevice.
static TypeId GetTypeId()
Get the TypeId.
Mac48Address m_address
Mac48Address of this NetDevice.
uint32_t GetIfIndex() const override
Time m_tInterframeGap
The interframe gap that the Net Device uses to throttle packet transmission.
Ptr< Packet > m_currentPkt
Current packet processed.
bool ProcessHeader(Ptr< Packet > p, uint16_t &param)
Removes, from a packet of data, all headers and trailers that relate to the protocol implemented by t...
void Receive(Ptr< Packet > p)
Receive a packet from a connected PointToPointChannel.
TracedCallback< Ptr< const Packet > > m_phyRxBeginTrace
The trace source fired when a packet begins the reception process from the medium – when the simulate...
Ptr< Queue< Packet > > m_queue
The Queue which this PointToPointNetDevice uses as a packet source.
TracedCallback< Ptr< const Packet > > m_promiscSnifferTrace
A trace source that emulates a promiscuous mode protocol sniffer connected to the device.
TracedCallback< Ptr< const Packet > > m_phyTxEndTrace
The trace source fired when a packet ends the transmission process on the medium.
TxMachineState m_txMachineState
The state of the Net Device transmit state machine.
void DoMpiReceive(Ptr< Packet > p)
Handler for MPI receive event.
void SetDataRate(DataRate bps)
Set the Data Rate used for transmission of packets.
uint32_t m_mtu
The Maximum Transmission Unit.
Ptr< Node > m_node
Node owning this NetDevice.
TracedCallback< Ptr< const Packet > > m_snifferTrace
A trace source that emulates a non-promiscuous protocol sniffer connected to the device.
bool SetMtu(const uint16_t mtu) override
TracedCallback< Ptr< const Packet > > m_macTxDropTrace
The trace source fired when packets coming into the "top" of the device at the L3/L2 transition are d...
NetDevice::PromiscReceiveCallback m_promiscCallback
Receive callback.
NetDevice::ReceiveCallback m_rxCallback
Receive callback.
void SetPromiscReceiveCallback(PromiscReceiveCallback cb) override
uint32_t m_ifIndex
Index of the interface.
AttributeValue implementation for Pointer.
Packet header for PPP.
Definition ppp-header.h:38
void SetProtocol(uint16_t protocol)
Set the protocol type carried by this PPP packet.
Definition ppp-header.cc:86
uint16_t GetProtocol() const
Get the protocol type carried by this PPP packet.
Definition ppp-header.cc:92
Smart pointer class similar to boost::intrusive_ptr.
Template class for packet Queues.
Definition queue.h:257
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:560
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition time.cc:404
@ S
second
Definition nstime.h:105
void ConnectWithoutContext(const CallbackBase &callback)
Append a Callback to the chain (without a context).
a unique identifier for an interface.
Definition type-id.h:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
Hold an unsigned integer type.
Definition uinteger.h:34
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition assert.h:75
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition pointer.h:248
Ptr< AttributeChecker > MakePointerChecker()
Create a PointerChecker for a type.
Definition pointer.h:269
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:271
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeUintegerChecker()
Definition uinteger.h:85
Ptr< const AttributeAccessor > MakeDataRateAccessor(T1 a1)
Definition data-rate.h:285
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition nstime.h:1396
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition uinteger.h:35
Ptr< const AttributeAccessor > MakeMac48AddressAccessor(T1 a1)
Ptr< const AttributeChecker > MakeMac48AddressChecker()
Ptr< const AttributeChecker > MakeDataRateChecker()
Definition data-rate.cc:20
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition nstime.h:1416