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