A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
simple-net-device.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2008 INRIA
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
7 */
8#include "simple-net-device.h"
9
10#include "error-model.h"
11#include "queue.h"
12#include "simple-channel.h"
13
14#include "ns3/boolean.h"
15#include "ns3/log.h"
16#include "ns3/node.h"
17#include "ns3/packet.h"
18#include "ns3/pointer.h"
19#include "ns3/simulator.h"
20#include "ns3/string.h"
21#include "ns3/tag.h"
22#include "ns3/trace-source-accessor.h"
23
24namespace ns3
25{
26
27NS_LOG_COMPONENT_DEFINE("SimpleNetDevice");
28
29/**
30 * \brief SimpleNetDevice tag to store source, destination and protocol of each packet.
31 */
32class SimpleTag : public Tag
33{
34 public:
35 /**
36 * \brief Get the type ID.
37 * \return the object TypeId
38 */
39 static TypeId GetTypeId();
40 TypeId GetInstanceTypeId() const override;
41
42 uint32_t GetSerializedSize() const override;
43 void Serialize(TagBuffer i) const override;
44 void Deserialize(TagBuffer i) override;
45
46 /**
47 * Set the source address
48 * \param src source address
49 */
50 void SetSrc(Mac48Address src);
51 /**
52 * Get the source address
53 * \return the source address
54 */
55 Mac48Address GetSrc() const;
56
57 /**
58 * Set the destination address
59 * \param dst destination address
60 */
61 void SetDst(Mac48Address dst);
62 /**
63 * Get the destination address
64 * \return the destination address
65 */
66 Mac48Address GetDst() const;
67
68 /**
69 * Set the protocol number
70 * \param proto protocol number
71 */
72 void SetProto(uint16_t proto);
73 /**
74 * Get the protocol number
75 * \return the protocol number
76 */
77 uint16_t GetProto() const;
78
79 void Print(std::ostream& os) const override;
80
81 private:
82 Mac48Address m_src; //!< source address
83 Mac48Address m_dst; //!< destination address
84 uint16_t m_protocolNumber; //!< protocol number
85};
86
88
91{
92 static TypeId tid = TypeId("ns3::SimpleTag")
93 .SetParent<Tag>()
94 .SetGroupName("Network")
95 .AddConstructor<SimpleTag>();
96 return tid;
97}
98
101{
102 return GetTypeId();
103}
104
107{
108 return 8 + 8 + 2;
109}
110
111void
113{
114 uint8_t mac[6];
115 m_src.CopyTo(mac);
116 i.Write(mac, 6);
117 m_dst.CopyTo(mac);
118 i.Write(mac, 6);
120}
121
122void
124{
125 uint8_t mac[6];
126 i.Read(mac, 6);
127 m_src.CopyFrom(mac);
128 i.Read(mac, 6);
129 m_dst.CopyFrom(mac);
131}
132
133void
135{
136 m_src = src;
137}
138
141{
142 return m_src;
143}
144
145void
147{
148 m_dst = dst;
149}
150
153{
154 return m_dst;
155}
156
157void
158SimpleTag::SetProto(uint16_t proto)
159{
160 m_protocolNumber = proto;
161}
162
163uint16_t
165{
166 return m_protocolNumber;
167}
168
169void
170SimpleTag::Print(std::ostream& os) const
171{
172 os << "src=" << m_src << " dst=" << m_dst << " proto=" << m_protocolNumber;
173}
174
176
177TypeId
179{
180 static TypeId tid =
181 TypeId("ns3::SimpleNetDevice")
183 .SetGroupName("Network")
184 .AddConstructor<SimpleNetDevice>()
185 .AddAttribute("ReceiveErrorModel",
186 "The receiver error model used to simulate packet loss",
187 PointerValue(),
190 .AddAttribute("PointToPointMode",
191 "The device is configured in Point to Point mode",
192 BooleanValue(false),
195 .AddAttribute("TxQueue",
196 "A queue to use as the transmit queue in the device.",
197 StringValue("ns3::DropTailQueue<Packet>"),
200 .AddAttribute("DataRate",
201 "The default data rate for point to point links. Zero means infinite",
202 DataRateValue(DataRate("0b/s")),
205 .AddTraceSource("PhyRxDrop",
206 "Trace source indicating a packet has been dropped "
207 "by the device during reception",
209 "ns3::Packet::TracedCallback");
210 return tid;
211}
212
214 : m_channel(nullptr),
215 m_node(nullptr),
216 m_mtu(0xffff),
217 m_ifIndex(0),
218 m_linkUp(false)
219{
220 NS_LOG_FUNCTION(this);
221}
222
223void
225{
226 NS_LOG_FUNCTION(this << packet << protocol << to << from);
227 NetDevice::PacketType packetType;
228
229 if (m_receiveErrorModel && m_receiveErrorModel->IsCorrupt(packet))
230 {
231 m_phyRxDropTrace(packet);
232 return;
233 }
234
235 if (to == m_address)
236 {
237 packetType = NetDevice::PACKET_HOST;
238 }
239 else if (to.IsBroadcast())
240 {
241 packetType = NetDevice::PACKET_BROADCAST;
242 }
243 else if (to.IsGroup())
244 {
245 packetType = NetDevice::PACKET_MULTICAST;
246 }
247 else
248 {
249 packetType = NetDevice::PACKET_OTHERHOST;
250 }
251
252 if (packetType != NetDevice::PACKET_OTHERHOST)
253 {
254 m_rxCallback(this, packet, protocol, from);
255 }
256
258 {
259 m_promiscCallback(this, packet, protocol, from, to, packetType);
260 }
261}
262
263void
265{
266 NS_LOG_FUNCTION(this << channel);
267 m_channel = channel;
268 m_channel->Add(this);
269 m_linkUp = true;
271}
272
275{
276 NS_LOG_FUNCTION(this);
277 return m_queue;
278}
279
280void
286
287void
293
294void
296{
297 NS_LOG_FUNCTION(this << index);
298 m_ifIndex = index;
299}
300
303{
304 NS_LOG_FUNCTION(this);
305 return m_ifIndex;
306}
307
310{
311 NS_LOG_FUNCTION(this);
312 return m_channel;
313}
314
315void
317{
318 NS_LOG_FUNCTION(this << address);
320}
321
324{
325 //
326 // Implicit conversion from Mac48Address to Address
327 //
328 NS_LOG_FUNCTION(this);
329 return m_address;
330}
331
332bool
333SimpleNetDevice::SetMtu(const uint16_t mtu)
334{
335 NS_LOG_FUNCTION(this << mtu);
336 m_mtu = mtu;
337 return true;
338}
339
340uint16_t
342{
343 NS_LOG_FUNCTION(this);
344 return m_mtu;
345}
346
347bool
349{
350 NS_LOG_FUNCTION(this);
351 return m_linkUp;
352}
353
354void
360
361bool
363{
364 NS_LOG_FUNCTION(this);
365 return !m_pointToPointMode;
366}
367
374
375bool
377{
378 NS_LOG_FUNCTION(this);
379 return !m_pointToPointMode;
380}
381
384{
385 NS_LOG_FUNCTION(this << multicastGroup);
386 return Mac48Address::GetMulticast(multicastGroup);
387}
388
391{
392 NS_LOG_FUNCTION(this << addr);
393 return Mac48Address::GetMulticast(addr);
394}
395
396bool
402
403bool
405{
406 NS_LOG_FUNCTION(this);
407 return false;
408}
409
410bool
411SimpleNetDevice::Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
412{
413 NS_LOG_FUNCTION(this << packet << dest << protocolNumber);
414
415 return SendFrom(packet, m_address, dest, protocolNumber);
416}
417
418bool
420 const Address& source,
421 const Address& dest,
422 uint16_t protocolNumber)
423{
424 NS_LOG_FUNCTION(this << p << source << dest << protocolNumber);
425 if (p->GetSize() > GetMtu())
426 {
427 return false;
428 }
429
432
433 SimpleTag tag;
434 tag.SetSrc(from);
435 tag.SetDst(to);
436 tag.SetProto(protocolNumber);
437
438 p->AddPacketTag(tag);
439
440 if (m_queue->Enqueue(p))
441 {
442 if (m_queue->GetNPackets() == 1 && !FinishTransmissionEvent.IsPending())
443 {
445 }
446 return true;
447 }
448
449 return false;
450}
451
452void
454{
455 if (m_queue->GetNPackets() == 0)
456 {
457 return;
458 }
460 "Tried to transmit a packet while another transmission was in progress");
461 Ptr<Packet> packet = m_queue->Dequeue();
462
463 /**
464 * SimpleChannel will deliver the packet to the far end(s) of the link as soon as Send is called
465 * (or after its fixed delay, if one is configured). So we have to handle the rate of the link
466 * here, which we do by scheduling FinishTransmission (packetSize / linkRate) time in the
467 * future. While that event is running, the transmit path of this NetDevice is busy, so we can't
468 * send other packets.
469 *
470 * SimpleChannel doesn't have a locking mechanism, and doesn't check for collisions, so there's
471 * nothing we need to do with the channel until the transmission has "completed" from the
472 * perspective of this NetDevice.
473 */
474 Time txTime = Time(0);
475 if (m_bps > DataRate(0))
476 {
477 txTime = m_bps.CalculateBytesTxTime(packet->GetSize());
478 }
481}
482
483void
485{
486 NS_LOG_FUNCTION(this);
487
488 SimpleTag tag;
489 packet->RemovePacketTag(tag);
490
491 Mac48Address src = tag.GetSrc();
492 Mac48Address dst = tag.GetDst();
493 uint16_t proto = tag.GetProto();
494
495 m_channel->Send(packet, proto, dst, src, this);
496
498}
499
502{
503 NS_LOG_FUNCTION(this);
504 return m_node;
505}
506
507void
509{
510 NS_LOG_FUNCTION(this << node);
511 m_node = node;
512}
513
514bool
516{
517 NS_LOG_FUNCTION(this);
518 return !m_pointToPointMode;
519}
520
521void
527
528void
530{
531 NS_LOG_FUNCTION(this);
532 m_channel = nullptr;
533 m_node = nullptr;
534 m_receiveErrorModel = nullptr;
535 m_queue->Dispose();
537 {
539 }
541}
542
543void
549
550bool
552{
553 NS_LOG_FUNCTION(this);
554 return true;
555}
556
557} // 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
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition event-id.cc:44
bool IsPending() const
This method is syntactic sugar for !IsExpired().
Definition event-id.cc:65
Ipv4 addresses are stored in host order in this class.
Describes an IPv6 address.
an EUI-48 address
static Mac48Address GetMulticast(Ipv4Address address)
bool IsGroup() const
void CopyFrom(const uint8_t buffer[6])
static Mac48Address ConvertFrom(const Address &address)
static Mac48Address GetBroadcast()
void CopyTo(uint8_t buffer[6]) const
bool IsBroadcast() const
Network layer to device interface.
Definition net-device.h:87
PacketType
Packet types are used as they are in Linux.
Definition net-device.h:289
@ PACKET_HOST
Packet addressed to us.
Definition net-device.h:290
@ PACKET_OTHERHOST
Packet addressed to someone else.
Definition net-device.h:296
@ PACKET_BROADCAST
Packet addressed to all.
Definition net-device.h:292
@ PACKET_MULTICAST
Packet addressed to multicast group.
Definition net-device.h:294
void Dispose()
Dispose of this Object.
Definition object.cc:247
virtual void DoDispose()
Destructor implementation.
Definition object.cc:433
AttributeValue implementation for Pointer.
Smart pointer class similar to boost::intrusive_ptr.
Template class for packet Queues.
Definition queue.h:257
This device assumes 48-bit mac addressing; there is also the possibility to add an ErrorModel if you ...
bool NeedsArp() const override
void DoDispose() override
Destructor implementation.
void SetPromiscReceiveCallback(PromiscReceiveCallback cb) override
TracedCallback< Ptr< const Packet > > m_phyRxDropTrace
The trace source fired when the phy layer drops a packet it has received due to the error model being...
TracedCallback m_linkChangeCallbacks
List of callbacks to fire if the link changes state (up or down).
bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber) override
void SetNode(Ptr< Node > node) override
void SetAddress(Address address) override
Set the address of this interface.
void SetIfIndex(const uint32_t index) override
void SetQueue(Ptr< Queue< Packet > > queue)
Attach a queue to the SimpleNetDevice.
bool SetMtu(const uint16_t mtu) override
NetDevice::ReceiveCallback m_rxCallback
Receive callback.
bool SendFrom(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber) override
static TypeId GetTypeId()
Get the type ID.
DataRate m_bps
The device nominal Data rate.
Ptr< Queue< Packet > > m_queue
The Queue for outgoing packets.
bool IsPointToPoint() const override
Return true if the net device is on a point-to-point link.
Ptr< Channel > GetChannel() const override
void SetReceiveErrorModel(Ptr< ErrorModel > em)
Attach a receive ErrorModel to the SimpleNetDevice.
uint16_t GetMtu() const override
EventId FinishTransmissionEvent
the Tx Complete event
bool m_linkUp
Flag indicating whether or not the link is up.
void AddLinkChangeCallback(Callback< void > callback) override
bool m_pointToPointMode
Flag indicating whether or not the NetDevice is a Point to Point model.
Address GetMulticast(Ipv4Address multicastGroup) const override
Make and return a MAC multicast address using the provided multicast group.
void FinishTransmission(Ptr< Packet > packet)
The FinishTransmission method is used internally to finish the process of sending a packet out on the...
uint32_t GetIfIndex() const override
Ptr< ErrorModel > m_receiveErrorModel
Receive error model.
bool IsMulticast() const override
Ptr< SimpleChannel > m_channel
the channel the device is connected to
Ptr< Node > m_node
Node this netDevice is associated to.
uint32_t m_ifIndex
Interface index.
Mac48Address m_address
MAC address.
Ptr< Queue< Packet > > GetQueue() const
Get a copy of the attached Queue.
Ptr< Node > GetNode() const override
bool IsLinkUp() const override
void StartTransmission()
The StartTransmission method is used internally to start the process of sending a packet out on the c...
Address GetBroadcast() const override
NetDevice::PromiscReceiveCallback m_promiscCallback
Promiscuous receive callback.
bool IsBridge() const override
Return true if the net device is acting as a bridge.
bool IsBroadcast() const override
bool SupportsSendFrom() const override
void SetReceiveCallback(NetDevice::ReceiveCallback cb) override
void Receive(Ptr< Packet > packet, uint16_t protocol, Mac48Address to, Mac48Address from)
Receive a packet from a connected SimpleChannel.
void SetChannel(Ptr< SimpleChannel > channel)
Attach a channel to this net device.
Address GetAddress() const override
SimpleNetDevice tag to store source, destination and protocol of each packet.
Mac48Address GetDst() const
Get the destination address.
Mac48Address GetSrc() const
Get the source address.
Mac48Address m_dst
destination address
void Deserialize(TagBuffer i) override
static TypeId GetTypeId()
Get the type ID.
uint16_t m_protocolNumber
protocol number
void Print(std::ostream &os) const override
void SetSrc(Mac48Address src)
Set the source address.
uint32_t GetSerializedSize() const override
void SetProto(uint16_t proto)
Set the protocol number.
Mac48Address m_src
source address
uint16_t GetProto() const
Get the protocol number.
void Serialize(TagBuffer i) const override
TypeId GetInstanceTypeId() const override
Get the most derived TypeId for this Object.
void SetDst(Mac48Address dst)
Set the destination address.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:560
Hold variables of type string.
Definition string.h:45
read and write tag data
Definition tag-buffer.h:41
void Read(uint8_t *buffer, uint32_t size)
TAG_BUFFER_INLINE uint16_t ReadU16()
Definition tag-buffer.h:195
void Write(const uint8_t *buffer, uint32_t size)
TAG_BUFFER_INLINE void WriteU16(uint16_t v)
Definition tag-buffer.h:169
tag a set of bytes in a packet
Definition tag.h:28
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
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
#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_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
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 > MakeBooleanChecker()
Definition boolean.cc:113
Ptr< const AttributeAccessor > MakeDataRateAccessor(T1 a1)
Definition data-rate.h:285
Ptr< const AttributeChecker > MakeDataRateChecker()
Definition data-rate.cc:20
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition boolean.h:70