A Discrete-Event Network Simulator
API
csma-net-device.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2007 Emmanuelle Laprise
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
18  */
19 
20 #include "csma-net-device.h"
21 
22 #include "csma-channel.h"
23 
24 #include "ns3/boolean.h"
25 #include "ns3/enum.h"
26 #include "ns3/error-model.h"
27 #include "ns3/ethernet-header.h"
28 #include "ns3/ethernet-trailer.h"
29 #include "ns3/llc-snap-header.h"
30 #include "ns3/log.h"
31 #include "ns3/pointer.h"
32 #include "ns3/queue.h"
33 #include "ns3/simulator.h"
34 #include "ns3/trace-source-accessor.h"
35 #include "ns3/uinteger.h"
36 
37 namespace ns3
38 {
39 
40 NS_LOG_COMPONENT_DEFINE("CsmaNetDevice");
41 
42 NS_OBJECT_ENSURE_REGISTERED(CsmaNetDevice);
43 
44 TypeId
46 {
47  static TypeId tid =
48  TypeId("ns3::CsmaNetDevice")
50  .SetGroupName("Csma")
51  .AddConstructor<CsmaNetDevice>()
52  .AddAttribute("Address",
53  "The MAC address of this device.",
54  Mac48AddressValue(Mac48Address("ff:ff:ff:ff:ff:ff")),
55  MakeMac48AddressAccessor(&CsmaNetDevice::m_address),
56  MakeMac48AddressChecker())
57  .AddAttribute("Mtu",
58  "The MAC-level Maximum Transmission Unit",
61  MakeUintegerChecker<uint16_t>())
62  .AddAttribute("EncapsulationMode",
63  "The link-layer encapsulation type to use.",
64  EnumValue(DIX),
65  MakeEnumAccessor<EncapsulationMode>(&CsmaNetDevice::SetEncapsulationMode),
66  MakeEnumChecker(DIX, "Dix", LLC, "Llc"))
67  .AddAttribute("SendEnable",
68  "Enable or disable the transmitter section of the device.",
69  BooleanValue(true),
72  .AddAttribute("ReceiveEnable",
73  "Enable or disable the receiver section of the device.",
74  BooleanValue(true),
77  .AddAttribute("ReceiveErrorModel",
78  "The receiver error model used to simulate packet loss",
79  PointerValue(),
81  MakePointerChecker<ErrorModel>())
82 
83  //
84  // Transmit queueing discipline for the device which includes its own set
85  // of trace hooks.
86  //
87  .AddAttribute("TxQueue",
88  "A queue to use as the transmit queue in the device.",
89  PointerValue(),
91  MakePointerChecker<Queue<Packet>>())
92 
93  //
94  // Trace sources at the "top" of the net device, where packets transition
95  // to/from higher layers.
96  //
97  .AddTraceSource("MacTx",
98  "Trace source indicating a packet has "
99  "arrived for transmission by this device",
101  "ns3::Packet::TracedCallback")
102  .AddTraceSource("MacTxDrop",
103  "Trace source indicating a packet has been "
104  "dropped by the device before transmission",
106  "ns3::Packet::TracedCallback")
107  .AddTraceSource("MacPromiscRx",
108  "A packet has been received by this device, "
109  "has been passed up from the physical layer "
110  "and is being forwarded up the local protocol stack. "
111  "This is a promiscuous trace,",
113  "ns3::Packet::TracedCallback")
114  .AddTraceSource("MacRx",
115  "A packet has been received by this device, "
116  "has been passed up from the physical layer "
117  "and is being forwarded up the local protocol stack. "
118  "This is a non-promiscuous trace,",
120  "ns3::Packet::TracedCallback")
121 #if 0
122  // Not currently implemented in this device
123  .AddTraceSource ("MacRxDrop",
124  "Trace source indicating a packet was received, "
125  "but dropped before being forwarded up the stack",
127  "ns3::Packet::TracedCallback")
128 #endif
129  .AddTraceSource("MacTxBackoff",
130  "Trace source indicating a packet has been "
131  "delayed by the CSMA backoff process",
133  "ns3::Packet::TracedCallback")
134  //
135  // Trace sources at the "bottom" of the net device, where packets transition
136  // to/from the channel.
137  //
138  .AddTraceSource("PhyTxBegin",
139  "Trace source indicating a packet has "
140  "begun transmitting over the channel",
142  "ns3::Packet::TracedCallback")
143  .AddTraceSource("PhyTxEnd",
144  "Trace source indicating a packet has been "
145  "completely transmitted over the channel",
147  "ns3::Packet::TracedCallback")
148  .AddTraceSource("PhyTxDrop",
149  "Trace source indicating a packet has been "
150  "dropped by the device during transmission",
152  "ns3::Packet::TracedCallback")
153 #if 0
154  // Not currently implemented in this device
155  .AddTraceSource ("PhyRxBegin",
156  "Trace source indicating a packet has "
157  "begun being received by the device",
159  "ns3::Packet::TracedCallback")
160 #endif
161  .AddTraceSource("PhyRxEnd",
162  "Trace source indicating a packet has been "
163  "completely received by the device",
165  "ns3::Packet::TracedCallback")
166  .AddTraceSource("PhyRxDrop",
167  "Trace source indicating a packet has been "
168  "dropped by the device during reception",
170  "ns3::Packet::TracedCallback")
171  //
172  // Trace sources designed to simulate a packet sniffer facility (tcpdump).
173  //
174  .AddTraceSource("Sniffer",
175  "Trace source simulating a non-promiscuous "
176  "packet sniffer attached to the device",
178  "ns3::Packet::TracedCallback")
179  .AddTraceSource("PromiscSniffer",
180  "Trace source simulating a promiscuous "
181  "packet sniffer attached to the device",
183  "ns3::Packet::TracedCallback");
184  return tid;
185 }
186 
188  : m_linkUp(false)
189 {
190  NS_LOG_FUNCTION(this);
193  m_channel = nullptr;
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 = nullptr;
213 }
214 
215 void
217 {
219  m_channel = nullptr;
220  m_node = nullptr;
221  m_queue = nullptr;
223 }
224 
225 void
227 {
228  NS_LOG_FUNCTION(mode);
229 
230  m_encapMode = mode;
231 
232  NS_LOG_LOGIC("m_encapMode = " << m_encapMode);
233  NS_LOG_LOGIC("m_mtu = " << m_mtu);
234 }
235 
238 {
240  return m_encapMode;
241 }
242 
243 bool
245 {
246  NS_LOG_FUNCTION(this << mtu);
247  m_mtu = mtu;
248 
249  NS_LOG_LOGIC("m_encapMode = " << m_encapMode);
250  NS_LOG_LOGIC("m_mtu = " << m_mtu);
251 
252  return true;
253 }
254 
255 uint16_t
257 {
259  return m_mtu;
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
299  uint32_t minSlots,
300  uint32_t maxSlots,
301  uint32_t ceiling,
302  uint32_t maxRetries)
303 {
304  NS_LOG_FUNCTION(slotTime << minSlots << maxSlots << ceiling << maxRetries);
305  m_backoff.m_slotTime = slotTime;
306  m_backoff.m_minSlots = minSlots;
307  m_backoff.m_maxSlots = maxSlots;
308  m_backoff.m_ceiling = ceiling;
309  m_backoff.m_maxRetries = maxRetries;
310 }
311 
312 void
314  Mac48Address source,
315  Mac48Address dest,
316  uint16_t protocolNumber)
317 {
318  NS_LOG_FUNCTION(p << source << dest << protocolNumber);
319 
320  EthernetHeader header(false);
321  header.SetSource(source);
322  header.SetDestination(dest);
323 
324  EthernetTrailer trailer;
325 
326  NS_LOG_LOGIC("p->GetSize () = " << p->GetSize());
327  NS_LOG_LOGIC("m_encapMode = " << m_encapMode);
328  NS_LOG_LOGIC("m_mtu = " << m_mtu);
329 
330  uint16_t lengthType = 0;
331  switch (m_encapMode)
332  {
333  case DIX:
334  NS_LOG_LOGIC("Encapsulating packet as DIX (type interpretation)");
335  //
336  // This corresponds to the type interpretation of the lengthType field as
337  // in the old Ethernet Blue Book.
338  //
339  lengthType = protocolNumber;
340 
341  //
342  // All Ethernet frames must carry a minimum payload of 46 bytes. We need
343  // to pad out if we don't have enough bytes. These must be real bytes
344  // since they will be written to pcap files and compared in regression
345  // trace files.
346  //
347  if (p->GetSize() < 46)
348  {
349  uint8_t buffer[46];
350  memset(buffer, 0, 46);
351  Ptr<Packet> padd = Create<Packet>(buffer, 46 - p->GetSize());
352  p->AddAtEnd(padd);
353  }
354  break;
355  case LLC: {
356  NS_LOG_LOGIC("Encapsulating packet as LLC (length interpretation)");
357 
358  LlcSnapHeader llc;
359  llc.SetType(protocolNumber);
360  p->AddHeader(llc);
361 
362  //
363  // This corresponds to the length interpretation of the lengthType
364  // field but with an LLC/SNAP header added to the payload as in
365  // IEEE 802.2
366  //
367  lengthType = p->GetSize();
368 
369  //
370  // All Ethernet frames must carry a minimum payload of 46 bytes. The
371  // LLC SNAP header counts as part of this payload. We need to pad out
372  // if we don't have enough bytes. These must be real bytes since they
373  // will be written to pcap files and compared in regression trace files.
374  //
375  if (p->GetSize() < 46)
376  {
377  uint8_t buffer[46];
378  memset(buffer, 0, 46);
379  Ptr<Packet> padd = Create<Packet>(buffer, 46 - p->GetSize());
380  p->AddAtEnd(padd);
381  }
382 
383  NS_ASSERT_MSG(p->GetSize() <= GetMtu(),
384  "CsmaNetDevice::AddHeader(): 802.3 Length/Type field with LLC/SNAP: "
385  "length interpretation must not exceed device frame size minus overhead");
386  }
387  break;
388  case ILLEGAL:
389  default:
390  NS_FATAL_ERROR("CsmaNetDevice::AddHeader(): Unknown packet encapsulation mode");
391  break;
392  }
393 
394  NS_LOG_LOGIC("header.SetLengthType (" << lengthType << ")");
395  header.SetLengthType(lengthType);
396  p->AddHeader(header);
397 
398  if (Node::ChecksumEnabled())
399  {
400  trailer.EnableFcs(true);
401  }
402  trailer.CalcFcs(p);
403  p->AddTrailer(trailer);
404 }
405 
406 #if 0
407 bool
408 CsmaNetDevice::ProcessHeader (Ptr<Packet> p, uint16_t & param)
409 {
410  NS_LOG_FUNCTION (p << param);
411 
412  EthernetTrailer trailer;
413  p->RemoveTrailer (trailer);
414 
415  EthernetHeader header (false);
416  p->RemoveHeader (header);
417 
418  if ((header.GetDestination () != GetBroadcast ()) &&
419  (header.GetDestination () != GetAddress ()))
420  {
421  return false;
422  }
423 
424  switch (m_encapMode)
425  {
426  case DIX:
427  param = header.GetLengthType ();
428  break;
429  case LLC:
430  {
431  LlcSnapHeader llc;
432  p->RemoveHeader (llc);
433  param = llc.GetType ();
434  }
435  break;
436  case ILLEGAL:
437  default:
438  NS_FATAL_ERROR ("CsmaNetDevice::ProcessHeader(): Unknown packet encapsulation mode");
439  break;
440  }
441  return true;
442 }
443 #endif
444 
445 void
447 {
449 
450  //
451  // This function is called to start the process of transmitting a packet. We
452  // expect that the packet to transmit will be found in m_currentPkt.
453  //
454  NS_ASSERT_MSG(m_currentPkt, "CsmaNetDevice::TransmitStart(): m_currentPkt not set");
455 
456  NS_LOG_LOGIC("m_currentPkt = " << m_currentPkt);
457  NS_LOG_LOGIC("UID = " << m_currentPkt->GetUid());
458 
459  //
460  // Only transmit if the send side of net device is enabled
461  //
462  if (!IsSendEnabled())
463  {
465  m_currentPkt = nullptr;
466  return;
467  }
468 
469  //
470  // Somebody has called here telling us to start transmitting a packet. They
471  // can only do this if the state machine is in the READY or BACKOFF state.
472  // Specifically, if we are ready to start transmitting, we cannot already
473  // be transmitting (i.e., BUSY)
474  //
476  "Must be READY to transmit. Tx state is: " << m_txMachineState);
477 
478  //
479  // Now we have to sense the state of the medium and either start transmitting
480  // if it is idle, or backoff our transmission if someone else is on the wire.
481  //
482  if (m_channel->GetState() != IDLE)
483  {
484  //
485  // The channel is busy -- backoff and rechedule TransmitStart() unless
486  // we have exhausted all of our retries.
487  //
489 
491  {
492  //
493  // Too many retries, abort transmission of packet
494  //
495  TransmitAbort();
496  }
497  else
498  {
500 
502  Time backoffTime = m_backoff.GetBackoffTime();
503 
504  NS_LOG_LOGIC("Channel busy, backing off for " << backoffTime.As(Time::S));
505 
507  }
508  }
509  else
510  {
511  //
512  // The channel is free, transmit the packet
513  //
515  if (!m_channel->TransmitStart(m_currentPkt, m_deviceId))
516  {
517  NS_LOG_WARN("Channel TransmitStart returns an error");
519  m_currentPkt = nullptr;
521  }
522  else
523  {
524  //
525  // Transmission succeeded, reset the backoff time parameters and
526  // schedule a transmit complete event.
527  //
530 
532  NS_LOG_LOGIC("Schedule TransmitCompleteEvent in " << tEvent.As(Time::S));
534  }
535  }
536 }
537 
538 void
540 {
542 
543  //
544  // When we started the process of transmitting the current packet, it was
545  // placed in m_currentPkt. So we had better find one there.
546  //
547  NS_ASSERT_MSG(m_currentPkt, "CsmaNetDevice::TransmitAbort(): m_currentPkt zero");
548  NS_LOG_LOGIC("m_currentPkt=" << m_currentPkt);
549  NS_LOG_LOGIC("Pkt UID is " << m_currentPkt->GetUid() << ")");
550 
552  m_currentPkt = nullptr;
553 
555  "Must be in BACKOFF state to abort. Tx state is: " << m_txMachineState);
556 
557  //
558  // We're done with that one, so reset the backoff algorithm and ready the
559  // transmit state machine.
560  //
563 
564  //
565  // If there is another packet on the input queue, we need to start trying to
566  // get that out. If the queue is empty we just wait until someone puts one
567  // in.
568  //
569  if (m_queue->IsEmpty())
570  {
571  return;
572  }
573  else
574  {
575  Ptr<Packet> packet = m_queue->Dequeue();
576  NS_ASSERT_MSG(packet,
577  "CsmaNetDevice::TransmitAbort(): IsEmpty false but no Packet on queue?");
578  m_currentPkt = packet;
581  TransmitStart();
582  }
583 }
584 
585 void
587 {
589 
590  //
591  // This function is called to finish the process of transmitting a packet.
592  // We need to tell the channel that we've stopped wiggling the wire and
593  // schedule an event that will be executed when it's time to re-enable
594  // the transmitter after the interframe gap.
595  //
597  "CsmaNetDevice::transmitCompleteEvent(): Must be BUSY if transmitting");
598  NS_ASSERT(m_channel->GetState() == TRANSMITTING);
600 
601  //
602  // When we started transmitting the current packet, it was placed in
603  // m_currentPkt. So we had better find one there.
604  //
605  NS_ASSERT_MSG(m_currentPkt, "CsmaNetDevice::TransmitCompleteEvent(): m_currentPkt zero");
606  NS_LOG_LOGIC("m_currentPkt=" << m_currentPkt);
607  NS_LOG_LOGIC("Pkt UID is " << m_currentPkt->GetUid() << ")");
608 
609  m_channel->TransmitEnd();
611  m_currentPkt = nullptr;
612 
613  NS_LOG_LOGIC("Schedule TransmitReadyEvent in " << m_tInterframeGap.As(Time::S));
614 
616 }
617 
618 void
620 {
622 
623  //
624  // This function is called to enable the transmitter after the interframe
625  // gap has passed. If there are pending transmissions, we use this opportunity
626  // to start the next transmit.
627  //
629  "CsmaNetDevice::TransmitReadyEvent(): Must be in interframe gap");
631 
632  //
633  // We expect that the packet we had been transmitting was cleared when the
634  // TransmitCompleteEvent() was executed.
635  //
636  NS_ASSERT_MSG(!m_currentPkt, "CsmaNetDevice::TransmitReadyEvent(): m_currentPkt nonzero");
637 
638  //
639  // Get the next packet from the queue for transmitting
640  //
641  if (m_queue->IsEmpty())
642  {
643  return;
644  }
645  else
646  {
647  Ptr<Packet> packet = m_queue->Dequeue();
648  NS_ASSERT_MSG(packet,
649  "CsmaNetDevice::TransmitReadyEvent(): IsEmpty false but no Packet on queue?");
650  m_currentPkt = packet;
653  TransmitStart();
654  }
655 }
656 
657 bool
659 {
660  NS_LOG_FUNCTION(this << &ch);
661 
662  m_channel = ch;
663 
664  m_deviceId = m_channel->Attach(this);
665 
666  //
667  // The channel provides us with the transmitter data rate.
668  //
669  m_bps = m_channel->GetDataRate();
670 
671  //
672  // We use the Ethernet interframe gap of 96 bit times.
673  //
675 
676  //
677  // This device is up whenever a channel is attached to it.
678  //
679  NotifyLinkUp();
680  return true;
681 }
682 
683 void
685 {
686  NS_LOG_FUNCTION(q);
687  m_queue = q;
688 }
689 
690 void
692 {
693  NS_LOG_FUNCTION(em);
694  m_receiveErrorModel = em;
695 }
696 
697 void
699 {
700  NS_LOG_FUNCTION(packet << senderDevice);
701  NS_LOG_LOGIC("UID is " << packet->GetUid());
702 
703  //
704  // We never forward up packets that we sent. Real devices don't do this since
705  // their receivers are disabled during send, so we don't.
706  //
707  if (senderDevice == this)
708  {
709  return;
710  }
711 
712  //
713  // Hit the trace hook. This trace will fire on all packets received from the
714  // channel except those originated by this device.
715  //
716  m_phyRxEndTrace(packet);
717 
718  //
719  // Only receive if the send side of net device is enabled
720  //
721  if (!IsReceiveEnabled())
722  {
723  m_phyRxDropTrace(packet);
724  return;
725  }
726 
727  Ptr<Packet> pktCopy = packet->Copy();
728 
729  if (m_receiveErrorModel && m_receiveErrorModel->IsCorrupt(pktCopy))
730  {
731  NS_LOG_LOGIC("Dropping pkt due to error model ");
732  m_phyRxDropTrace(packet);
733  return;
734  }
735 
736  //
737  // Trace sinks will expect complete packets, not packets without some of the
738  // headers.
739  //
740 
741  EthernetTrailer trailer;
742  pktCopy->RemoveTrailer(trailer);
743  if (Node::ChecksumEnabled())
744  {
745  trailer.EnableFcs(true);
746  }
747 
748  bool crcGood = trailer.CheckFcs(pktCopy);
749  if (!crcGood)
750  {
751  NS_LOG_INFO("CRC error on Packet " << packet);
752  m_phyRxDropTrace(packet);
753  return;
754  }
755 
756  EthernetHeader header(false);
757  pktCopy->RemoveHeader(header);
758 
759  NS_LOG_LOGIC("Pkt source is " << header.GetSource());
760  NS_LOG_LOGIC("Pkt destination is " << header.GetDestination());
761 
762  uint16_t protocol;
763  //
764  // If the length/type is less than 1500, it corresponds to a length
765  // interpretation packet. In this case, it is an 802.3 packet and
766  // will also have an 802.2 LLC header. If greater than 1500, we
767  // find the protocol number (Ethernet type) directly.
768  //
769  if (header.GetLengthType() <= 1500)
770  {
771  NS_ASSERT(pktCopy->GetSize() >= header.GetLengthType());
772  uint32_t padlen = pktCopy->GetSize() - header.GetLengthType();
773  NS_ASSERT(padlen <= 46);
774  if (padlen > 0)
775  {
776  pktCopy->RemoveAtEnd(padlen);
777  }
778 
779  LlcSnapHeader llc;
780  pktCopy->RemoveHeader(llc);
781  protocol = llc.GetType();
782  }
783  else
784  {
785  protocol = header.GetLengthType();
786  }
787 
788  //
789  // Classify the packet based on its destination.
790  //
791  PacketType packetType;
792 
793  if (header.GetDestination().IsBroadcast())
794  {
795  packetType = PACKET_BROADCAST;
796  }
797  else if (header.GetDestination().IsGroup())
798  {
799  packetType = PACKET_MULTICAST;
800  }
801  else if (header.GetDestination() == m_address)
802  {
803  packetType = PACKET_HOST;
804  }
805  else
806  {
807  packetType = PACKET_OTHERHOST;
808  }
809 
810  //
811  // For all kinds of packetType we receive, we hit the promiscuous sniffer
812  // hook and pass a copy up to the promiscuous callback. Pass a copy to
813  // make sure that nobody messes with our packet.
814  //
815  m_promiscSnifferTrace(packet);
817  {
818  m_macPromiscRxTrace(packet);
819  m_promiscRxCallback(this,
820  pktCopy,
821  protocol,
822  header.GetSource(),
823  header.GetDestination(),
824  packetType);
825  }
826 
827  //
828  // If this packet is not destined for some other host, it must be for us
829  // as either a broadcast, multicast or unicast. We need to hit the mac
830  // packet received trace hook and forward the packet up the stack.
831  //
832  if (packetType != PACKET_OTHERHOST)
833  {
834  m_snifferTrace(packet);
835  m_macRxTrace(packet);
836  m_rxCallback(this, pktCopy, protocol, header.GetSource());
837  }
838 }
839 
842 {
844  return m_queue;
845 }
846 
847 void
849 {
851  m_linkUp = true;
853 }
854 
855 void
856 CsmaNetDevice::SetIfIndex(const uint32_t index)
857 {
858  NS_LOG_FUNCTION(index);
859  m_ifIndex = index;
860 }
861 
862 uint32_t
864 {
866  return m_ifIndex;
867 }
868 
871 {
873  return m_channel;
874 }
875 
876 void
878 {
881 }
882 
883 Address
885 {
887  return m_address;
888 }
889 
890 bool
892 {
894  return m_linkUp;
895 }
896 
897 void
899 {
900  NS_LOG_FUNCTION(&callback);
902 }
903 
904 bool
906 {
908  return true;
909 }
910 
911 Address
913 {
915  return Mac48Address("ff:ff:ff:ff:ff:ff");
916 }
917 
918 bool
920 {
922  return true;
923 }
924 
925 Address
927 {
928  NS_LOG_FUNCTION(multicastGroup);
929 
930  Mac48Address ad = Mac48Address::GetMulticast(multicastGroup);
931 
932  //
933  // Implicit conversion (operator Address ()) is defined for Mac48Address, so
934  // use it by just returning the EUI-48 address which is automagically converted
935  // to an Address.
936  //
937  NS_LOG_LOGIC("multicast address is " << ad);
938 
939  return ad;
940 }
941 
942 bool
944 {
946  return false;
947 }
948 
949 bool
951 {
953  return false;
954 }
955 
956 bool
957 CsmaNetDevice::Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
958 {
959  NS_LOG_FUNCTION(packet << dest << protocolNumber);
960  return SendFrom(packet, m_address, dest, protocolNumber);
961 }
962 
963 bool
965  const Address& src,
966  const Address& dest,
967  uint16_t protocolNumber)
968 {
969  NS_LOG_FUNCTION(packet << src << dest << protocolNumber);
970  NS_LOG_LOGIC("packet =" << packet);
971  NS_LOG_LOGIC("UID is " << packet->GetUid() << ")");
972 
973  NS_ASSERT(IsLinkUp());
974 
975  //
976  // Only transmit if send side of net device is enabled
977  //
978  if (!IsSendEnabled())
979  {
980  m_macTxDropTrace(packet);
981  return false;
982  }
983 
984  Mac48Address destination = Mac48Address::ConvertFrom(dest);
986  AddHeader(packet, source, destination, protocolNumber);
987 
988  m_macTxTrace(packet);
989 
990  //
991  // Place the packet to be sent on the send queue. Note that the
992  // queue may fire a drop trace, but we will too.
993  //
994  if (!m_queue->Enqueue(packet))
995  {
996  m_macTxDropTrace(packet);
997  return false;
998  }
999 
1000  //
1001  // If the device is idle, we need to start a transmission. Otherwise,
1002  // the transmission will be started when the current packet finished
1003  // transmission (see TransmitCompleteEvent)
1004  //
1005  if (m_txMachineState == READY)
1006  {
1007  if (!m_queue->IsEmpty())
1008  {
1009  Ptr<Packet> packet = m_queue->Dequeue();
1010  NS_ASSERT_MSG(packet,
1011  "CsmaNetDevice::SendFrom(): IsEmpty false but no Packet on queue?");
1012  m_currentPkt = packet;
1015  TransmitStart();
1016  }
1017  }
1018  return true;
1019 }
1020 
1021 Ptr<Node>
1023 {
1025  return m_node;
1026 }
1027 
1028 void
1030 {
1031  NS_LOG_FUNCTION(node);
1032 
1033  m_node = node;
1034 }
1035 
1036 bool
1038 {
1040  return true;
1041 }
1042 
1043 void
1045 {
1046  NS_LOG_FUNCTION(&cb);
1047  m_rxCallback = cb;
1048 }
1049 
1050 Address
1052 {
1054 
1055  NS_LOG_LOGIC("MAC IPv6 multicast address is " << ad);
1056  return ad;
1057 }
1058 
1059 void
1061 {
1062  NS_LOG_FUNCTION(&cb);
1063  m_promiscRxCallback = cb;
1064 }
1065 
1066 bool
1068 {
1070  return true;
1071 }
1072 
1073 int64_t
1075 {
1076  return m_backoff.AssignStreams(stream);
1077 }
1078 
1079 } // namespace ns3
a polymophic address class
Definition: address.h:101
void ResetBackoffTime()
Indicates to the backoff object that the last packet was successfully transmitted and that the number...
Definition: backoff.cc:85
uint32_t m_maxRetries
Maximum number of transmission retries before the packet is dropped.
Definition: backoff.h:61
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
Definition: backoff.cc:103
uint32_t m_maxSlots
Maximum number of backoff slots (when multiplied by m_slotTime, determines maximum backoff time)
Definition: backoff.h:51
bool MaxRetriesReached() const
Definition: backoff.cc:91
void IncrNumRetries()
Increments the number of retries by 1.
Definition: backoff.cc:97
uint32_t m_minSlots
Minimum number of backoff slots (when multiplied by m_slotTime, determines minimum backoff time)
Definition: backoff.h:45
Time GetBackoffTime()
Definition: backoff.cc:58
uint32_t m_ceiling
Caps the exponential function when the number of retries reaches m_ceiling.
Definition: backoff.h:56
Time m_slotTime
Length of one slot.
Definition: backoff.h:67
bool IsNull() const
Check for null implementation.
Definition: callback.h:569
A Device for a Csma Network Link.
void SetInterframeGap(Time t)
Set the interframe gap used to separate packets.
Ptr< Queue< Packet > > GetQueue() const
Get a copy of the attached Queue.
TracedCallback< Ptr< const Packet > > m_macRxDropTrace
The trace source fired for packets successfully received by the device but dropped before being forwa...
Ptr< Node > GetNode() const override
Get the node to which this device is attached.
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.
void SetReceiveEnable(bool enable)
Enable or disable the receive side of the network device.
void SetQueue(Ptr< Queue< Packet >> queue)
Attach a queue to the CsmaNetDevice.
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.
void DoDispose() override
Perform any object release functionality required to break reference cycles in reference counted obje...
~CsmaNetDevice() override
Destroy a CsmaNetDevice.
bool SetMtu(const uint16_t mtu) override
void TransmitAbort()
Aborts the transmission of the current packet.
EncapsulationMode m_encapMode
The type of packet that should be created by the AddHeader function and that should be processed by t...
bool NeedsArp() const override
Does this device need to use the address resolution protocol?
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.
void SetIfIndex(const uint32_t index) override
@ 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.
bool SupportsSendFrom() const override
NetDevice::PromiscReceiveCallback m_promiscRxCallback
The callback used to notify higher layers that a packet has been received in promiscuous mode.
CsmaNetDevice()
Construct a CsmaNetDevice.
void SetPromiscReceiveCallback(PromiscReceiveCallback cb) override
Address GetBroadcast() const override
static TypeId GetTypeId()
Get the type ID.
bool IsPointToPoint() const override
Is this a point to point link?
Ptr< CsmaChannel > m_channel
The CsmaChannel to which this CsmaNetDevice has been attached.
bool Attach(Ptr< CsmaChannel > ch)
Attach the device to a channel.
bool IsBridge() const override
Is this a bridge?
void TransmitCompleteEvent()
Stop Sending a Packet Down the Wire and Begin the Interframe Gap.
bool SendFrom(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber) override
Start sending a packet down the channel, with MAC spoofing.
void Receive(Ptr< const Packet > p, Ptr< CsmaNetDevice > sender)
Receive a packet from a connected CsmaChannel.
bool IsMulticast() const override
TracedCallback m_linkChangeCallbacks
List of callbacks to fire if the link changes state (up or down).
TracedCallback< Ptr< const Packet > > m_phyTxBeginTrace
The trace source fired when a packet begins the transmission process on the medium.
CsmaNetDevice::EncapsulationMode GetEncapsulationMode()
Get the encapsulation mode of this device.
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.
uint16_t GetMtu() const override
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
Ptr< Channel > GetChannel() const override
void NotifyLinkUp()
Notify any interested parties that the link has come up.
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...
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.
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.
TracedCallback< Ptr< const Packet > > m_phyRxDropTrace
The trace source fired when the phy layer drops a packet it has received.
Address GetMulticast(Ipv4Address multicastGroup) const override
Make and return a MAC multicast address using the provided multicast group.
Ptr< Node > m_node
The Node to which this device is attached.
void SetReceiveErrorModel(Ptr< ErrorModel > em)
Attach a receive ErrorModel to the CsmaNetDevice.
void SetSendEnable(bool enable)
Enable or disable the send side of the network device.
bool IsLinkUp() const override
void TransmitReadyEvent()
Cause the Transmitter to Become Ready to Send Another Packet.
TracedCallback< Ptr< const Packet > > m_promiscSnifferTrace
A trace source that emulates a promiscuous mode protocol sniffer connected to the device.
uint32_t GetIfIndex() const override
bool IsBroadcast() const override
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.
bool m_sendEnable
Enable net device to send packets.
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...
bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber) override
Start sending a packet down the channel.
bool IsSendEnabled() const
Is the send side of the network device enabled?
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 SetReceiveCallback(NetDevice::ReceiveCallback cb) override
Set the callback to be used to notify higher layers when a packet has been received.
TracedCallback< Ptr< const Packet > > m_phyTxDropTrace
The trace source fired when the phy layer drops a packet as it tries to transmit it.
Address GetAddress() const override
void AddLinkChangeCallback(Callback< void > callback) override
void SetNode(Ptr< Node > node) override
Set the node to which this device is being attached.
void SetAddress(Address address) override
Set the address of this interface.
Mac48Address m_address
The MAC address which has been assigned to this device.
Time m_tInterframeGap
The interframe gap that the Net Device uses insert time between packet transmission.
Ptr< ErrorModel > m_receiveErrorModel
Error model for receive packet events.
TxMachineState m_txMachineState
The state of the Net Device transmit state machine.
uint32_t m_ifIndex
The interface index (really net evice index) that has been assigned to this network device.
bool IsReceiveEnabled() const
Is the receive side of the network device enabled?
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:291
Hold variables of type enum.
Definition: enum.h:62
Packet header for Ethernet.
uint16_t GetLengthType() const
void SetDestination(Mac48Address destination)
Mac48Address GetDestination() const
void SetLengthType(uint16_t size)
void SetSource(Mac48Address source)
Mac48Address GetSource() 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:42
Describes an IPv6 address.
Definition: ipv6-address.h:49
Header for the LLC/SNAP encapsulation.
uint16_t GetType()
Return the Ethertype.
void SetType(uint16_t type)
Set the Ethertype.
an EUI-48 address
Definition: mac48-address.h:46
static Mac48Address GetMulticast(Ipv4Address address)
bool IsGroup() const
static Mac48Address ConvertFrom(const Address &address)
bool IsBroadcast() const
Network layer to device interface.
Definition: net-device.h:98
PacketType
Packet types are used as they are in Linux.
Definition: net-device.h:300
@ PACKET_HOST
Packet addressed to us.
Definition: net-device.h:301
@ PACKET_OTHERHOST
Packet addressed to someone else.
Definition: net-device.h:307
@ PACKET_BROADCAST
Packet addressed to all.
Definition: net-device.h:303
@ PACKET_MULTICAST
Packet addressed to multicast group.
Definition: net-device.h:305
static bool ChecksumEnabled()
Definition: node.cc:285
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:352
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:294
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
Definition: packet.cc:354
uint32_t RemoveTrailer(Trailer &trailer)
Remove a deserialized trailer from the internal buffer.
Definition: packet.cc:336
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:268
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:861
void RemoveAtEnd(uint32_t size)
Remove size bytes from the end of the current packet.
Definition: packet.cc:376
Ptr< Packet > Copy() const
performs a COW copy of the packet.
Definition: packet.cc:131
uint64_t GetUid() const
Returns the packet's Uid.
Definition: packet.cc:412
void AddTrailer(const Trailer &trailer)
Add trailer to this packet.
Definition: packet.cc:324
Hold objects of type Ptr<T>.
Definition: pointer.h:37
Template class for packet Queues.
Definition: queue.h:268
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:415
@ S
second
Definition: nstime.h:116
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:931
Hold an unsigned integer type.
Definition: uinteger.h:45
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#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:86
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#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:261
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
address
Definition: first.py:47
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Definition: pointer.h:227
Ptr< const AttributeChecker > MakeEnumChecker(T v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.
Definition: enum.h:194
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:86
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
@ TRANSMITTING
Channel is BUSY, a packet is being written by a net device.
Definition: csma-channel.h:77
@ IDLE
Channel is IDLE, no packet is being transmitted.
Definition: csma-channel.h:76