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  .AddConstructor<CsmaNetDevice> ()
48  .AddAttribute ("Address",
49  "The MAC address of this device.",
50  Mac48AddressValue (Mac48Address ("ff:ff:ff:ff:ff:ff")),
53  .AddAttribute ("Mtu", "The MAC-level Maximum Transmission Unit",
57  MakeUintegerChecker<uint16_t> ())
58  .AddAttribute ("EncapsulationMode",
59  "The link-layer encapsulation type to use.",
60  EnumValue (DIX),
62  MakeEnumChecker (DIX, "Dix",
63  LLC, "Llc"))
64  .AddAttribute ("SendEnable",
65  "Enable or disable the transmitter section of the device.",
66  BooleanValue (true),
69  .AddAttribute ("ReceiveEnable",
70  "Enable or disable the receiver section of the device.",
71  BooleanValue (true),
74  .AddAttribute ("ReceiveErrorModel",
75  "The receiver error model used to simulate packet loss",
76  PointerValue (),
78  MakePointerChecker<ErrorModel> ())
79 
80  //
81  // Transmit queueing discipline for the device which includes its own set
82  // of trace hooks.
83  //
84  .AddAttribute ("TxQueue",
85  "A queue to use as the transmit queue in the device.",
86  PointerValue (),
88  MakePointerChecker<Queue> ())
89 
90  //
91  // Trace sources at the "top" of the net device, where packets transition
92  // to/from higher layers.
93  //
94  .AddTraceSource ("MacTx",
95  "Trace source indicating a packet has "
96  "arrived for transmission by this device",
98  "ns3::Packet::TracedCallback")
99  .AddTraceSource ("MacTxDrop",
100  "Trace source indicating a packet has been "
101  "dropped by the device before transmission",
103  "ns3::Packet::TracedCallback")
104  .AddTraceSource ("MacPromiscRx",
105  "A packet has been received by this device, "
106  "has been passed up from the physical layer "
107  "and is being forwarded up the local protocol stack. "
108  "This is a promiscuous trace,",
110  "ns3::Packet::TracedCallback")
111  .AddTraceSource ("MacRx",
112  "A packet has been received by this device, "
113  "has been passed up from the physical layer "
114  "and is being forwarded up the local protocol stack. "
115  "This is a non-promiscuous trace,",
117  "ns3::Packet::TracedCallback")
118 #if 0
119  // Not currently implemented in this device
120  .AddTraceSource ("MacRxDrop",
121  "Trace source indicating a packet was received, "
122  "but dropped before being forwarded up the stack",
124  "ns3::Packet::TracedCallback")
125 #endif
126  .AddTraceSource ("MacTxBackoff",
127  "Trace source indicating a packet has been "
128  "delayed by the CSMA backoff process",
130  "ns3::Packet::TracedCallback")
131  //
132  // Trace souces at the "bottom" of the net device, where packets transition
133  // to/from the channel.
134  //
135  .AddTraceSource ("PhyTxBegin",
136  "Trace source indicating a packet has "
137  "begun transmitting over the channel",
139  "ns3::Packet::TracedCallback")
140  .AddTraceSource ("PhyTxEnd",
141  "Trace source indicating a packet has been "
142  "completely transmitted over the channel",
144  "ns3::Packet::TracedCallback")
145  .AddTraceSource ("PhyTxDrop",
146  "Trace source indicating a packet has been "
147  "dropped by the device during transmission",
149  "ns3::Packet::TracedCallback")
150 #if 0
151  // Not currently implemented in this device
152  .AddTraceSource ("PhyRxBegin",
153  "Trace source indicating a packet has "
154  "begun being received by the device",
156  "ns3::Packet::TracedCallback")
157 #endif
158  .AddTraceSource ("PhyRxEnd",
159  "Trace source indicating a packet has been "
160  "completely received by the device",
162  "ns3::Packet::TracedCallback")
163  .AddTraceSource ("PhyRxDrop",
164  "Trace source indicating a packet has been "
165  "dropped by the device during reception",
167  "ns3::Packet::TracedCallback")
168  //
169  // Trace sources designed to simulate a packet sniffer facility (tcpdump).
170  //
171  .AddTraceSource ("Sniffer",
172  "Trace source simulating a non-promiscuous "
173  "packet sniffer attached to the device",
175  "ns3::Packet::TracedCallback")
176  .AddTraceSource ("PromiscSniffer",
177  "Trace source simulating a promiscuous "
178  "packet sniffer attached to the device",
180  "ns3::Packet::TracedCallback")
181  ;
182  return tid;
183 }
184 
186  : m_linkUp (false)
187 {
188  NS_LOG_FUNCTION (this);
191  m_channel = 0;
192 
193  //
194  // We would like to let the attribute system take care of initializing the
195  // packet encapsulation stuff, but we also don't want to get caught up in
196  // initialization order changes. So we'll get the three problem variables
197  // into a consistent state here before the attribute calls, and then depend
198  // on the semantics of the setters to preserve a consistent state. This
199  // really doesn't have to be the same set of values as the initial values
200  // set by the attributes, but it does have to be a consistent set. That is,
201  // you can just change the default encapsulation mode above without having
202  // to change it here.
203  //
204  m_encapMode = DIX;
205 }
206 
208 {
210  m_queue = 0;
211 }
212 
213 void
215 {
217  m_channel = 0;
218  m_node = 0;
220 }
221 
222 void
224 {
225  NS_LOG_FUNCTION (mode);
226 
227  m_encapMode = mode;
228 
229  NS_LOG_LOGIC ("m_encapMode = " << m_encapMode);
230  NS_LOG_LOGIC ("m_mtu = " << m_mtu);
231 }
232 
235 {
237  return m_encapMode;
238 }
239 
240 bool
241 CsmaNetDevice::SetMtu (uint16_t mtu)
242 {
243  NS_LOG_FUNCTION (this << mtu);
244  m_mtu = mtu;
245 
246  NS_LOG_LOGIC ("m_encapMode = " << m_encapMode);
247  NS_LOG_LOGIC ("m_mtu = " << m_mtu);
248 
249  return true;
250 }
251 
252 uint16_t
254 {
256  return m_mtu;
257 }
258 
259 
260 void
262 {
263  NS_LOG_FUNCTION (sendEnable);
264  m_sendEnable = sendEnable;
265 }
266 
267 void
269 {
270  NS_LOG_FUNCTION (receiveEnable);
271  m_receiveEnable = receiveEnable;
272 }
273 
274 bool
276 {
278  return m_sendEnable;
279 }
280 
281 bool
283 {
285  return m_receiveEnable;
286 }
287 
288 void
290 {
291  NS_LOG_FUNCTION (t);
292  m_tInterframeGap = t;
293 }
294 
295 void
296 CsmaNetDevice::SetBackoffParams (Time slotTime, uint32_t minSlots, uint32_t maxSlots, uint32_t ceiling, uint32_t maxRetries)
297 {
298  NS_LOG_FUNCTION (slotTime << minSlots << maxSlots << ceiling << maxRetries);
299  m_backoff.m_slotTime = slotTime;
300  m_backoff.m_minSlots = minSlots;
301  m_backoff.m_maxSlots = maxSlots;
302  m_backoff.m_ceiling = ceiling;
303  m_backoff.m_maxRetries = maxRetries;
304 }
305 
306 void
307 CsmaNetDevice::AddHeader (Ptr<Packet> p, Mac48Address source, Mac48Address dest, uint16_t protocolNumber)
308 {
309  NS_LOG_FUNCTION (p << source << dest << protocolNumber);
310 
311  EthernetHeader header (false);
312  header.SetSource (source);
313  header.SetDestination (dest);
314 
315  EthernetTrailer trailer;
316 
317  NS_LOG_LOGIC ("p->GetSize () = " << p->GetSize ());
318  NS_LOG_LOGIC ("m_encapMode = " << m_encapMode);
319  NS_LOG_LOGIC ("m_mtu = " << m_mtu);
320 
321  uint16_t lengthType = 0;
322  switch (m_encapMode)
323  {
324  case DIX:
325  NS_LOG_LOGIC ("Encapsulating packet as DIX (type interpretation)");
326  //
327  // This corresponds to the type interpretation of the lengthType field as
328  // in the old Ethernet Blue Book.
329  //
330  lengthType = protocolNumber;
331 
332  //
333  // All Ethernet frames must carry a minimum payload of 46 bytes. We need
334  // to pad out if we don't have enough bytes. These must be real bytes
335  // since they will be written to pcap files and compared in regression
336  // trace files.
337  //
338  if (p->GetSize () < 46)
339  {
340  uint8_t buffer[46];
341  memset (buffer, 0, 46);
342  Ptr<Packet> padd = Create<Packet> (buffer, 46 - p->GetSize ());
343  p->AddAtEnd (padd);
344  }
345  break;
346  case LLC:
347  {
348  NS_LOG_LOGIC ("Encapsulating packet as LLC (length interpretation)");
349 
350  LlcSnapHeader llc;
351  llc.SetType (protocolNumber);
352  p->AddHeader (llc);
353 
354  //
355  // This corresponds to the length interpretation of the lengthType
356  // field but with an LLC/SNAP header added to the payload as in
357  // IEEE 802.2
358  //
359  lengthType = p->GetSize ();
360 
361  //
362  // All Ethernet frames must carry a minimum payload of 46 bytes. The
363  // LLC SNAP header counts as part of this payload. We need to padd out
364  // if we don't have enough bytes. These must be real bytes since they
365  // will be written to pcap files and compared in regression trace files.
366  //
367  if (p->GetSize () < 46)
368  {
369  uint8_t buffer[46];
370  memset (buffer, 0, 46);
371  Ptr<Packet> padd = Create<Packet> (buffer, 46 - p->GetSize ());
372  p->AddAtEnd (padd);
373  }
374 
375  NS_ASSERT_MSG (p->GetSize () <= GetMtu (),
376  "CsmaNetDevice::AddHeader(): 802.3 Length/Type field with LLC/SNAP: "
377  "length interpretation must not exceed device frame size minus overhead");
378  }
379  break;
380  case ILLEGAL:
381  default:
382  NS_FATAL_ERROR ("CsmaNetDevice::AddHeader(): Unknown packet encapsulation mode");
383  break;
384  }
385 
386  NS_LOG_LOGIC ("header.SetLengthType (" << lengthType << ")");
387  header.SetLengthType (lengthType);
388  p->AddHeader (header);
389 
390  if (Node::ChecksumEnabled ())
391  {
392  trailer.EnableFcs (true);
393  }
394  trailer.CalcFcs (p);
395  p->AddTrailer (trailer);
396 }
397 
398 #if 0
399 bool
400 CsmaNetDevice::ProcessHeader (Ptr<Packet> p, uint16_t & param)
401 {
402  NS_LOG_FUNCTION (p << param);
403 
404  EthernetTrailer trailer;
405  p->RemoveTrailer (trailer);
406 
407  EthernetHeader header (false);
408  p->RemoveHeader (header);
409 
410  if ((header.GetDestination () != GetBroadcast ()) &&
411  (header.GetDestination () != GetAddress ()))
412  {
413  return false;
414  }
415 
416  switch (m_encapMode)
417  {
418  case DIX:
419  param = header.GetLengthType ();
420  break;
421  case LLC:
422  {
423  LlcSnapHeader llc;
424  p->RemoveHeader (llc);
425  param = llc.GetType ();
426  }
427  break;
428  case ILLEGAL:
429  default:
430  NS_FATAL_ERROR ("CsmaNetDevice::ProcessHeader(): Unknown packet encapsulation mode");
431  break;
432  }
433  return true;
434 }
435 #endif
436 
437 void
439 {
441 
442  //
443  // This function is called to start the process of transmitting a packet. We
444  // expect that the packet to transmit will be found in m_currentPkt.
445  //
446  NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitStart(): m_currentPkt not set");
447 
448  NS_LOG_LOGIC ("m_currentPkt = " << m_currentPkt);
449  NS_LOG_LOGIC ("UID = " << m_currentPkt->GetUid ());
450 
451  //
452  // Only transmit if the send side of net device is enabled
453  //
454  if (IsSendEnabled () == false)
455  {
457  m_currentPkt = 0;
458  return;
459  }
460 
461  //
462  // Somebody has called here telling us to start transmitting a packet. They
463  // can only do this if the state machine is in the READY or BACKOFF state.
464  // Specifically, if we are ready to start transmitting, we cannot already
465  // be transmitting (i.e., BUSY)
466  //
468  "Must be READY to transmit. Tx state is: " << m_txMachineState);
469 
470  //
471  // Now we have to sense the state of the medium and either start transmitting
472  // if it is idle, or backoff our transmission if someone else is on the wire.
473  //
474  if (m_channel->GetState () != IDLE)
475  {
476  //
477  // The channel is busy -- backoff and rechedule TransmitStart() unless
478  // we have exhausted all of our retries.
479  //
481 
483  {
484  //
485  // Too many retries, abort transmission of packet
486  //
487  TransmitAbort ();
488  }
489  else
490  {
492 
494  Time backoffTime = m_backoff.GetBackoffTime ();
495 
496  NS_LOG_LOGIC ("Channel busy, backing off for " << backoffTime.GetSeconds () << " sec");
497 
499  }
500  }
501  else
502  {
503  //
504  // The channel is free, transmit the packet
505  //
506  if (m_channel->TransmitStart (m_currentPkt, m_deviceId) == false)
507  {
508  NS_LOG_WARN ("Channel TransmitStart returns an error");
510  m_currentPkt = 0;
512  }
513  else
514  {
515  //
516  // Transmission succeeded, reset the backoff time parameters and
517  // schedule a transmit complete event.
518  //
522 
524  NS_LOG_LOGIC ("Schedule TransmitCompleteEvent in " << tEvent.GetSeconds () << "sec");
526  }
527  }
528 }
529 
530 void
532 {
534 
535  //
536  // When we started the process of transmitting the current packet, it was
537  // placed in m_currentPkt. So we had better find one there.
538  //
539  NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitAbort(): m_currentPkt zero");
540  NS_LOG_LOGIC ("m_currentPkt=" << m_currentPkt);
541  NS_LOG_LOGIC ("Pkt UID is " << m_currentPkt->GetUid () << ")");
542 
544  m_currentPkt = 0;
545 
546  NS_ASSERT_MSG (m_txMachineState == BACKOFF, "Must be in BACKOFF state to abort. Tx state is: " << m_txMachineState);
547 
548  //
549  // We're done with that one, so reset the backoff algorithm and ready the
550  // transmit state machine.
551  //
554 
555  //
556  // If there is another packet on the input queue, we need to start trying to
557  // get that out. If the queue is empty we just wait until someone puts one
558  // in.
559  //
560  if (m_queue->IsEmpty ())
561  {
562  return;
563  }
564  else
565  {
566  m_currentPkt = m_queue->Dequeue ();
567  NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitAbort(): IsEmpty false but no Packet on queue?");
570  TransmitStart ();
571  }
572 }
573 
574 void
576 {
578 
579  //
580  // This function is called to finish the process of transmitting a packet.
581  // We need to tell the channel that we've stopped wiggling the wire and
582  // schedule an event that will be executed when it's time to re-enable
583  // the transmitter after the interframe gap.
584  //
585  NS_ASSERT_MSG (m_txMachineState == BUSY, "CsmaNetDevice::transmitCompleteEvent(): Must be BUSY if transmitting");
586  NS_ASSERT (m_channel->GetState () == TRANSMITTING);
588 
589  //
590  // When we started transmitting the current packet, it was placed in
591  // m_currentPkt. So we had better find one there.
592  //
593  NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitCompleteEvent(): m_currentPkt zero");
594  NS_LOG_LOGIC ("m_currentPkt=" << m_currentPkt);
595  NS_LOG_LOGIC ("Pkt UID is " << m_currentPkt->GetUid () << ")");
596 
597  m_channel->TransmitEnd ();
599  m_currentPkt = 0;
600 
601  NS_LOG_LOGIC ("Schedule TransmitReadyEvent in " << m_tInterframeGap.GetSeconds () << "sec");
602 
604 }
605 
606 void
608 {
610 
611  //
612  // This function is called to enable the transmitter after the interframe
613  // gap has passed. If there are pending transmissions, we use this opportunity
614  // to start the next transmit.
615  //
616  NS_ASSERT_MSG (m_txMachineState == GAP, "CsmaNetDevice::TransmitReadyEvent(): Must be in interframe gap");
618 
619  //
620  // We expect that the packet we had been transmitting was cleared when the
621  // TransmitCompleteEvent() was executed.
622  //
623  NS_ASSERT_MSG (m_currentPkt == 0, "CsmaNetDevice::TransmitReadyEvent(): m_currentPkt nonzero");
624 
625  //
626  // Get the next packet from the queue for transmitting
627  //
628  if (m_queue->IsEmpty ())
629  {
630  return;
631  }
632  else
633  {
634  m_currentPkt = m_queue->Dequeue ();
635  NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitReadyEvent(): IsEmpty false but no Packet on queue?");
638  TransmitStart ();
639  }
640 }
641 
642 bool
644 {
645  NS_LOG_FUNCTION (this << &ch);
646 
647  m_channel = ch;
648 
649  m_deviceId = m_channel->Attach (this);
650 
651  //
652  // The channel provides us with the transmitter data rate.
653  //
654  m_bps = m_channel->GetDataRate ();
655 
656  //
657  // We use the Ethernet interframe gap of 96 bit times.
658  //
660 
661  //
662  // This device is up whenever a channel is attached to it.
663  //
664  NotifyLinkUp ();
665  return true;
666 }
667 
668 void
670 {
671  NS_LOG_FUNCTION (q);
672  m_queue = q;
673 }
674 
675 void
677 {
678  NS_LOG_FUNCTION (em);
679  m_receiveErrorModel = em;
680 }
681 
682 void
684 {
685  NS_LOG_FUNCTION (packet << senderDevice);
686  NS_LOG_LOGIC ("UID is " << packet->GetUid ());
687 
688  //
689  // We never forward up packets that we sent. Real devices don't do this since
690  // their receivers are disabled during send, so we don't.
691  //
692  if (senderDevice == this)
693  {
694  return;
695  }
696 
697  //
698  // Hit the trace hook. This trace will fire on all packets received from the
699  // channel except those originated by this device.
700  //
701  m_phyRxEndTrace (packet);
702 
703  //
704  // Only receive if the send side of net device is enabled
705  //
706  if (IsReceiveEnabled () == false)
707  {
708  m_phyRxDropTrace (packet);
709  return;
710  }
711 
712  if (m_receiveErrorModel && m_receiveErrorModel->IsCorrupt (packet) )
713  {
714  NS_LOG_LOGIC ("Dropping pkt due to error model ");
715  m_phyRxDropTrace (packet);
716  return;
717  }
718 
719  //
720  // Trace sinks will expect complete packets, not packets without some of the
721  // headers.
722  //
723  Ptr<Packet> originalPacket = packet->Copy ();
724 
725  EthernetTrailer trailer;
726  packet->RemoveTrailer (trailer);
727  if (Node::ChecksumEnabled ())
728  {
729  trailer.EnableFcs (true);
730  }
731 
732  bool crcGood = trailer.CheckFcs (packet);
733  if (!crcGood)
734  {
735  NS_LOG_INFO ("CRC error on Packet " << packet);
736  m_phyRxDropTrace (packet);
737  return;
738  }
739 
740  EthernetHeader header (false);
741  packet->RemoveHeader (header);
742 
743  NS_LOG_LOGIC ("Pkt source is " << header.GetSource ());
744  NS_LOG_LOGIC ("Pkt destination is " << header.GetDestination ());
745 
746  uint16_t protocol;
747  //
748  // If the length/type is less than 1500, it corresponds to a length
749  // interpretation packet. In this case, it is an 802.3 packet and
750  // will also have an 802.2 LLC header. If greater than 1500, we
751  // find the protocol number (Ethernet type) directly.
752  //
753  if (header.GetLengthType () <= 1500)
754  {
755  NS_ASSERT (packet->GetSize () >= header.GetLengthType ());
756  uint32_t padlen = packet->GetSize () - header.GetLengthType ();
757  NS_ASSERT (padlen <= 46);
758  if (padlen > 0)
759  {
760  packet->RemoveAtEnd (padlen);
761  }
762 
763  LlcSnapHeader llc;
764  packet->RemoveHeader (llc);
765  protocol = llc.GetType ();
766  }
767  else
768  {
769  protocol = header.GetLengthType ();
770  }
771 
772  //
773  // Classify the packet based on its destination.
774  //
775  PacketType packetType;
776 
777  if (header.GetDestination ().IsBroadcast ())
778  {
779  packetType = PACKET_BROADCAST;
780  }
781  else if (header.GetDestination ().IsGroup ())
782  {
783  packetType = PACKET_MULTICAST;
784  }
785  else if (header.GetDestination () == m_address)
786  {
787  packetType = PACKET_HOST;
788  }
789  else
790  {
791  packetType = PACKET_OTHERHOST;
792  }
793 
794  //
795  // For all kinds of packetType we receive, we hit the promiscuous sniffer
796  // hook and pass a copy up to the promiscuous callback. Pass a copy to
797  // make sure that nobody messes with our packet.
798  //
799  m_promiscSnifferTrace (originalPacket);
800  if (!m_promiscRxCallback.IsNull ())
801  {
802  m_macPromiscRxTrace (originalPacket);
803  m_promiscRxCallback (this, packet, protocol, header.GetSource (), header.GetDestination (), packetType);
804  }
805 
806  //
807  // If this packet is not destined for some other host, it must be for us
808  // as either a broadcast, multicast or unicast. We need to hit the mac
809  // packet received trace hook and forward the packet up the stack.
810  //
811  if (packetType != PACKET_OTHERHOST)
812  {
813  m_snifferTrace (originalPacket);
814  m_macRxTrace (originalPacket);
815  m_rxCallback (this, packet, protocol, header.GetSource ());
816  }
817 }
818 
821 {
823  return m_queue;
824 }
825 
826 void
828 {
830  m_linkUp = true;
832 }
833 
834 void
835 CsmaNetDevice::SetIfIndex (const uint32_t index)
836 {
837  NS_LOG_FUNCTION (index);
838  m_ifIndex = index;
839 }
840 
841 uint32_t
843 {
845  return m_ifIndex;
846 }
847 
850 {
852  return m_channel;
853 }
854 
855 void
857 {
860 }
861 
862 Address
864 {
866  return m_address;
867 }
868 
869 bool
871 {
873  return m_linkUp;
874 }
875 
876 void
878 {
879  NS_LOG_FUNCTION (&callback);
881 }
882 
883 bool
885 {
887  return true;
888 }
889 
890 Address
892 {
894  return Mac48Address ("ff:ff:ff:ff:ff:ff");
895 }
896 
897 bool
899 {
901  return true;
902 }
903 
904 Address
906 {
907  NS_LOG_FUNCTION (multicastGroup);
908 
909  Mac48Address ad = Mac48Address::GetMulticast (multicastGroup);
910 
911  //
912  // Implicit conversion (operator Address ()) is defined for Mac48Address, so
913  // use it by just returning the EUI-48 address which is automagically converted
914  // to an Address.
915  //
916  NS_LOG_LOGIC ("multicast address is " << ad);
917 
918  return ad;
919 }
920 
921 bool
923 {
925  return false;
926 }
927 
928 bool
930 {
932  return false;
933 }
934 
935 bool
936 CsmaNetDevice::Send (Ptr<Packet> packet,const Address& dest, uint16_t protocolNumber)
937 {
938  NS_LOG_FUNCTION (packet << dest << protocolNumber);
939  return SendFrom (packet, m_address, dest, protocolNumber);
940 }
941 
942 bool
943 CsmaNetDevice::SendFrom (Ptr<Packet> packet, const Address& src, const Address& dest, uint16_t protocolNumber)
944 {
945  NS_LOG_FUNCTION (packet << src << dest << protocolNumber);
946  NS_LOG_LOGIC ("packet =" << packet);
947  NS_LOG_LOGIC ("UID is " << packet->GetUid () << ")");
948 
949  NS_ASSERT (IsLinkUp ());
950 
951  //
952  // Only transmit if send side of net device is enabled
953  //
954  if (IsSendEnabled () == false)
955  {
956  m_macTxDropTrace (packet);
957  return false;
958  }
959 
960  Mac48Address destination = Mac48Address::ConvertFrom (dest);
962  AddHeader (packet, source, destination, protocolNumber);
963 
964  m_macTxTrace (packet);
965 
966  //
967  // Place the packet to be sent on the send queue. Note that the
968  // queue may fire a drop trace, but we will too.
969  //
970  if (m_queue->Enqueue (packet) == false)
971  {
972  m_macTxDropTrace (packet);
973  return false;
974  }
975 
976  //
977  // If the device is idle, we need to start a transmission. Otherwise,
978  // the transmission will be started when the current packet finished
979  // transmission (see TransmitCompleteEvent)
980  //
981  if (m_txMachineState == READY)
982  {
983  if (m_queue->IsEmpty () == false)
984  {
985  m_currentPkt = m_queue->Dequeue ();
986  NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::SendFrom(): IsEmpty false but no Packet on queue?");
989  TransmitStart ();
990  }
991  }
992  return true;
993 }
994 
995 Ptr<Node>
997 {
999  return m_node;
1000 }
1001 
1002 void
1004 {
1005  NS_LOG_FUNCTION (node);
1006 
1007  m_node = node;
1008 }
1009 
1010 bool
1012 {
1014  return true;
1015 }
1016 
1017 void
1019 {
1020  NS_LOG_FUNCTION (&cb);
1021  m_rxCallback = cb;
1022 }
1023 
1025 {
1027 
1028  NS_LOG_LOGIC ("MAC IPv6 multicast address is " << ad);
1029  return ad;
1030 }
1031 
1032 void
1034 {
1035  NS_LOG_FUNCTION (&cb);
1036  m_promiscRxCallback = cb;
1037 }
1038 
1039 bool
1041 {
1043  return true;
1044 }
1045 
1046 int64_t
1048 {
1049  return m_backoff.AssignStreams (stream);
1050 }
1051 
1052 } // 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:95
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:78
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.
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:268
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:380
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:1072
#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
PacketType
Packet types are used as they are in Linux.
Definition: net-device.h:272
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:62
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:766
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
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:338
#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)
Fatal error handling.
Definition: fatal-error.h:100
Ptr< const AttributeChecker > MakeMac48AddressChecker(void)
Packet addressed to multicast group.
Definition: net-device.h:278
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
void SetType(uint16_t type)
Set the Ethertype.
virtual Address GetBroadcast(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:819
Packet addressed oo us.
Definition: net-device.h:274
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:84
Channel is BUSY, a packet is being written by a net device.
Definition: csma-channel.h:63
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:327
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:317
The transmitter is waiting for the channel to be free.
double CalculateTxTime(uint32_t bytes) const
Calculate transmission time.
Definition: data-rate.cc:229
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:210
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
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)
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
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
Packet addressed to someone else.
Definition: net-device.h:280
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: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:346
static const uint16_t DEFAULT_MTU
uint32_t RemoveTrailer(Trailer &trailer)
Remove a deserialized trailer from the internal buffer.
Definition: packet.cc:300
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:96
virtual bool SetMtu(const uint16_t mtu)
virtual bool SupportsSendFrom(void) const
Time GetBackoffTime()
Definition: backoff.cc:51
#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
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:47
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:75
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:276
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:859
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:51
virtual bool IsBroadcast(void) const
Time m_slotTime
Length of one slot.
Definition: backoff.h:62
TypeId SetParent(TypeId tid)
Definition: type-id.cc:631
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:253
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:90
uint32_t m_ceiling
Caps the exponential function when the number of retries reaches m_ceiling.
Definition: backoff.h:52