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<Packet> > ())
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 sources 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;
220  m_queue = 0;
222 }
223 
224 void
226 {
227  NS_LOG_FUNCTION (mode);
228 
229  m_encapMode = mode;
230 
231  NS_LOG_LOGIC ("m_encapMode = " << m_encapMode);
232  NS_LOG_LOGIC ("m_mtu = " << m_mtu);
233 }
234 
237 {
239  return m_encapMode;
240 }
241 
242 bool
243 CsmaNetDevice::SetMtu (uint16_t mtu)
244 {
245  NS_LOG_FUNCTION (this << mtu);
246  m_mtu = mtu;
247 
248  NS_LOG_LOGIC ("m_encapMode = " << m_encapMode);
249  NS_LOG_LOGIC ("m_mtu = " << m_mtu);
250 
251  return true;
252 }
253 
254 uint16_t
256 {
258  return m_mtu;
259 }
260 
261 
262 void
264 {
265  NS_LOG_FUNCTION (sendEnable);
266  m_sendEnable = sendEnable;
267 }
268 
269 void
271 {
272  NS_LOG_FUNCTION (receiveEnable);
273  m_receiveEnable = receiveEnable;
274 }
275 
276 bool
278 {
280  return m_sendEnable;
281 }
282 
283 bool
285 {
287  return m_receiveEnable;
288 }
289 
290 void
292 {
293  NS_LOG_FUNCTION (t);
294  m_tInterframeGap = t;
295 }
296 
297 void
298 CsmaNetDevice::SetBackoffParams (Time slotTime, uint32_t minSlots, uint32_t maxSlots, uint32_t ceiling, uint32_t maxRetries)
299 {
300  NS_LOG_FUNCTION (slotTime << minSlots << maxSlots << ceiling << maxRetries);
301  m_backoff.m_slotTime = slotTime;
302  m_backoff.m_minSlots = minSlots;
303  m_backoff.m_maxSlots = maxSlots;
304  m_backoff.m_ceiling = ceiling;
305  m_backoff.m_maxRetries = maxRetries;
306 }
307 
308 void
309 CsmaNetDevice::AddHeader (Ptr<Packet> p, Mac48Address source, Mac48Address dest, uint16_t protocolNumber)
310 {
311  NS_LOG_FUNCTION (p << source << dest << protocolNumber);
312 
313  EthernetHeader header (false);
314  header.SetSource (source);
315  header.SetDestination (dest);
316 
317  EthernetTrailer trailer;
318 
319  NS_LOG_LOGIC ("p->GetSize () = " << p->GetSize ());
320  NS_LOG_LOGIC ("m_encapMode = " << m_encapMode);
321  NS_LOG_LOGIC ("m_mtu = " << m_mtu);
322 
323  uint16_t lengthType = 0;
324  switch (m_encapMode)
325  {
326  case DIX:
327  NS_LOG_LOGIC ("Encapsulating packet as DIX (type interpretation)");
328  //
329  // This corresponds to the type interpretation of the lengthType field as
330  // in the old Ethernet Blue Book.
331  //
332  lengthType = protocolNumber;
333 
334  //
335  // All Ethernet frames must carry a minimum payload of 46 bytes. We need
336  // to pad out if we don't have enough bytes. These must be real bytes
337  // since they will be written to pcap files and compared in regression
338  // trace files.
339  //
340  if (p->GetSize () < 46)
341  {
342  uint8_t buffer[46];
343  memset (buffer, 0, 46);
344  Ptr<Packet> padd = Create<Packet> (buffer, 46 - p->GetSize ());
345  p->AddAtEnd (padd);
346  }
347  break;
348  case LLC:
349  {
350  NS_LOG_LOGIC ("Encapsulating packet as LLC (length interpretation)");
351 
352  LlcSnapHeader llc;
353  llc.SetType (protocolNumber);
354  p->AddHeader (llc);
355 
356  //
357  // This corresponds to the length interpretation of the lengthType
358  // field but with an LLC/SNAP header added to the payload as in
359  // IEEE 802.2
360  //
361  lengthType = p->GetSize ();
362 
363  //
364  // All Ethernet frames must carry a minimum payload of 46 bytes. The
365  // LLC SNAP header counts as part of this payload. We need to padd out
366  // if we don't have enough bytes. These must be real bytes since they
367  // will be written to pcap files and compared in regression trace files.
368  //
369  if (p->GetSize () < 46)
370  {
371  uint8_t buffer[46];
372  memset (buffer, 0, 46);
373  Ptr<Packet> padd = Create<Packet> (buffer, 46 - p->GetSize ());
374  p->AddAtEnd (padd);
375  }
376 
377  NS_ASSERT_MSG (p->GetSize () <= GetMtu (),
378  "CsmaNetDevice::AddHeader(): 802.3 Length/Type field with LLC/SNAP: "
379  "length interpretation must not exceed device frame size minus overhead");
380  }
381  break;
382  case ILLEGAL:
383  default:
384  NS_FATAL_ERROR ("CsmaNetDevice::AddHeader(): Unknown packet encapsulation mode");
385  break;
386  }
387 
388  NS_LOG_LOGIC ("header.SetLengthType (" << lengthType << ")");
389  header.SetLengthType (lengthType);
390  p->AddHeader (header);
391 
392  if (Node::ChecksumEnabled ())
393  {
394  trailer.EnableFcs (true);
395  }
396  trailer.CalcFcs (p);
397  p->AddTrailer (trailer);
398 }
399 
400 #if 0
401 bool
402 CsmaNetDevice::ProcessHeader (Ptr<Packet> p, uint16_t & param)
403 {
404  NS_LOG_FUNCTION (p << param);
405 
406  EthernetTrailer trailer;
407  p->RemoveTrailer (trailer);
408 
409  EthernetHeader header (false);
410  p->RemoveHeader (header);
411 
412  if ((header.GetDestination () != GetBroadcast ()) &&
413  (header.GetDestination () != GetAddress ()))
414  {
415  return false;
416  }
417 
418  switch (m_encapMode)
419  {
420  case DIX:
421  param = header.GetLengthType ();
422  break;
423  case LLC:
424  {
425  LlcSnapHeader llc;
426  p->RemoveHeader (llc);
427  param = llc.GetType ();
428  }
429  break;
430  case ILLEGAL:
431  default:
432  NS_FATAL_ERROR ("CsmaNetDevice::ProcessHeader(): Unknown packet encapsulation mode");
433  break;
434  }
435  return true;
436 }
437 #endif
438 
439 void
441 {
443 
444  //
445  // This function is called to start the process of transmitting a packet. We
446  // expect that the packet to transmit will be found in m_currentPkt.
447  //
448  NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitStart(): m_currentPkt not set");
449 
450  NS_LOG_LOGIC ("m_currentPkt = " << m_currentPkt);
451  NS_LOG_LOGIC ("UID = " << m_currentPkt->GetUid ());
452 
453  //
454  // Only transmit if the send side of net device is enabled
455  //
456  if (IsSendEnabled () == false)
457  {
459  m_currentPkt = 0;
460  return;
461  }
462 
463  //
464  // Somebody has called here telling us to start transmitting a packet. They
465  // can only do this if the state machine is in the READY or BACKOFF state.
466  // Specifically, if we are ready to start transmitting, we cannot already
467  // be transmitting (i.e., BUSY)
468  //
470  "Must be READY to transmit. Tx state is: " << m_txMachineState);
471 
472  //
473  // Now we have to sense the state of the medium and either start transmitting
474  // if it is idle, or backoff our transmission if someone else is on the wire.
475  //
476  if (m_channel->GetState () != IDLE)
477  {
478  //
479  // The channel is busy -- backoff and rechedule TransmitStart() unless
480  // we have exhausted all of our retries.
481  //
483 
485  {
486  //
487  // Too many retries, abort transmission of packet
488  //
489  TransmitAbort ();
490  }
491  else
492  {
494 
496  Time backoffTime = m_backoff.GetBackoffTime ();
497 
498  NS_LOG_LOGIC ("Channel busy, backing off for " << backoffTime.As (Time::S));
499 
501  }
502  }
503  else
504  {
505  //
506  // The channel is free, transmit the packet
507  //
509  if (m_channel->TransmitStart (m_currentPkt, m_deviceId) == false)
510  {
511  NS_LOG_WARN ("Channel TransmitStart returns an error");
513  m_currentPkt = 0;
515  }
516  else
517  {
518  //
519  // Transmission succeeded, reset the backoff time parameters and
520  // schedule a transmit complete event.
521  //
524 
526  NS_LOG_LOGIC ("Schedule TransmitCompleteEvent in " << tEvent.As (Time::S));
528  }
529  }
530 }
531 
532 void
534 {
536 
537  //
538  // When we started the process of transmitting the current packet, it was
539  // placed in m_currentPkt. So we had better find one there.
540  //
541  NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitAbort(): m_currentPkt zero");
542  NS_LOG_LOGIC ("m_currentPkt=" << m_currentPkt);
543  NS_LOG_LOGIC ("Pkt UID is " << m_currentPkt->GetUid () << ")");
544 
546  m_currentPkt = 0;
547 
548  NS_ASSERT_MSG (m_txMachineState == BACKOFF, "Must be in BACKOFF state to abort. Tx state is: " << m_txMachineState);
549 
550  //
551  // We're done with that one, so reset the backoff algorithm and ready the
552  // transmit state machine.
553  //
556 
557  //
558  // If there is another packet on the input queue, we need to start trying to
559  // get that out. If the queue is empty we just wait until someone puts one
560  // in.
561  //
562  if (m_queue->IsEmpty ())
563  {
564  return;
565  }
566  else
567  {
568  Ptr<Packet> packet = m_queue->Dequeue ();
569  NS_ASSERT_MSG (packet != 0, "CsmaNetDevice::TransmitAbort(): IsEmpty false but no Packet on queue?");
570  m_currentPkt = packet;
573  TransmitStart ();
574  }
575 }
576 
577 void
579 {
581 
582  //
583  // This function is called to finish the process of transmitting a packet.
584  // We need to tell the channel that we've stopped wiggling the wire and
585  // schedule an event that will be executed when it's time to re-enable
586  // the transmitter after the interframe gap.
587  //
588  NS_ASSERT_MSG (m_txMachineState == BUSY, "CsmaNetDevice::transmitCompleteEvent(): Must be BUSY if transmitting");
589  NS_ASSERT (m_channel->GetState () == TRANSMITTING);
591 
592  //
593  // When we started transmitting the current packet, it was placed in
594  // m_currentPkt. So we had better find one there.
595  //
596  NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitCompleteEvent(): m_currentPkt zero");
597  NS_LOG_LOGIC ("m_currentPkt=" << m_currentPkt);
598  NS_LOG_LOGIC ("Pkt UID is " << m_currentPkt->GetUid () << ")");
599 
600  m_channel->TransmitEnd ();
602  m_currentPkt = 0;
603 
604  NS_LOG_LOGIC ("Schedule TransmitReadyEvent in " << m_tInterframeGap.As (Time::S));
605 
607 }
608 
609 void
611 {
613 
614  //
615  // This function is called to enable the transmitter after the interframe
616  // gap has passed. If there are pending transmissions, we use this opportunity
617  // to start the next transmit.
618  //
619  NS_ASSERT_MSG (m_txMachineState == GAP, "CsmaNetDevice::TransmitReadyEvent(): Must be in interframe gap");
621 
622  //
623  // We expect that the packet we had been transmitting was cleared when the
624  // TransmitCompleteEvent() was executed.
625  //
626  NS_ASSERT_MSG (m_currentPkt == 0, "CsmaNetDevice::TransmitReadyEvent(): m_currentPkt nonzero");
627 
628  //
629  // Get the next packet from the queue for transmitting
630  //
631  if (m_queue->IsEmpty ())
632  {
633  return;
634  }
635  else
636  {
637  Ptr<Packet> packet = m_queue->Dequeue ();
638  NS_ASSERT_MSG (packet != 0, "CsmaNetDevice::TransmitReadyEvent(): IsEmpty false but no Packet on queue?");
639  m_currentPkt = packet;
642  TransmitStart ();
643  }
644 }
645 
646 bool
648 {
649  NS_LOG_FUNCTION (this << &ch);
650 
651  m_channel = ch;
652 
653  m_deviceId = m_channel->Attach (this);
654 
655  //
656  // The channel provides us with the transmitter data rate.
657  //
658  m_bps = m_channel->GetDataRate ();
659 
660  //
661  // We use the Ethernet interframe gap of 96 bit times.
662  //
664 
665  //
666  // This device is up whenever a channel is attached to it.
667  //
668  NotifyLinkUp ();
669  return true;
670 }
671 
672 void
674 {
675  NS_LOG_FUNCTION (q);
676  m_queue = q;
677 }
678 
679 void
681 {
682  NS_LOG_FUNCTION (em);
683  m_receiveErrorModel = em;
684 }
685 
686 void
688 {
689  NS_LOG_FUNCTION (packet << senderDevice);
690  NS_LOG_LOGIC ("UID is " << packet->GetUid ());
691 
692  //
693  // We never forward up packets that we sent. Real devices don't do this since
694  // their receivers are disabled during send, so we don't.
695  //
696  if (senderDevice == this)
697  {
698  return;
699  }
700 
701  //
702  // Hit the trace hook. This trace will fire on all packets received from the
703  // channel except those originated by this device.
704  //
705  m_phyRxEndTrace (packet);
706 
707  //
708  // Only receive if the send side of net device is enabled
709  //
710  if (IsReceiveEnabled () == false)
711  {
712  m_phyRxDropTrace (packet);
713  return;
714  }
715 
716  if (m_receiveErrorModel && m_receiveErrorModel->IsCorrupt (packet) )
717  {
718  NS_LOG_LOGIC ("Dropping pkt due to error model ");
719  m_phyRxDropTrace (packet);
720  return;
721  }
722 
723  //
724  // Trace sinks will expect complete packets, not packets without some of the
725  // headers.
726  //
727  Ptr<Packet> originalPacket = packet->Copy ();
728 
729  EthernetTrailer trailer;
730  packet->RemoveTrailer (trailer);
731  if (Node::ChecksumEnabled ())
732  {
733  trailer.EnableFcs (true);
734  }
735 
736  bool crcGood = trailer.CheckFcs (packet);
737  if (!crcGood)
738  {
739  NS_LOG_INFO ("CRC error on Packet " << packet);
740  m_phyRxDropTrace (packet);
741  return;
742  }
743 
744  EthernetHeader header (false);
745  packet->RemoveHeader (header);
746 
747  NS_LOG_LOGIC ("Pkt source is " << header.GetSource ());
748  NS_LOG_LOGIC ("Pkt destination is " << header.GetDestination ());
749 
750  uint16_t protocol;
751  //
752  // If the length/type is less than 1500, it corresponds to a length
753  // interpretation packet. In this case, it is an 802.3 packet and
754  // will also have an 802.2 LLC header. If greater than 1500, we
755  // find the protocol number (Ethernet type) directly.
756  //
757  if (header.GetLengthType () <= 1500)
758  {
759  NS_ASSERT (packet->GetSize () >= header.GetLengthType ());
760  uint32_t padlen = packet->GetSize () - header.GetLengthType ();
761  NS_ASSERT (padlen <= 46);
762  if (padlen > 0)
763  {
764  packet->RemoveAtEnd (padlen);
765  }
766 
767  LlcSnapHeader llc;
768  packet->RemoveHeader (llc);
769  protocol = llc.GetType ();
770  }
771  else
772  {
773  protocol = header.GetLengthType ();
774  }
775 
776  //
777  // Classify the packet based on its destination.
778  //
779  PacketType packetType;
780 
781  if (header.GetDestination ().IsBroadcast ())
782  {
783  packetType = PACKET_BROADCAST;
784  }
785  else if (header.GetDestination ().IsGroup ())
786  {
787  packetType = PACKET_MULTICAST;
788  }
789  else if (header.GetDestination () == m_address)
790  {
791  packetType = PACKET_HOST;
792  }
793  else
794  {
795  packetType = PACKET_OTHERHOST;
796  }
797 
798  //
799  // For all kinds of packetType we receive, we hit the promiscuous sniffer
800  // hook and pass a copy up to the promiscuous callback. Pass a copy to
801  // make sure that nobody messes with our packet.
802  //
803  m_promiscSnifferTrace (originalPacket);
804  if (!m_promiscRxCallback.IsNull ())
805  {
806  m_macPromiscRxTrace (originalPacket);
807  m_promiscRxCallback (this, packet, protocol, header.GetSource (), header.GetDestination (), packetType);
808  }
809 
810  //
811  // If this packet is not destined for some other host, it must be for us
812  // as either a broadcast, multicast or unicast. We need to hit the mac
813  // packet received trace hook and forward the packet up the stack.
814  //
815  if (packetType != PACKET_OTHERHOST)
816  {
817  m_snifferTrace (originalPacket);
818  m_macRxTrace (originalPacket);
819  m_rxCallback (this, packet, protocol, header.GetSource ());
820  }
821 }
822 
825 {
827  return m_queue;
828 }
829 
830 void
832 {
834  m_linkUp = true;
836 }
837 
838 void
839 CsmaNetDevice::SetIfIndex (const uint32_t index)
840 {
841  NS_LOG_FUNCTION (index);
842  m_ifIndex = index;
843 }
844 
845 uint32_t
847 {
849  return m_ifIndex;
850 }
851 
854 {
856  return m_channel;
857 }
858 
859 void
861 {
864 }
865 
866 Address
868 {
870  return m_address;
871 }
872 
873 bool
875 {
877  return m_linkUp;
878 }
879 
880 void
882 {
883  NS_LOG_FUNCTION (&callback);
885 }
886 
887 bool
889 {
891  return true;
892 }
893 
894 Address
896 {
898  return Mac48Address ("ff:ff:ff:ff:ff:ff");
899 }
900 
901 bool
903 {
905  return true;
906 }
907 
908 Address
910 {
911  NS_LOG_FUNCTION (multicastGroup);
912 
913  Mac48Address ad = Mac48Address::GetMulticast (multicastGroup);
914 
915  //
916  // Implicit conversion (operator Address ()) is defined for Mac48Address, so
917  // use it by just returning the EUI-48 address which is automagically converted
918  // to an Address.
919  //
920  NS_LOG_LOGIC ("multicast address is " << ad);
921 
922  return ad;
923 }
924 
925 bool
927 {
929  return false;
930 }
931 
932 bool
934 {
936  return false;
937 }
938 
939 bool
940 CsmaNetDevice::Send (Ptr<Packet> packet,const Address& dest, uint16_t protocolNumber)
941 {
942  NS_LOG_FUNCTION (packet << dest << protocolNumber);
943  return SendFrom (packet, m_address, dest, protocolNumber);
944 }
945 
946 bool
947 CsmaNetDevice::SendFrom (Ptr<Packet> packet, const Address& src, const Address& dest, uint16_t protocolNumber)
948 {
949  NS_LOG_FUNCTION (packet << src << dest << protocolNumber);
950  NS_LOG_LOGIC ("packet =" << packet);
951  NS_LOG_LOGIC ("UID is " << packet->GetUid () << ")");
952 
953  NS_ASSERT (IsLinkUp ());
954 
955  //
956  // Only transmit if send side of net device is enabled
957  //
958  if (IsSendEnabled () == false)
959  {
960  m_macTxDropTrace (packet);
961  return false;
962  }
963 
964  Mac48Address destination = Mac48Address::ConvertFrom (dest);
966  AddHeader (packet, source, destination, protocolNumber);
967 
968  m_macTxTrace (packet);
969 
970  //
971  // Place the packet to be sent on the send queue. Note that the
972  // queue may fire a drop trace, but we will too.
973  //
974  if (m_queue->Enqueue (packet) == false)
975  {
976  m_macTxDropTrace (packet);
977  return false;
978  }
979 
980  //
981  // If the device is idle, we need to start a transmission. Otherwise,
982  // the transmission will be started when the current packet finished
983  // transmission (see TransmitCompleteEvent)
984  //
985  if (m_txMachineState == READY)
986  {
987  if (m_queue->IsEmpty () == false)
988  {
989  Ptr<Packet> packet = m_queue->Dequeue ();
990  NS_ASSERT_MSG (packet != 0, "CsmaNetDevice::SendFrom(): IsEmpty false but no Packet on queue?");
991  m_currentPkt = packet;
994  TransmitStart ();
995  }
996  }
997  return true;
998 }
999 
1000 Ptr<Node>
1002 {
1004  return m_node;
1005 }
1006 
1007 void
1009 {
1010  NS_LOG_FUNCTION (node);
1011 
1012  m_node = node;
1013 }
1014 
1015 bool
1017 {
1019  return true;
1020 }
1021 
1022 void
1024 {
1025  NS_LOG_FUNCTION (&cb);
1026  m_rxCallback = cb;
1027 }
1028 
1030 {
1032 
1033  NS_LOG_LOGIC ("MAC IPv6 multicast address is " << ad);
1034  return ad;
1035 }
1036 
1037 void
1039 {
1040  NS_LOG_FUNCTION (&cb);
1041  m_promiscRxCallback = cb;
1042 }
1043 
1044 bool
1046 {
1048  return true;
1049 }
1050 
1051 int64_t
1053 {
1054  return m_backoff.AssignStreams (stream);
1055 }
1056 
1057 } // namespace ns3
a polymophic address class
Definition: address.h:91
void ResetBackoffTime(void)
Indicates to the backoff object that the last packet was successfully transmitted and that the number...
Definition: backoff.cc:80
uint32_t m_maxRetries
Maximum number of transmission retries before the packet is dropped.
Definition: backoff.h:57
bool MaxRetriesReached(void)
Definition: backoff.cc:86
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
uint32_t m_maxSlots
Maximum number of backoff slots (when multiplied by m_slotTime, determines maximum backoff time)
Definition: backoff.h:47
uint32_t m_minSlots
Minimum number of backoff slots (when multiplied by m_slotTime, determines minimum backoff time)
Definition: backoff.h:42
Time GetBackoffTime()
Definition: backoff.cc:53
uint32_t m_ceiling
Caps the exponential function when the number of retries reaches m_ceiling.
Definition: backoff.h:52
Time m_slotTime
Length of one slot.
Definition: backoff.h:62
void IncrNumRetries(void)
Increments the number of retries by 1.
Definition: backoff.cc:92
AttributeValue implementation for Boolean.
Definition: boolean.h:37
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1386
A Device for a Csma Network Link.
void SetInterframeGap(Time t)
Set the interframe gap used to separate packets.
TracedCallback< Ptr< const Packet > > m_macRxDropTrace
The trace source fired for packets successfully received by the device but dropped before being forwa...
EncapsulationMode
Enumeration of the types of packets supported in the class.
@ ILLEGAL
Encapsulation mode not set.
@ DIX
DIX II / Ethernet II packet.
@ LLC
802.2 LLC/SNAP Packet
NetDevice::ReceiveCallback m_rxCallback
The callback used to notify higher layers that a packet has been received.
TracedCallback< Ptr< const Packet > > m_macTxBackoffTrace
The trace source fired when the mac layer is forced to begin the backoff process for a packet.
virtual bool NeedsArp(void) const
Does this device need to use the address resolution protocol?
virtual bool IsLinkUp(void) const
void SetReceiveEnable(bool enable)
Enable or disable the receive side of the network device.
void TransmitReadyEvent(void)
Cause the Transmitter to Become Ready to Send Another Packet.
Backoff m_backoff
Holds the backoff parameters and is used to calculate the next backoff time to use when the channel i...
DataRate m_bps
The data rate that the Net Device uses to simulate packet transmission timing.
virtual Ptr< Channel > GetChannel(void) const
virtual void SetAddress(Address address)
Set the address of this interface.
EncapsulationMode m_encapMode
The type of packet that should be created by the AddHeader function and that should be processed by t...
void TransmitCompleteEvent(void)
Stop Sending a Packet Down the Wire and Begin the Interframe Gap.
bool IsSendEnabled(void)
Is the send side of the network device enabled?
TracedCallback< Ptr< const Packet > > m_macRxTrace
The trace source fired for packets successfully received by the device immediately before being forwa...
void TransmitStart()
Start Sending a Packet Down the Wire.
virtual void SetIfIndex(const uint32_t index)
@ BACKOFF
The transmitter is waiting for the channel to be free.
@ READY
The transmitter is ready to begin transmission of a packet.
@ BUSY
The transmitter is busy transmitting a packet.
@ GAP
The transmitter is in the interframe gap time.
Ptr< Queue< Packet > > m_queue
The Queue which this CsmaNetDevice uses as a packet source.
TracedCallback< Ptr< const Packet > > m_macPromiscRxTrace
The trace source fired for packets successfully received by the device immediately before being forwa...
uint32_t m_mtu
The Maximum Transmission Unit.
NetDevice::PromiscReceiveCallback m_promiscRxCallback
The callback used to notify higher layers that a packet has been received in promiscuous mode.
void NotifyLinkUp(void)
Notify any interested parties that the link has come up.
CsmaNetDevice()
Construct a CsmaNetDevice.
CsmaNetDevice::EncapsulationMode GetEncapsulationMode(void)
Get the encapsulation mode of this device.
Ptr< CsmaChannel > m_channel
The CsmaChannel to which this CsmaNetDevice has been attached.
bool Attach(Ptr< CsmaChannel > ch)
Attach the device to a channel.
virtual Ptr< Node > GetNode(void) const
Get the node to which this device is attached.
void Receive(Ptr< Packet > p, Ptr< CsmaNetDevice > sender)
Receive a packet from a connected CsmaChannel.
TracedCallback m_linkChangeCallbacks
List of callbacks to fire if the link changes state (up or down).
bool IsReceiveEnabled(void)
Is the receive side of the network device enabled?
TracedCallback< Ptr< const Packet > > m_phyTxBeginTrace
The trace source fired when a packet begins the transmission process on the medium.
virtual bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber)
Start sending a packet down the channel.
virtual bool SetMtu(const uint16_t mtu)
Ptr< Queue< Packet > > GetQueue(void) const
Get a copy of the attached Queue.
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.
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.
virtual void SetNode(Ptr< Node > node)
Set the node to which this device is being attached.
virtual void SetPromiscReceiveCallback(PromiscReceiveCallback cb)
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...
virtual uint32_t GetIfIndex(void) const
Ptr< Packet > m_currentPkt
Next packet that will be transmitted (if transmitter is not currently transmitting) or packet that is...
TracedCallback< Ptr< const Packet > > m_snifferTrace
A trace source that emulates a non-promiscuous protocol sniffer connected to the device.
virtual bool IsMulticast(void) const
TracedCallback< Ptr< const Packet > > m_phyTxEndTrace
The trace source fired when a packet ends the transmission process on the medium.
uint32_t m_deviceId
Device ID returned by the attached functions.
bool m_receiveEnable
Enable net device to receive packets.
virtual uint16_t GetMtu(void) const
TracedCallback< Ptr< const Packet > > m_phyRxDropTrace
The trace source fired when the phy layer drops a packet it has received.
virtual void AddLinkChangeCallback(Callback< void > callback)
virtual void DoDispose(void)
Perform any object release functionality required to break reference cycles in reference counted obje...
Ptr< Node > m_node
The Node to which this device is attached.
void SetReceiveErrorModel(Ptr< ErrorModel > em)
Attach a receive ErrorModel to the CsmaNetDevice.
virtual Address GetMulticast(Ipv4Address multicastGroup) const
Make and return a MAC multicast address using the provided multicast group.
void SetSendEnable(bool enable)
Enable or disable the send side of the network device.
TracedCallback< Ptr< const Packet > > m_promiscSnifferTrace
A trace source that emulates a promiscuous mode protocol sniffer connected to the device.
virtual bool IsBroadcast(void) const
static const uint16_t DEFAULT_MTU
Default Maximum Transmission Unit (MTU) for the CsmaNetDevice.
void SetEncapsulationMode(CsmaNetDevice::EncapsulationMode mode)
Set the encapsulation mode of this device.
TracedCallback< Ptr< const Packet > > m_phyRxBeginTrace
The trace source fired when a packet begins the reception process from the medium.
virtual Address GetAddress(void) const
bool m_sendEnable
Enable net device to send packets.
void TransmitAbort(void)
Aborts the transmission of the current packet.
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...
TracedCallback< Ptr< const Packet > > m_macTxTrace
The trace source fired when packets come into the "top" of the device at the L3/L2 transition,...
virtual Address GetBroadcast(void) const
TracedCallback< Ptr< const Packet > > m_phyTxDropTrace
The trace source fired when the phy layer drops a packet as it tries to transmit it.
virtual bool IsBridge(void) const
Is this a bridge?
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.
Mac48Address m_address
The MAC address which has been assigned to this device.
virtual bool IsPointToPoint(void) const
Is this a point to point link?
Time m_tInterframeGap
The interframe gap that the Net Device uses insert time between packet transmission.
void SetQueue(Ptr< Queue< Packet > > queue)
Attach a queue to the CsmaNetDevice.
static TypeId GetTypeId(void)
Get the type ID.
Ptr< ErrorModel > m_receiveErrorModel
Error model for receive packet events.
TxMachineState m_txMachineState
The state of the Net Device transmit state machine.
virtual ~CsmaNetDevice()
Destroy a CsmaNetDevice.
uint32_t m_ifIndex
The interface index (really net evice index) that has been assigned to this network device.
virtual bool SupportsSendFrom(void) const
bool m_linkUp
Flag indicating whether or not the link is up.
TracedCallback< Ptr< const Packet > > m_phyRxEndTrace
The trace source fired when a packet ends the reception process from the medium.
Time CalculateBytesTxTime(uint32_t bytes) const
Calculate transmission time.
Definition: data-rate.cc:275
Hold variables of type enum.
Definition: enum.h:55
Packet header for Ethernet.
void SetDestination(Mac48Address destination)
void SetLengthType(uint16_t size)
void SetSource(Mac48Address source)
Mac48Address GetDestination(void) const
Mac48Address GetSource(void) const
uint16_t GetLengthType(void) const
Packet trailer for Ethernet.
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...
void EnableFcs(bool enable)
Enable or disable FCS checking and calculations.
void CalcFcs(Ptr< const Packet > p)
Updates the Fcs Field to the correct FCS.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:41
Describes an IPv6 address.
Definition: ipv6-address.h:50
Header for the LLC/SNAP encapsulation.
uint16_t GetType(void)
Return the Ethertype.
void SetType(uint16_t type)
Set the Ethertype.
an EUI-48 address
Definition: mac48-address.h:44
static Mac48Address GetMulticast(Ipv4Address address)
bool IsGroup(void) const
bool IsBroadcast(void) const
static Mac48Address ConvertFrom(const Address &address)
AttributeValue implementation for Mac48Address.
Network layer to device interface.
Definition: net-device.h:96
PacketType
Packet types are used as they are in Linux.
Definition: net-device.h:297
@ PACKET_HOST
Packet addressed oo us.
Definition: net-device.h:298
@ PACKET_OTHERHOST
Packet addressed to someone else.
Definition: net-device.h:304
@ PACKET_BROADCAST
Packet addressed to all.
Definition: net-device.h:300
@ PACKET_MULTICAST
Packet addressed to multicast group.
Definition: net-device.h:302
static bool ChecksumEnabled(void)
Definition: node.cc:278
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:280
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
Definition: packet.cc:335
uint32_t RemoveTrailer(Trailer &trailer)
Remove a deserialized trailer from the internal buffer.
Definition: packet.cc:318
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
void RemoveAtEnd(uint32_t size)
Remove size bytes from the end of the current packet.
Definition: packet.cc:355
uint64_t GetUid(void) const
Returns the packet's Uid.
Definition: packet.cc:390
void AddTrailer(const Trailer &trailer)
Add trailer to this packet.
Definition: packet.cc:307
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:856
Hold objects of type Ptr<T>.
Definition: pointer.h:37
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:556
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
@ S
second
Definition: nstime.h:114
TimeWithUnit As(const enum Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:418
void ConnectWithoutContext(const CallbackBase &callback)
Append a Callback to the chain (without a context).
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
Hold an unsigned integer type.
Definition: uinteger.h:44
#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
#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:88
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
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:85
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:205
Ptr< const AttributeAccessor > MakeMac48AddressAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Ptr< const AttributeChecker > MakeMac48AddressChecker(void)
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:227
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
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:265
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
address
Definition: first.py:44
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeEnumChecker(int v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.
Definition: enum.h:162
@ TRANSMITTING
Channel is BUSY, a packet is being written by a net device.
Definition: csma-channel.h:76
@ IDLE
Channel is IDLE, no packet is being transmitted.
Definition: csma-channel.h:75