A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
point-to-point-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) 2007, 2008 University of Washington
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 
19 #include "ns3/log.h"
20 #include "ns3/queue.h"
21 #include "ns3/simulator.h"
22 #include "ns3/mac48-address.h"
23 #include "ns3/llc-snap-header.h"
24 #include "ns3/error-model.h"
25 #include "ns3/trace-source-accessor.h"
26 #include "ns3/uinteger.h"
27 #include "ns3/pointer.h"
29 #include "point-to-point-channel.h"
30 #include "ppp-header.h"
31 
32 NS_LOG_COMPONENT_DEFINE ("PointToPointNetDevice");
33 
34 namespace ns3 {
35 
36 NS_OBJECT_ENSURE_REGISTERED (PointToPointNetDevice);
37 
38 TypeId
40 {
41  static TypeId tid = TypeId ("ns3::PointToPointNetDevice")
42  .SetParent<NetDevice> ()
43  .AddConstructor<PointToPointNetDevice> ()
44  .AddAttribute ("Mtu", "The MAC-level Maximum Transmission Unit",
46  MakeUintegerAccessor (&PointToPointNetDevice::SetMtu,
48  MakeUintegerChecker<uint16_t> ())
49  .AddAttribute ("Address",
50  "The MAC address of this device.",
51  Mac48AddressValue (Mac48Address ("ff:ff:ff:ff:ff:ff")),
52  MakeMac48AddressAccessor (&PointToPointNetDevice::m_address),
53  MakeMac48AddressChecker ())
54  .AddAttribute ("DataRate",
55  "The default data rate for point to point links",
56  DataRateValue (DataRate ("32768b/s")),
57  MakeDataRateAccessor (&PointToPointNetDevice::m_bps),
58  MakeDataRateChecker ())
59  .AddAttribute ("ReceiveErrorModel",
60  "The receiver error model used to simulate packet loss",
61  PointerValue (),
62  MakePointerAccessor (&PointToPointNetDevice::m_receiveErrorModel),
63  MakePointerChecker<ErrorModel> ())
64  .AddAttribute ("InterframeGap",
65  "The time to wait between packet (frame) transmissions",
66  TimeValue (Seconds (0.0)),
67  MakeTimeAccessor (&PointToPointNetDevice::m_tInterframeGap),
68  MakeTimeChecker ())
69 
70  //
71  // Transmit queueing discipline for the device which includes its own set
72  // of trace hooks.
73  //
74  .AddAttribute ("TxQueue",
75  "A queue to use as the transmit queue in the device.",
76  PointerValue (),
77  MakePointerAccessor (&PointToPointNetDevice::m_queue),
78  MakePointerChecker<Queue> ())
79 
80  //
81  // Trace sources at the "top" of the net device, where packets transition
82  // to/from higher layers.
83  //
84  .AddTraceSource ("MacTx",
85  "Trace source indicating a packet has arrived for transmission by this device",
87  .AddTraceSource ("MacTxDrop",
88  "Trace source indicating a packet has been dropped by the device before transmission",
90  .AddTraceSource ("MacPromiscRx",
91  "A packet has been received by this device, has been passed up from the physical layer "
92  "and is being forwarded up the local protocol stack. This is a promiscuous trace,",
94  .AddTraceSource ("MacRx",
95  "A packet has been received by this device, has been passed up from the physical layer "
96  "and is being forwarded up the local protocol stack. This is a non-promiscuous trace,",
98 #if 0
99  // Not currently implemented for this device
100  .AddTraceSource ("MacRxDrop",
101  "Trace source indicating a packet was dropped before being forwarded up the stack",
103 #endif
104  //
105  // Trace souces at the "bottom" of the net device, where packets transition
106  // to/from the channel.
107  //
108  .AddTraceSource ("PhyTxBegin",
109  "Trace source indicating a packet has begun transmitting over the channel",
111  .AddTraceSource ("PhyTxEnd",
112  "Trace source indicating a packet has been completely transmitted over the channel",
114  .AddTraceSource ("PhyTxDrop",
115  "Trace source indicating a packet has been dropped by the device during transmission",
117 #if 0
118  // Not currently implemented for this device
119  .AddTraceSource ("PhyRxBegin",
120  "Trace source indicating a packet has begun being received by the device",
122 #endif
123  .AddTraceSource ("PhyRxEnd",
124  "Trace source indicating a packet has been completely received by the device",
126  .AddTraceSource ("PhyRxDrop",
127  "Trace source indicating a packet has been dropped by the device during reception",
129 
130  //
131  // Trace sources designed to simulate a packet sniffer facility (tcpdump).
132  // Note that there is really no difference between promiscuous and
133  // non-promiscuous traces in a point-to-point link.
134  //
135  .AddTraceSource ("Sniffer",
136  "Trace source simulating a non-promiscuous packet sniffer attached to the device",
138  .AddTraceSource ("PromiscSniffer",
139  "Trace source simulating a promiscuous packet sniffer attached to the device",
141  ;
142  return tid;
143 }
144 
145 
147  :
148  m_txMachineState (READY),
149  m_channel (0),
150  m_linkUp (false),
151  m_currentPkt (0)
152 {
153  NS_LOG_FUNCTION (this);
154 }
155 
157 {
159 }
160 
161 void
162 PointToPointNetDevice::AddHeader (Ptr<Packet> p, uint16_t protocolNumber)
163 {
165  PppHeader ppp;
166  ppp.SetProtocol (EtherToPpp (protocolNumber));
167  p->AddHeader (ppp);
168 }
169 
170 bool
172 {
174  PppHeader ppp;
175  p->RemoveHeader (ppp);
176  param = PppToEther (ppp.GetProtocol ());
177  return true;
178 }
179 
180 void
182 {
184  m_node = 0;
185  m_channel = 0;
187  m_currentPkt = 0;
189 }
190 
191 void
193 {
195  m_bps = bps;
196 }
197 
198 void
200 {
202  m_tInterframeGap = t;
203 }
204 
205 bool
207 {
208  NS_LOG_FUNCTION (this << p);
209  NS_LOG_LOGIC ("UID is " << p->GetUid () << ")");
210 
211  //
212  // This function is called to start the process of transmitting a packet.
213  // We need to tell the channel that we've started wiggling the wire and
214  // schedule an event that will be executed when the transmission is complete.
215  //
216  NS_ASSERT_MSG (m_txMachineState == READY, "Must be READY to transmit");
218  m_currentPkt = p;
220 
221  Time txTime = Seconds (m_bps.CalculateTxTime (p->GetSize ()));
222  Time txCompleteTime = txTime + m_tInterframeGap;
223 
224  NS_LOG_LOGIC ("Schedule TransmitCompleteEvent in " << txCompleteTime.GetSeconds () << "sec");
226 
227  bool result = m_channel->TransmitStart (p, this, txTime);
228  if (result == false)
229  {
230  m_phyTxDropTrace (p);
231  }
232  return result;
233 }
234 
235 void
237 {
239 
240  //
241  // This function is called to when we're all done transmitting a packet.
242  // We try and pull another packet off of the transmit queue. If the queue
243  // is empty, we are done, otherwise we need to start transmitting the
244  // next packet.
245  //
246  NS_ASSERT_MSG (m_txMachineState == BUSY, "Must be BUSY if transmitting");
248 
249  NS_ASSERT_MSG (m_currentPkt != 0, "PointToPointNetDevice::TransmitComplete(): m_currentPkt zero");
250 
252  m_currentPkt = 0;
253 
254  Ptr<Packet> p = m_queue->Dequeue ();
255  if (p == 0)
256  {
257  //
258  // No packet was on the queue, so we just exit.
259  //
260  return;
261  }
262 
263  //
264  // Got another packet off of the queue, so start the transmit process agin.
265  //
266  m_snifferTrace (p);
268  TransmitStart (p);
269 }
270 
271 bool
273 {
274  NS_LOG_FUNCTION (this << &ch);
275 
276  m_channel = ch;
277 
278  m_channel->Attach (this);
279 
280  //
281  // This device is up whenever it is attached to a channel. A better plan
282  // would be to have the link come up when both devices are attached, but this
283  // is not done for now.
284  //
285  NotifyLinkUp ();
286  return true;
287 }
288 
289 void
291 {
292  NS_LOG_FUNCTION (this << q);
293  m_queue = q;
294 }
295 
296 void
298 {
299  NS_LOG_FUNCTION (this << em);
300  m_receiveErrorModel = em;
301 }
302 
303 void
305 {
306  NS_LOG_FUNCTION (this << packet);
307  uint16_t protocol = 0;
308 
309  if (m_receiveErrorModel && m_receiveErrorModel->IsCorrupt (packet) )
310  {
311  //
312  // If we have an error model and it indicates that it is time to lose a
313  // corrupted packet, don't forward this packet up, let it go.
314  //
315  m_phyRxDropTrace (packet);
316  }
317  else
318  {
319  //
320  // Hit the trace hooks. All of these hooks are in the same place in this
321  // device because it is so simple, but this is not usually the case in
322  // more complicated devices.
323  //
324  m_snifferTrace (packet);
325  m_promiscSnifferTrace (packet);
326  m_phyRxEndTrace (packet);
327 
328  //
329  // Trace sinks will expect complete packets, not packets without some of the
330  // headers.
331  //
332  Ptr<Packet> originalPacket = packet->Copy ();
333 
334  //
335  // Strip off the point-to-point protocol header and forward this packet
336  // up the protocol stack. Since this is a simple point-to-point link,
337  // there is no difference in what the promisc callback sees and what the
338  // normal receive callback sees.
339  //
340  ProcessHeader (packet, protocol);
341 
342  if (!m_promiscCallback.IsNull ())
343  {
344  m_macPromiscRxTrace (originalPacket);
345  m_promiscCallback (this, packet, protocol, GetRemote (), GetAddress (), NetDevice::PACKET_HOST);
346  }
347 
348  m_macRxTrace (originalPacket);
349  m_rxCallback (this, packet, protocol, GetRemote ());
350  }
351 }
352 
355 {
357  return m_queue;
358 }
359 
360 void
362 {
363  m_linkUp = true;
365 }
366 
367 void
368 PointToPointNetDevice::SetIfIndex (const uint32_t index)
369 {
370  m_ifIndex = index;
371 }
372 
373 uint32_t
375 {
376  return m_ifIndex;
377 }
378 
381 {
382  return m_channel;
383 }
384 
385 //
386 // This is a point-to-point device, so we really don't need any kind of address
387 // information. However, the base class NetDevice wants us to define the
388 // methods to get and set the address. Rather than be rude and assert, we let
389 // clients get and set the address, but simply ignore them.
390 
391 void
393 {
395 }
396 
397 Address
399 {
400  return m_address;
401 }
402 
403 bool
405 {
406  return m_linkUp;
407 }
408 
409 void
411 {
413 }
414 
415 //
416 // This is a point-to-point device, so every transmission is a broadcast to
417 // all of the devices on the network.
418 //
419 bool
421 {
422  return true;
423 }
424 
425 //
426 // We don't really need any addressing information since this is a
427 // point-to-point device. The base class NetDevice wants us to return a
428 // broadcast address, so we make up something reasonable.
429 //
430 Address
432 {
433  return Mac48Address ("ff:ff:ff:ff:ff:ff");
434 }
435 
436 bool
438 {
439  return true;
440 }
441 
442 Address
444 {
445  return Mac48Address ("01:00:5e:00:00:00");
446 }
447 
448 Address
450 {
451  NS_LOG_FUNCTION (this << addr);
452  return Mac48Address ("33:33:00:00:00:00");
453 }
454 
455 bool
457 {
458  return true;
459 }
460 
461 bool
463 {
464  return false;
465 }
466 
467 bool
469  Ptr<Packet> packet,
470  const Address &dest,
471  uint16_t protocolNumber)
472 {
474  NS_LOG_LOGIC ("p=" << packet << ", dest=" << &dest);
475  NS_LOG_LOGIC ("UID is " << packet->GetUid ());
476 
477  //
478  // If IsLinkUp() is false it means there is no channel to send any packet
479  // over so we just hit the drop trace on the packet and return an error.
480  //
481  if (IsLinkUp () == false)
482  {
483  m_macTxDropTrace (packet);
484  return false;
485  }
486 
487  //
488  // Stick a point to point protocol header on the packet in preparation for
489  // shoving it out the door.
490  //
491  AddHeader (packet, protocolNumber);
492 
493  m_macTxTrace (packet);
494 
495  //
496  // We should enqueue and dequeue the packet to hit the tracing hooks.
497  //
498  if (m_queue->Enqueue (packet))
499  {
500  //
501  // If the channel is ready for transition we send the packet right now
502  //
503  if (m_txMachineState == READY)
504  {
505  packet = m_queue->Dequeue ();
506  m_snifferTrace (packet);
507  m_promiscSnifferTrace (packet);
508  return TransmitStart (packet);
509  }
510  return true;
511  }
512 
513  // Enqueue may fail (overflow)
514  m_macTxDropTrace (packet);
515  return false;
516 }
517 
518 bool
520  const Address &source,
521  const Address &dest,
522  uint16_t protocolNumber)
523 {
524  return false;
525 }
526 
527 Ptr<Node>
529 {
530  return m_node;
531 }
532 
533 void
535 {
536  m_node = node;
537 }
538 
539 bool
541 {
542  return false;
543 }
544 
545 void
547 {
548  m_rxCallback = cb;
549 }
550 
551 void
553 {
554  m_promiscCallback = cb;
555 }
556 
557 bool
559 {
560  return false;
561 }
562 
563 void
565 {
566  Receive (p);
567 }
568 
569 Address
571 {
572  NS_ASSERT (m_channel->GetNDevices () == 2);
573  for (uint32_t i = 0; i < m_channel->GetNDevices (); ++i)
574  {
575  Ptr<NetDevice> tmp = m_channel->GetDevice (i);
576  if (tmp != this)
577  {
578  return tmp->GetAddress ();
579  }
580  }
581  NS_ASSERT (false);
582  // quiet compiler.
583  return Address ();
584 }
585 
586 bool
588 {
589  NS_LOG_FUNCTION (this << mtu);
590  m_mtu = mtu;
591  return true;
592 }
593 
594 uint16_t
596 {
598  return m_mtu;
599 }
600 
601 uint16_t
603 {
604  switch(proto)
605  {
606  case 0x0021: return 0x0800; //IPv4
607  case 0x0057: return 0x86DD; //IPv6
608  default: NS_ASSERT_MSG (false, "PPP Protocol number not defined!");
609  }
610  return 0;
611 }
612 
613 uint16_t
615 {
616  switch(proto)
617  {
618  case 0x0800: return 0x0021; //IPv4
619  case 0x86DD: return 0x0057; //IPv6
620  default: NS_ASSERT_MSG (false, "PPP Protocol number not defined!");
621  }
622  return 0;
623 }
624 
625 
626 } // namespace ns3
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:268
void SetReceiveErrorModel(Ptr< ErrorModel > em)
Attach a receive ErrorModel to the PointToPointNetDevice.
PointToPointNetDevice()
Construct a PointToPointNetDevice.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:79
NetDevice::ReceiveCallback m_rxCallback
virtual bool IsLinkUp(void) const
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
Ptr< Queue > GetQueue(void) const
Get a copy of the attached Queue.
The transmitter is busy transmitting a packet.
TracedCallback< Ptr< const Packet > > m_phyTxDropTrace
The trace source fired when the phy layer drops a packet before it tries to transmit it...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register the class in the ns-3 factory.
Definition: object-base.h:38
uint32_t m_mtu
The Maximum Transmission Unit.
virtual bool SupportsSendFrom(void) const
virtual ~PointToPointNetDevice()
Destroy a PointToPointNetDevice.
TracedCallback< Ptr< const Packet > > m_phyRxEndTrace
The trace source fired when a packet ends the reception process from the medium.
TracedCallback< Ptr< const Packet > > m_phyRxDropTrace
The trace source fired when the phy layer drops a packet it has received.
uint64_t GetUid(void) const
Returns the packet's Uid.
Definition: packet.cc:393
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1018
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:61
TracedCallback< Ptr< const Packet > > m_phyTxBeginTrace
The trace source fired when a packet begins the transmission process on the medium.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:170
static uint16_t EtherToPpp(uint16_t protocol)
Ethernet to PPP protocol number mapping.
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:744
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Definition: object.cc:335
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
virtual Ptr< Node > GetNode(void) const
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Schedule an event to expire at the relative time "time" is reached.
Definition: simulator.h:825
TracedCallback< Ptr< const Packet > > m_macRxTrace
The trace source fired for packets successfully received by the device immediately before being forwa...
The transmitter is ready to begin transmission of a packet.
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...
a polymophic address class
Definition: address.h:86
Packet header for PPP.
Definition: ppp-header.h:48
virtual Address GetMulticast(Ipv4Address multicastGroup) const
Make and return a MAC multicast address using the provided multicast group.
static uint16_t PppToEther(uint16_t protocol)
PPP to Ethernet protocol number mapping.
Class for representing data rates.
Definition: data-rate.h:71
virtual bool IsPointToPoint(void) const
Return true if the net device is on a point-to-point link.
double GetSeconds(void) const
Definition: nstime.h:272
double CalculateTxTime(uint32_t bytes) const
Calculate transmission time.
Definition: data-rate.cc:229
virtual void SetPromiscReceiveCallback(PromiscReceiveCallback cb)
void SetProtocol(uint16_t protocol)
Set the protocol type carried by this PPP packet.
Definition: ppp-header.cc:95
virtual void SetAddress(Address address)
Set the address of this interface.
hold objects of type ns3::Time
Definition: nstime.h:1008
Hold an unsigned integer type.
Definition: uinteger.h:46
void TransmitComplete(void)
Stop Sending a Packet Down the Wire and Begin the Interframe Gap.
TracedCallback< Ptr< const Packet > > m_snifferTrace
A trace source that emulates a non-promiscuous protocol sniffer connected to the device.
bool TransmitStart(Ptr< Packet > p)
Start Sending a Packet Down the Wire.
void SetInterframeGap(Time t)
Set the interframe gap used to separate packets.
NetDevice::PromiscReceiveCallback m_promiscCallback
uint16_t GetProtocol(void)
Get the protocol type carried by this PPP packet.
Definition: ppp-header.cc:101
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:233
Time m_tInterframeGap
The interframe gap that the Net Device uses to throttle packet transmission.
virtual void AddLinkChangeCallback(Callback< void > callback)
static Mac48Address ConvertFrom(const Address &address)
virtual bool NeedsArp(void) const
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:122
virtual void SetReceiveCallback(NetDevice::ReceiveCallback cb)
virtual uint32_t GetIfIndex(void) const
hold objects of type Ptr
Definition: pointer.h:33
virtual Ptr< Channel > GetChannel(void) const
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
virtual Address GetAddress(void) const
an EUI-48 address
Definition: mac48-address.h:41
virtual bool IsBridge(void) const
Return true if the net device is acting as a bridge.
DataRate m_bps
The data rate that the Net Device uses to simulate packet transmission timing.
Ptr< PointToPointChannel > m_channel
The PointToPointChannel to which this PointToPointNetDevice has been attached.
TracedCallback< Ptr< const Packet > > m_promiscSnifferTrace
A trace source that emulates a promiscuous mode protocol sniffer connected to the device...
Ptr< ErrorModel > m_receiveErrorModel
Error model for receive packet events.
#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:84
virtual bool SendFrom(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber)
virtual bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber)
Describes an IPv6 address.
Definition: ipv6-address.h:46
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
TracedCallback< Ptr< const Packet > > m_macPromiscRxTrace
The trace source fired for packets successfully received by the device immediately before being forwa...
TracedCallback< Ptr< const Packet > > m_phyRxBeginTrace
The trace source fired when a packet begins the reception process from the medium – when the simulat...
void ConnectWithoutContext(const CallbackBase &callback)
TxMachineState m_txMachineState
The state of the Net Device transmit state machine.
Packet addressed oo us.
Definition: net-device.h:276
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...
Network layer to device interface.
Definition: net-device.h:75
virtual bool SetMtu(const uint16_t mtu)
virtual void SetIfIndex(const uint32_t index)
hold objects of type ns3::DataRate
hold objects of type ns3::Mac48Address
void SetDataRate(DataRate bps)
Set the Data Rate used for transmission of packets.
TracedCallback< Ptr< const Packet > > m_macRxDropTrace
The trace source fired for packets successfully received by the device but are dropped before being f...
void Receive(Ptr< Packet > p)
Receive a packet from a connected PointToPointChannel.
virtual bool IsBroadcast(void) const
bool Attach(Ptr< PointToPointChannel > ch)
Attach the device to a channel.
Ptr< Queue > m_queue
The Queue which this PointToPointNetDevice uses as a packet source.
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:441
virtual void SetNode(Ptr< Node > node)
tuple address
Definition: first.py:37
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...
virtual uint16_t GetMtu(void) const
virtual bool IsMulticast(void) const
a unique identifier for an interface.
Definition: type-id.h:49
TracedCallback< Ptr< const Packet > > m_macTxTrace
The trace source fired when packets come into the "top" of the device at the L3/L2 transition...
TypeId SetParent(TypeId tid)
Definition: type-id.cc:610
virtual Address GetBroadcast(void) const
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:253
void SetQueue(Ptr< Queue > queue)
Attach a queue to the PointToPointNetDevice.
TracedCallback< Ptr< const Packet > > m_phyTxEndTrace
The trace source fired when a packet ends the transmission process on the medium. ...