A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 NS_LOG_COMPONENT_DEFINE ("CsmaNetDevice");
37 
38 namespace ns3 {
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")),
51  MakeMac48AddressAccessor (&CsmaNetDevice::m_address),
52  MakeMac48AddressChecker ())
53  .AddAttribute ("Mtu", "The MAC-level Maximum Transmission Unit",
55  MakeUintegerAccessor (&CsmaNetDevice::SetMtu,
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),
67  MakeBooleanAccessor (&CsmaNetDevice::m_sendEnable),
68  MakeBooleanChecker ())
69  .AddAttribute ("ReceiveEnable",
70  "Enable or disable the receiver section of the device.",
71  BooleanValue (true),
72  MakeBooleanAccessor (&CsmaNetDevice::m_receiveEnable),
73  MakeBooleanChecker ())
74  .AddAttribute ("ReceiveErrorModel",
75  "The receiver error model used to simulate packet loss",
76  PointerValue (),
77  MakePointerAccessor (&CsmaNetDevice::m_receiveErrorModel),
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 (),
87  MakePointerAccessor (&CsmaNetDevice::m_queue),
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 arrived for transmission by this device",
97  .AddTraceSource ("MacTxDrop",
98  "Trace source indicating a packet has been dropped by the device before transmission",
100  .AddTraceSource ("MacPromiscRx",
101  "A packet has been received by this device, has been passed up from the physical layer "
102  "and is being forwarded up the local protocol stack. This is a promiscuous trace,",
104  .AddTraceSource ("MacRx",
105  "A packet has been received by this device, has been passed up from the physical layer "
106  "and is being forwarded up the local protocol stack. This is a non-promiscuous trace,",
108 #if 0
109  // Not currently implemented in this device
110  .AddTraceSource ("MacRxDrop",
111  "Trace source indicating a packet was received, but dropped before being forwarded up the stack",
113 #endif
114  .AddTraceSource ("MacTxBackoff",
115  "Trace source indicating a packet has been delayed by the CSMA backoff process",
117  //
118  // Trace souces at the "bottom" of the net device, where packets transition
119  // to/from the channel.
120  //
121  .AddTraceSource ("PhyTxBegin",
122  "Trace source indicating a packet has begun transmitting over the channel",
124  .AddTraceSource ("PhyTxEnd",
125  "Trace source indicating a packet has been completely transmitted over the channel",
127  .AddTraceSource ("PhyTxDrop",
128  "Trace source indicating a packet has been dropped by the device during transmission",
130 #if 0
131  // Not currently implemented in this device
132  .AddTraceSource ("PhyRxBegin",
133  "Trace source indicating a packet has begun being received by the device",
135 #endif
136  .AddTraceSource ("PhyRxEnd",
137  "Trace source indicating a packet has been completely received by the device",
139  .AddTraceSource ("PhyRxDrop",
140  "Trace source indicating a packet has been dropped by the device during reception",
142  //
143  // Trace sources designed to simulate a packet sniffer facility (tcpdump).
144  //
145  .AddTraceSource ("Sniffer",
146  "Trace source simulating a non-promiscuous packet sniffer attached to the device",
148  .AddTraceSource ("PromiscSniffer",
149  "Trace source simulating a promiscuous packet sniffer attached to the device",
151  ;
152  return tid;
153 }
154 
156  : m_linkUp (false)
157 {
158  NS_LOG_FUNCTION (this);
160  m_tInterframeGap = Seconds (0);
161  m_channel = 0;
162 
163  //
164  // We would like to let the attribute system take care of initializing the
165  // packet encapsulation stuff, but we also don't want to get caught up in
166  // initialization order changes. So we'll get the three problem variables
167  // into a consistent state here before the attribute calls, and then depend
168  // on the semantics of the setters to preserve a consistent state. This
169  // really doesn't have to be the same set of values as the initial values
170  // set by the attributes, but it does have to be a consistent set. That is,
171  // you can just change the default encapsulation mode above without having
172  // to change it here.
173  //
174  m_encapMode = DIX;
175 }
176 
178 {
180  m_queue = 0;
181 }
182 
183 void
185 {
187  m_channel = 0;
188  m_node = 0;
190 }
191 
192 void
194 {
195  NS_LOG_FUNCTION (mode);
196 
197  m_encapMode = mode;
198 
199  NS_LOG_LOGIC ("m_encapMode = " << m_encapMode);
200  NS_LOG_LOGIC ("m_mtu = " << m_mtu);
201 }
202 
205 {
207  return m_encapMode;
208 }
209 
210 bool
211 CsmaNetDevice::SetMtu (uint16_t mtu)
212 {
213  NS_LOG_FUNCTION (this << mtu);
214  m_mtu = mtu;
215 
216  NS_LOG_LOGIC ("m_encapMode = " << m_encapMode);
217  NS_LOG_LOGIC ("m_mtu = " << m_mtu);
218 
219  return true;
220 }
221 
222 uint16_t
224 {
226  return m_mtu;
227 }
228 
229 
230 void
232 {
233  NS_LOG_FUNCTION (sendEnable);
234  m_sendEnable = sendEnable;
235 }
236 
237 void
239 {
240  NS_LOG_FUNCTION (receiveEnable);
241  m_receiveEnable = receiveEnable;
242 }
243 
244 bool
246 {
248  return m_sendEnable;
249 }
250 
251 bool
253 {
255  return m_receiveEnable;
256 }
257 
258 void
260 {
261  NS_LOG_FUNCTION (t);
262  m_tInterframeGap = t;
263 }
264 
265 void
266 CsmaNetDevice::SetBackoffParams (Time slotTime, uint32_t minSlots, uint32_t maxSlots, uint32_t ceiling, uint32_t maxRetries)
267 {
268  NS_LOG_FUNCTION (slotTime << minSlots << maxSlots << ceiling << maxRetries);
269  m_backoff.m_slotTime = slotTime;
270  m_backoff.m_minSlots = minSlots;
271  m_backoff.m_maxSlots = maxSlots;
272  m_backoff.m_ceiling = ceiling;
273  m_backoff.m_maxRetries = maxRetries;
274 }
275 
276 void
277 CsmaNetDevice::AddHeader (Ptr<Packet> p, Mac48Address source, Mac48Address dest, uint16_t protocolNumber)
278 {
279  NS_LOG_FUNCTION (p << source << dest << protocolNumber);
280 
281  EthernetHeader header (false);
282  header.SetSource (source);
283  header.SetDestination (dest);
284 
285  EthernetTrailer trailer;
286 
287  NS_LOG_LOGIC ("p->GetSize () = " << p->GetSize ());
288  NS_LOG_LOGIC ("m_encapMode = " << m_encapMode);
289  NS_LOG_LOGIC ("m_mtu = " << m_mtu);
290 
291  uint16_t lengthType = 0;
292  switch (m_encapMode)
293  {
294  case DIX:
295  NS_LOG_LOGIC ("Encapsulating packet as DIX (type interpretation)");
296  //
297  // This corresponds to the type interpretation of the lengthType field as
298  // in the old Ethernet Blue Book.
299  //
300  lengthType = protocolNumber;
301 
302  //
303  // All Ethernet frames must carry a minimum payload of 46 bytes. We need
304  // to pad out if we don't have enough bytes. These must be real bytes
305  // since they will be written to pcap files and compared in regression
306  // trace files.
307  //
308  if (p->GetSize () < 46)
309  {
310  uint8_t buffer[46];
311  memset (buffer, 0, 46);
312  Ptr<Packet> padd = Create<Packet> (buffer, 46 - p->GetSize ());
313  p->AddAtEnd (padd);
314  }
315  break;
316  case LLC:
317  {
318  NS_LOG_LOGIC ("Encapsulating packet as LLC (length interpretation)");
319 
320  LlcSnapHeader llc;
321  llc.SetType (protocolNumber);
322  p->AddHeader (llc);
323 
324  //
325  // This corresponds to the length interpretation of the lengthType
326  // field but with an LLC/SNAP header added to the payload as in
327  // IEEE 802.2
328  //
329  lengthType = p->GetSize ();
330 
331  //
332  // All Ethernet frames must carry a minimum payload of 46 bytes. The
333  // LLC SNAP header counts as part of this payload. We need to padd out
334  // if we don't have enough bytes. These must be real bytes since they
335  // will be written to pcap files and compared in regression trace files.
336  //
337  if (p->GetSize () < 46)
338  {
339  uint8_t buffer[46];
340  memset (buffer, 0, 46);
341  Ptr<Packet> padd = Create<Packet> (buffer, 46 - p->GetSize ());
342  p->AddAtEnd (padd);
343  }
344 
345  NS_ASSERT_MSG (p->GetSize () <= GetMtu (),
346  "CsmaNetDevice::AddHeader(): 802.3 Length/Type field with LLC/SNAP: "
347  "length interpretation must not exceed device frame size minus overhead");
348  }
349  break;
350  case ILLEGAL:
351  default:
352  NS_FATAL_ERROR ("CsmaNetDevice::AddHeader(): Unknown packet encapsulation mode");
353  break;
354  }
355 
356  NS_LOG_LOGIC ("header.SetLengthType (" << lengthType << ")");
357  header.SetLengthType (lengthType);
358  p->AddHeader (header);
359 
360  if (Node::ChecksumEnabled ())
361  {
362  trailer.EnableFcs (true);
363  }
364  trailer.CalcFcs (p);
365  p->AddTrailer (trailer);
366 }
367 
368 #if 0
369 bool
370 CsmaNetDevice::ProcessHeader (Ptr<Packet> p, uint16_t & param)
371 {
372  NS_LOG_FUNCTION (p << param);
373 
374  EthernetTrailer trailer;
375  p->RemoveTrailer (trailer);
376 
377  EthernetHeader header (false);
378  p->RemoveHeader (header);
379 
380  if ((header.GetDestination () != GetBroadcast ()) &&
381  (header.GetDestination () != GetAddress ()))
382  {
383  return false;
384  }
385 
386  switch (m_encapMode)
387  {
388  case DIX:
389  param = header.GetLengthType ();
390  break;
391  case LLC:
392  {
393  LlcSnapHeader llc;
394  p->RemoveHeader (llc);
395  param = llc.GetType ();
396  }
397  break;
398  case ILLEGAL:
399  default:
400  NS_FATAL_ERROR ("CsmaNetDevice::ProcessHeader(): Unknown packet encapsulation mode");
401  break;
402  }
403  return true;
404 }
405 #endif
406 
407 void
409 {
411 
412  //
413  // This function is called to start the process of transmitting a packet. We
414  // expect that the packet to transmit will be found in m_currentPkt.
415  //
416  NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitStart(): m_currentPkt not set");
417 
418  NS_LOG_LOGIC ("m_currentPkt = " << m_currentPkt);
419  NS_LOG_LOGIC ("UID = " << m_currentPkt->GetUid ());
420 
421  //
422  // Only transmit if the send side of net device is enabled
423  //
424  if (IsSendEnabled () == false)
425  {
427  m_currentPkt = 0;
428  return;
429  }
430 
431  //
432  // Somebody has called here telling us to start transmitting a packet. They
433  // can only do this if the state machine is in the READY or BACKOFF state.
434  // Specifically, if we are ready to start transmitting, we cannot already
435  // be transmitting (i.e., BUSY)
436  //
438  "Must be READY to transmit. Tx state is: " << m_txMachineState);
439 
440  //
441  // Now we have to sense the state of the medium and either start transmitting
442  // if it is idle, or backoff our transmission if someone else is on the wire.
443  //
444  if (m_channel->GetState () != IDLE)
445  {
446  //
447  // The channel is busy -- backoff and rechedule TransmitStart() unless
448  // we have exhausted all of our retries.
449  //
451 
453  {
454  //
455  // Too many retries, abort transmission of packet
456  //
457  TransmitAbort ();
458  }
459  else
460  {
462 
464  Time backoffTime = m_backoff.GetBackoffTime ();
465 
466  NS_LOG_LOGIC ("Channel busy, backing off for " << backoffTime.GetSeconds () << " sec");
467 
469  }
470  }
471  else
472  {
473  //
474  // The channel is free, transmit the packet
475  //
476  if (m_channel->TransmitStart (m_currentPkt, m_deviceId) == false)
477  {
478  NS_LOG_WARN ("Channel TransmitStart returns an error");
480  m_currentPkt = 0;
482  }
483  else
484  {
485  //
486  // Transmission succeeded, reset the backoff time parameters and
487  // schedule a transmit complete event.
488  //
492 
493  Time tEvent = Seconds (m_bps.CalculateTxTime (m_currentPkt->GetSize ()));
494  NS_LOG_LOGIC ("Schedule TransmitCompleteEvent in " << tEvent.GetSeconds () << "sec");
496  }
497  }
498 }
499 
500 void
502 {
504 
505  //
506  // When we started the process of transmitting the current packet, it was
507  // placed in m_currentPkt. So we had better find one there.
508  //
509  NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitAbort(): m_currentPkt zero");
510  NS_LOG_LOGIC ("m_currentPkt=" << m_currentPkt);
511  NS_LOG_LOGIC ("Pkt UID is " << m_currentPkt->GetUid () << ")");
512 
514  m_currentPkt = 0;
515 
516  NS_ASSERT_MSG (m_txMachineState == BACKOFF, "Must be in BACKOFF state to abort. Tx state is: " << m_txMachineState);
517 
518  //
519  // We're done with that one, so reset the backoff algorithm and ready the
520  // transmit state machine.
521  //
524 
525  //
526  // If there is another packet on the input queue, we need to start trying to
527  // get that out. If the queue is empty we just wait until someone puts one
528  // in.
529  //
530  if (m_queue->IsEmpty ())
531  {
532  return;
533  }
534  else
535  {
536  m_currentPkt = m_queue->Dequeue ();
537  NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitAbort(): IsEmpty false but no Packet on queue?");
540  TransmitStart ();
541  }
542 }
543 
544 void
546 {
548 
549  //
550  // This function is called to finish the process of transmitting a packet.
551  // We need to tell the channel that we've stopped wiggling the wire and
552  // schedule an event that will be executed when it's time to re-enable
553  // the transmitter after the interframe gap.
554  //
555  NS_ASSERT_MSG (m_txMachineState == BUSY, "CsmaNetDevice::transmitCompleteEvent(): Must be BUSY if transmitting");
556  NS_ASSERT (m_channel->GetState () == TRANSMITTING);
558 
559  //
560  // When we started transmitting the current packet, it was placed in
561  // m_currentPkt. So we had better find one there.
562  //
563  NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitCompleteEvent(): m_currentPkt zero");
564  NS_LOG_LOGIC ("m_currentPkt=" << m_currentPkt);
565  NS_LOG_LOGIC ("Pkt UID is " << m_currentPkt->GetUid () << ")");
566 
567  m_channel->TransmitEnd ();
569  m_currentPkt = 0;
570 
571  NS_LOG_LOGIC ("Schedule TransmitReadyEvent in " << m_tInterframeGap.GetSeconds () << "sec");
572 
574 }
575 
576 void
578 {
580 
581  //
582  // This function is called to enable the transmitter after the interframe
583  // gap has passed. If there are pending transmissions, we use this opportunity
584  // to start the next transmit.
585  //
586  NS_ASSERT_MSG (m_txMachineState == GAP, "CsmaNetDevice::TransmitReadyEvent(): Must be in interframe gap");
588 
589  //
590  // We expect that the packet we had been transmitting was cleared when the
591  // TransmitCompleteEvent() was executed.
592  //
593  NS_ASSERT_MSG (m_currentPkt == 0, "CsmaNetDevice::TransmitReadyEvent(): m_currentPkt nonzero");
594 
595  //
596  // Get the next packet from the queue for transmitting
597  //
598  if (m_queue->IsEmpty ())
599  {
600  return;
601  }
602  else
603  {
604  m_currentPkt = m_queue->Dequeue ();
605  NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitReadyEvent(): IsEmpty false but no Packet on queue?");
608  TransmitStart ();
609  }
610 }
611 
612 bool
614 {
615  NS_LOG_FUNCTION (this << &ch);
616 
617  m_channel = ch;
618 
619  m_deviceId = m_channel->Attach (this);
620 
621  //
622  // The channel provides us with the transmitter data rate.
623  //
624  m_bps = m_channel->GetDataRate ();
625 
626  //
627  // We use the Ethernet interframe gap of 96 bit times.
628  //
629  m_tInterframeGap = Seconds (m_bps.CalculateTxTime (96/8));
630 
631  //
632  // This device is up whenever a channel is attached to it.
633  //
634  NotifyLinkUp ();
635  return true;
636 }
637 
638 void
640 {
641  NS_LOG_FUNCTION (q);
642  m_queue = q;
643 }
644 
645 void
647 {
648  NS_LOG_FUNCTION (em);
649  m_receiveErrorModel = em;
650 }
651 
652 void
654 {
655  NS_LOG_FUNCTION (packet << senderDevice);
656  NS_LOG_LOGIC ("UID is " << packet->GetUid ());
657 
658  //
659  // We never forward up packets that we sent. Real devices don't do this since
660  // their receivers are disabled during send, so we don't.
661  //
662  if (senderDevice == this)
663  {
664  return;
665  }
666 
667  //
668  // Hit the trace hook. This trace will fire on all packets received from the
669  // channel except those originated by this device.
670  //
671  m_phyRxEndTrace (packet);
672 
673  //
674  // Only receive if the send side of net device is enabled
675  //
676  if (IsReceiveEnabled () == false)
677  {
678  m_phyRxDropTrace (packet);
679  return;
680  }
681 
682  if (m_receiveErrorModel && m_receiveErrorModel->IsCorrupt (packet) )
683  {
684  NS_LOG_LOGIC ("Dropping pkt due to error model ");
685  m_phyRxDropTrace (packet);
686  return;
687  }
688 
689  //
690  // Trace sinks will expect complete packets, not packets without some of the
691  // headers.
692  //
693  Ptr<Packet> originalPacket = packet->Copy ();
694 
695  EthernetTrailer trailer;
696  packet->RemoveTrailer (trailer);
697  if (Node::ChecksumEnabled ())
698  {
699  trailer.EnableFcs (true);
700  }
701 
702  bool crcGood = trailer.CheckFcs (packet);
703  if (!crcGood)
704  {
705  NS_LOG_INFO ("CRC error on Packet " << packet);
706  m_phyRxDropTrace (packet);
707  return;
708  }
709 
710  EthernetHeader header (false);
711  packet->RemoveHeader (header);
712 
713  NS_LOG_LOGIC ("Pkt source is " << header.GetSource ());
714  NS_LOG_LOGIC ("Pkt destination is " << header.GetDestination ());
715 
716  uint16_t protocol;
717  //
718  // If the length/type is less than 1500, it corresponds to a length
719  // interpretation packet. In this case, it is an 802.3 packet and
720  // will also have an 802.2 LLC header. If greater than 1500, we
721  // find the protocol number (Ethernet type) directly.
722  //
723  if (header.GetLengthType () <= 1500)
724  {
725  NS_ASSERT (packet->GetSize () >= header.GetLengthType ());
726  uint32_t padlen = packet->GetSize () - header.GetLengthType ();
727  NS_ASSERT (padlen <= 46);
728  if (padlen > 0)
729  {
730  packet->RemoveAtEnd (padlen);
731  }
732 
733  LlcSnapHeader llc;
734  packet->RemoveHeader (llc);
735  protocol = llc.GetType ();
736  }
737  else
738  {
739  protocol = header.GetLengthType ();
740  }
741 
742  //
743  // Classify the packet based on its destination.
744  //
745  PacketType packetType;
746 
747  if (header.GetDestination ().IsBroadcast ())
748  {
749  packetType = PACKET_BROADCAST;
750  }
751  else if (header.GetDestination ().IsGroup ())
752  {
753  packetType = PACKET_MULTICAST;
754  }
755  else if (header.GetDestination () == m_address)
756  {
757  packetType = PACKET_HOST;
758  }
759  else
760  {
761  packetType = PACKET_OTHERHOST;
762  }
763 
764  //
765  // For all kinds of packetType we receive, we hit the promiscuous sniffer
766  // hook and pass a copy up to the promiscuous callback. Pass a copy to
767  // make sure that nobody messes with our packet.
768  //
769  m_promiscSnifferTrace (originalPacket);
770  if (!m_promiscRxCallback.IsNull ())
771  {
772  m_macPromiscRxTrace (originalPacket);
773  m_promiscRxCallback (this, packet, protocol, header.GetSource (), header.GetDestination (), packetType);
774  }
775 
776  //
777  // If this packet is not destined for some other host, it must be for us
778  // as either a broadcast, multicast or unicast. We need to hit the mac
779  // packet received trace hook and forward the packet up the stack.
780  //
781  if (packetType != PACKET_OTHERHOST)
782  {
783  m_snifferTrace (originalPacket);
784  m_macRxTrace (originalPacket);
785  m_rxCallback (this, packet, protocol, header.GetSource ());
786  }
787 }
788 
791 {
793  return m_queue;
794 }
795 
796 void
798 {
800  m_linkUp = true;
802 }
803 
804 void
805 CsmaNetDevice::SetIfIndex (const uint32_t index)
806 {
807  NS_LOG_FUNCTION (index);
808  m_ifIndex = index;
809 }
810 
811 uint32_t
813 {
815  return m_ifIndex;
816 }
817 
820 {
822  return m_channel;
823 }
824 
825 void
827 {
830 }
831 
832 Address
834 {
836  return m_address;
837 }
838 
839 bool
841 {
843  return m_linkUp;
844 }
845 
846 void
848 {
849  NS_LOG_FUNCTION (&callback);
851 }
852 
853 bool
855 {
857  return true;
858 }
859 
860 Address
862 {
864  return Mac48Address ("ff:ff:ff:ff:ff:ff");
865 }
866 
867 bool
869 {
871  return true;
872 }
873 
874 Address
876 {
877  NS_LOG_FUNCTION (multicastGroup);
878 
879  Mac48Address ad = Mac48Address::GetMulticast (multicastGroup);
880 
881  //
882  // Implicit conversion (operator Address ()) is defined for Mac48Address, so
883  // use it by just returning the EUI-48 address which is automagically converted
884  // to an Address.
885  //
886  NS_LOG_LOGIC ("multicast address is " << ad);
887 
888  return ad;
889 }
890 
891 bool
893 {
895  return false;
896 }
897 
898 bool
900 {
902  return false;
903 }
904 
905 bool
906 CsmaNetDevice::Send (Ptr<Packet> packet,const Address& dest, uint16_t protocolNumber)
907 {
908  NS_LOG_FUNCTION (packet << dest << protocolNumber);
909  return SendFrom (packet, m_address, dest, protocolNumber);
910 }
911 
912 bool
913 CsmaNetDevice::SendFrom (Ptr<Packet> packet, const Address& src, const Address& dest, uint16_t protocolNumber)
914 {
915  NS_LOG_FUNCTION (packet << src << dest << protocolNumber);
916  NS_LOG_LOGIC ("packet =" << packet);
917  NS_LOG_LOGIC ("UID is " << packet->GetUid () << ")");
918 
919  NS_ASSERT (IsLinkUp ());
920 
921  //
922  // Only transmit if send side of net device is enabled
923  //
924  if (IsSendEnabled () == false)
925  {
926  m_macTxDropTrace (packet);
927  return false;
928  }
929 
930  Mac48Address destination = Mac48Address::ConvertFrom (dest);
932  AddHeader (packet, source, destination, protocolNumber);
933 
934  m_macTxTrace (packet);
935 
936  //
937  // Place the packet to be sent on the send queue. Note that the
938  // queue may fire a drop trace, but we will too.
939  //
940  if (m_queue->Enqueue (packet) == false)
941  {
942  m_macTxDropTrace (packet);
943  return false;
944  }
945 
946  //
947  // If the device is idle, we need to start a transmission. Otherwise,
948  // the transmission will be started when the current packet finished
949  // transmission (see TransmitCompleteEvent)
950  //
951  if (m_txMachineState == READY)
952  {
953  if (m_queue->IsEmpty () == false)
954  {
955  m_currentPkt = m_queue->Dequeue ();
956  NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::SendFrom(): IsEmpty false but no Packet on queue?");
959  TransmitStart ();
960  }
961  }
962  return true;
963 }
964 
965 Ptr<Node>
967 {
969  return m_node;
970 }
971 
972 void
974 {
975  NS_LOG_FUNCTION (node);
976 
977  m_node = node;
978 }
979 
980 bool
982 {
984  return true;
985 }
986 
987 void
989 {
990  NS_LOG_FUNCTION (&cb);
991  m_rxCallback = cb;
992 }
993 
995 {
997 
998  NS_LOG_LOGIC ("MAC IPv6 multicast address is " << ad);
999  return ad;
1000 }
1001 
1002 void
1004 {
1005  NS_LOG_FUNCTION (&cb);
1006  m_promiscRxCallback = cb;
1007 }
1008 
1009 bool
1011 {
1013  return true;
1014 }
1015 
1016 int64_t
1018 {
1019  return m_backoff.AssignStreams (stream);
1020 }
1021 
1022 } // 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:79
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.
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)
Definition: enum.cc:178
void SetReceiveEnable(bool enable)
Enable or disable the receive side of the network device.
Hold a bool native type.
Definition: boolean.h:38
Packet addressed to someone else.
Definition: net-device.h:282
void SetEncapsulationMode(CsmaNetDevice::EncapsulationMode mode)
Set the encapsulation mode of this device.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register the class in the ns-3 factory.
Definition: object-base.h:38
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.
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:393
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:1018
#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
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:170
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:744
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)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Definition: object.cc:335
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:223
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:95
#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:825
void SetSource(Mac48Address source)
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:86
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
Definition: nstime.h:272
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.
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:37
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:46
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:233
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.
Packet trailer for Ethernet.
hold objects of type Ptr
Definition: pointer.h:33
void EnableFcs(bool enable)
Enable or disable FCS checking and calculations.
bool IsGroup(void) const
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
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:41
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
Ptr< const AttributeAccessor > MakeEnumAccessor(T1 a1)
Definition: enum.h:118
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.
Describes an IPv6 address.
Definition: ipv6-address.h:46
Mac48Address GetDestination(void) const
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
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)
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...
Packet addressed oo us.
Definition: net-device.h:276
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:203
hold objects of type ns3::Mac48Address
void SetSendEnable(bool enable)
Enable or disable the send side of the network device.
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.
PacketType
Packet types are used as they are in Linux.
Definition: net-device.h:274
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.
Packet addressed to multicast group.
Definition: net-device.h:280
virtual bool IsMulticast(void) const
virtual Address GetMulticast(Ipv4Address multicastGroup) const
Make and return a MAC multicast address using the provided multicast group.
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:49
virtual bool IsBroadcast(void) const
Time m_slotTime
Length of one slot.
Definition: backoff.h:62
TypeId SetParent(TypeId tid)
Definition: type-id.cc:610
Packet addressed to all.
Definition: net-device.h:278
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