A Discrete-Event Network Simulator
API
csma-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 Emmanuelle Laprise
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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
19  */
20 
21 #include "ns3/log.h"
22 #include "ns3/queue.h"
23 #include "ns3/simulator.h"
24 #include "ns3/ethernet-header.h"
25 #include "ns3/ethernet-trailer.h"
26 #include "ns3/llc-snap-header.h"
27 #include "ns3/error-model.h"
28 #include "ns3/enum.h"
29 #include "ns3/boolean.h"
30 #include "ns3/uinteger.h"
31 #include "ns3/pointer.h"
32 #include "ns3/trace-source-accessor.h"
33 #include "csma-net-device.h"
34 #include "csma-channel.h"
35 
36 namespace ns3 {
37 
38 NS_LOG_COMPONENT_DEFINE ("CsmaNetDevice");
39 
40 NS_OBJECT_ENSURE_REGISTERED (CsmaNetDevice);
41 
42 TypeId
44 {
45  static TypeId tid = TypeId ("ns3::CsmaNetDevice")
46  .SetParent<NetDevice> ()
47  .SetGroupName ("Csma")
48  .AddConstructor<CsmaNetDevice> ()
49  .AddAttribute ("Address",
50  "The MAC address of this device.",
51  Mac48AddressValue (Mac48Address ("ff:ff:ff:ff:ff:ff")),
54  .AddAttribute ("Mtu", "The MAC-level Maximum Transmission Unit",
58  MakeUintegerChecker<uint16_t> ())
59  .AddAttribute ("EncapsulationMode",
60  "The link-layer encapsulation type to use.",
61  EnumValue (DIX),
63  MakeEnumChecker (DIX, "Dix",
64  LLC, "Llc"))
65  .AddAttribute ("SendEnable",
66  "Enable or disable the transmitter section of the device.",
67  BooleanValue (true),
70  .AddAttribute ("ReceiveEnable",
71  "Enable or disable the receiver section of the device.",
72  BooleanValue (true),
75  .AddAttribute ("ReceiveErrorModel",
76  "The receiver error model used to simulate packet loss",
77  PointerValue (),
79  MakePointerChecker<ErrorModel> ())
80 
81  //
82  // Transmit queueing discipline for the device which includes its own set
83  // of trace hooks.
84  //
85  .AddAttribute ("TxQueue",
86  "A queue to use as the transmit queue in the device.",
87  PointerValue (),
89  MakePointerChecker<Queue> ())
90 
91  //
92  // Trace sources at the "top" of the net device, where packets transition
93  // to/from higher layers.
94  //
95  .AddTraceSource ("MacTx",
96  "Trace source indicating a packet has "
97  "arrived for transmission by this device",
99  "ns3::Packet::TracedCallback")
100  .AddTraceSource ("MacTxDrop",
101  "Trace source indicating a packet has been "
102  "dropped by the device before transmission",
104  "ns3::Packet::TracedCallback")
105  .AddTraceSource ("MacPromiscRx",
106  "A packet has been received by this device, "
107  "has been passed up from the physical layer "
108  "and is being forwarded up the local protocol stack. "
109  "This is a promiscuous trace,",
111  "ns3::Packet::TracedCallback")
112  .AddTraceSource ("MacRx",
113  "A packet has been received by this device, "
114  "has been passed up from the physical layer "
115  "and is being forwarded up the local protocol stack. "
116  "This is a non-promiscuous trace,",
118  "ns3::Packet::TracedCallback")
119 #if 0
120  // Not currently implemented in this device
121  .AddTraceSource ("MacRxDrop",
122  "Trace source indicating a packet was received, "
123  "but dropped before being forwarded up the stack",
125  "ns3::Packet::TracedCallback")
126 #endif
127  .AddTraceSource ("MacTxBackoff",
128  "Trace source indicating a packet has been "
129  "delayed by the CSMA backoff process",
131  "ns3::Packet::TracedCallback")
132  //
133  // Trace souces at the "bottom" of the net device, where packets transition
134  // to/from the channel.
135  //
136  .AddTraceSource ("PhyTxBegin",
137  "Trace source indicating a packet has "
138  "begun transmitting over the channel",
140  "ns3::Packet::TracedCallback")
141  .AddTraceSource ("PhyTxEnd",
142  "Trace source indicating a packet has been "
143  "completely transmitted over the channel",
145  "ns3::Packet::TracedCallback")
146  .AddTraceSource ("PhyTxDrop",
147  "Trace source indicating a packet has been "
148  "dropped by the device during transmission",
150  "ns3::Packet::TracedCallback")
151 #if 0
152  // Not currently implemented in this device
153  .AddTraceSource ("PhyRxBegin",
154  "Trace source indicating a packet has "
155  "begun being received by the device",
157  "ns3::Packet::TracedCallback")
158 #endif
159  .AddTraceSource ("PhyRxEnd",
160  "Trace source indicating a packet has been "
161  "completely received by the device",
163  "ns3::Packet::TracedCallback")
164  .AddTraceSource ("PhyRxDrop",
165  "Trace source indicating a packet has been "
166  "dropped by the device during reception",
168  "ns3::Packet::TracedCallback")
169  //
170  // Trace sources designed to simulate a packet sniffer facility (tcpdump).
171  //
172  .AddTraceSource ("Sniffer",
173  "Trace source simulating a non-promiscuous "
174  "packet sniffer attached to the device",
176  "ns3::Packet::TracedCallback")
177  .AddTraceSource ("PromiscSniffer",
178  "Trace source simulating a promiscuous "
179  "packet sniffer attached to the device",
181  "ns3::Packet::TracedCallback")
182  ;
183  return tid;
184 }
185 
187  : m_linkUp (false)
188 {
189  NS_LOG_FUNCTION (this);
192  m_channel = 0;
193 
194  //
195  // We would like to let the attribute system take care of initializing the
196  // packet encapsulation stuff, but we also don't want to get caught up in
197  // initialization order changes. So we'll get the three problem variables
198  // into a consistent state here before the attribute calls, and then depend
199  // on the semantics of the setters to preserve a consistent state. This
200  // really doesn't have to be the same set of values as the initial values
201  // set by the attributes, but it does have to be a consistent set. That is,
202  // you can just change the default encapsulation mode above without having
203  // to change it here.
204  //
205  m_encapMode = DIX;
206 }
207 
209 {
211  m_queue = 0;
212 }
213 
214 void
216 {
218  m_channel = 0;
219  m_node = 0;
221 }
222 
223 void
225 {
226  NS_LOG_FUNCTION (mode);
227 
228  m_encapMode = mode;
229 
230  NS_LOG_LOGIC ("m_encapMode = " << m_encapMode);
231  NS_LOG_LOGIC ("m_mtu = " << m_mtu);
232 }
233 
236 {
238  return m_encapMode;
239 }
240 
241 bool
242 CsmaNetDevice::SetMtu (uint16_t mtu)
243 {
244  NS_LOG_FUNCTION (this << mtu);
245  m_mtu = mtu;
246 
247  NS_LOG_LOGIC ("m_encapMode = " << m_encapMode);
248  NS_LOG_LOGIC ("m_mtu = " << m_mtu);
249 
250  return true;
251 }
252 
253 uint16_t
255 {
257  return m_mtu;
258 }
259 
260 
261 void
263 {
264  NS_LOG_FUNCTION (sendEnable);
265  m_sendEnable = sendEnable;
266 }
267 
268 void
270 {
271  NS_LOG_FUNCTION (receiveEnable);
272  m_receiveEnable = receiveEnable;
273 }
274 
275 bool
277 {
279  return m_sendEnable;
280 }
281 
282 bool
284 {
286  return m_receiveEnable;
287 }
288 
289 void
291 {
292  NS_LOG_FUNCTION (t);
293  m_tInterframeGap = t;
294 }
295 
296 void
297 CsmaNetDevice::SetBackoffParams (Time slotTime, uint32_t minSlots, uint32_t maxSlots, uint32_t ceiling, uint32_t maxRetries)
298 {
299  NS_LOG_FUNCTION (slotTime << minSlots << maxSlots << ceiling << maxRetries);
300  m_backoff.m_slotTime = slotTime;
301  m_backoff.m_minSlots = minSlots;
302  m_backoff.m_maxSlots = maxSlots;
303  m_backoff.m_ceiling = ceiling;
304  m_backoff.m_maxRetries = maxRetries;
305 }
306 
307 void
308 CsmaNetDevice::AddHeader (Ptr<Packet> p, Mac48Address source, Mac48Address dest, uint16_t protocolNumber)
309 {
310  NS_LOG_FUNCTION (p << source << dest << protocolNumber);
311 
312  EthernetHeader header (false);
313  header.SetSource (source);
314  header.SetDestination (dest);
315 
316  EthernetTrailer trailer;
317 
318  NS_LOG_LOGIC ("p->GetSize () = " << p->GetSize ());
319  NS_LOG_LOGIC ("m_encapMode = " << m_encapMode);
320  NS_LOG_LOGIC ("m_mtu = " << m_mtu);
321 
322  uint16_t lengthType = 0;
323  switch (m_encapMode)
324  {
325  case DIX:
326  NS_LOG_LOGIC ("Encapsulating packet as DIX (type interpretation)");
327  //
328  // This corresponds to the type interpretation of the lengthType field as
329  // in the old Ethernet Blue Book.
330  //
331  lengthType = protocolNumber;
332 
333  //
334  // All Ethernet frames must carry a minimum payload of 46 bytes. We need
335  // to pad out if we don't have enough bytes. These must be real bytes
336  // since they will be written to pcap files and compared in regression
337  // trace files.
338  //
339  if (p->GetSize () < 46)
340  {
341  uint8_t buffer[46];
342  memset (buffer, 0, 46);
343  Ptr<Packet> padd = Create<Packet> (buffer, 46 - p->GetSize ());
344  p->AddAtEnd (padd);
345  }
346  break;
347  case LLC:
348  {
349  NS_LOG_LOGIC ("Encapsulating packet as LLC (length interpretation)");
350 
351  LlcSnapHeader llc;
352  llc.SetType (protocolNumber);
353  p->AddHeader (llc);
354 
355  //
356  // This corresponds to the length interpretation of the lengthType
357  // field but with an LLC/SNAP header added to the payload as in
358  // IEEE 802.2
359  //
360  lengthType = p->GetSize ();
361 
362  //
363  // All Ethernet frames must carry a minimum payload of 46 bytes. The
364  // LLC SNAP header counts as part of this payload. We need to padd out
365  // if we don't have enough bytes. These must be real bytes since they
366  // will be written to pcap files and compared in regression trace files.
367  //
368  if (p->GetSize () < 46)
369  {
370  uint8_t buffer[46];
371  memset (buffer, 0, 46);
372  Ptr<Packet> padd = Create<Packet> (buffer, 46 - p->GetSize ());
373  p->AddAtEnd (padd);
374  }
375 
376  NS_ASSERT_MSG (p->GetSize () <= GetMtu (),
377  "CsmaNetDevice::AddHeader(): 802.3 Length/Type field with LLC/SNAP: "
378  "length interpretation must not exceed device frame size minus overhead");
379  }
380  break;
381  case ILLEGAL:
382  default:
383  NS_FATAL_ERROR ("CsmaNetDevice::AddHeader(): Unknown packet encapsulation mode");
384  break;
385  }
386 
387  NS_LOG_LOGIC ("header.SetLengthType (" << lengthType << ")");
388  header.SetLengthType (lengthType);
389  p->AddHeader (header);
390 
391  if (Node::ChecksumEnabled ())
392  {
393  trailer.EnableFcs (true);
394  }
395  trailer.CalcFcs (p);
396  p->AddTrailer (trailer);
397 }
398 
399 #if 0
400 bool
401 CsmaNetDevice::ProcessHeader (Ptr<Packet> p, uint16_t & param)
402 {
403  NS_LOG_FUNCTION (p << param);
404 
405  EthernetTrailer trailer;
406  p->RemoveTrailer (trailer);
407 
408  EthernetHeader header (false);
409  p->RemoveHeader (header);
410 
411  if ((header.GetDestination () != GetBroadcast ()) &&
412  (header.GetDestination () != GetAddress ()))
413  {
414  return false;
415  }
416 
417  switch (m_encapMode)
418  {
419  case DIX:
420  param = header.GetLengthType ();
421  break;
422  case LLC:
423  {
424  LlcSnapHeader llc;
425  p->RemoveHeader (llc);
426  param = llc.GetType ();
427  }
428  break;
429  case ILLEGAL:
430  default:
431  NS_FATAL_ERROR ("CsmaNetDevice::ProcessHeader(): Unknown packet encapsulation mode");
432  break;
433  }
434  return true;
435 }
436 #endif
437 
438 void
440 {
442 
443  //
444  // This function is called to start the process of transmitting a packet. We
445  // expect that the packet to transmit will be found in m_currentPkt.
446  //
447  NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitStart(): m_currentPkt not set");
448 
449  NS_LOG_LOGIC ("m_currentPkt = " << m_currentPkt);
450  NS_LOG_LOGIC ("UID = " << m_currentPkt->GetUid ());
451 
452  //
453  // Only transmit if the send side of net device is enabled
454  //
455  if (IsSendEnabled () == false)
456  {
458  m_currentPkt = 0;
459  return;
460  }
461 
462  //
463  // Somebody has called here telling us to start transmitting a packet. They
464  // can only do this if the state machine is in the READY or BACKOFF state.
465  // Specifically, if we are ready to start transmitting, we cannot already
466  // be transmitting (i.e., BUSY)
467  //
469  "Must be READY to transmit. Tx state is: " << m_txMachineState);
470 
471  //
472  // Now we have to sense the state of the medium and either start transmitting
473  // if it is idle, or backoff our transmission if someone else is on the wire.
474  //
475  if (m_channel->GetState () != IDLE)
476  {
477  //
478  // The channel is busy -- backoff and rechedule TransmitStart() unless
479  // we have exhausted all of our retries.
480  //
482 
484  {
485  //
486  // Too many retries, abort transmission of packet
487  //
488  TransmitAbort ();
489  }
490  else
491  {
493 
495  Time backoffTime = m_backoff.GetBackoffTime ();
496 
497  NS_LOG_LOGIC ("Channel busy, backing off for " << backoffTime.GetSeconds () << " sec");
498 
500  }
501  }
502  else
503  {
504  //
505  // The channel is free, transmit the packet
506  //
507  if (m_channel->TransmitStart (m_currentPkt, m_deviceId) == false)
508  {
509  NS_LOG_WARN ("Channel TransmitStart returns an error");
511  m_currentPkt = 0;
513  }
514  else
515  {
516  //
517  // Transmission succeeded, reset the backoff time parameters and
518  // schedule a transmit complete event.
519  //
523 
525  NS_LOG_LOGIC ("Schedule TransmitCompleteEvent in " << tEvent.GetSeconds () << "sec");
527  }
528  }
529 }
530 
531 void
533 {
535 
536  //
537  // When we started the process of transmitting the current packet, it was
538  // placed in m_currentPkt. So we had better find one there.
539  //
540  NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitAbort(): m_currentPkt zero");
541  NS_LOG_LOGIC ("m_currentPkt=" << m_currentPkt);
542  NS_LOG_LOGIC ("Pkt UID is " << m_currentPkt->GetUid () << ")");
543 
545  m_currentPkt = 0;
546 
547  NS_ASSERT_MSG (m_txMachineState == BACKOFF, "Must be in BACKOFF state to abort. Tx state is: " << m_txMachineState);
548 
549  //
550  // We're done with that one, so reset the backoff algorithm and ready the
551  // transmit state machine.
552  //
555 
556  //
557  // If there is another packet on the input queue, we need to start trying to
558  // get that out. If the queue is empty we just wait until someone puts one
559  // in.
560  //
561  if (m_queue->IsEmpty ())
562  {
563  return;
564  }
565  else
566  {
567  Ptr<QueueItem> item = m_queue->Dequeue ();
568  NS_ASSERT_MSG (item != 0, "CsmaNetDevice::TransmitAbort(): IsEmpty false but no Packet on queue?");
569  m_currentPkt = item->GetPacket ();
572  TransmitStart ();
573  }
574 }
575 
576 void
578 {
580 
581  //
582  // This function is called to finish the process of transmitting a packet.
583  // We need to tell the channel that we've stopped wiggling the wire and
584  // schedule an event that will be executed when it's time to re-enable
585  // the transmitter after the interframe gap.
586  //
587  NS_ASSERT_MSG (m_txMachineState == BUSY, "CsmaNetDevice::transmitCompleteEvent(): Must be BUSY if transmitting");
588  NS_ASSERT (m_channel->GetState () == TRANSMITTING);
590 
591  //
592  // When we started transmitting the current packet, it was placed in
593  // m_currentPkt. So we had better find one there.
594  //
595  NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitCompleteEvent(): m_currentPkt zero");
596  NS_LOG_LOGIC ("m_currentPkt=" << m_currentPkt);
597  NS_LOG_LOGIC ("Pkt UID is " << m_currentPkt->GetUid () << ")");
598 
599  m_channel->TransmitEnd ();
601  m_currentPkt = 0;
602 
603  NS_LOG_LOGIC ("Schedule TransmitReadyEvent in " << m_tInterframeGap.GetSeconds () << "sec");
604 
606 }
607 
608 void
610 {
612 
613  //
614  // This function is called to enable the transmitter after the interframe
615  // gap has passed. If there are pending transmissions, we use this opportunity
616  // to start the next transmit.
617  //
618  NS_ASSERT_MSG (m_txMachineState == GAP, "CsmaNetDevice::TransmitReadyEvent(): Must be in interframe gap");
620 
621  //
622  // We expect that the packet we had been transmitting was cleared when the
623  // TransmitCompleteEvent() was executed.
624  //
625  NS_ASSERT_MSG (m_currentPkt == 0, "CsmaNetDevice::TransmitReadyEvent(): m_currentPkt nonzero");
626 
627  //
628  // Get the next packet from the queue for transmitting
629  //
630  if (m_queue->IsEmpty ())
631  {
632  return;
633  }
634  else
635  {
636  Ptr<QueueItem> item = m_queue->Dequeue ();
637  NS_ASSERT_MSG (item != 0, "CsmaNetDevice::TransmitReadyEvent(): IsEmpty false but no Packet on queue?");
638  m_currentPkt = item->GetPacket ();
641  TransmitStart ();
642  }
643 }
644 
645 bool
647 {
648  NS_LOG_FUNCTION (this << &ch);
649 
650  m_channel = ch;
651 
652  m_deviceId = m_channel->Attach (this);
653 
654  //
655  // The channel provides us with the transmitter data rate.
656  //
657  m_bps = m_channel->GetDataRate ();
658 
659  //
660  // We use the Ethernet interframe gap of 96 bit times.
661  //
663 
664  //
665  // This device is up whenever a channel is attached to it.
666  //
667  NotifyLinkUp ();
668  return true;
669 }
670 
671 void
673 {
674  NS_LOG_FUNCTION (q);
675  m_queue = q;
676 }
677 
678 void
680 {
681  NS_LOG_FUNCTION (em);
682  m_receiveErrorModel = em;
683 }
684 
685 void
687 {
688  NS_LOG_FUNCTION (packet << senderDevice);
689  NS_LOG_LOGIC ("UID is " << packet->GetUid ());
690 
691  //
692  // We never forward up packets that we sent. Real devices don't do this since
693  // their receivers are disabled during send, so we don't.
694  //
695  if (senderDevice == this)
696  {
697  return;
698  }
699 
700  //
701  // Hit the trace hook. This trace will fire on all packets received from the
702  // channel except those originated by this device.
703  //
704  m_phyRxEndTrace (packet);
705 
706  //
707  // Only receive if the send side of net device is enabled
708  //
709  if (IsReceiveEnabled () == false)
710  {
711  m_phyRxDropTrace (packet);
712  return;
713  }
714 
715  if (m_receiveErrorModel && m_receiveErrorModel->IsCorrupt (packet) )
716  {
717  NS_LOG_LOGIC ("Dropping pkt due to error model ");
718  m_phyRxDropTrace (packet);
719  return;
720  }
721 
722  //
723  // Trace sinks will expect complete packets, not packets without some of the
724  // headers.
725  //
726  Ptr<Packet> originalPacket = packet->Copy ();
727 
728  EthernetTrailer trailer;
729  packet->RemoveTrailer (trailer);
730  if (Node::ChecksumEnabled ())
731  {
732  trailer.EnableFcs (true);
733  }
734 
735  bool crcGood = trailer.CheckFcs (packet);
736  if (!crcGood)
737  {
738  NS_LOG_INFO ("CRC error on Packet " << packet);
739  m_phyRxDropTrace (packet);
740  return;
741  }
742 
743  EthernetHeader header (false);
744  packet->RemoveHeader (header);
745 
746  NS_LOG_LOGIC ("Pkt source is " << header.GetSource ());
747  NS_LOG_LOGIC ("Pkt destination is " << header.GetDestination ());
748 
749  uint16_t protocol;
750  //
751  // If the length/type is less than 1500, it corresponds to a length
752  // interpretation packet. In this case, it is an 802.3 packet and
753  // will also have an 802.2 LLC header. If greater than 1500, we
754  // find the protocol number (Ethernet type) directly.
755  //
756  if (header.GetLengthType () <= 1500)
757  {
758  NS_ASSERT (packet->GetSize () >= header.GetLengthType ());
759  uint32_t padlen = packet->GetSize () - header.GetLengthType ();
760  NS_ASSERT (padlen <= 46);
761  if (padlen > 0)
762  {
763  packet->RemoveAtEnd (padlen);
764  }
765 
766  LlcSnapHeader llc;
767  packet->RemoveHeader (llc);
768  protocol = llc.GetType ();
769  }
770  else
771  {
772  protocol = header.GetLengthType ();
773  }
774 
775  //
776  // Classify the packet based on its destination.
777  //
778  PacketType packetType;
779 
780  if (header.GetDestination ().IsBroadcast ())
781  {
782  packetType = PACKET_BROADCAST;
783  }
784  else if (header.GetDestination ().IsGroup ())
785  {
786  packetType = PACKET_MULTICAST;
787  }
788  else if (header.GetDestination () == m_address)
789  {
790  packetType = PACKET_HOST;
791  }
792  else
793  {
794  packetType = PACKET_OTHERHOST;
795  }
796 
797  //
798  // For all kinds of packetType we receive, we hit the promiscuous sniffer
799  // hook and pass a copy up to the promiscuous callback. Pass a copy to
800  // make sure that nobody messes with our packet.
801  //
802  m_promiscSnifferTrace (originalPacket);
803  if (!m_promiscRxCallback.IsNull ())
804  {
805  m_macPromiscRxTrace (originalPacket);
806  m_promiscRxCallback (this, packet, protocol, header.GetSource (), header.GetDestination (), packetType);
807  }
808 
809  //
810  // If this packet is not destined for some other host, it must be for us
811  // as either a broadcast, multicast or unicast. We need to hit the mac
812  // packet received trace hook and forward the packet up the stack.
813  //
814  if (packetType != PACKET_OTHERHOST)
815  {
816  m_snifferTrace (originalPacket);
817  m_macRxTrace (originalPacket);
818  m_rxCallback (this, packet, protocol, header.GetSource ());
819  }
820 }
821 
824 {
826  return m_queue;
827 }
828 
829 void
831 {
833  m_linkUp = true;
835 }
836 
837 void
838 CsmaNetDevice::SetIfIndex (const uint32_t index)
839 {
840  NS_LOG_FUNCTION (index);
841  m_ifIndex = index;
842 }
843 
844 uint32_t
846 {
848  return m_ifIndex;
849 }
850 
853 {
855  return m_channel;
856 }
857 
858 void
860 {
863 }
864 
865 Address
867 {
869  return m_address;
870 }
871 
872 bool
874 {
876  return m_linkUp;
877 }
878 
879 void
881 {
882  NS_LOG_FUNCTION (&callback);
884 }
885 
886 bool
888 {
890  return true;
891 }
892 
893 Address
895 {
897  return Mac48Address ("ff:ff:ff:ff:ff:ff");
898 }
899 
900 bool
902 {
904  return true;
905 }
906 
907 Address
909 {
910  NS_LOG_FUNCTION (multicastGroup);
911 
912  Mac48Address ad = Mac48Address::GetMulticast (multicastGroup);
913 
914  //
915  // Implicit conversion (operator Address ()) is defined for Mac48Address, so
916  // use it by just returning the EUI-48 address which is automagically converted
917  // to an Address.
918  //
919  NS_LOG_LOGIC ("multicast address is " << ad);
920 
921  return ad;
922 }
923 
924 bool
926 {
928  return false;
929 }
930 
931 bool
933 {
935  return false;
936 }
937 
938 bool
939 CsmaNetDevice::Send (Ptr<Packet> packet,const Address& dest, uint16_t protocolNumber)
940 {
941  NS_LOG_FUNCTION (packet << dest << protocolNumber);
942  return SendFrom (packet, m_address, dest, protocolNumber);
943 }
944 
945 bool
946 CsmaNetDevice::SendFrom (Ptr<Packet> packet, const Address& src, const Address& dest, uint16_t protocolNumber)
947 {
948  NS_LOG_FUNCTION (packet << src << dest << protocolNumber);
949  NS_LOG_LOGIC ("packet =" << packet);
950  NS_LOG_LOGIC ("UID is " << packet->GetUid () << ")");
951 
952  NS_ASSERT (IsLinkUp ());
953 
954  //
955  // Only transmit if send side of net device is enabled
956  //
957  if (IsSendEnabled () == false)
958  {
959  m_macTxDropTrace (packet);
960  return false;
961  }
962 
963  Mac48Address destination = Mac48Address::ConvertFrom (dest);
965  AddHeader (packet, source, destination, protocolNumber);
966 
967  m_macTxTrace (packet);
968 
969  //
970  // Place the packet to be sent on the send queue. Note that the
971  // queue may fire a drop trace, but we will too.
972  //
973  if (m_queue->Enqueue (Create<QueueItem> (packet)) == false)
974  {
975  m_macTxDropTrace (packet);
976  return false;
977  }
978 
979  //
980  // If the device is idle, we need to start a transmission. Otherwise,
981  // the transmission will be started when the current packet finished
982  // transmission (see TransmitCompleteEvent)
983  //
984  if (m_txMachineState == READY)
985  {
986  if (m_queue->IsEmpty () == false)
987  {
988  Ptr<QueueItem> item = m_queue->Dequeue ();
989  NS_ASSERT_MSG (item != 0, "CsmaNetDevice::SendFrom(): IsEmpty false but no Packet on queue?");
990  m_currentPkt = item->GetPacket ();
993  TransmitStart ();
994  }
995  }
996  return true;
997 }
998 
999 Ptr<Node>
1001 {
1003  return m_node;
1004 }
1005 
1006 void
1008 {
1009  NS_LOG_FUNCTION (node);
1010 
1011  m_node = node;
1012 }
1013 
1014 bool
1016 {
1018  return true;
1019 }
1020 
1021 void
1023 {
1024  NS_LOG_FUNCTION (&cb);
1025  m_rxCallback = cb;
1026 }
1027 
1029 {
1031 
1032  NS_LOG_LOGIC ("MAC IPv6 multicast address is " << ad);
1033  return ad;
1034 }
1035 
1036 void
1038 {
1039  NS_LOG_FUNCTION (&cb);
1040  m_promiscRxCallback = cb;
1041 }
1042 
1043 bool
1045 {
1047  return true;
1048 }
1049 
1050 int64_t
1052 {
1053  return m_backoff.AssignStreams (stream);
1054 }
1055 
1056 } // namespace ns3
uint32_t m_ifIndex
The interface index (really net evice index) that has been assigned to this network device...
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:268
TracedCallback< Ptr< const Packet > > m_phyRxBeginTrace
The trace source fired when a packet begins the reception process from the medium.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
Ptr< Queue > m_queue
The Queue which this CsmaNetDevice uses as a packet source.
void ResetBackoffTime(void)
Indicates to the backoff object that the last packet was successfully transmitted and that the number...
Definition: backoff.cc:80
TracedCallback< Ptr< const Packet > > m_phyTxBeginTrace
The trace source fired when a packet begins the transmission process on the medium.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
TxMachineState m_txMachineState
The state of the Net Device transmit state machine.
void SetReceiveEnable(bool enable)
Enable or disable the receive side of the network device.
AttributeValue implementation for Boolean.
Definition: boolean.h:34
void SetEncapsulationMode(CsmaNetDevice::EncapsulationMode mode)
Set the encapsulation mode of this device.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:44
CsmaNetDevice::EncapsulationMode GetEncapsulationMode(void)
Get the encapsulation mode of this device.
Time CalculateBytesTxTime(uint32_t bytes) const
Calculate transmission time.
Definition: data-rate.cc:235
void TransmitReadyEvent(void)
Cause the Transmitter to Become Ready to Send Another Packet.
void AddHeader(Ptr< Packet > p, Mac48Address source, Mac48Address dest, uint16_t protocolNumber)
Adds the necessary headers and trailers to a packet of data in order to respect the packet type...
TracedCallback< Ptr< const Packet > > m_macPromiscRxTrace
The trace source fired for packets successfully received by the device immediately before being forwa...
uint32_t m_maxSlots
Maximum number of backoff slots (when multiplied by m_slotTime, determines maximum backoff time) ...
Definition: backoff.h:47
CsmaNetDevice()
Construct a CsmaNetDevice.
Ptr< const AttributeAccessor > MakeEnumAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: enum.h:209
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:81
TracedCallback< Ptr< const Packet > > m_phyTxEndTrace
The trace source fired when a packet ends the transmission process on the medium. ...
void CalcFcs(Ptr< const Packet > p)
Updates the Fcs Field to the correct FCS.
void Receive(Ptr< Packet > p, Ptr< CsmaNetDevice > sender)
Receive a packet from a connected CsmaChannel.
static bool ChecksumEnabled(void)
Definition: node.cc:276
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_phyRxEndTrace
The trace source fired when a packet ends the reception process from the medium.
uint64_t GetUid(void) const
Returns the packet's Uid.
Definition: packet.cc:368
Ptr< Packet > m_currentPkt
Next packet that will be transmitted (if transmitter is not currently transmitting) or packet that is...
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1270
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
PacketType
Packet types are used as they are in Linux.
Definition: net-device.h:606
void SetReceiveErrorModel(Ptr< ErrorModel > em)
Attach a receive ErrorModel to the CsmaNetDevice.
The transmitter is busy transmitting a packet.
Channel is IDLE, no packet is being transmitted.
Definition: csma-channel.h:75
void TransmitAbort(void)
Aborts the transmission of the current packet.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
uint32_t m_maxRetries
Maximum number of transmission retries before the packet is dropped.
Definition: backoff.h:57
virtual bool SendFrom(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber)
Start sending a packet down the channel, with MAC spoofing.
uint16_t GetLengthType(void) const
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:792
bool IsBroadcast(void) const
TracedCallback< Ptr< const Packet > > m_macRxDropTrace
The trace source fired for packets successfully received by the device but dropped before being forwa...
802.2 LLC/SNAP Packet
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:244
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
Ptr< const AttributeChecker > MakeMac48AddressChecker(void)
Packet addressed to multicast group.
Definition: net-device.h:612
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
void SetType(uint16_t type)
Set the Ethertype.
virtual Address GetBroadcast(void) const
Packet addressed oo us.
Definition: net-device.h:608
void SetSource(Mac48Address source)
Ptr< const AttributeAccessor > MakeMac48AddressAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
virtual void SetIfIndex(const uint32_t index)
EncapsulationMode
Enumeration of the types of packets supported in the class.
virtual ~CsmaNetDevice()
Destroy a CsmaNetDevice.
virtual bool NeedsArp(void) const
Does this device need to use the address resolution protocol?
TracedCallback< Ptr< const Packet > > m_promiscSnifferTrace
A trace source that emulates a promiscuous mode protocol sniffer connected to the device...
a polymophic address class
Definition: address.h:90
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
bool MaxRetriesReached(void)
Definition: backoff.cc:86
Channel is BUSY, a packet is being written by a net device.
Definition: csma-channel.h:76
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:341
TracedCallback m_linkChangeCallbacks
List of callbacks to fire if the link changes state (up or down).
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
Definition: packet.cc:313
The transmitter is waiting for the channel to be free.
TracedCallback< Ptr< const Packet > > m_macTxBackoffTrace
The trace source fired when the mac layer is forced to begin the backoff process for a packet...
DataRate m_bps
The data rate that the Net Device uses to simulate packet transmission timing.
virtual bool IsLinkUp(void) const
void SetQueue(Ptr< Queue > queue)
Attach a queue to the CsmaNetDevice.
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
TracedCallback< Ptr< const Packet > > m_snifferTrace
A trace source that emulates a non-promiscuous protocol sniffer connected to the device.
Hold variables of type enum.
Definition: enum.h:54
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1238
bool CheckFcs(Ptr< const Packet > p) const
Calculate an FCS on the provided packet and check this value against the FCS found when the trailer w...
static TypeId GetTypeId(void)
Get the type ID.
static Mac48Address GetMulticast(Ipv4Address address)
uint16_t GetType(void)
Return the Ethertype.
void TransmitCompleteEvent(void)
Stop Sending a Packet Down the Wire and Begin the Interframe Gap.
Hold an unsigned integer type.
Definition: uinteger.h:44
bool IsReceiveEnabled(void)
Is the receive side of the network device enabled?
uint32_t m_deviceId
Device ID returned by the attached functions.
virtual Ptr< Node > GetNode(void) const
Get the node to which this device is attached.
bool m_sendEnable
Enable net device to send packets.
Ptr< Queue > GetQueue(void) const
Get a copy of the attached Queue.
void NotifyLinkUp(void)
Notify any interested parties that the link has come up.
void SetInterframeGap(Time t)
Set the interframe gap used to separate packets.
virtual Address GetAddress(void) const
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:252
virtual uint32_t GetIfIndex(void) const
static Mac48Address ConvertFrom(const Address &address)
virtual uint16_t GetMtu(void) const
virtual void SetPromiscReceiveCallback(PromiscReceiveCallback cb)
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:122
TracedCallback< Ptr< const Packet > > m_phyTxDropTrace
The trace source fired when the phy layer drops a packet as it tries to transmit it.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Packet trailer for Ethernet.
Hold objects of type Ptr.
Definition: pointer.h:36
void EnableFcs(bool enable)
Enable or disable FCS checking and calculations.
bool IsGroup(void) const
A Device for a Csma Network Link.
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
Packet addressed to someone else.
Definition: net-device.h:614
bool m_receiveEnable
Enable net device to receive packets.
Ptr< ErrorModel > m_receiveErrorModel
Error model for receive packet events.
void AddTrailer(const Trailer &trailer)
Add trailer to this packet.
Definition: packet.cc:285
Ptr< CsmaChannel > m_channel
The CsmaChannel to which this CsmaNetDevice has been attached.
void RemoveAtEnd(uint32_t size)
Remove size bytes from the end of the current packet.
Definition: packet.cc:333
static const uint16_t DEFAULT_MTU
Default Maximum Transmission Unit (MTU) for the CsmaNetDevice.
uint32_t RemoveTrailer(Trailer &trailer)
Remove a deserialized trailer from the internal buffer.
Definition: packet.cc:296
an EUI-48 address
Definition: mac48-address.h:43
Packet header for Ethernet.
Time m_tInterframeGap
The interframe gap that the Net Device uses insert time between packet transmission.
virtual Ptr< Channel > GetChannel(void) const
virtual bool IsBridge(void) const
Is this a bridge?
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model...
Definition: backoff.cc:98
virtual bool SetMtu(const uint16_t mtu)
virtual bool SupportsSendFrom(void) const
Time GetBackoffTime()
Definition: backoff.cc:53
#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
Encapsulation mode not set.
Mac48Address GetSource(void) const
bool m_linkUp
Flag indicating whether or not the link is up.
Mac48Address m_address
The MAC address which has been assigned to this device.
Ptr< const AttributeChecker > MakeEnumChecker(int v1, std::string n1, int v2, std::string n2, int v3, std::string n3, int v4, std::string n4, int v5, std::string n5, int v6, std::string n6, int v7, std::string n7, int v8, std::string n8, int v9, std::string n9, int v10, std::string n10, int v11, std::string n11, int v12, std::string n12, int v13, std::string n13, int v14, std::string n14, int v15, std::string n15, int v16, std::string n16, int v17, std::string n17, int v18, std::string n18, int v19, std::string n19, int v20, std::string n20, int v21, std::string n21, int v22, std::string n22)
Make an EnumChecker pre-configured with a set of allowed values by name.
Definition: enum.cc:184
Describes an IPv6 address.
Definition: ipv6-address.h:48
Mac48Address GetDestination(void) const
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:40
EncapsulationMode m_encapMode
The type of packet that should be created by the AddHeader function and that should be processed by t...
NetDevice::ReceiveCallback m_rxCallback
The callback used to notify higher layers that a packet has been received.
uint32_t m_mtu
The Maximum Transmission Unit.
void SetBackoffParams(Time slotTime, uint32_t minSlots, uint32_t maxSlots, uint32_t maxRetries, uint32_t ceiling)
Set the backoff parameters used to determine the wait to retry transmitting a packet when the channel...
void ConnectWithoutContext(const CallbackBase &callback)
Append a Callback to the chain (without a context).
Backoff m_backoff
Holds the backoff parameters and is used to calculate the next backoff time to use when the channel i...
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:405
The transmitter is ready to begin transmission of a packet.
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:228
AttributeValue implementation for Mac48Address.
Packet addressed to all.
Definition: net-device.h:610
void SetSendEnable(bool enable)
Enable or disable the send side of the network device.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:895
virtual void SetReceiveCallback(NetDevice::ReceiveCallback cb)
Set the callback to be used to notify higher layers when a packet has been received.
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model...
uint32_t m_minSlots
Minimum number of backoff slots (when multiplied by m_slotTime, determines minimum backoff time) ...
Definition: backoff.h:42
void SetLengthType(uint16_t size)
NetDevice::PromiscReceiveCallback m_promiscRxCallback
The callback used to notify higher layers that a packet has been received in promiscuous mode...
virtual void SetAddress(Address address)
Set the address of this interface.
bool IsSendEnabled(void)
Is the send side of the network device enabled?
void TransmitStart()
Start Sending a Packet Down the Wire.
tuple address
Definition: first.py:37
Ptr< Node > m_node
The Node to which this device is attached.
virtual void AddLinkChangeCallback(Callback< void > callback)
bool Attach(Ptr< CsmaChannel > ch)
Attach the device to a channel.
virtual void SetNode(Ptr< Node > node)
Set the node to which this device is being attached.
TracedCallback< Ptr< const Packet > > m_phyRxDropTrace
The trace source fired when the phy layer drops a packet it has received.
void SetDestination(Mac48Address destination)
virtual bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber)
Start sending a packet down the channel.
virtual bool IsMulticast(void) const
virtual Address GetMulticast(Ipv4Address multicastGroup) const
Make and return a MAC multicast address using the provided multicast group.
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: uinteger.h:45
virtual void DoDispose(void)
Perform any object release functionality required to break reference cycles in reference counted obje...
a unique identifier for an interface.
Definition: type-id.h:58
virtual bool IsBroadcast(void) const
Time m_slotTime
Length of one slot.
Definition: backoff.h:62
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:904
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:257
Header for the LLC/SNAP encapsulation.
DIX II / Ethernet II packet.
virtual bool IsPointToPoint(void) const
Is this a point to point link?
The transmitter is in the interframe gap time.
TracedCallback< Ptr< const Packet > > m_macTxTrace
The trace source fired when packets come into the "top" of the device at the L3/L2 transition...
void IncrNumRetries(void)
Increments the number of retries by 1.
Definition: backoff.cc:92
uint32_t m_ceiling
Caps the exponential function when the number of retries reaches m_ceiling.
Definition: backoff.h:52