1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
3 * Copyright (c) 2007 Emmanuelle Laprise
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;
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.
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
18 * Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca
21 #ifndef CSMA_NET_DEVICE_H
22 #define CSMA_NET_DEVICE_H
26 #include "ns3/backoff.h"
27 #include "ns3/address.h"
28 #include "ns3/net-device.h"
29 #include "ns3/callback.h"
30 #include "ns3/packet.h"
31 #include "ns3/traced-callback.h"
32 #include "ns3/nstime.h"
33 #include "ns3/data-rate.h"
35 #include "ns3/random-variable.h"
36 #include "ns3/mac48-address.h"
45 * \class CsmaNetDevice
46 * \brief A Device for a Csma Network Link.
48 * The Csma net device class is analogous to layer 1 and 2 of the
49 * TCP stack. The NetDevice takes a raw packet of bytes and creates a
50 * protocol specific packet from them.
52 * Each Csma net device will receive all packets written to the Csma link.
53 * The ProcessHeader function can be used to filter out the packets such that
54 * higher level layers only receive packets that are addressed to their
55 * associated net devices
57 class CsmaNetDevice : public NetDevice
60 static TypeId GetTypeId (void);
63 * Enumeration of the types of packets supported in the class.
66 enum EncapsulationMode {
67 ILLEGAL, /**< Encapsulation mode not set */
68 DIX, /**< DIX II / Ethernet II packet */
69 LLC, /**< 802.2 LLC/SNAP Packet*/
73 * Construct a CsmaNetDevice
75 * This is the default constructor for a CsmaNetDevice.
80 * Destroy a CsmaNetDevice
82 * This is the destructor for a CsmaNetDevice.
84 virtual ~CsmaNetDevice ();
87 * Set the inteframe gap used to separate packets. The interframe gap
88 * defines the minimum space required between packets sent by this device.
89 * As in Ethernet, it defaults to 96 bit times.
91 * \param t the interframe gap time
93 void SetInterframeGap (Time t);
96 * Set the backoff parameters used to determine the wait to retry
97 * transmitting a packet when the channel is busy.
100 * \param slotTime Length of a packet slot (or average packet time)
101 * \param minSlots Minimum number of slots to wait
102 * \param maxSlots Maximum number of slots to wait
103 * \param maxRetries Maximum number of retries before packet is discard
104 * \param ceiling Cap on the exponential function when calculating max slots
106 void SetBackoffParams (Time slotTime, uint32_t minSlots, uint32_t maxSlots,
107 uint32_t maxRetries, uint32_t ceiling);
110 * Attach the device to a channel.
112 * The function Attach is used to add a CsmaNetDevice to a CsmaChannel.
114 * \see SetDataRate ()
115 * \see SetInterframeGap ()
116 * \param ch a pointer to the channel to which this object is being attached.
118 bool Attach (Ptr<CsmaChannel> ch);
121 * Attach a queue to the CsmaNetDevice.
123 * The CsmaNetDevice "owns" a queue. This queue may be set by higher
124 * level topology objects to implement a particular queueing method such as
129 * \param queue a Ptr to the queue for being assigned to the device.
131 void SetQueue (Ptr<Queue> queue);
134 * Attach a receive ErrorModel to the CsmaNetDevice.
136 * The CsmaNetDevice may optionally include an ErrorModel in
137 * the packet receive chain to simulate data errors in during transmission.
140 * \param em a pointer to the ErrorModel
142 void SetReceiveErrorModel (Ptr<ErrorModel> em);
145 * Receive a packet from a connected CsmaChannel.
147 * The CsmaNetDevice receives packets from its connected channel
148 * and forwards them up the protocol stack. This is the public method
149 * used by the channel to indicate that the last bit of a packet has
150 * arrived at the device.
153 * \param p a reference to the received packet
154 * \param sender the CsmaNetDevice that transmitted the packet in the first place
156 void Receive (Ptr<Packet> p, Ptr<CsmaNetDevice> sender);
159 * Is the send side of the network device enabled?
161 * \returns True if the send side is enabled, otherwise false.
163 bool IsSendEnabled (void);
166 * Enable or disable the send side of the network device.
168 * \param enable Enable the send side if true, otherwise disable.
170 void SetSendEnable (bool enable);
173 * Is the receive side of the network device enabled?
175 * \returns True if the receiver side is enabled, otherwise false.
177 bool IsReceiveEnabled (void);
180 * Enable or disable the receive side of the network device.
182 * \param enable Enable the receive side if true, otherwise disable.
184 void SetReceiveEnable (bool enable);
187 * Set the MAC address of the the network device.
189 * \param addr The Mac48Address to use as the address of the device.
191 void SetAddress (Mac48Address addr);
194 * Set The max frame size of packets sent over this device.
196 * Okay, that was easy to say, but the details are a bit thorny. We have a MAC-level MTU that is the payload that higher
197 * level protocols see. We have a PHY-level MTU which is the maximum number of bytes we can send over the link
198 * (cf. 1500 bytes for Ethernet). We also have a frame size which is some total number of bytes in a packet which could
199 * or could not include any framing and overhead. There can be a lot of inconsistency in definitions of these terms. For
200 * example, RFC 1042 asserts that the terms maximum transmission unit and maximum packet size are equivalent. RFC 791,
201 * however, defines MTU as the maximum sized IP datagram that can be sent. Packet size and frame size are sometimes
202 * used interchangeably.
204 * So, some careful definitions are in order to avoid confusion:
206 * In real Ethernet, a packet on the wire starts with a preamble of seven bytes of alternating ones and zeroes followed by
207 * a Start-of-Frame-Delimeter (10101011). This is followed by what is usually called the packet: a MAC destination and
208 * source, a type field, payload, a possible padding field and a CRC. To be strictly and pedantically correct the frame
209 * size is necessarily larger than the packet size on a real Ethernet. But, this isn't a real Ethernet, it's a simulation
210 * of a device similar to Ethernet, and we have no good reason to add framing bits. So, in the case of the CSMA device,
211 * the frame size is equal to the packet size. Since these two values are equal, there is no danger in assuming they are
212 * identical. We do not implement any padding out to a minimum frame size, so padding is a non-issue. We define packet
213 * size to be equal to frame size and this excludes the preamble and SFD bytes of a real Ethernet frame. We define a
214 * single (MAC-level) MTU that coresponds to the payload size of the packet, which is the IP-centric view of the term as
217 * To make this concrete, consider DIX II (Digital Equipment, Intel, Xerox type II) framing, which is used in most TCP/IP
218 * stacks. NetWare and Wireshark call this framing Ethernet II, by the way. In this framing scheme, a real packet on the
219 * wire starts with the preamble and Start-of-Frame-Delimeter (10101011). We ignore these bits on this device since it they
220 * are not needed. In DIX II, the SFD is followed by the MAC (48) destination address (6 bytes), source address (6 bytes),
221 * the EtherType field (2 bytes), payload (0-1500 bytes) and a CRC (4 bytes) -- this corresponds to our entire frame. The
222 * payload of the packet/frame in DIX can be from 0 to 1500 bytes. It is the maxmimum value of this payload that we call
223 * the MTU. Typically, one sees the MTU set to 1500 bytes and the maximum frame size set to 1518 bytes in Ethernet-based
226 * Different framing schemes can make for different MTU and frame size relationships. For example, we support LLC/SNAP
227 * encapsulation which adds eight bytes of header overhead to the usual DIX framing. In this case, if the maximum frame
228 * size is left at 1518 bytes, we need to export an MTU that reflects the loss of eight bytes for a total of 1492.
230 * Another complication is that IEEE 802.1Q adds four bytes to the maximum frame size for VLAN tagging. In order to
231 * provide an MTU of 1500 bytes, the frame size would need to increased to 1522 bytes to absorb the additional overhead.
233 * So, there are really three variables that are not entirely free at work here. There is the maximum frame size, the
234 * MTU and the framing scheme which we call the encapsulation mode.
236 * So, what do we do since there are be three values which must always be consistent in the driver? Which values to we
237 * allow to be changed and how do we ensure the other two are consistent? We want to actually allow a user to change
238 * these three variables in flexible ways, but we want the results (even at intermediate stages of her ultimate change) to
239 * be consistent. We certainly don't want to require that users must understand the various requirements of an enapsulation
240 * mode in order to set these variables.
242 * Consider the following situation: A user wants to set the maximum frame size to 1418 bytes instead of 1518. This
243 * user shouldn't have to concern herself that the current encapuslation mode is LLC/SNAP and this will consume eight bytes.
244 * She should not have to also figure out that the MTU needs to be set to 1392 bytes, and she should certainly not have to
245 * do this in some special order to keep intermediate steps consistent.
247 * Similarly, a user who is interested in setting the MTU to 1400 bytes should not be forced to understand that
248 * (based on encapsulation mode) the frame size may need to be set to eighteen + eight bytes more than what he wants
249 * in certain cases (802,3 + LLC/SNAP), twenty-two + zero bytes in others (802.1Q) and other inscrutable combinations
251 * Now, consider a user who is only interested in changing the encapsulation mode from LLC/SNAP to DIX. This
252 * is going to change the relationship between the MTU and the frame size. We've may have to come up with a new value
253 * for at least one of the these? Which one? There are too many free variables.
255 * We could play games trying to figure out what the user wants to do, but that is typically a bad plan and programmers
256 * have a long and distinguished history of guessing wrong. We'll avoid all of that and just define a flexible behavior
257 * that can be worked to get what you want. Here it is:
259 * - If the user is changing the encapsulation mode, the PHY MTU will remain fixed and the MAC MTU will change, if required,
260 * to make the three values consistent;
262 * - If the user is changing the MTU, she is interested in getting that part of the system set, so the frame size
263 * will be changed to make the three values consistent;
265 * - If the user is changing the frame size, he is interested in getting that part of the system set, so the MTU
266 * will be changed to make the three values consistent;
268 * - You cannot define the MTU and frame size separately -- they are always tied together by the emulation mode. This
269 * is not a restriction. Consider what this means. Perhaps you want to set the frame size to some large number and the
270 * MTU to some small number. The largest packet you can send is going to be limited by the MTU, so it is not possible to
271 * send a frame larger than the MTU plus overhead. The larger frame size is not useful.
273 * So, if a user calls SetFrameSize, we assume that the maximum frame size is the interesting thing for that user and
274 * we just adjust the MTU to a new "correct value" based on the current encapsulation mode. If a user calls SetMtu, we
275 * assume that the MTU is the interesting property for that user, and we adjust the frame size to a new "correct value"
276 * for the current encapsulation mode. If a user calls SetEncapsulationMode, then we take the MTU as the free variable
277 * and set its value to match the current frame size.
279 * \param frameSize The max frame size of packets sent over this device.
281 void SetFrameSize (uint16_t frameSize);
284 * Get The max frame size of packets sent over this device.
286 * \returns The max frame size of packets sent over this device.
288 uint16_t GetFrameSize (void) const;
291 * Set the encapsulation mode of this device.
293 * \param mode The encapsulation mode of this device.
297 void SetEncapsulationMode (CsmaNetDevice::EncapsulationMode mode);
300 * Get the encapsulation mode of this device.
302 * \returns The encapsulation mode of this device.
304 CsmaNetDevice::EncapsulationMode GetEncapsulationMode (void);
307 // The following methods are inherited from NetDevice base class.
309 virtual void SetName (const std::string name);
310 virtual std::string GetName (void) const;
311 virtual void SetIfIndex (const uint32_t index);
312 virtual uint32_t GetIfIndex (void) const;
313 virtual Ptr<Channel> GetChannel (void) const;
314 virtual bool SetMtu (const uint16_t mtu);
315 virtual uint16_t GetMtu (void) const;
316 virtual Address GetAddress (void) const;
317 virtual bool IsLinkUp (void) const;
318 virtual void SetLinkChangeCallback (Callback<void> callback);
319 virtual bool IsBroadcast (void) const;
320 virtual Address GetBroadcast (void) const;
321 virtual bool IsMulticast (void) const;
324 * \brief Make and return a MAC multicast address using the provided
327 * RFC 1112 says that an Ipv4 host group address is mapped to an Ethernet
328 * multicast address by placing the low-order 23-bits of the IP address into
329 * the low-order 23 bits of the Ethernet multicast address
330 * 01-00-5E-00-00-00 (hex).
332 * This method performs the multicast address creation function appropriate
333 * to an EUI-48-based CSMA device. This MAC address is encapsulated in an
334 * abstract Address to avoid dependencies on the exact address format.
336 * \param multicastGroup The IP address for the multicast group destination
338 * \return The MAC multicast Address used to send packets to the provided
345 virtual Address GetMulticast (Ipv4Address multicastGroup) const;
348 * Is this a point to point link?
351 virtual bool IsPointToPoint (void) const;
354 * Start sending a packet down the channel.
356 virtual bool Send (Ptr<Packet> packet, const Address& dest,
357 uint16_t protocolNumber);
360 * Start sending a packet down the channel, with MAC spoofing
362 virtual bool SendFrom (Ptr<Packet> packet, const Address& source, const Address& dest,
363 uint16_t protocolNumber);
366 * Get the node to which this device is attached.
368 * \returns Ptr to the Node to which the device is attached.
370 virtual Ptr<Node> GetNode (void) const;
373 * Set the node to which this device is being attached.
375 * \param node Ptr to the Node to which the device is being attached.
377 virtual void SetNode (Ptr<Node> node);
380 * Does this device need to use the address resolution protocol?
382 * \returns True if the encapsulation mode is set to a value that requires
383 * ARP (IP_ARP or LLC).
385 virtual bool NeedsArp (void) const;
388 * Set the callback to be used to notify higher layers when a packet has been
391 * \param cb The callback.
393 virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
396 * \brief Get the MAC multicast address corresponding
397 * to the IPv6 address provided.
398 * \param addr IPv6 address
399 * \return the MAC multicast address
400 * \warning Calling this method is invalid if IsMulticast returns not true.
402 virtual Address GetMulticast (Ipv6Address addr) const;
405 virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb);
406 virtual bool SupportsSendFrom (void) const;
410 * Perform any object release functionality required to break reference
411 * cycles in reference counted objects held by the device.
413 virtual void DoDispose (void);
416 * Get a copy of the attached Queue.
418 * This method is provided for any derived class that may need to get
419 * direct access to the underlying queue.
421 * \return a pointer to the queue.
423 Ptr<Queue> GetQueue (void) const;
426 * Adds the necessary headers and trailers to a packet of data in order to
427 * respect the packet type
429 * \param p Packet to which header should be added
430 * \param source MAC source address from which packet should be sent
431 * \param dest MAC destination address to which packet should be sent
432 * \param protocolNumber In some protocols, identifies the type of
433 * payload contained in this packet.
435 void AddHeader (Ptr<Packet> p, Mac48Address source, Mac48Address dest, uint16_t protocolNumber);
438 * Removes, from a packet of data, all headers and trailers that
439 * relate to the packet type
441 * \param p Packet whose headers need to be processed
442 * \param param An integer parameter that can be set by the function
443 * to return information gathered in the header
444 * \return Returns true if the packet should be forwarded up the
447 bool ProcessHeader (Ptr<Packet> p, uint16_t & param);
452 * Operator = is declared but not implemented. This disables the assigment
453 * operator for CsmaNetDevice objects.
456 CsmaNetDevice &operator = (const CsmaNetDevice &o);
459 * Copy constructor is declared but not implemented. This disables the
460 * copy constructor for CsmaNetDevice objects.
462 CsmaNetDevice (const CsmaNetDevice &o);
465 * Initialization function used during object construction.
467 void Init (bool sendEnable, bool receiveEnable);
470 * Calculate the value for the MTU that would result from
471 * setting the frame size to the given value.
473 uint32_t MtuFromFrameSize (uint32_t frameSize);
476 * Calculate the value for the frame size that would be required
477 * to be able to set the MTU to the given value.
479 uint32_t FrameSizeFromMtu (uint32_t mtu);
482 * Start Sending a Packet Down the Wire.
484 * The TransmitStart method is the method that is used internally in
485 * the CsmaNetDevice to begin the process of sending a packet
486 * out on the channel. A corresponding method is called on the
487 * channel to let it know that the physical device this class
488 * represents has actually started sending signals, this causes the
489 * channel to enter the BUSY state. An event is scheduled for the time at
490 * which the bits have been completely transmitted.
492 * If the channel is found to be BUSY, this method reschedules itself for
493 * execution at a later time (within the backoff period).
495 * \see CsmaChannel::TransmitStart ()
496 * \see TransmitCompleteEvent ()
498 void TransmitStart ();
501 * Stop Sending a Packet Down the Wire and Begin the Interframe Gap.
503 * The TransmitCompleteEvent method is used internally to finish the process
504 * of sending a packet out on the channel. During execution of this method
505 * the TransmitEnd method is called on the channel to let it know that the
506 * physical device this class represents has finished sending simulated
507 * signals. The channel uses this event to begin its speed of light delay
508 * timer after which it notifies the Net Device(s) at the other end of the
509 * link that new bits have arrived (it delivers the Packet). During this
510 * method, the net device also schedules the TransmitReadyEvent at which
511 * time the transmitter becomes ready to send the next packet.
513 * \see CsmaChannel::TransmitEnd ()
514 * \see TransmitReadyEvent ()
516 void TransmitCompleteEvent (void);
519 * Cause the Transmitter to Become Ready to Send Another Packet.
521 * The TransmitReadyEvent method is used internally to re-enable the
522 * transmit machine of the net device. It is scheduled after a suitable
523 * interframe gap after the completion of the previous transmission.
524 * The queue is checked at this time, and if there is a packet waiting on
525 * the queue, the transmission process is begun.
527 * If a packet is in the queue, it is extracted for the queue as the
528 * next packet to be transmitted by the net device.
530 * \see TransmitStart ()
532 void TransmitReadyEvent (void);
535 * Aborts the transmission of the current packet
537 * If the net device has tried to transmit a packet for more times
538 * than the maximum allowed number of retries (channel always busy)
539 * then the packet is dropped.
541 void TransmitAbort (void);
544 * Notify any interested parties that the link has come up.
546 void NotifyLinkUp (void);
549 * Device ID returned by the attached functions. It is used by the
550 * mp-channel to identify each net device to make sure that only
551 * active net devices are writing to the channel
556 * Enable net device to send packets. True by default
561 * Enable net device to receive packets. True by default
563 bool m_receiveEnable;
566 * Enumeration of the states of the transmit machine of the net device.
570 READY, /**< The transmitter is ready to begin transmission of a packet */
571 BUSY, /**< The transmitter is busy transmitting a packet */
572 GAP, /**< The transmitter is in the interframe gap time */
573 BACKOFF /**< The transmitter is waiting for the channel to be free */
577 * The state of the Net Device transmit state machine.
578 * \see TxMachineState
580 TxMachineState m_txMachineState;
583 * The type of packet that should be created by the AddHeader
584 * function and that should be processed by the ProcessHeader
587 EncapsulationMode m_encapMode;
590 * The data rate that the Net Device uses to simulate packet transmission
592 * \see class DataRate
597 * The interframe gap that the Net Device uses insert time between packet
601 Time m_tInterframeGap;
604 * Holds the backoff parameters and is used to calculate the next
605 * backoff time to use when the channel is busy and the net device
606 * is ready to transmit
611 * Next packet that will be transmitted (if transmitter is not
612 * currently transmitting) or packet that is currently being
615 Ptr<Packet> m_currentPkt;
618 * The CsmaChannel to which this CsmaNetDevice has been
620 * \see class CsmaChannel
622 Ptr<CsmaChannel> m_channel;
625 * The Queue which this CsmaNetDevice uses as a packet source.
626 * Management of this Queue has been delegated to the CsmaNetDevice
627 * and it has the responsibility for deletion.
629 * \see class DropTailQueue
634 * Error model for receive packet events
636 Ptr<ErrorModel> m_receiveErrorModel;
639 * The trace source for the packet reception events that the device can
642 * \see class CallBackTraceSource
644 TracedCallback<Ptr<const Packet> > m_rxTrace;
647 * The trace source for the packet drop events that the device can
650 * \see class CallBackTraceSource
652 TracedCallback<Ptr<const Packet> > m_dropTrace;
655 * The Node to which this device is attached.
660 * The MAC address which has been assigned to this device.
662 Mac48Address m_address;
665 * The callback used to notify higher layers that a packet has been received.
667 NetDevice::ReceiveCallback m_rxCallback;
669 * The callback used to notify higher layers that a packet has been received in promiscuous mode.
671 NetDevice::PromiscReceiveCallback m_promiscRxCallback;
674 * The interface index (really net evice index) that has been assigned to
675 * this network device.
680 * The human readable name of this device.
685 * Flag indicating whether or not the link is up. In this case,
686 * whether or not the device is connected to a channel.
691 * Callback to fire if the link changes state (up or down).
693 Callback<void> m_linkChangeCallback;
695 static const uint16_t DEFAULT_FRAME_SIZE = 1518;
696 static const uint16_t ETHERNET_OVERHEAD = 18;
699 * The frame size/packet size. This corresponds to the maximum
700 * number of bytes that can be transmitted as a packet without framing.
701 * This corresponds to the 1518 byte packet size often seen on Ethernet.
703 uint32_t m_frameSize;
706 * The Maxmimum Transmission Unit. This corresponds to the maximum
707 * number of bytes that can be transmitted as seen from higher layers.
708 * This corresponds to the 1500 byte MTU size often seen on IP over
716 #endif // CSMA_NET_DEVICE_H