A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
csma-net-device.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2007 Emmanuelle Laprise
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
7 */
8
9#include "csma-net-device.h"
10
11#include "csma-channel.h"
12
13#include "ns3/boolean.h"
14#include "ns3/enum.h"
15#include "ns3/error-model.h"
16#include "ns3/ethernet-header.h"
17#include "ns3/ethernet-trailer.h"
18#include "ns3/llc-snap-header.h"
19#include "ns3/log.h"
20#include "ns3/pointer.h"
21#include "ns3/queue.h"
22#include "ns3/simulator.h"
23#include "ns3/trace-source-accessor.h"
24#include "ns3/uinteger.h"
25
26namespace ns3
27{
28
29NS_LOG_COMPONENT_DEFINE("CsmaNetDevice");
30
32
35{
36 static TypeId tid =
37 TypeId("ns3::CsmaNetDevice")
39 .SetGroupName("Csma")
40 .AddConstructor<CsmaNetDevice>()
41 .AddAttribute("Address",
42 "The MAC address of this device.",
43 Mac48AddressValue(Mac48Address("ff:ff:ff:ff:ff:ff")),
46 .AddAttribute("Mtu",
47 "The MAC-level Maximum Transmission Unit",
51 .AddAttribute("EncapsulationMode",
52 "The link-layer encapsulation type to use.",
55 MakeEnumChecker(DIX, "Dix", LLC, "Llc"))
56 .AddAttribute("SendEnable",
57 "Enable or disable the transmitter section of the device.",
58 BooleanValue(true),
61 .AddAttribute("ReceiveEnable",
62 "Enable or disable the receiver section of the device.",
63 BooleanValue(true),
66 .AddAttribute("ReceiveErrorModel",
67 "The receiver error model used to simulate packet loss",
71
72 //
73 // Transmit queueing discipline for the device which includes its own set
74 // of trace hooks.
75 //
76 .AddAttribute("TxQueue",
77 "A queue to use as the transmit queue in the device.",
81
82 //
83 // Trace sources at the "top" of the net device, where packets transition
84 // to/from higher layers.
85 //
86 .AddTraceSource("MacTx",
87 "Trace source indicating a packet has "
88 "arrived for transmission by this device",
90 "ns3::Packet::TracedCallback")
91 .AddTraceSource("MacTxDrop",
92 "Trace source indicating a packet has been "
93 "dropped by the device before transmission",
95 "ns3::Packet::TracedCallback")
96 .AddTraceSource("MacPromiscRx",
97 "A packet has been received by this device, "
98 "has been passed up from the physical layer "
99 "and is being forwarded up the local protocol stack. "
100 "This is a promiscuous trace, and it is only fired "
101 "when a promiscuous receive callback has been "
102 "installed via SetPromiscReceiveCallback.",
104 "ns3::Packet::TracedCallback")
105 .AddTraceSource("MacRx",
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 non-promiscuous trace,",
111 "ns3::Packet::TracedCallback")
112#if 0
113 // Not currently implemented in this device
114 .AddTraceSource ("MacRxDrop",
115 "Trace source indicating a packet was received, "
116 "but dropped before being forwarded up the stack",
118 "ns3::Packet::TracedCallback")
119#endif
120 .AddTraceSource("MacTxBackoff",
121 "Trace source indicating a packet has been "
122 "delayed by the CSMA backoff process",
124 "ns3::Packet::TracedCallback")
125 //
126 // Trace sources at the "bottom" of the net device, where packets transition
127 // to/from the channel.
128 //
129 .AddTraceSource("PhyTxBegin",
130 "Trace source indicating a packet has "
131 "begun transmitting over the channel",
133 "ns3::Packet::TracedCallback")
134 .AddTraceSource("PhyTxEnd",
135 "Trace source indicating a packet has been "
136 "completely transmitted over the channel",
138 "ns3::Packet::TracedCallback")
139 .AddTraceSource("PhyTxDrop",
140 "Trace source indicating a packet has been "
141 "dropped by the device during transmission",
143 "ns3::Packet::TracedCallback")
144#if 0
145 // Not currently implemented in this device
146 .AddTraceSource ("PhyRxBegin",
147 "Trace source indicating a packet has "
148 "begun being received by the device",
150 "ns3::Packet::TracedCallback")
151#endif
152 .AddTraceSource("PhyRxEnd",
153 "Trace source indicating a packet has been "
154 "completely received by the device",
156 "ns3::Packet::TracedCallback")
157 .AddTraceSource("PhyRxDrop",
158 "Trace source indicating a packet has been "
159 "dropped by the device during reception",
161 "ns3::Packet::TracedCallback")
162 //
163 // Trace sources designed to simulate a packet sniffer facility (tcpdump).
164 //
165 .AddTraceSource("Sniffer",
166 "Trace source simulating a non-promiscuous "
167 "packet sniffer attached to the device",
169 "ns3::Packet::TracedCallback")
170 .AddTraceSource("PromiscSniffer",
171 "Trace source simulating a promiscuous "
172 "packet sniffer attached to the device",
174 "ns3::Packet::TracedCallback");
175 return tid;
176}
177
179 : m_linkUp(false)
180{
181 NS_LOG_FUNCTION(this);
184 m_channel = nullptr;
185
186 //
187 // We would like to let the attribute system take care of initializing the
188 // packet encapsulation stuff, but we also don't want to get caught up in
189 // initialization order changes. So we'll get the three problem variables
190 // into a consistent state here before the attribute calls, and then depend
191 // on the semantics of the setters to preserve a consistent state. This
192 // really doesn't have to be the same set of values as the initial values
193 // set by the attributes, but it does have to be a consistent set. That is,
194 // you can just change the default encapsulation mode above without having
195 // to change it here.
196 //
198}
199
205
206void
208{
210 m_channel = nullptr;
211 m_node = nullptr;
212 m_queue = nullptr;
214}
215
216void
218{
219 NS_LOG_FUNCTION(mode);
220
221 m_encapMode = mode;
222
223 NS_LOG_LOGIC("m_encapMode = " << m_encapMode);
224 NS_LOG_LOGIC("m_mtu = " << m_mtu);
225}
226
233
234bool
236{
237 NS_LOG_FUNCTION(this << mtu);
238 m_mtu = mtu;
239
240 NS_LOG_LOGIC("m_encapMode = " << m_encapMode);
241 NS_LOG_LOGIC("m_mtu = " << m_mtu);
242
243 return true;
244}
245
246uint16_t
248{
250 return m_mtu;
251}
252
253void
255{
256 NS_LOG_FUNCTION(sendEnable);
257 m_sendEnable = sendEnable;
258}
259
260void
262{
263 NS_LOG_FUNCTION(receiveEnable);
264 m_receiveEnable = receiveEnable;
265}
266
267bool
273
274bool
280
281void
287
288void
290 uint32_t minSlots,
291 uint32_t maxSlots,
292 uint32_t ceiling,
293 uint32_t maxRetries)
294{
295 NS_LOG_FUNCTION(slotTime << minSlots << maxSlots << ceiling << maxRetries);
296 m_backoff.m_slotTime = slotTime;
297 m_backoff.m_minSlots = minSlots;
298 m_backoff.m_maxSlots = maxSlots;
299 m_backoff.m_ceiling = ceiling;
300 m_backoff.m_maxRetries = maxRetries;
301}
302
303void
305 Mac48Address source,
306 Mac48Address dest,
307 uint16_t protocolNumber)
308{
309 NS_LOG_FUNCTION(p << source << dest << protocolNumber);
310
311 EthernetHeader header(false);
312 header.SetSource(source);
313 header.SetDestination(dest);
314
315 EthernetTrailer trailer;
316
317 NS_LOG_LOGIC("p->GetSize () = " << p->GetSize());
318 NS_LOG_LOGIC("m_encapMode = " << m_encapMode);
319 NS_LOG_LOGIC("m_mtu = " << m_mtu);
320
321 uint16_t lengthType = 0;
322 switch (m_encapMode)
323 {
324 case DIX:
325 NS_LOG_LOGIC("Encapsulating packet as DIX (type interpretation)");
326 //
327 // This corresponds to the type interpretation of the lengthType field as
328 // in the old Ethernet Blue Book.
329 //
330 lengthType = protocolNumber;
331
332 //
333 // All Ethernet frames must carry a minimum payload of 46 bytes. We need
334 // to pad out if we don't have enough bytes. These must be real bytes
335 // since they will be written to pcap files and compared in regression
336 // 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 break;
346 case LLC: {
347 NS_LOG_LOGIC("Encapsulating packet as LLC (length interpretation)");
348
349 LlcSnapHeader llc;
350 llc.SetType(protocolNumber);
351 p->AddHeader(llc);
352
353 //
354 // This corresponds to the length interpretation of the lengthType
355 // field but with an LLC/SNAP header added to the payload as in
356 // IEEE 802.2
357 //
358 lengthType = p->GetSize();
359
360 //
361 // All Ethernet frames must carry a minimum payload of 46 bytes. The
362 // LLC SNAP header counts as part of this payload. We need to pad out
363 // if we don't have enough bytes. These must be real bytes since they
364 // will be written to pcap files and compared in regression trace files.
365 //
366 if (p->GetSize() < 46)
367 {
368 uint8_t buffer[46];
369 memset(buffer, 0, 46);
370 Ptr<Packet> padd = Create<Packet>(buffer, 46 - p->GetSize());
371 p->AddAtEnd(padd);
372 }
373
374 NS_ASSERT_MSG(p->GetSize() <= GetMtu(),
375 "CsmaNetDevice::AddHeader(): 802.3 Length/Type field with LLC/SNAP: "
376 "length interpretation must not exceed device frame size minus overhead");
377 }
378 break;
379 case ILLEGAL:
380 default:
381 NS_FATAL_ERROR("CsmaNetDevice::AddHeader(): Unknown packet encapsulation mode");
382 break;
383 }
384
385 NS_LOG_LOGIC("header.SetLengthType (" << lengthType << ")");
386 header.SetLengthType(lengthType);
387 p->AddHeader(header);
388
390 {
391 trailer.EnableFcs(true);
392 }
393 trailer.CalcFcs(p);
394 p->AddTrailer(trailer);
395}
396
397#if 0
398bool
399CsmaNetDevice::ProcessHeader (Ptr<Packet> p, uint16_t & param)
400{
401 NS_LOG_FUNCTION (p << param);
402
403 EthernetTrailer trailer;
404 p->RemoveTrailer (trailer);
405
406 EthernetHeader header (false);
407 p->RemoveHeader (header);
408
409 if ((header.GetDestination () != GetBroadcast ()) &&
410 (header.GetDestination () != GetAddress ()))
411 {
412 return false;
413 }
414
415 switch (m_encapMode)
416 {
417 case DIX:
418 param = header.GetLengthType ();
419 break;
420 case LLC:
421 {
422 LlcSnapHeader llc;
423 p->RemoveHeader (llc);
424 param = llc.GetType ();
425 }
426 break;
427 case ILLEGAL:
428 default:
429 NS_FATAL_ERROR ("CsmaNetDevice::ProcessHeader(): Unknown packet encapsulation mode");
430 break;
431 }
432 return true;
433}
434#endif
435
436void
438{
440
441 //
442 // This function is called to start the process of transmitting a packet. We
443 // expect that the packet to transmit will be found in m_currentPkt.
444 //
445 NS_ASSERT_MSG(m_currentPkt, "CsmaNetDevice::TransmitStart(): m_currentPkt not set");
446
447 NS_LOG_LOGIC("m_currentPkt = " << m_currentPkt);
448 NS_LOG_LOGIC("UID = " << m_currentPkt->GetUid());
449
450 //
451 // Only transmit if the send side of net device is enabled
452 //
453 if (!IsSendEnabled())
454 {
456 m_currentPkt = nullptr;
457 return;
458 }
459
460 //
461 // Somebody has called here telling us to start transmitting a packet. They
462 // can only do this if the state machine is in the READY or BACKOFF state.
463 // Specifically, if we are ready to start transmitting, we cannot already
464 // be transmitting (i.e., BUSY)
465 //
467 "Must be READY to transmit. Tx state is: " << m_txMachineState);
468
469 //
470 // Now we have to sense the state of the medium and either start transmitting
471 // if it is idle, or backoff our transmission if someone else is on the wire.
472 //
473 if (m_channel->GetState() != IDLE)
474 {
475 //
476 // The channel is busy -- backoff and rechedule TransmitStart() unless
477 // we have exhausted all of our retries.
478 //
480
481 if (m_backoff.MaxRetriesReached())
482 {
483 //
484 // Too many retries, abort transmission of packet
485 //
487 }
488 else
489 {
491
492 m_backoff.IncrNumRetries();
493 Time backoffTime = m_backoff.GetBackoffTime();
494
495 NS_LOG_LOGIC("Channel busy, backing off for " << backoffTime.As(Time::S));
496
498 }
499 }
500 else
501 {
502 //
503 // The channel is free, transmit the packet
504 //
506 if (!m_channel->TransmitStart(m_currentPkt, m_deviceId))
507 {
508 NS_LOG_WARN("Channel TransmitStart returns an error");
510 m_currentPkt = nullptr;
512 }
513 else
514 {
515 //
516 // Transmission succeeded, reset the backoff time parameters and
517 // schedule a transmit complete event.
518 //
519 m_backoff.ResetBackoffTime();
521
522 Time tEvent = m_bps.CalculateBytesTxTime(m_currentPkt->GetSize());
523 NS_LOG_LOGIC("Schedule TransmitCompleteEvent in " << tEvent.As(Time::S));
525 }
526 }
527}
528
529void
531{
533
534 //
535 // When we started the process of transmitting the current packet, it was
536 // placed in m_currentPkt. So we had better find one there.
537 //
538 NS_ASSERT_MSG(m_currentPkt, "CsmaNetDevice::TransmitAbort(): m_currentPkt zero");
539 NS_LOG_LOGIC("m_currentPkt=" << m_currentPkt);
540 NS_LOG_LOGIC("Pkt UID is " << m_currentPkt->GetUid() << ")");
541
543 m_currentPkt = nullptr;
544
546 "Must be in BACKOFF state to abort. Tx state is: " << m_txMachineState);
547
548 //
549 // We're done with that one, so reset the backoff algorithm and ready the
550 // transmit state machine.
551 //
552 m_backoff.ResetBackoffTime();
554
555 //
556 // If there is another packet on the input queue, we need to start trying to
557 // get that out. If the queue is empty we just wait until someone puts one
558 // in.
559 //
560 if (m_queue->IsEmpty())
561 {
562 return;
563 }
564 else
565 {
566 Ptr<Packet> packet = m_queue->Dequeue();
567 NS_ASSERT_MSG(packet,
568 "CsmaNetDevice::TransmitAbort(): IsEmpty false but no Packet on queue?");
569 m_currentPkt = packet;
573 }
574}
575
576void
578{
580
581 //
582 // This function is called to finish the process of transmitting a packet.
583 // We need to tell the channel that we've stopped wiggling the wire and
584 // schedule an event that will be executed when it's time to re-enable
585 // the transmitter after the interframe gap.
586 //
588 "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, "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 = nullptr;
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 //
620 "CsmaNetDevice::TransmitReadyEvent(): Must be in interframe gap");
622
623 //
624 // We expect that the packet we had been transmitting was cleared when the
625 // TransmitCompleteEvent() was executed.
626 //
627 NS_ASSERT_MSG(!m_currentPkt, "CsmaNetDevice::TransmitReadyEvent(): m_currentPkt nonzero");
628
629 //
630 // Get the next packet from the queue for transmitting
631 //
632 if (m_queue->IsEmpty())
633 {
634 return;
635 }
636 else
637 {
638 Ptr<Packet> packet = m_queue->Dequeue();
639 NS_ASSERT_MSG(packet,
640 "CsmaNetDevice::TransmitReadyEvent(): IsEmpty false but no Packet on queue?");
641 m_currentPkt = packet;
645 }
646}
647
648bool
650{
651 NS_LOG_FUNCTION(this << &ch);
652
653 m_channel = ch;
654
655 m_deviceId = m_channel->Attach(this);
656
657 //
658 // The channel provides us with the transmitter data rate.
659 //
660 m_bps = m_channel->GetDataRate();
661
662 //
663 // We use the Ethernet interframe gap of 96 bit times.
664 //
665 m_tInterframeGap = m_bps.CalculateBytesTxTime(96 / 8);
666
667 //
668 // This device is up whenever a channel is attached to it.
669 //
670 NotifyLinkUp();
671 return true;
672}
673
674void
680
681void
687
688void
690{
691 NS_LOG_FUNCTION(packet << senderDevice);
692 NS_LOG_LOGIC("UID is " << packet->GetUid());
693
694 //
695 // We never forward up packets that we sent. Real devices don't do this since
696 // their receivers are disabled during send, so we don't.
697 //
698 if (senderDevice == this)
699 {
700 return;
701 }
702
703 //
704 // Hit the trace hook. This trace will fire on all packets received from the
705 // channel except those originated by this device.
706 //
707 m_phyRxEndTrace(packet);
708
709 //
710 // Only receive if the send side of net device is enabled
711 //
712 if (!IsReceiveEnabled())
713 {
714 m_phyRxDropTrace(packet);
715 return;
716 }
717
718 Ptr<Packet> pktCopy = packet->Copy();
719
720 if (m_receiveErrorModel && m_receiveErrorModel->IsCorrupt(pktCopy))
721 {
722 NS_LOG_LOGIC("Dropping pkt due to error model ");
723 m_phyRxDropTrace(packet);
724 return;
725 }
726
727 //
728 // Trace sinks will expect complete packets, not packets without some of the
729 // headers.
730 //
731
732 EthernetTrailer trailer;
733 pktCopy->RemoveTrailer(trailer);
735 {
736 trailer.EnableFcs(true);
737 }
738
739 bool crcGood = trailer.CheckFcs(pktCopy);
740 if (!crcGood)
741 {
742 NS_LOG_INFO("CRC error on Packet " << packet);
743 m_phyRxDropTrace(packet);
744 return;
745 }
746
747 EthernetHeader header(false);
748 pktCopy->RemoveHeader(header);
749
750 NS_LOG_LOGIC("Pkt source is " << header.GetSource());
751 NS_LOG_LOGIC("Pkt destination is " << header.GetDestination());
752
753 uint16_t protocol;
754 //
755 // If the length/type is less than 1500, it corresponds to a length
756 // interpretation packet. In this case, it is an 802.3 packet and
757 // will also have an 802.2 LLC header. If greater than 1500, we
758 // find the protocol number (Ethernet type) directly.
759 //
760 if (header.GetLengthType() <= 1500)
761 {
762 NS_ASSERT(pktCopy->GetSize() >= header.GetLengthType());
763 uint32_t padlen = pktCopy->GetSize() - header.GetLengthType();
764 NS_ASSERT(padlen <= 46);
765 if (padlen > 0)
766 {
767 pktCopy->RemoveAtEnd(padlen);
768 }
769
770 LlcSnapHeader llc;
771 pktCopy->RemoveHeader(llc);
772 protocol = llc.GetType();
773 }
774 else
775 {
776 protocol = header.GetLengthType();
777 }
778
779 //
780 // Classify the packet based on its destination.
781 //
782 PacketType packetType;
783
784 if (header.GetDestination().IsBroadcast())
785 {
786 packetType = PACKET_BROADCAST;
787 }
788 else if (header.GetDestination().IsGroup())
789 {
790 packetType = PACKET_MULTICAST;
791 }
792 else if (header.GetDestination() == m_address)
793 {
794 packetType = PACKET_HOST;
795 }
796 else
797 {
798 packetType = PACKET_OTHERHOST;
799 }
800
801 //
802 // For all kinds of packetType we receive, we hit the promiscuous sniffer
803 // hook and pass a copy up to the promiscuous callback. Pass a copy to
804 // make sure that nobody messes with our packet.
805 //
806 m_promiscSnifferTrace(packet);
807 if (!m_promiscRxCallback.IsNull())
808 {
809 m_macPromiscRxTrace(packet);
811 pktCopy,
812 protocol,
813 header.GetSource(),
814 header.GetDestination(),
815 packetType);
816 }
817
818 //
819 // If this packet is not destined for some other host, it must be for us
820 // as either a broadcast, multicast or unicast. We need to hit the mac
821 // packet received trace hook and forward the packet up the stack.
822 //
823 if (packetType != PACKET_OTHERHOST)
824 {
825 m_snifferTrace(packet);
826 m_macRxTrace(packet);
827 m_rxCallback(this, pktCopy, protocol, header.GetSource());
828 }
829}
830
833{
835 return m_queue;
836}
837
838void
845
846void
848{
849 NS_LOG_FUNCTION(index);
850 m_ifIndex = index;
851}
852
855{
857 return m_ifIndex;
858}
859
862{
864 return m_channel;
865}
866
867void
873
876{
878 return m_address;
879}
880
881bool
883{
885 return m_linkUp;
886}
887
888void
890{
891 NS_LOG_FUNCTION(&callback);
892 m_linkChangeCallbacks.ConnectWithoutContext(callback);
893}
894
895bool
897{
899 return true;
900}
901
908
909bool
911{
913 return true;
914}
915
918{
919 NS_LOG_FUNCTION(multicastGroup);
920
921 Mac48Address ad = Mac48Address::GetMulticast(multicastGroup);
922
923 //
924 // Implicit conversion (operator Address ()) is defined for Mac48Address, so
925 // use it by just returning the EUI-48 address which is automagically converted
926 // to an Address.
927 //
928 NS_LOG_LOGIC("multicast address is " << ad);
929
930 return ad;
931}
932
933bool
935{
937 return false;
938}
939
940bool
942{
944 return false;
945}
946
947bool
948CsmaNetDevice::Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
949{
950 NS_LOG_FUNCTION(packet << dest << protocolNumber);
951 return SendFrom(packet, m_address, dest, protocolNumber);
952}
953
954bool
956 const Address& src,
957 const Address& dest,
958 uint16_t protocolNumber)
959{
960 NS_LOG_FUNCTION(packet << src << dest << protocolNumber);
961 NS_LOG_LOGIC("packet =" << packet);
962 NS_LOG_LOGIC("UID is " << packet->GetUid() << ")");
963
965
966 //
967 // Only transmit if send side of net device is enabled
968 //
969 if (!IsSendEnabled())
970 {
971 m_macTxDropTrace(packet);
972 return false;
973 }
974
975 Mac48Address destination = Mac48Address::ConvertFrom(dest);
977 AddHeader(packet, source, destination, protocolNumber);
978
979 m_macTxTrace(packet);
980
981 //
982 // Place the packet to be sent on the send queue. Note that the
983 // queue may fire a drop trace, but we will too.
984 //
985 if (!m_queue->Enqueue(packet))
986 {
987 m_macTxDropTrace(packet);
988 return false;
989 }
990
991 //
992 // If the device is idle, we need to start a transmission. Otherwise,
993 // the transmission will be started when the current packet finished
994 // transmission (see TransmitCompleteEvent)
995 //
996 if (m_txMachineState == READY)
997 {
998 if (!m_queue->IsEmpty())
999 {
1000 Ptr<Packet> packet = m_queue->Dequeue();
1001 NS_ASSERT_MSG(packet,
1002 "CsmaNetDevice::SendFrom(): IsEmpty false but no Packet on queue?");
1003 m_currentPkt = packet;
1006 TransmitStart();
1007 }
1008 }
1009 return true;
1010}
1011
1014{
1016 return m_node;
1017}
1018
1019void
1021{
1022 NS_LOG_FUNCTION(node);
1023
1024 m_node = node;
1025}
1026
1027bool
1029{
1031 return true;
1032}
1033
1034void
1040
1041Address
1043{
1045
1046 NS_LOG_LOGIC("MAC IPv6 multicast address is " << ad);
1047 return ad;
1048}
1049
1050void
1056
1057bool
1059{
1061 return true;
1062}
1063
1064int64_t
1066{
1067 return m_backoff.AssignStreams(stream);
1068}
1069
1070} // namespace ns3
uint32_t q
a polymophic address class
Definition address.h:114
AttributeValue implementation for Boolean.
Definition boolean.h:26
Callback template class.
Definition callback.h:428
A Device for a Csma Network Link.
void SetInterframeGap(Time t)
Set the interframe gap used to separate packets.
Ptr< Queue< Packet > > GetQueue() const
Get a copy of the attached Queue.
TracedCallback< Ptr< const Packet > > m_macRxDropTrace
The trace source fired for packets successfully received by the device but dropped before being forwa...
Ptr< Node > GetNode() const override
Get the node to which this device is attached.
EncapsulationMode
Enumeration of the types of packets supported in the class.
@ ILLEGAL
Encapsulation mode not set.
@ DIX
DIX II / Ethernet II packet.
@ LLC
802.2 LLC/SNAP Packet
NetDevice::ReceiveCallback m_rxCallback
The callback used to notify higher layers that a packet has been received.
TracedCallback< Ptr< const Packet > > m_macTxBackoffTrace
The trace source fired when the mac layer is forced to begin the backoff process for a packet.
void SetReceiveEnable(bool enable)
Enable or disable the receive side of the network device.
Backoff m_backoff
Holds the backoff parameters and is used to calculate the next backoff time to use when the channel i...
DataRate m_bps
The data rate that the Net Device uses to simulate packet transmission timing.
void DoDispose() override
Perform any object release functionality required to break reference cycles in reference counted obje...
~CsmaNetDevice() override
Destroy a CsmaNetDevice.
bool SetMtu(const uint16_t mtu) override
void TransmitAbort()
Aborts the transmission of the current packet.
EncapsulationMode m_encapMode
The type of packet that should be created by the AddHeader function and that should be processed by t...
bool NeedsArp() const override
Does this device need to use the address resolution protocol?
TracedCallback< Ptr< const Packet > > m_macRxTrace
The trace source fired for packets successfully received by the device immediately before being forwa...
void TransmitStart()
Start Sending a Packet Down the Wire.
void SetIfIndex(const uint32_t index) override
@ BACKOFF
The transmitter is waiting for the channel to be free.
@ READY
The transmitter is ready to begin transmission of a packet.
@ BUSY
The transmitter is busy transmitting a packet.
@ GAP
The transmitter is in the interframe gap time.
Ptr< Queue< Packet > > m_queue
The Queue which this CsmaNetDevice uses as a packet source.
TracedCallback< Ptr< const Packet > > m_macPromiscRxTrace
The trace source fired for packets successfully received by the device immediately before being forwa...
uint32_t m_mtu
The Maximum Transmission Unit.
bool SupportsSendFrom() const override
NetDevice::PromiscReceiveCallback m_promiscRxCallback
The callback used to notify higher layers that a packet has been received in promiscuous mode.
CsmaNetDevice()
Construct a CsmaNetDevice.
void SetPromiscReceiveCallback(PromiscReceiveCallback cb) override
Address GetBroadcast() const override
static TypeId GetTypeId()
Get the type ID.
bool IsPointToPoint() const override
Is this a point to point link?
Ptr< CsmaChannel > m_channel
The CsmaChannel to which this CsmaNetDevice has been attached.
bool Attach(Ptr< CsmaChannel > ch)
Attach the device to a channel.
bool IsBridge() const override
Is this a bridge?
void TransmitCompleteEvent()
Stop Sending a Packet Down the Wire and Begin the Interframe Gap.
bool SendFrom(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber) override
Start sending a packet down the channel, with MAC spoofing.
void Receive(Ptr< const Packet > p, Ptr< CsmaNetDevice > sender)
Receive a packet from a connected CsmaChannel.
bool IsMulticast() const override
TracedCallback m_linkChangeCallbacks
List of callbacks to fire if the link changes state (up or down).
TracedCallback< Ptr< const Packet > > m_phyTxBeginTrace
The trace source fired when a packet begins the transmission process on the medium.
CsmaNetDevice::EncapsulationMode GetEncapsulationMode()
Get the encapsulation mode of this device.
void AddHeader(Ptr< Packet > p, Mac48Address source, Mac48Address dest, uint16_t protocolNumber)
Adds the necessary headers and trailers to a packet of data in order to respect the packet type.
uint16_t GetMtu() const override
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
Ptr< Channel > GetChannel() const override
void NotifyLinkUp()
Notify any interested parties that the link has come up.
void SetBackoffParams(Time slotTime, uint32_t minSlots, uint32_t maxSlots, uint32_t maxRetries, uint32_t ceiling)
Set the backoff parameters used to determine the wait to retry transmitting a packet when the channel...
Ptr< Packet > m_currentPkt
Next packet that will be transmitted (if transmitter is not currently transmitting) or packet that is...
TracedCallback< Ptr< const Packet > > m_snifferTrace
A trace source that emulates a non-promiscuous protocol sniffer connected to the device.
TracedCallback< Ptr< const Packet > > m_phyTxEndTrace
The trace source fired when a packet ends the transmission process on the medium.
uint32_t m_deviceId
Device ID returned by the attached functions.
bool m_receiveEnable
Enable net device to receive packets.
TracedCallback< Ptr< const Packet > > m_phyRxDropTrace
The trace source fired when the phy layer drops a packet it has received.
Address GetMulticast(Ipv4Address multicastGroup) const override
Make and return a MAC multicast address using the provided multicast group.
Ptr< Node > m_node
The Node to which this device is attached.
void SetReceiveErrorModel(Ptr< ErrorModel > em)
Attach a receive ErrorModel to the CsmaNetDevice.
void SetSendEnable(bool enable)
Enable or disable the send side of the network device.
bool IsLinkUp() const override
void TransmitReadyEvent()
Cause the Transmitter to Become Ready to Send Another Packet.
TracedCallback< Ptr< const Packet > > m_promiscSnifferTrace
A trace source that emulates a promiscuous mode protocol sniffer connected to the device.
uint32_t GetIfIndex() const override
bool IsBroadcast() const override
static const uint16_t DEFAULT_MTU
Default Maximum Transmission Unit (MTU) for the CsmaNetDevice.
void SetEncapsulationMode(CsmaNetDevice::EncapsulationMode mode)
Set the encapsulation mode of this device.
TracedCallback< Ptr< const Packet > > m_phyRxBeginTrace
The trace source fired when a packet begins the reception process from the medium.
bool m_sendEnable
Enable net device to send packets.
TracedCallback< Ptr< const Packet > > m_macTxDropTrace
The trace source fired when packets coming into the "top" of the device at the L3/L2 transition are d...
bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber) override
Start sending a packet down the channel.
bool IsSendEnabled() const
Is the send side of the network device enabled?
TracedCallback< Ptr< const Packet > > m_macTxTrace
The trace source fired when packets come into the "top" of the device at the L3/L2 transition,...
void SetReceiveCallback(NetDevice::ReceiveCallback cb) override
Set the callback to be used to notify higher layers when a packet has been received.
TracedCallback< Ptr< const Packet > > m_phyTxDropTrace
The trace source fired when the phy layer drops a packet as it tries to transmit it.
Address GetAddress() const override
void AddLinkChangeCallback(Callback< void > callback) override
void SetNode(Ptr< Node > node) override
Set the node to which this device is being attached.
void SetAddress(Address address) override
Set the address of this interface.
Mac48Address m_address
The MAC address which has been assigned to this device.
Time m_tInterframeGap
The interframe gap that the Net Device uses insert time between packet transmission.
void SetQueue(Ptr< Queue< Packet > > queue)
Attach a queue to the CsmaNetDevice.
Ptr< ErrorModel > m_receiveErrorModel
Error model for receive packet events.
TxMachineState m_txMachineState
The state of the Net Device transmit state machine.
uint32_t m_ifIndex
The interface index (really net evice index) that has been assigned to this network device.
bool IsReceiveEnabled() const
Is the receive side of the network device enabled?
bool m_linkUp
Flag indicating whether or not the link is up.
TracedCallback< Ptr< const Packet > > m_phyRxEndTrace
The trace source fired when a packet ends the reception process from the medium.
Hold variables of type enum.
Definition enum.h:52
Packet header for Ethernet.
uint16_t GetLengthType() const
void SetDestination(Mac48Address destination)
Mac48Address GetDestination() const
void SetLengthType(uint16_t size)
void SetSource(Mac48Address source)
Mac48Address GetSource() const
Packet trailer for Ethernet.
bool CheckFcs(Ptr< const Packet > p) const
Calculate an FCS on the provided packet and check this value against the FCS found when the trailer w...
void EnableFcs(bool enable)
Enable or disable FCS checking and calculations.
void CalcFcs(Ptr< const Packet > p)
Updates the Fcs Field to the correct FCS.
Ipv4 addresses are stored in host order in this class.
Describes an IPv6 address.
Header for the LLC/SNAP encapsulation.
uint16_t GetType()
Return the Ethertype.
void SetType(uint16_t type)
Set the Ethertype.
an EUI-48 address
static Mac48Address GetMulticast(Ipv4Address address)
bool IsGroup() const
static Mac48Address ConvertFrom(const Address &address)
static Mac48Address GetBroadcast()
bool IsBroadcast() const
AttributeValue implementation for Mac48Address.
Network layer to device interface.
Definition net-device.h:87
Callback< bool, Ptr< NetDevice >, Ptr< const Packet >, uint16_t, const Address &, const Address &, PacketType > PromiscReceiveCallback
Definition net-device.h:341
PacketType
Packet types are used as they are in Linux.
Definition net-device.h:289
@ PACKET_HOST
Packet addressed to us.
Definition net-device.h:290
@ PACKET_OTHERHOST
Packet addressed to someone else.
Definition net-device.h:296
@ PACKET_BROADCAST
Packet addressed to all.
Definition net-device.h:292
@ PACKET_MULTICAST
Packet addressed to multicast group.
Definition net-device.h:294
Callback< bool, Ptr< NetDevice >, Ptr< const Packet >, uint16_t, const Address & > ReceiveCallback
Definition net-device.h:311
static bool ChecksumEnabled()
Definition node.cc:267
virtual void DoDispose()
Destructor implementation.
Definition object.cc:430
AttributeValue implementation for Pointer.
Definition pointer.h:37
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:70
Template class for packet Queues.
Definition queue.h:257
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:580
Simulation virtual time values and global simulation resolution.
Definition nstime.h:95
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition time.cc:408
@ S
second
Definition nstime.h:106
a unique identifier for an interface.
Definition type-id.h:50
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:999
Hold an unsigned integer type.
Definition uinteger.h:34
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#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:75
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition boolean.cc:113
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition boolean.h:70
Ptr< const AttributeAccessor > MakeEnumAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition enum.h:223
Ptr< const AttributeAccessor > MakeMac48AddressAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Ptr< const AttributeChecker > MakeMac48AddressChecker()
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition pointer.h:250
Ptr< AttributeChecker > MakePointerChecker()
Create a PointerChecker for a type.
Definition pointer.h:273
Ptr< const AttributeChecker > MakeUintegerChecker()
Definition uinteger.h:85
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition uinteger.h:35
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:194
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:274
#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:253
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:267
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:454
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1273
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeEnumChecker(T v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.
Definition enum.h:181
@ TRANSMITTING
Channel is BUSY, a packet is being written by a net device.
@ IDLE
Channel is IDLE, no packet is being transmitted.