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