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 #include "ns3/net-device-queue-interface.h"
36 
37 namespace ns3 {
38 
39 NS_LOG_COMPONENT_DEFINE ("CsmaNetDevice");
40 
41 NS_OBJECT_ENSURE_REGISTERED (CsmaNetDevice);
42 
43 TypeId
45 {
46  static TypeId tid = TypeId ("ns3::CsmaNetDevice")
47  .SetParent<NetDevice> ()
48  .SetGroupName ("Csma")
49  .AddConstructor<CsmaNetDevice> ()
50  .AddAttribute ("Address",
51  "The MAC address of this device.",
52  Mac48AddressValue (Mac48Address ("ff:ff:ff:ff:ff:ff")),
55  .AddAttribute ("Mtu", "The MAC-level Maximum Transmission Unit",
59  MakeUintegerChecker<uint16_t> ())
60  .AddAttribute ("EncapsulationMode",
61  "The link-layer encapsulation type to use.",
62  EnumValue (DIX),
64  MakeEnumChecker (DIX, "Dix",
65  LLC, "Llc"))
66  .AddAttribute ("SendEnable",
67  "Enable or disable the transmitter section of the device.",
68  BooleanValue (true),
71  .AddAttribute ("ReceiveEnable",
72  "Enable or disable the receiver section of the device.",
73  BooleanValue (true),
76  .AddAttribute ("ReceiveErrorModel",
77  "The receiver error model used to simulate packet loss",
78  PointerValue (),
80  MakePointerChecker<ErrorModel> ())
81 
82  //
83  // Transmit queueing discipline for the device which includes its own set
84  // of trace hooks.
85  //
86  .AddAttribute ("TxQueue",
87  "A queue to use as the transmit queue in the device.",
88  PointerValue (),
91 
92  //
93  // Trace sources at the "top" of the net device, where packets transition
94  // to/from higher layers.
95  //
96  .AddTraceSource ("MacTx",
97  "Trace source indicating a packet has "
98  "arrived for transmission by this device",
100  "ns3::Packet::TracedCallback")
101  .AddTraceSource ("MacTxDrop",
102  "Trace source indicating a packet has been "
103  "dropped by the device before transmission",
105  "ns3::Packet::TracedCallback")
106  .AddTraceSource ("MacPromiscRx",
107  "A packet has been received by this device, "
108  "has been passed up from the physical layer "
109  "and is being forwarded up the local protocol stack. "
110  "This is a promiscuous trace,",
112  "ns3::Packet::TracedCallback")
113  .AddTraceSource ("MacRx",
114  "A packet has been received by this device, "
115  "has been passed up from the physical layer "
116  "and is being forwarded up the local protocol stack. "
117  "This is a non-promiscuous trace,",
119  "ns3::Packet::TracedCallback")
120 #if 0
121  // Not currently implemented in this device
122  .AddTraceSource ("MacRxDrop",
123  "Trace source indicating a packet was received, "
124  "but dropped before being forwarded up the stack",
126  "ns3::Packet::TracedCallback")
127 #endif
128  .AddTraceSource ("MacTxBackoff",
129  "Trace source indicating a packet has been "
130  "delayed by the CSMA backoff process",
132  "ns3::Packet::TracedCallback")
133  //
134  // Trace souces at the "bottom" of the net device, where packets transition
135  // to/from the channel.
136  //
137  .AddTraceSource ("PhyTxBegin",
138  "Trace source indicating a packet has "
139  "begun transmitting over the channel",
141  "ns3::Packet::TracedCallback")
142  .AddTraceSource ("PhyTxEnd",
143  "Trace source indicating a packet has been "
144  "completely transmitted over the channel",
146  "ns3::Packet::TracedCallback")
147  .AddTraceSource ("PhyTxDrop",
148  "Trace source indicating a packet has been "
149  "dropped by the device during transmission",
151  "ns3::Packet::TracedCallback")
152 #if 0
153  // Not currently implemented in this device
154  .AddTraceSource ("PhyRxBegin",
155  "Trace source indicating a packet has "
156  "begun being received by the device",
158  "ns3::Packet::TracedCallback")
159 #endif
160  .AddTraceSource ("PhyRxEnd",
161  "Trace source indicating a packet has been "
162  "completely received by the device",
164  "ns3::Packet::TracedCallback")
165  .AddTraceSource ("PhyRxDrop",
166  "Trace source indicating a packet has been "
167  "dropped by the device during reception",
169  "ns3::Packet::TracedCallback")
170  //
171  // Trace sources designed to simulate a packet sniffer facility (tcpdump).
172  //
173  .AddTraceSource ("Sniffer",
174  "Trace source simulating a non-promiscuous "
175  "packet sniffer attached to the device",
177  "ns3::Packet::TracedCallback")
178  .AddTraceSource ("PromiscSniffer",
179  "Trace source simulating a promiscuous "
180  "packet sniffer attached to the device",
182  "ns3::Packet::TracedCallback")
183  ;
184  return tid;
185 }
186 
188  : m_linkUp (false)
189 {
190  NS_LOG_FUNCTION (this);
193  m_channel = 0;
194 
195  //
196  // We would like to let the attribute system take care of initializing the
197  // packet encapsulation stuff, but we also don't want to get caught up in
198  // initialization order changes. So we'll get the three problem variables
199  // into a consistent state here before the attribute calls, and then depend
200  // on the semantics of the setters to preserve a consistent state. This
201  // really doesn't have to be the same set of values as the initial values
202  // set by the attributes, but it does have to be a consistent set. That is,
203  // you can just change the default encapsulation mode above without having
204  // to change it here.
205  //
206  m_encapMode = DIX;
207 }
208 
210 {
212  m_queue = 0;
213 }
214 
215 void
217 {
219  m_channel = 0;
220  m_node = 0;
221  m_queue = 0;
222  m_queueInterface = 0;
224 }
225 
226 void
228 {
229  if (m_queueInterface)
230  {
231  NS_ASSERT_MSG (m_queue != 0, "A Queue object has not been attached to the device");
232 
233  // connect the traced callbacks of m_queue to the static methods provided by
234  // the NetDeviceQueue class to support flow control and dynamic queue limits.
235  // This could not be done in NotifyNewAggregate because at that time we are
236  // not guaranteed that a queue has been attached to the netdevice
237  m_queueInterface->ConnectQueueTraces (m_queue, 0);
238  }
239 
241 }
242 
243 void
245 {
246  NS_LOG_FUNCTION (this);
247  if (m_queueInterface == 0)
248  {
249  Ptr<NetDeviceQueueInterface> ndqi = this->GetObject<NetDeviceQueueInterface> ();
250  //verify that it's a valid netdevice queue interface and that
251  //the netdevice queue interface was not set before
252  if (ndqi != 0)
253  {
254  m_queueInterface = ndqi;
255  }
256  }
258 }
259 
260 void
262 {
263  NS_LOG_FUNCTION (mode);
264 
265  m_encapMode = mode;
266 
267  NS_LOG_LOGIC ("m_encapMode = " << m_encapMode);
268  NS_LOG_LOGIC ("m_mtu = " << m_mtu);
269 }
270 
273 {
275  return m_encapMode;
276 }
277 
278 bool
279 CsmaNetDevice::SetMtu (uint16_t mtu)
280 {
281  NS_LOG_FUNCTION (this << mtu);
282  m_mtu = mtu;
283 
284  NS_LOG_LOGIC ("m_encapMode = " << m_encapMode);
285  NS_LOG_LOGIC ("m_mtu = " << m_mtu);
286 
287  return true;
288 }
289 
290 uint16_t
292 {
294  return m_mtu;
295 }
296 
297 
298 void
300 {
301  NS_LOG_FUNCTION (sendEnable);
302  m_sendEnable = sendEnable;
303 }
304 
305 void
307 {
308  NS_LOG_FUNCTION (receiveEnable);
309  m_receiveEnable = receiveEnable;
310 }
311 
312 bool
314 {
316  return m_sendEnable;
317 }
318 
319 bool
321 {
323  return m_receiveEnable;
324 }
325 
326 void
328 {
329  NS_LOG_FUNCTION (t);
330  m_tInterframeGap = t;
331 }
332 
333 void
334 CsmaNetDevice::SetBackoffParams (Time slotTime, uint32_t minSlots, uint32_t maxSlots, uint32_t ceiling, uint32_t maxRetries)
335 {
336  NS_LOG_FUNCTION (slotTime << minSlots << maxSlots << ceiling << maxRetries);
337  m_backoff.m_slotTime = slotTime;
338  m_backoff.m_minSlots = minSlots;
339  m_backoff.m_maxSlots = maxSlots;
340  m_backoff.m_ceiling = ceiling;
341  m_backoff.m_maxRetries = maxRetries;
342 }
343 
344 void
345 CsmaNetDevice::AddHeader (Ptr<Packet> p, Mac48Address source, Mac48Address dest, uint16_t protocolNumber)
346 {
347  NS_LOG_FUNCTION (p << source << dest << protocolNumber);
348 
349  EthernetHeader header (false);
350  header.SetSource (source);
351  header.SetDestination (dest);
352 
353  EthernetTrailer trailer;
354 
355  NS_LOG_LOGIC ("p->GetSize () = " << p->GetSize ());
356  NS_LOG_LOGIC ("m_encapMode = " << m_encapMode);
357  NS_LOG_LOGIC ("m_mtu = " << m_mtu);
358 
359  uint16_t lengthType = 0;
360  switch (m_encapMode)
361  {
362  case DIX:
363  NS_LOG_LOGIC ("Encapsulating packet as DIX (type interpretation)");
364  //
365  // This corresponds to the type interpretation of the lengthType field as
366  // in the old Ethernet Blue Book.
367  //
368  lengthType = protocolNumber;
369 
370  //
371  // All Ethernet frames must carry a minimum payload of 46 bytes. We need
372  // to pad out if we don't have enough bytes. These must be real bytes
373  // since they will be written to pcap files and compared in regression
374  // trace files.
375  //
376  if (p->GetSize () < 46)
377  {
378  uint8_t buffer[46];
379  memset (buffer, 0, 46);
380  Ptr<Packet> padd = Create<Packet> (buffer, 46 - p->GetSize ());
381  p->AddAtEnd (padd);
382  }
383  break;
384  case LLC:
385  {
386  NS_LOG_LOGIC ("Encapsulating packet as LLC (length interpretation)");
387 
388  LlcSnapHeader llc;
389  llc.SetType (protocolNumber);
390  p->AddHeader (llc);
391 
392  //
393  // This corresponds to the length interpretation of the lengthType
394  // field but with an LLC/SNAP header added to the payload as in
395  // IEEE 802.2
396  //
397  lengthType = p->GetSize ();
398 
399  //
400  // All Ethernet frames must carry a minimum payload of 46 bytes. The
401  // LLC SNAP header counts as part of this payload. We need to padd out
402  // if we don't have enough bytes. These must be real bytes since they
403  // will be written to pcap files and compared in regression trace files.
404  //
405  if (p->GetSize () < 46)
406  {
407  uint8_t buffer[46];
408  memset (buffer, 0, 46);
409  Ptr<Packet> padd = Create<Packet> (buffer, 46 - p->GetSize ());
410  p->AddAtEnd (padd);
411  }
412 
413  NS_ASSERT_MSG (p->GetSize () <= GetMtu (),
414  "CsmaNetDevice::AddHeader(): 802.3 Length/Type field with LLC/SNAP: "
415  "length interpretation must not exceed device frame size minus overhead");
416  }
417  break;
418  case ILLEGAL:
419  default:
420  NS_FATAL_ERROR ("CsmaNetDevice::AddHeader(): Unknown packet encapsulation mode");
421  break;
422  }
423 
424  NS_LOG_LOGIC ("header.SetLengthType (" << lengthType << ")");
425  header.SetLengthType (lengthType);
426  p->AddHeader (header);
427 
428  if (Node::ChecksumEnabled ())
429  {
430  trailer.EnableFcs (true);
431  }
432  trailer.CalcFcs (p);
433  p->AddTrailer (trailer);
434 }
435 
436 #if 0
437 bool
438 CsmaNetDevice::ProcessHeader (Ptr<Packet> p, uint16_t & param)
439 {
440  NS_LOG_FUNCTION (p << param);
441 
442  EthernetTrailer trailer;
443  p->RemoveTrailer (trailer);
444 
445  EthernetHeader header (false);
446  p->RemoveHeader (header);
447 
448  if ((header.GetDestination () != GetBroadcast ()) &&
449  (header.GetDestination () != GetAddress ()))
450  {
451  return false;
452  }
453 
454  switch (m_encapMode)
455  {
456  case DIX:
457  param = header.GetLengthType ();
458  break;
459  case LLC:
460  {
461  LlcSnapHeader llc;
462  p->RemoveHeader (llc);
463  param = llc.GetType ();
464  }
465  break;
466  case ILLEGAL:
467  default:
468  NS_FATAL_ERROR ("CsmaNetDevice::ProcessHeader(): Unknown packet encapsulation mode");
469  break;
470  }
471  return true;
472 }
473 #endif
474 
475 void
477 {
479 
480  //
481  // This function is called to start the process of transmitting a packet. We
482  // expect that the packet to transmit will be found in m_currentPkt.
483  //
484  NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitStart(): m_currentPkt not set");
485 
486  NS_LOG_LOGIC ("m_currentPkt = " << m_currentPkt);
487  NS_LOG_LOGIC ("UID = " << m_currentPkt->GetUid ());
488 
489  //
490  // Only transmit if the send side of net device is enabled
491  //
492  if (IsSendEnabled () == false)
493  {
495  m_currentPkt = 0;
496  return;
497  }
498 
499  //
500  // Somebody has called here telling us to start transmitting a packet. They
501  // can only do this if the state machine is in the READY or BACKOFF state.
502  // Specifically, if we are ready to start transmitting, we cannot already
503  // be transmitting (i.e., BUSY)
504  //
506  "Must be READY to transmit. Tx state is: " << m_txMachineState);
507 
508  //
509  // Now we have to sense the state of the medium and either start transmitting
510  // if it is idle, or backoff our transmission if someone else is on the wire.
511  //
512  if (m_channel->GetState () != IDLE)
513  {
514  //
515  // The channel is busy -- backoff and rechedule TransmitStart() unless
516  // we have exhausted all of our retries.
517  //
519 
521  {
522  //
523  // Too many retries, abort transmission of packet
524  //
525  TransmitAbort ();
526  }
527  else
528  {
530 
532  Time backoffTime = m_backoff.GetBackoffTime ();
533 
534  NS_LOG_LOGIC ("Channel busy, backing off for " << backoffTime.GetSeconds () << " sec");
535 
537  }
538  }
539  else
540  {
541  //
542  // The channel is free, transmit the packet
543  //
544  if (m_channel->TransmitStart (m_currentPkt, m_deviceId) == false)
545  {
546  NS_LOG_WARN ("Channel TransmitStart returns an error");
548  m_currentPkt = 0;
550  }
551  else
552  {
553  //
554  // Transmission succeeded, reset the backoff time parameters and
555  // schedule a transmit complete event.
556  //
560 
562  NS_LOG_LOGIC ("Schedule TransmitCompleteEvent in " << tEvent.GetSeconds () << "sec");
564  }
565  }
566 }
567 
568 void
570 {
572 
573  //
574  // When we started the process of transmitting the current packet, it was
575  // placed in m_currentPkt. So we had better find one there.
576  //
577  NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitAbort(): m_currentPkt zero");
578  NS_LOG_LOGIC ("m_currentPkt=" << m_currentPkt);
579  NS_LOG_LOGIC ("Pkt UID is " << m_currentPkt->GetUid () << ")");
580 
582  m_currentPkt = 0;
583 
584  NS_ASSERT_MSG (m_txMachineState == BACKOFF, "Must be in BACKOFF state to abort. Tx state is: " << m_txMachineState);
585 
586  //
587  // We're done with that one, so reset the backoff algorithm and ready the
588  // transmit state machine.
589  //
592 
593  //
594  // If there is another packet on the input queue, we need to start trying to
595  // get that out. If the queue is empty we just wait until someone puts one
596  // in.
597  //
598  if (m_queue->IsEmpty ())
599  {
600  return;
601  }
602  else
603  {
604  Ptr<Packet> packet = m_queue->Dequeue ();
605  NS_ASSERT_MSG (packet != 0, "CsmaNetDevice::TransmitAbort(): IsEmpty false but no Packet on queue?");
606  m_currentPkt = packet;
609  TransmitStart ();
610  }
611 }
612 
613 void
615 {
617 
618  //
619  // This function is called to finish the process of transmitting a packet.
620  // We need to tell the channel that we've stopped wiggling the wire and
621  // schedule an event that will be executed when it's time to re-enable
622  // the transmitter after the interframe gap.
623  //
624  NS_ASSERT_MSG (m_txMachineState == BUSY, "CsmaNetDevice::transmitCompleteEvent(): Must be BUSY if transmitting");
625  NS_ASSERT (m_channel->GetState () == TRANSMITTING);
627 
628  //
629  // When we started transmitting the current packet, it was placed in
630  // m_currentPkt. So we had better find one there.
631  //
632  NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitCompleteEvent(): m_currentPkt zero");
633  NS_LOG_LOGIC ("m_currentPkt=" << m_currentPkt);
634  NS_LOG_LOGIC ("Pkt UID is " << m_currentPkt->GetUid () << ")");
635 
636  m_channel->TransmitEnd ();
638  m_currentPkt = 0;
639 
640  NS_LOG_LOGIC ("Schedule TransmitReadyEvent in " << m_tInterframeGap.GetSeconds () << "sec");
641 
643 }
644 
645 void
647 {
649 
650  //
651  // This function is called to enable the transmitter after the interframe
652  // gap has passed. If there are pending transmissions, we use this opportunity
653  // to start the next transmit.
654  //
655  NS_ASSERT_MSG (m_txMachineState == GAP, "CsmaNetDevice::TransmitReadyEvent(): Must be in interframe gap");
657 
658  //
659  // We expect that the packet we had been transmitting was cleared when the
660  // TransmitCompleteEvent() was executed.
661  //
662  NS_ASSERT_MSG (m_currentPkt == 0, "CsmaNetDevice::TransmitReadyEvent(): m_currentPkt nonzero");
663 
664  //
665  // Get the next packet from the queue for transmitting
666  //
667  if (m_queue->IsEmpty ())
668  {
669  return;
670  }
671  else
672  {
673  Ptr<Packet> packet = m_queue->Dequeue ();
674  NS_ASSERT_MSG (packet != 0, "CsmaNetDevice::TransmitReadyEvent(): IsEmpty false but no Packet on queue?");
675  m_currentPkt = packet;
678  TransmitStart ();
679  }
680 }
681 
682 bool
684 {
685  NS_LOG_FUNCTION (this << &ch);
686 
687  m_channel = ch;
688 
689  m_deviceId = m_channel->Attach (this);
690 
691  //
692  // The channel provides us with the transmitter data rate.
693  //
694  m_bps = m_channel->GetDataRate ();
695 
696  //
697  // We use the Ethernet interframe gap of 96 bit times.
698  //
700 
701  //
702  // This device is up whenever a channel is attached to it.
703  //
704  NotifyLinkUp ();
705  return true;
706 }
707 
708 void
710 {
711  NS_LOG_FUNCTION (q);
712  m_queue = q;
713 }
714 
715 void
717 {
718  NS_LOG_FUNCTION (em);
719  m_receiveErrorModel = em;
720 }
721 
722 void
724 {
725  NS_LOG_FUNCTION (packet << senderDevice);
726  NS_LOG_LOGIC ("UID is " << packet->GetUid ());
727 
728  //
729  // We never forward up packets that we sent. Real devices don't do this since
730  // their receivers are disabled during send, so we don't.
731  //
732  if (senderDevice == this)
733  {
734  return;
735  }
736 
737  //
738  // Hit the trace hook. This trace will fire on all packets received from the
739  // channel except those originated by this device.
740  //
741  m_phyRxEndTrace (packet);
742 
743  //
744  // Only receive if the send side of net device is enabled
745  //
746  if (IsReceiveEnabled () == false)
747  {
748  m_phyRxDropTrace (packet);
749  return;
750  }
751 
752  if (m_receiveErrorModel && m_receiveErrorModel->IsCorrupt (packet) )
753  {
754  NS_LOG_LOGIC ("Dropping pkt due to error model ");
755  m_phyRxDropTrace (packet);
756  return;
757  }
758 
759  //
760  // Trace sinks will expect complete packets, not packets without some of the
761  // headers.
762  //
763  Ptr<Packet> originalPacket = packet->Copy ();
764 
765  EthernetTrailer trailer;
766  packet->RemoveTrailer (trailer);
767  if (Node::ChecksumEnabled ())
768  {
769  trailer.EnableFcs (true);
770  }
771 
772  bool crcGood = trailer.CheckFcs (packet);
773  if (!crcGood)
774  {
775  NS_LOG_INFO ("CRC error on Packet " << packet);
776  m_phyRxDropTrace (packet);
777  return;
778  }
779 
780  EthernetHeader header (false);
781  packet->RemoveHeader (header);
782 
783  NS_LOG_LOGIC ("Pkt source is " << header.GetSource ());
784  NS_LOG_LOGIC ("Pkt destination is " << header.GetDestination ());
785 
786  uint16_t protocol;
787  //
788  // If the length/type is less than 1500, it corresponds to a length
789  // interpretation packet. In this case, it is an 802.3 packet and
790  // will also have an 802.2 LLC header. If greater than 1500, we
791  // find the protocol number (Ethernet type) directly.
792  //
793  if (header.GetLengthType () <= 1500)
794  {
795  NS_ASSERT (packet->GetSize () >= header.GetLengthType ());
796  uint32_t padlen = packet->GetSize () - header.GetLengthType ();
797  NS_ASSERT (padlen <= 46);
798  if (padlen > 0)
799  {
800  packet->RemoveAtEnd (padlen);
801  }
802 
803  LlcSnapHeader llc;
804  packet->RemoveHeader (llc);
805  protocol = llc.GetType ();
806  }
807  else
808  {
809  protocol = header.GetLengthType ();
810  }
811 
812  //
813  // Classify the packet based on its destination.
814  //
815  PacketType packetType;
816 
817  if (header.GetDestination ().IsBroadcast ())
818  {
819  packetType = PACKET_BROADCAST;
820  }
821  else if (header.GetDestination ().IsGroup ())
822  {
823  packetType = PACKET_MULTICAST;
824  }
825  else if (header.GetDestination () == m_address)
826  {
827  packetType = PACKET_HOST;
828  }
829  else
830  {
831  packetType = PACKET_OTHERHOST;
832  }
833 
834  //
835  // For all kinds of packetType we receive, we hit the promiscuous sniffer
836  // hook and pass a copy up to the promiscuous callback. Pass a copy to
837  // make sure that nobody messes with our packet.
838  //
839  m_promiscSnifferTrace (originalPacket);
840  if (!m_promiscRxCallback.IsNull ())
841  {
842  m_macPromiscRxTrace (originalPacket);
843  m_promiscRxCallback (this, packet, protocol, header.GetSource (), header.GetDestination (), packetType);
844  }
845 
846  //
847  // If this packet is not destined for some other host, it must be for us
848  // as either a broadcast, multicast or unicast. We need to hit the mac
849  // packet received trace hook and forward the packet up the stack.
850  //
851  if (packetType != PACKET_OTHERHOST)
852  {
853  m_snifferTrace (originalPacket);
854  m_macRxTrace (originalPacket);
855  m_rxCallback (this, packet, protocol, header.GetSource ());
856  }
857 }
858 
861 {
863  return m_queue;
864 }
865 
866 void
868 {
870  m_linkUp = true;
872 }
873 
874 void
875 CsmaNetDevice::SetIfIndex (const uint32_t index)
876 {
877  NS_LOG_FUNCTION (index);
878  m_ifIndex = index;
879 }
880 
881 uint32_t
883 {
885  return m_ifIndex;
886 }
887 
890 {
892  return m_channel;
893 }
894 
895 void
897 {
900 }
901 
902 Address
904 {
906  return m_address;
907 }
908 
909 bool
911 {
913  return m_linkUp;
914 }
915 
916 void
918 {
919  NS_LOG_FUNCTION (&callback);
921 }
922 
923 bool
925 {
927  return true;
928 }
929 
930 Address
932 {
934  return Mac48Address ("ff:ff:ff:ff:ff:ff");
935 }
936 
937 bool
939 {
941  return true;
942 }
943 
944 Address
946 {
947  NS_LOG_FUNCTION (multicastGroup);
948 
949  Mac48Address ad = Mac48Address::GetMulticast (multicastGroup);
950 
951  //
952  // Implicit conversion (operator Address ()) is defined for Mac48Address, so
953  // use it by just returning the EUI-48 address which is automagically converted
954  // to an Address.
955  //
956  NS_LOG_LOGIC ("multicast address is " << ad);
957 
958  return ad;
959 }
960 
961 bool
963 {
965  return false;
966 }
967 
968 bool
970 {
972  return false;
973 }
974 
975 bool
976 CsmaNetDevice::Send (Ptr<Packet> packet,const Address& dest, uint16_t protocolNumber)
977 {
978  NS_LOG_FUNCTION (packet << dest << protocolNumber);
979  return SendFrom (packet, m_address, dest, protocolNumber);
980 }
981 
982 bool
983 CsmaNetDevice::SendFrom (Ptr<Packet> packet, const Address& src, const Address& dest, uint16_t protocolNumber)
984 {
985  NS_LOG_FUNCTION (packet << src << dest << protocolNumber);
986  NS_LOG_LOGIC ("packet =" << packet);
987  NS_LOG_LOGIC ("UID is " << packet->GetUid () << ")");
988 
989  NS_ASSERT (IsLinkUp ());
990 
991  //
992  // Only transmit if send side of net device is enabled
993  //
994  if (IsSendEnabled () == false)
995  {
996  m_macTxDropTrace (packet);
997  return false;
998  }
999 
1000  Mac48Address destination = Mac48Address::ConvertFrom (dest);
1001  Mac48Address source = Mac48Address::ConvertFrom (src);
1002  AddHeader (packet, source, destination, protocolNumber);
1003 
1004  m_macTxTrace (packet);
1005 
1006  //
1007  // Place the packet to be sent on the send queue. Note that the
1008  // queue may fire a drop trace, but we will too.
1009  //
1010  if (m_queue->Enqueue (packet) == false)
1011  {
1012  m_macTxDropTrace (packet);
1013  return false;
1014  }
1015 
1016  //
1017  // If the device is idle, we need to start a transmission. Otherwise,
1018  // the transmission will be started when the current packet finished
1019  // transmission (see TransmitCompleteEvent)
1020  //
1021  if (m_txMachineState == READY)
1022  {
1023  if (m_queue->IsEmpty () == false)
1024  {
1025  Ptr<Packet> packet = m_queue->Dequeue ();
1026  NS_ASSERT_MSG (packet != 0, "CsmaNetDevice::SendFrom(): IsEmpty false but no Packet on queue?");
1027  m_currentPkt = packet;
1030  TransmitStart ();
1031  }
1032  }
1033  return true;
1034 }
1035 
1036 Ptr<Node>
1038 {
1040  return m_node;
1041 }
1042 
1043 void
1045 {
1046  NS_LOG_FUNCTION (node);
1047 
1048  m_node = node;
1049 }
1050 
1051 bool
1053 {
1055  return true;
1056 }
1057 
1058 void
1060 {
1061  NS_LOG_FUNCTION (&cb);
1062  m_rxCallback = cb;
1063 }
1064 
1066 {
1068 
1069  NS_LOG_LOGIC ("MAC IPv6 multicast address is " << ad);
1070  return ad;
1071 }
1072 
1073 void
1075 {
1076  NS_LOG_FUNCTION (&cb);
1077  m_promiscRxCallback = cb;
1078 }
1079 
1080 bool
1082 {
1084  return true;
1085 }
1086 
1087 int64_t
1089 {
1090  return m_backoff.AssignStreams (stream);
1091 }
1092 
1093 } // 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:267
TracedCallback< Ptr< const Packet > > m_phyRxBeginTrace
The trace source fired when a packet begins the reception process from the medium.
virtual void DoInitialize(void)
Initialize() implementation.
Definition: object.cc:353
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
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.
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 "...
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:36
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:45
CsmaNetDevice::EncapsulationMode GetEncapsulationMode(void)
Get the encapsulation mode of this device.
Ptr< Queue< Packet > > GetQueue(void) const
Get a copy of the attached Queue.
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...
Ptr< AttributeChecker > MakePointerChecker(void)
Create a PointerChecker for a type.
Definition: pointer.h:224
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:84
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:367
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:296
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:796
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:277
#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:302
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:298
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:312
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
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:1375
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.
virtual void NotifyNewAggregate(void)
Notify all Objects aggregated to this one of a new Object being aggregated.
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.
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
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:121
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:304
bool m_receiveEnable
Enable net device to receive packets.
Ptr< ErrorModel > m_receiveErrorModel
Error model for receive packet events.
Ptr< NetDeviceQueueInterface > m_queueInterface
NetDevice queue interface.
void AddTrailer(const Trailer &trailer)
Add trailer to this packet.
Definition: packet.cc:284
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:332
Ptr< Queue< Packet > > m_queue
The Queue which this CsmaNetDevice uses as a packet source.
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:295
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)
NS_LOG_LOGIC("Net device "<< nd<< " is not bridged")
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:95
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:261
AttributeValue implementation for Mac48Address.
Packet addressed to all.
Definition: net-device.h:300
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:993
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 DoInitialize(void)
Initialize() implementation.
virtual void SetAddress(Address address)
Set the address of this interface.
void SetQueue(Ptr< Queue< Packet > > queue)
Attach a queue to the CsmaNetDevice.
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 NotifyNewAggregate(void)
Notify all Objects aggregated to this one of a new Object being aggregated.
Definition: object.cc:325
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:914
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
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