A Discrete-Event Network Simulator
API
simple-net-device.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2008 INRIA
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 #include "simple-net-device.h"
21 #include "simple-channel.h"
22 #include "ns3/node.h"
23 #include "ns3/packet.h"
24 #include "ns3/log.h"
25 #include "ns3/pointer.h"
26 #include "ns3/error-model.h"
27 #include "ns3/trace-source-accessor.h"
28 #include "ns3/boolean.h"
29 #include "ns3/string.h"
30 #include "ns3/tag.h"
31 #include "ns3/simulator.h"
32 #include "ns3/net-device-queue-interface.h"
33 
34 namespace ns3 {
35 
36 NS_LOG_COMPONENT_DEFINE ("SimpleNetDevice");
37 
41 class SimpleTag : public Tag {
42 public:
47  static TypeId GetTypeId (void);
48  virtual TypeId GetInstanceTypeId (void) const;
49 
50  virtual uint32_t GetSerializedSize (void) const;
51  virtual void Serialize (TagBuffer i) const;
52  virtual void Deserialize (TagBuffer i);
53 
58  void SetSrc (Mac48Address src);
63  Mac48Address GetSrc (void) const;
64 
69  void SetDst (Mac48Address dst);
74  Mac48Address GetDst (void) const;
75 
80  void SetProto (uint16_t proto);
85  uint16_t GetProto (void) const;
86 
87  void Print (std::ostream &os) const;
88 
89 private:
92  uint16_t m_protocolNumber;
93 };
94 
95 
97 
98 TypeId
100 {
101  static TypeId tid = TypeId ("ns3::SimpleTag")
102  .SetParent<Tag> ()
103  .SetGroupName("Network")
104  .AddConstructor<SimpleTag> ()
105  ;
106  return tid;
107 }
108 TypeId
110 {
111  return GetTypeId ();
112 }
113 
114 uint32_t
116 {
117  return 8+8+2;
118 }
119 void
121 {
122  uint8_t mac[6];
123  m_src.CopyTo (mac);
124  i.Write (mac, 6);
125  m_dst.CopyTo (mac);
126  i.Write (mac, 6);
128 }
129 void
131 {
132  uint8_t mac[6];
133  i.Read (mac, 6);
134  m_src.CopyFrom (mac);
135  i.Read (mac, 6);
136  m_dst.CopyFrom (mac);
137  m_protocolNumber = i.ReadU16 ();
138 }
139 
140 void
142 {
143  m_src = src;
144 }
145 
147 SimpleTag::GetSrc (void) const
148 {
149  return m_src;
150 }
151 
152 void
154 {
155  m_dst = dst;
156 }
157 
159 SimpleTag::GetDst (void) const
160 {
161  return m_dst;
162 }
163 
164 void
165 SimpleTag::SetProto (uint16_t proto)
166 {
167  m_protocolNumber = proto;
168 }
169 
170 uint16_t
172 {
173  return m_protocolNumber;
174 }
175 
176 void
177 SimpleTag::Print (std::ostream &os) const
178 {
179  os << "src=" << m_src << " dst=" << m_dst << " proto=" << m_protocolNumber;
180 }
181 
182 
183 
185 
186 TypeId
188 {
189  static TypeId tid = TypeId ("ns3::SimpleNetDevice")
190  .SetParent<NetDevice> ()
191  .SetGroupName("Network")
192  .AddConstructor<SimpleNetDevice> ()
193  .AddAttribute ("ReceiveErrorModel",
194  "The receiver error model used to simulate packet loss",
195  PointerValue (),
197  MakePointerChecker<ErrorModel> ())
198  .AddAttribute ("PointToPointMode",
199  "The device is configured in Point to Point mode",
200  BooleanValue (false),
203  .AddAttribute ("TxQueue",
204  "A queue to use as the transmit queue in the device.",
205  StringValue ("ns3::DropTailQueue<Packet>"),
208  .AddAttribute ("DataRate",
209  "The default data rate for point to point links. Zero means infinite",
210  DataRateValue (DataRate ("0b/s")),
213  .AddTraceSource ("PhyRxDrop",
214  "Trace source indicating a packet has been dropped "
215  "by the device during reception",
217  "ns3::Packet::TracedCallback")
218  ;
219  return tid;
220 }
221 
223  : m_channel (0),
224  m_node (0),
225  m_mtu (0xffff),
226  m_ifIndex (0),
227  m_linkUp (false)
228 {
229  NS_LOG_FUNCTION (this);
230 }
231 
232 void
234 {
235  if (m_queueInterface)
236  {
237  NS_ASSERT_MSG (m_queue != 0, "A Queue object has not been attached to the device");
238 
239  // connect the traced callbacks of m_queue to the static methods provided by
240  // the NetDeviceQueue class to support flow control and dynamic queue limits.
241  // This could not be done in NotifyNewAggregate because at that time we are
242  // not guaranteed that a queue has been attached to the netdevice
243  m_queueInterface->ConnectQueueTraces (m_queue, 0);
244  }
245 
247 }
248 
249 void
251 {
252  NS_LOG_FUNCTION (this);
253  if (m_queueInterface == 0)
254  {
255  Ptr<NetDeviceQueueInterface> ndqi = this->GetObject<NetDeviceQueueInterface> ();
256  //verify that it's a valid netdevice queue interface and that
257  //the netdevice queue interface was not set before
258  if (ndqi != 0)
259  {
260  m_queueInterface = ndqi;
261  }
262  }
264 }
265 
266 void
267 SimpleNetDevice::Receive (Ptr<Packet> packet, uint16_t protocol,
268  Mac48Address to, Mac48Address from)
269 {
270  NS_LOG_FUNCTION (this << packet << protocol << to << from);
271  NetDevice::PacketType packetType;
272 
273  if (m_receiveErrorModel && m_receiveErrorModel->IsCorrupt (packet) )
274  {
275  m_phyRxDropTrace (packet);
276  return;
277  }
278 
279  if (to == m_address)
280  {
281  packetType = NetDevice::PACKET_HOST;
282  }
283  else if (to.IsBroadcast ())
284  {
285  packetType = NetDevice::PACKET_BROADCAST;
286  }
287  else if (to.IsGroup ())
288  {
289  packetType = NetDevice::PACKET_MULTICAST;
290  }
291  else
292  {
293  packetType = NetDevice::PACKET_OTHERHOST;
294  }
295 
296  if (packetType != NetDevice::PACKET_OTHERHOST)
297  {
298  m_rxCallback (this, packet, protocol, from);
299  }
300 
301  if (!m_promiscCallback.IsNull ())
302  {
303  m_promiscCallback (this, packet, protocol, from, to, packetType);
304  }
305 }
306 
307 void
309 {
310  NS_LOG_FUNCTION (this << channel);
311  m_channel = channel;
312  m_channel->Add (this);
313  m_linkUp = true;
315 }
316 
319 {
320  NS_LOG_FUNCTION (this);
321  return m_queue;
322 }
323 
324 void
326 {
327  NS_LOG_FUNCTION (this << q);
328  m_queue = q;
329 }
330 
331 void
333 {
334  NS_LOG_FUNCTION (this << em);
335  m_receiveErrorModel = em;
336 }
337 
338 void
339 SimpleNetDevice::SetIfIndex (const uint32_t index)
340 {
341  NS_LOG_FUNCTION (this << index);
342  m_ifIndex = index;
343 }
344 uint32_t
346 {
347  NS_LOG_FUNCTION (this);
348  return m_ifIndex;
349 }
352 {
353  NS_LOG_FUNCTION (this);
354  return m_channel;
355 }
356 void
358 {
359  NS_LOG_FUNCTION (this << address);
361 }
362 Address
364 {
365  //
366  // Implicit conversion from Mac48Address to Address
367  //
368  NS_LOG_FUNCTION (this);
369  return m_address;
370 }
371 bool
372 SimpleNetDevice::SetMtu (const uint16_t mtu)
373 {
374  NS_LOG_FUNCTION (this << mtu);
375  m_mtu = mtu;
376  return true;
377 }
378 uint16_t
380 {
381  NS_LOG_FUNCTION (this);
382  return m_mtu;
383 }
384 bool
386 {
387  NS_LOG_FUNCTION (this);
388  return m_linkUp;
389 }
390 void
392 {
393  NS_LOG_FUNCTION (this << &callback);
395 }
396 bool
398 {
399  NS_LOG_FUNCTION (this);
400  if (m_pointToPointMode)
401  {
402  return false;
403  }
404  return true;
405 }
406 Address
408 {
409  NS_LOG_FUNCTION (this);
410  return Mac48Address ("ff:ff:ff:ff:ff:ff");
411 }
412 bool
414 {
415  NS_LOG_FUNCTION (this);
416  if (m_pointToPointMode)
417  {
418  return false;
419  }
420  return true;
421 }
422 Address
424 {
425  NS_LOG_FUNCTION (this << multicastGroup);
426  return Mac48Address::GetMulticast (multicastGroup);
427 }
428 
430 {
431  NS_LOG_FUNCTION (this << addr);
432  return Mac48Address::GetMulticast (addr);
433 }
434 
435 bool
437 {
438  NS_LOG_FUNCTION (this);
439  if (m_pointToPointMode)
440  {
441  return true;
442  }
443  return false;
444 }
445 
446 bool
448 {
449  NS_LOG_FUNCTION (this);
450  return false;
451 }
452 
453 bool
454 SimpleNetDevice::Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
455 {
456  NS_LOG_FUNCTION (this << packet << dest << protocolNumber);
457 
458  return SendFrom (packet, m_address, dest, protocolNumber);
459 }
460 
461 bool
462 SimpleNetDevice::SendFrom (Ptr<Packet> p, const Address& source, const Address& dest, uint16_t protocolNumber)
463 {
464  NS_LOG_FUNCTION (this << p << source << dest << protocolNumber);
465  if (p->GetSize () > GetMtu ())
466  {
467  return false;
468  }
469  Ptr<Packet> packet = p->Copy ();
470 
472  Mac48Address from = Mac48Address::ConvertFrom (source);
473 
474  SimpleTag tag;
475  tag.SetSrc (from);
476  tag.SetDst (to);
477  tag.SetProto (protocolNumber);
478 
479  p->AddPacketTag (tag);
480 
481  if (m_queue->Enqueue (p))
482  {
483  if (m_queue->GetNPackets () == 1 && !TransmitCompleteEvent.IsRunning ())
484  {
485  p = m_queue->Dequeue ();
486  p->RemovePacketTag (tag);
487  Time txTime = Time (0);
488  if (m_bps > DataRate (0))
489  {
490  txTime = m_bps.CalculateBytesTxTime (packet->GetSize ());
491  }
492  m_channel->Send (p, protocolNumber, to, from, this);
494  }
495  return true;
496  }
497 
498 
499  m_channel->Send (packet, protocolNumber, to, from, this);
500  return true;
501 }
502 
503 
504 void
506 {
507  NS_LOG_FUNCTION (this);
508 
509  if (m_queue->GetNPackets () == 0)
510  {
511  return;
512  }
513 
514  Ptr<Packet> packet = m_queue->Dequeue ();
515 
516  SimpleTag tag;
517  packet->RemovePacketTag (tag);
518 
519  Mac48Address src = tag.GetSrc ();
520  Mac48Address dst = tag.GetDst ();
521  uint16_t proto = tag.GetProto ();
522 
523  m_channel->Send (packet, proto, dst, src, this);
524 
525  if (m_queue->GetNPackets ())
526  {
527  Time txTime = Time (0);
528  if (m_bps > DataRate (0))
529  {
530  txTime = m_bps.CalculateBytesTxTime (packet->GetSize ());
531  }
533  }
534 
535  return;
536 }
537 
538 Ptr<Node>
540 {
541  NS_LOG_FUNCTION (this);
542  return m_node;
543 }
544 void
546 {
547  NS_LOG_FUNCTION (this << node);
548  m_node = node;
549 }
550 bool
552 {
553  NS_LOG_FUNCTION (this);
554  if (m_pointToPointMode)
555  {
556  return false;
557  }
558  return true;
559 }
560 void
562 {
563  NS_LOG_FUNCTION (this << &cb);
564  m_rxCallback = cb;
565 }
566 
567 void
569 {
570  NS_LOG_FUNCTION (this);
571  m_channel = 0;
572  m_node = 0;
574  m_queue->Flush ();
575  m_queueInterface = 0;
577  {
579  }
581 }
582 
583 
584 void
586 {
587  NS_LOG_FUNCTION (this << &cb);
588  m_promiscCallback = cb;
589 }
590 
591 bool
593 {
594  NS_LOG_FUNCTION (this);
595  return true;
596 }
597 
598 } // namespace ns3
virtual Address GetAddress(void) const
virtual bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber)
Mac48Address GetDst(void) const
Get the destination address.
tuple channel
Definition: third.py:85
Mac48Address m_src
source address
void Write(const uint8_t *buffer, uint32_t size)
Definition: tag-buffer.cc:125
virtual void DoInitialize(void)
Initialize() implementation.
Definition: object.cc:353
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
EventId TransmitCompleteEvent
the Tx Complete event
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
AttributeValue implementation for Boolean.
Definition: boolean.h:36
virtual void DoInitialize(void)
Initialize() implementation.
virtual uint32_t GetSerializedSize(void) const
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Ptr< Node > m_node
Node this netDevice is associated to.
Time CalculateBytesTxTime(uint32_t bytes) const
Calculate transmission time.
Definition: data-rate.cc:235
Hold variables of type string.
Definition: string.h:41
virtual Ptr< Channel > GetChannel(void) const
Ptr< AttributeChecker > MakePointerChecker(void)
Create a PointerChecker for a type.
Definition: pointer.h:224
uint16_t m_protocolNumber
protocol number
TracedCallback m_linkChangeCallbacks
List of callbacks to fire if the link changes state (up or down).
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: boolean.h:84
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:814
void Receive(Ptr< Packet > packet, uint16_t protocol, Mac48Address to, Mac48Address from)
Receive a packet from a connected SimpleChannel.
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1270
Mac48Address GetSrc(void) const
Get the source address.
PacketType
Packet types are used as they are in Linux.
Definition: net-device.h:296
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:796
bool IsBroadcast(void) const
void SetDst(Mac48Address dst)
Set the destination address.
virtual void SetIfIndex(const uint32_t index)
Packet addressed to multicast group.
Definition: net-device.h:302
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Definition: nstime.h:719
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:65
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
virtual bool IsBroadcast(void) const
virtual bool NeedsArp(void) const
bool m_pointToPointMode
Flag indicating whether or not the NetDevice is a Point to Point model.
virtual void Deserialize(TagBuffer i)
Packet addressed oo us.
Definition: net-device.h:298
virtual void Serialize(TagBuffer i) const
virtual bool IsMulticast(void) const
a polymophic address class
Definition: address.h:90
Ptr< const AttributeChecker > MakeDataRateChecker(void)
Definition: data-rate.cc:30
bool m_linkUp
Flag indicating whether or not the link is up.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Class for representing data rates.
Definition: data-rate.h:88
virtual void SetNode(Ptr< Node > node)
void SetProto(uint16_t proto)
Set the protocol number.
void CopyTo(uint8_t buffer[6]) const
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:220
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1375
static Mac48Address GetMulticast(Ipv4Address address)
virtual void SetPromiscReceiveCallback(PromiscReceiveCallback cb)
virtual bool SetMtu(const uint16_t mtu)
This device assumes 48-bit mac addressing; there is also the possibility to add an ErrorModel if you ...
virtual bool IsPointToPoint(void) const
Return true if the net device is on a point-to-point link.
Mac48Address m_address
MAC address.
TAG_BUFFER_INLINE void WriteU16(uint16_t v)
Definition: tag-buffer.h:180
tuple mac
Definition: third.py:92
Ptr< const AttributeAccessor > MakeDataRateAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: data-rate.h:242
SimpleNetDevice tag to store source, destination and protocol of each packet.
static Mac48Address ConvertFrom(const Address &address)
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
Ptr< Queue< Packet > > m_queue
The Queue for outgoing packets.
tag a set of bytes in a packet
Definition: tag.h:36
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Hold objects of type Ptr.
Definition: pointer.h:36
virtual Address GetMulticast(Ipv4Address multicastGroup) const
Make and return a MAC multicast address using the provided multicast group.
bool IsGroup(void) const
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
Packet addressed to someone else.
Definition: net-device.h:304
virtual void SetReceiveCallback(NetDevice::ReceiveCallback cb)
static TypeId GetTypeId(void)
Get the type ID.
an EUI-48 address
Definition: mac48-address.h:43
virtual uint16_t GetMtu(void) const
void SetReceiveErrorModel(Ptr< ErrorModel > em)
Attach a receive ErrorModel to the SimpleNetDevice.
Ptr< Queue< Packet > > GetQueue(void) const
Get a copy of the attached Queue.
Mac48Address m_dst
destination address
void CopyFrom(const uint8_t buffer[6])
virtual Ptr< Node > GetNode(void) const
uint16_t GetProto(void) const
Get the protocol number.
virtual TypeId GetInstanceTypeId(void) const
Get the most derived TypeId for this Object.
NetDevice::PromiscReceiveCallback m_promiscCallback
Promiscuous receive callback.
#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:90
Describes an IPv6 address.
Definition: ipv6-address.h:48
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:40
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...
read and write tag data
Definition: tag-buffer.h:51
virtual void NotifyNewAggregate(void)
Notify all Objects aggregated to this one of a new Object being aggregated.
void ConnectWithoutContext(const CallbackBase &callback)
Append a Callback to the chain (without a context).
Network layer to device interface.
Definition: net-device.h:95
virtual void AddLinkChangeCallback(Callback< void > callback)
AttributeValue implementation for DataRate.
Definition: data-rate.h:242
void SetQueue(Ptr< Queue< Packet > > queue)
Attach a queue to the SimpleNetDevice.
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:821
Packet addressed to all.
Definition: net-device.h:300
virtual void SetAddress(Address address)
Set the address of this interface.
Ptr< ErrorModel > m_receiveErrorModel
Receive error model.
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
void Read(uint8_t *buffer, uint32_t size)
Definition: tag-buffer.cc:176
virtual void DoDispose(void)
Destructor implementation.
virtual bool SendFrom(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber)
NetDevice::ReceiveCallback m_rxCallback
Receive callback.
TAG_BUFFER_INLINE uint16_t ReadU16(void)
Definition: tag-buffer.h:205
Ptr< SimpleChannel > m_channel
the channel the device is connected to
tuple address
Definition: first.py:37
void TransmitComplete(void)
The TransmitComplete method is used internally to finish the process of sending a packet out on the c...
virtual void NotifyNewAggregate(void)
Notify all Objects aggregated to this one of a new Object being aggregated.
Definition: object.cc:325
void SetSrc(Mac48Address src)
Set the source address.
virtual bool IsBridge(void) const
Return true if the net device is acting as a bridge.
void Print(std::ostream &os) const
Ptr< NetDeviceQueueInterface > m_queueInterface
NetDevice queue interface.
void SetChannel(Ptr< SimpleChannel > channel)
Attach a channel to this net device.
DataRate m_bps
The device nominal Data rate.
a unique identifier for an interface.
Definition: type-id.h:58
virtual Address GetBroadcast(void) const
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:914
virtual uint32_t GetIfIndex(void) const
static TypeId GetTypeId(void)
Get the type ID.
virtual bool SupportsSendFrom(void) const
virtual bool IsLinkUp(void) const
uint32_t m_ifIndex
Interface index.