src/devices/point-to-point/point-to-point-net-device.h
author vincent@clarinet.u-strasbg.fr
Fri Nov 07 11:36:15 2008 -0800 (2008-11-07)
changeset 3852 9cf7ad0cac85
parent 3841 1e7abf5fca79
child 3936 e525995ce5dc
permissions -rw-r--r--
Initial IPv6 capability
     1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
     2 /*
     3  * Copyright (c) 2007, 2008 University of Washington
     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 
    19 #ifndef POINT_TO_POINT_NET_DEVICE_H
    20 #define POINT_TO_POINT_NET_DEVICE_H
    21 
    22 #include <string.h>
    23 #include "ns3/address.h"
    24 #include "ns3/node.h"
    25 #include "ns3/net-device.h"
    26 #include "ns3/callback.h"
    27 #include "ns3/packet.h"
    28 #include "ns3/traced-callback.h"
    29 #include "ns3/nstime.h"
    30 #include "ns3/data-rate.h"
    31 #include "ns3/ptr.h"
    32 #include "ns3/mac48-address.h"
    33 
    34 namespace ns3 {
    35 
    36 class Queue;
    37 class PointToPointChannel;
    38 class ErrorModel;
    39 
    40 /**
    41  * \class PointToPointNetDevice
    42  * \brief A Device for a Point to Point Network Link.
    43  *
    44  * This PointToPointNetDevice class specializes the NetDevice abstract
    45  * base class.  Together with a PointToPointChannel (and a peer 
    46  * PointToPointNetDevice), the class models, with some level of 
    47  * abstraction, a generic point-to-point or serial link.  
    48  * Key parameters or objects that can be specified for this device 
    49  * include a queue, data rate, and interframe transmission gap (the 
    50  * propagation delay is set in the PointToPointChannel).
    51  */
    52 class PointToPointNetDevice : public NetDevice 
    53 {
    54 public:
    55   static TypeId GetTypeId (void);
    56 
    57   /**
    58    * Construct a PointToPointNetDevice
    59    *
    60    * This is the constructor for the PointToPointNetDevice.  It takes as a
    61    * parameter a pointer to the Node to which this device is connected, 
    62    * as well as an optional DataRate object.
    63    */
    64   PointToPointNetDevice ();
    65 
    66   /**
    67    * Destroy a PointToPointNetDevice
    68    *
    69    * This is the destructor for the PointToPointNetDevice.
    70    */
    71   virtual ~PointToPointNetDevice ();
    72 
    73   /**
    74    * Set the Data Rate used for transmission of packets.  The data rate is
    75    * set in the Attach () method from the corresponding field in the channel
    76    * to which the device is attached.  It can be overridden using this method.
    77    *
    78    * @see Attach ()
    79    * @param bps the data rate at which this object operates
    80    */
    81   void SetDataRate (DataRate bps);
    82 
    83   /**
    84    * Set the inteframe gap used to separate packets.  The interframe gap
    85    * defines the minimum space required between packets sent by this device.
    86    *
    87    * @param t the interframe gap time
    88    */
    89   void SetInterframeGap (Time t);
    90 
    91   /**
    92    * Attach the device to a channel.
    93    *
    94    * @param ch Ptr to the channel to which this object is being attached.
    95    */
    96   bool Attach (Ptr<PointToPointChannel> ch);
    97 
    98   /**
    99    * Attach a queue to the PointToPointNetDevice.
   100    *
   101    * The PointToPointNetDevice "owns" a queue that implements a queueing 
   102    * method such as DropTail or RED.  
   103    *
   104    * @see Queue
   105    * @see DropTailQueue
   106    * @param queue Ptr to the new queue.
   107    */
   108   void SetQueue (Ptr<Queue> queue);
   109 
   110   /**
   111    * Attach a receive ErrorModel to the PointToPointNetDevice.
   112    *
   113    * The PointToPointNetDevice may optionally include an ErrorModel in
   114    * the packet receive chain.
   115    *
   116    * @see ErrorModel
   117    * @param em Ptr to the ErrorModel.
   118    */
   119   void SetReceiveErrorModel(Ptr<ErrorModel> em);
   120 
   121   /**
   122    * Receive a packet from a connected PointToPointChannel.
   123    *
   124    * The PointToPointNetDevice receives packets from its connected channel
   125    * and forwards them up the protocol stack.  This is the public method
   126    * used by the channel to indicate that the last bit of a packet has 
   127    * arrived at the device.
   128    *
   129    * @see PointToPointChannel
   130    * @param p Ptr to the received packet.
   131    */
   132   void Receive (Ptr<Packet> p);
   133 
   134   /**
   135    * Assign a MAC address to this device.
   136    *
   137    * @see Mac48Address
   138    * @param addr The new address.
   139    */
   140   void SetAddress (Mac48Address addr);
   141 
   142   /**
   143    * Set The max frame size of packets sent over this device.
   144    *
   145    * 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 
   146    * level protocols see.  We have a PHY-level MTU which is the maximum number of bytes we can send over the link 
   147    * (cf. 1500 bytes for Ethernet).  We also have a frame size which is some total number of bytes in a packet which could
   148    * or could not include any framing and overhead.  There can be a lot of inconsistency in definitions of these terms.  For
   149    * example, RFC 1042 asserts that the terms maximum transmission unit and maximum packet size are equivalent.  RFC 791, 
   150    * however, defines MTU as the maximum sized IP datagram that can be sent.  Packet size and frame size are sometimes
   151    * used interchangeably.
   152    *
   153    * So, some careful definitions are in order to avoid confusion:
   154    *
   155    * In real serial channel (HDLC, for example), the wire idles (sends all ones) until the channel begins sending a packet.
   156    * A frame on the wire starts with a flag character (01111110).  This is followed by what is usually called the packet: 
   157    * address, control, payload, and a Frame Check Sequence (FCS).  This is followed by another flag character.  If the flag
   158    * characters are used, then bit stuffing must be used to prevent flag characters from appearing in the packet and confusing
   159    * the link.  Som to be strictly and pedantically correct the frame size is then necessarily larger than the packet size on 
   160    * a real link.  But, this isn't a real link, it's a simulation of a device similar to a point-to-point device, and we have
   161    * no good reason to add framing bits and therefore to do bit-stuffing.  So, in the case of the point-to-point device, the 
   162    * frame size is equal to the packet size.  Since these two values are defined to be equal, there is no danger in assuming
   163    * they are identical.  We define packet size to be equal to frame size and this excludes the flag characters.  We define a 
   164    * single (MAC-level) MTU that coresponds to the payload size of the packet, which is the IP-centric view of the term as
   165    * seen in RFC 791.
   166    *
   167    * To make this concrete, consider PPP framing on a synchronous link.  In this framing scheme, a real serial frame on the 
   168    * wire starts with a flag character, address and control characters, then a 16-bit PPP protocol ID (0x21 = IP).  Then we 
   169    * would see the actual payload we are supposed to send, presumably an IP datagram.  At then we see the FCS and finally 
   170    * another flag character to end the frame.  We ignore the flag bits on this device since it they are not needed.  We 
   171    * aren't really using HDLC to send frames across the link, so we don't need the address and control bits either.  In fact,
   172    * to encapsulate using unframed PPP all we need to do is prepend the two-byte protocol ID.
   173    *
   174    * Typically the limiting factor in frame size is due to hardware limitations in the underlying HDLC controller receive 
   175    * FIFO buffer size.  This number can vary widely.  For example, the Motorola MC92460 has a 64 KByte maximum frame size; 
   176    * the Intel IXP4XX series has a 16 KByte size.  Older USARTs have a maximum frame size around 2KBytes, and typical PPP
   177    * links on the Internet have their MTU set to 1500 bytes since this is what will typically be used on Ethernet segments
   178    * and will avoid path MTU issues.  We choose to make the default MTU 1500 bytes which then fixes the maximum frame size
   179    * as described below.
   180    *
   181    * So, there are really two related variables at work here.  There is the maximum frame size that can be sent over the
   182    * link and there is the MTU.
   183    *
   184    * So, what do we do since these values must always be consistent in the driver?  We want to actually allow a user to change 
   185    * these variables, but we want the results (even at intermediate stages of her ultimate change) to be consistent.  We 
   186    * certainly don't want to require that users must understand the details of PPP encapsulation in order to set these 
   187    * variables.
   188    *
   189    * Consider the following situation:  A user wants to set the maximum frame size to 16 KBytes.  This user shouldn't have to
   190    * concern herself that the PPP encapsulation will consume six bytes.  She should not have to figure out that the MTU needs
   191    * to be set to 16K - 2 bytes to make things consistent.
   192    *
   193    * Similarly, a user who is interested in setting the MTU to 1500 bytes should not be forced to understand that the frame 
   194    * size will need to be set to 1502 bytes. 
   195    *
   196    * We could play games trying to figure out what the user wants to do, but that is typically a bad plan and programmers
   197    * have a long and distinguished history of guessing wrong.  We'll avoid all of that and just define a flexible behavior
   198    * that can be worked to get what you want.  Here it is:
   199    *
   200    * - If the user is changing the MTU, she is interested in getting that part of the system set, so the frame size
   201    * will be changed to make it consistent;
   202    *
   203    * - If the user is changing the frame size, he is interested in getting that part of the system set, so the MTU
   204    * will be changed to make it consistent;
   205    *
   206    * - You cannot define the MTU and frame size separately -- they are always tied together by the overhead of the PPP 
   207    * encapsulation.  This is not a restriction.  Consider what this means.  Perhaps you want to set the frame size to some 
   208    * large number and the MTU to some small number.  The largest packet you can send is going to be limited by the MTU, so it
   209    * is not possible to send a frame larger than the MTU plus overhead.  Having the ability to set a  larger frame size is not
   210    * useful.
   211    * 
   212    * So, if a user calls SetFrameSize, we assume that the maximum frame size is the interesting thing for that user and
   213    * we just adjust the MTU to a new "correct value" based on the current encapsulation mode.  If a user calls SetMtu, we 
   214    * assume that the MTU is the interesting property for that user, and we adjust the frame size to a new "correct value" 
   215    * for the current encapsulation mode.  If a user calls SetEncapsulationMode, then we take the MTU as the free variable 
   216    * and set its value to match the current frame size.
   217    *
   218    * \param frameSize The max frame size of packets sent over this device.
   219    */
   220   void SetFrameSize (uint16_t frameSize);
   221 
   222   /**
   223    * Get The max frame size of packets sent over this device.
   224    *
   225    * \returns The max frame size of packets sent over this device.
   226    */
   227   uint16_t GetFrameSize (void) const;
   228 
   229 //
   230 // Pure virtual methods inherited from NetDevice we must implement.
   231 //
   232   virtual void SetName(const std::string name);
   233   virtual std::string GetName(void) const;
   234 
   235   virtual void SetIfIndex(const uint32_t index);
   236   virtual uint32_t GetIfIndex(void) const;
   237 
   238   virtual Ptr<Channel> GetChannel (void) const;
   239   virtual Address GetAddress (void) const;
   240 
   241   virtual bool SetMtu (const uint16_t mtu);
   242   virtual uint16_t GetMtu (void) const;
   243 
   244   virtual bool IsLinkUp (void) const;
   245 
   246   virtual void SetLinkChangeCallback (Callback<void> callback);
   247 
   248   virtual bool IsBroadcast (void) const;
   249   virtual Address GetBroadcast (void) const;
   250 
   251   virtual bool IsMulticast (void) const;
   252   virtual Address GetMulticast (Ipv4Address multicastGroup) const;
   253 
   254   virtual bool IsPointToPoint (void) const;
   255 
   256   virtual bool Send(Ptr<Packet> packet, const Address &dest, uint16_t protocolNumber);
   257   virtual bool SendFrom(Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber);
   258 
   259   virtual Ptr<Node> GetNode (void) const;
   260   virtual void SetNode (Ptr<Node> node);
   261 
   262   virtual bool NeedsArp (void) const;
   263 
   264   virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
   265 
   266   virtual Address GetMulticast (Ipv6Address addr) const;
   267 
   268   virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb);
   269   virtual bool SupportsSendFrom (void) const;
   270 
   271 private:
   272 
   273   virtual void DoDispose (void);
   274 
   275   /**
   276    * Get a copy of the attached Queue.
   277    *
   278    * This method is provided for any derived class that may need to get
   279    * direct access to the underlying queue.
   280    *
   281    * @returns Ptr to the queue.
   282    */
   283   Ptr<Queue> GetQueue(void) const; 
   284 
   285 private:
   286   /**
   287    * Calculate the value for the MTU that would result from 
   288    * setting the frame size to the given value.
   289    */
   290   uint32_t MtuFromFrameSize (uint32_t frameSize);
   291 
   292   /**
   293    * Calculate the value for the frame size that would be required
   294    * to be able to set the MTU to the given value.
   295    */
   296   uint32_t FrameSizeFromMtu (uint32_t mtu);
   297 
   298   /**
   299    * \returns the address of the remote device connected to this device
   300    * through the point to point channel.
   301    */
   302   Address GetRemote (void) const;
   303 
   304   /**
   305    * Adds the necessary headers and trailers to a packet of data in order to
   306    * respect the protocol implemented by the agent.
   307    */
   308   void AddHeader(Ptr<Packet> p, uint16_t protocolNumber);
   309 
   310   /**
   311    * Removes, from a packet of data, all headers and trailers that
   312    * relate to the protocol implemented by the agent
   313    * \return Returns true if the packet should be forwarded up the
   314    * protocol stack.
   315    */
   316   bool ProcessHeader(Ptr<Packet> p, uint16_t& param);
   317 
   318   /**
   319    * Start Sending a Packet Down the Wire.
   320    *
   321    * The TransmitStart method is the method that is used internally in the
   322    * PointToPointNetDevice to begin the process of sending a packet out on
   323    * the channel.  The corresponding method is called on the channel to let
   324    * it know that the physical device this class represents has virually
   325    * started sending signals.  An event is scheduled for the time at which
   326    * the bits have been completely transmitted.
   327    *
   328    * @see PointToPointChannel::TransmitStart ()
   329    * @see TransmitCompleteEvent ()
   330    * @param p a reference to the packet to send
   331    * @returns true if success, false on failure
   332    */
   333   bool TransmitStart (Ptr<Packet> p);
   334 
   335   /**
   336    * Stop Sending a Packet Down the Wire and Begin the Interframe Gap.
   337    *
   338    * The TransmitComplete method is used internally to finish the process
   339    * of sending a packet out on the channel.
   340    */
   341   void TransmitComplete(void);
   342 
   343   void NotifyLinkUp (void);
   344 
   345   /**
   346    * Enumeration of the states of the transmit machine of the net device.
   347    */
   348   enum TxMachineState
   349     {
   350       READY, /**< The transmitter is ready to begin transmission of a packet */
   351       BUSY   /**< The transmitter is busy transmitting a packet */
   352     };
   353   /**
   354    * The state of the Net Device transmit state machine.
   355    * @see TxMachineState
   356    */
   357   TxMachineState m_txMachineState;
   358 
   359   /**
   360    * The data rate that the Net Device uses to simulate packet transmission
   361    * timing.
   362    * @see class DataRate
   363    */
   364   DataRate       m_bps;
   365 
   366   /**
   367    * The interframe gap that the Net Device uses to throttle packet
   368    * transmission
   369    * @see class Time
   370    */
   371   Time           m_tInterframeGap;
   372 
   373   /**
   374    * The PointToPointChannel to which this PointToPointNetDevice has been
   375    * attached.
   376    * @see class PointToPointChannel
   377    */
   378   Ptr<PointToPointChannel> m_channel;
   379 
   380   /**
   381    * The Queue which this PointToPointNetDevice uses as a packet source.
   382    * Management of this Queue has been delegated to the PointToPointNetDevice
   383    * and it has the responsibility for deletion.
   384    * @see class Queue
   385    * @see class DropTailQueue
   386    */
   387   Ptr<Queue> m_queue;
   388 
   389   /**
   390    * The trace source for the packet reception events that the device can
   391    * fire.
   392    *
   393    * @see class CallBackTraceSource
   394    */
   395   TracedCallback<Ptr<const Packet> > m_rxTrace;
   396 
   397   /**
   398    * The trace source for the packet drop events that the device can
   399    * fire.
   400    *
   401    * @see class CallBackTraceSource
   402    */
   403   TracedCallback<Ptr<const Packet> > m_dropTrace;
   404 
   405   /**
   406    * Error model for receive packet events
   407    */
   408   Ptr<ErrorModel> m_receiveErrorModel;
   409 
   410   Ptr<Node> m_node;
   411   Mac48Address m_address;
   412   NetDevice::ReceiveCallback m_rxCallback;
   413   NetDevice::PromiscReceiveCallback m_promiscCallback;
   414   uint32_t m_ifIndex;
   415   std::string m_name;
   416   bool m_linkUp;
   417   Callback<void> m_linkChangeCallback;
   418 
   419   static const uint16_t DEFAULT_MTU = 1500;
   420   static const uint16_t PPP_OVERHEAD = 2;
   421   static const uint16_t DEFAULT_FRAME_SIZE = DEFAULT_MTU + PPP_OVERHEAD;
   422 
   423   /**
   424    * The frame size/packet size.  This corresponds to the maximum 
   425    * number of bytes that can be transmitted as a packet without framing.
   426    * This corresponds to the 1518 byte packet size often seen on Ethernet.
   427    */
   428   uint32_t m_frameSize;
   429 
   430   /**
   431    * The Maxmimum Transmission Unit.  This corresponds to the maximum 
   432    * number of bytes that can be transmitted as seen from higher layers.
   433    * This corresponds to the 1500 byte MTU size often seen on IP over 
   434    * Ethernet.
   435    */
   436   uint32_t m_mtu;
   437 };
   438 
   439 } // namespace ns3
   440 
   441 #endif // POINT_TO_POINT_NET_DEVICE_H
   442