00001 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ 00002 /* 00003 * Copyright (c) 2007, 2008 University of Washington 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License version 2 as 00007 * published by the Free Software Foundation; 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software 00016 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 */ 00018 00019 #ifndef POINT_TO_POINT_NET_DEVICE_H 00020 #define POINT_TO_POINT_NET_DEVICE_H 00021 00022 #include <string.h> 00023 #include "ns3/address.h" 00024 #include "ns3/node.h" 00025 #include "ns3/net-device.h" 00026 #include "ns3/callback.h" 00027 #include "ns3/packet.h" 00028 #include "ns3/traced-callback.h" 00029 #include "ns3/nstime.h" 00030 #include "ns3/data-rate.h" 00031 #include "ns3/ptr.h" 00032 #include "ns3/mac48-address.h" 00033 00034 namespace ns3 { 00035 00036 class Queue; 00037 class PointToPointChannel; 00038 class ErrorModel; 00039 00040 /** 00041 * \class PointToPointNetDevice 00042 * \brief A Device for a Point to Point Network Link. 00043 * 00044 * This PointToPointNetDevice class specializes the NetDevice abstract 00045 * base class. Together with a PointToPointChannel (and a peer 00046 * PointToPointNetDevice), the class models, with some level of 00047 * abstraction, a generic point-to-point or serial link. 00048 * Key parameters or objects that can be specified for this device 00049 * include a queue, data rate, and interframe transmission gap (the 00050 * propagation delay is set in the PointToPointChannel). 00051 */ 00052 class PointToPointNetDevice : public NetDevice 00053 { 00054 public: 00055 static TypeId GetTypeId (void); 00056 00057 /** 00058 * Construct a PointToPointNetDevice 00059 * 00060 * This is the constructor for the PointToPointNetDevice. It takes as a 00061 * parameter a pointer to the Node to which this device is connected, 00062 * as well as an optional DataRate object. 00063 */ 00064 PointToPointNetDevice (); 00065 00066 /** 00067 * Destroy a PointToPointNetDevice 00068 * 00069 * This is the destructor for the PointToPointNetDevice. 00070 */ 00071 virtual ~PointToPointNetDevice (); 00072 00073 /** 00074 * Set the Data Rate used for transmission of packets. The data rate is 00075 * set in the Attach () method from the corresponding field in the channel 00076 * to which the device is attached. It can be overridden using this method. 00077 * 00078 * @see Attach () 00079 * @param bps the data rate at which this object operates 00080 */ 00081 void SetDataRate (DataRate bps); 00082 00083 /** 00084 * Set the inteframe gap used to separate packets. The interframe gap 00085 * defines the minimum space required between packets sent by this device. 00086 * 00087 * @param t the interframe gap time 00088 */ 00089 void SetInterframeGap (Time t); 00090 00091 /** 00092 * Attach the device to a channel. 00093 * 00094 * @param ch Ptr to the channel to which this object is being attached. 00095 */ 00096 bool Attach (Ptr<PointToPointChannel> ch); 00097 00098 /** 00099 * Attach a queue to the PointToPointNetDevice. 00100 * 00101 * The PointToPointNetDevice "owns" a queue that implements a queueing 00102 * method such as DropTail or RED. 00103 * 00104 * @see Queue 00105 * @see DropTailQueue 00106 * @param queue Ptr to the new queue. 00107 */ 00108 void SetQueue (Ptr<Queue> queue); 00109 00110 /** 00111 * Attach a receive ErrorModel to the PointToPointNetDevice. 00112 * 00113 * The PointToPointNetDevice may optionally include an ErrorModel in 00114 * the packet receive chain. 00115 * 00116 * @see ErrorModel 00117 * @param em Ptr to the ErrorModel. 00118 */ 00119 void SetReceiveErrorModel(Ptr<ErrorModel> em); 00120 00121 /** 00122 * Receive a packet from a connected PointToPointChannel. 00123 * 00124 * The PointToPointNetDevice receives packets from its connected channel 00125 * and forwards them up the protocol stack. This is the public method 00126 * used by the channel to indicate that the last bit of a packet has 00127 * arrived at the device. 00128 * 00129 * @see PointToPointChannel 00130 * @param p Ptr to the received packet. 00131 */ 00132 void Receive (Ptr<Packet> p); 00133 00134 /** 00135 * Assign a MAC address to this device. 00136 * 00137 * @see Mac48Address 00138 * @param addr The new address. 00139 */ 00140 void SetAddress (Mac48Address addr); 00141 00142 /** 00143 * Set The max frame size of packets sent over this device. 00144 * 00145 * 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 00146 * level protocols see. We have a PHY-level MTU which is the maximum number of bytes we can send over the link 00147 * (cf. 1500 bytes for Ethernet). We also have a frame size which is some total number of bytes in a packet which could 00148 * or could not include any framing and overhead. There can be a lot of inconsistency in definitions of these terms. For 00149 * example, RFC 1042 asserts that the terms maximum transmission unit and maximum packet size are equivalent. RFC 791, 00150 * however, defines MTU as the maximum sized IP datagram that can be sent. Packet size and frame size are sometimes 00151 * used interchangeably. 00152 * 00153 * So, some careful definitions are in order to avoid confusion: 00154 * 00155 * In real serial channel (HDLC, for example), the wire idles (sends all ones) until the channel begins sending a packet. 00156 * A frame on the wire starts with a flag character (01111110). This is followed by what is usually called the packet: 00157 * address, control, payload, and a Frame Check Sequence (FCS). This is followed by another flag character. If the flag 00158 * characters are used, then bit stuffing must be used to prevent flag characters from appearing in the packet and confusing 00159 * the link. Som to be strictly and pedantically correct the frame size is then necessarily larger than the packet size on 00160 * 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 00161 * no good reason to add framing bits and therefore to do bit-stuffing. So, in the case of the point-to-point device, the 00162 * frame size is equal to the packet size. Since these two values are defined to be equal, there is no danger in assuming 00163 * they are identical. We define packet size to be equal to frame size and this excludes the flag characters. We define a 00164 * single (MAC-level) MTU that coresponds to the payload size of the packet, which is the IP-centric view of the term as 00165 * seen in RFC 791. 00166 * 00167 * To make this concrete, consider PPP framing on a synchronous link. In this framing scheme, a real serial frame on the 00168 * wire starts with a flag character, address and control characters, then a 16-bit PPP protocol ID (0x21 = IP). Then we 00169 * would see the actual payload we are supposed to send, presumably an IP datagram. At then we see the FCS and finally 00170 * another flag character to end the frame. We ignore the flag bits on this device since it they are not needed. We 00171 * aren't really using HDLC to send frames across the link, so we don't need the address and control bits either. In fact, 00172 * to encapsulate using unframed PPP all we need to do is prepend the two-byte protocol ID. 00173 * 00174 * Typically the limiting factor in frame size is due to hardware limitations in the underlying HDLC controller receive 00175 * FIFO buffer size. This number can vary widely. For example, the Motorola MC92460 has a 64 KByte maximum frame size; 00176 * the Intel IXP4XX series has a 16 KByte size. Older USARTs have a maximum frame size around 2KBytes, and typical PPP 00177 * links on the Internet have their MTU set to 1500 bytes since this is what will typically be used on Ethernet segments 00178 * and will avoid path MTU issues. We choose to make the default MTU 1500 bytes which then fixes the maximum frame size 00179 * as described below. 00180 * 00181 * So, there are really two related variables at work here. There is the maximum frame size that can be sent over the 00182 * link and there is the MTU. 00183 * 00184 * So, what do we do since these values must always be consistent in the driver? We want to actually allow a user to change 00185 * these variables, but we want the results (even at intermediate stages of her ultimate change) to be consistent. We 00186 * certainly don't want to require that users must understand the details of PPP encapsulation in order to set these 00187 * variables. 00188 * 00189 * Consider the following situation: A user wants to set the maximum frame size to 16 KBytes. This user shouldn't have to 00190 * concern herself that the PPP encapsulation will consume six bytes. She should not have to figure out that the MTU needs 00191 * to be set to 16K - 2 bytes to make things consistent. 00192 * 00193 * Similarly, a user who is interested in setting the MTU to 1500 bytes should not be forced to understand that the frame 00194 * size will need to be set to 1502 bytes. 00195 * 00196 * We could play games trying to figure out what the user wants to do, but that is typically a bad plan and programmers 00197 * have a long and distinguished history of guessing wrong. We'll avoid all of that and just define a flexible behavior 00198 * that can be worked to get what you want. Here it is: 00199 * 00200 * - If the user is changing the MTU, she is interested in getting that part of the system set, so the frame size 00201 * will be changed to make it consistent; 00202 * 00203 * - If the user is changing the frame size, he is interested in getting that part of the system set, so the MTU 00204 * will be changed to make it consistent; 00205 * 00206 * - You cannot define the MTU and frame size separately -- they are always tied together by the overhead of the PPP 00207 * encapsulation. This is not a restriction. Consider what this means. Perhaps you want to set the frame size to some 00208 * 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 00209 * is not possible to send a frame larger than the MTU plus overhead. Having the ability to set a larger frame size is not 00210 * useful. 00211 * 00212 * So, if a user calls SetFrameSize, we assume that the maximum frame size is the interesting thing for that user and 00213 * we just adjust the MTU to a new "correct value" based on the current encapsulation mode. If a user calls SetMtu, we 00214 * assume that the MTU is the interesting property for that user, and we adjust the frame size to a new "correct value" 00215 * for the current encapsulation mode. If a user calls SetEncapsulationMode, then we take the MTU as the free variable 00216 * and set its value to match the current frame size. 00217 * 00218 * \param frameSize The max frame size of packets sent over this device. 00219 */ 00220 void SetFrameSize (uint16_t frameSize); 00221 00222 /** 00223 * Get The max frame size of packets sent over this device. 00224 * 00225 * \returns The max frame size of packets sent over this device. 00226 */ 00227 uint16_t GetFrameSize (void) const; 00228 00229 // 00230 // Pure virtual methods inherited from NetDevice we must implement. 00231 // 00232 virtual void SetName(const std::string name); 00233 virtual std::string GetName(void) const; 00234 00235 virtual void SetIfIndex(const uint32_t index); 00236 virtual uint32_t GetIfIndex(void) const; 00237 00238 virtual Ptr<Channel> GetChannel (void) const; 00239 virtual Address GetAddress (void) const; 00240 00241 virtual bool SetMtu (const uint16_t mtu); 00242 virtual uint16_t GetMtu (void) const; 00243 00244 virtual bool IsLinkUp (void) const; 00245 00246 virtual void SetLinkChangeCallback (Callback<void> callback); 00247 00248 virtual bool IsBroadcast (void) const; 00249 virtual Address GetBroadcast (void) const; 00250 00251 virtual bool IsMulticast (void) const; 00252 virtual Address GetMulticast (Ipv4Address multicastGroup) const; 00253 00254 virtual bool IsPointToPoint (void) const; 00255 virtual bool IsBridge (void) const; 00256 00257 virtual bool Send(Ptr<Packet> packet, const Address &dest, uint16_t protocolNumber); 00258 virtual bool SendFrom(Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber); 00259 00260 virtual Ptr<Node> GetNode (void) const; 00261 virtual void SetNode (Ptr<Node> node); 00262 00263 virtual bool NeedsArp (void) const; 00264 00265 virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb); 00266 00267 virtual Address GetMulticast (Ipv6Address addr) const; 00268 00269 virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb); 00270 virtual bool SupportsSendFrom (void) const; 00271 00272 private: 00273 00274 virtual void DoDispose (void); 00275 00276 /** 00277 * Get a copy of the attached Queue. 00278 * 00279 * This method is provided for any derived class that may need to get 00280 * direct access to the underlying queue. 00281 * 00282 * @returns Ptr to the queue. 00283 */ 00284 Ptr<Queue> GetQueue(void) const; 00285 00286 private: 00287 /** 00288 * Calculate the value for the MTU that would result from 00289 * setting the frame size to the given value. 00290 */ 00291 uint32_t MtuFromFrameSize (uint32_t frameSize); 00292 00293 /** 00294 * Calculate the value for the frame size that would be required 00295 * to be able to set the MTU to the given value. 00296 */ 00297 uint32_t FrameSizeFromMtu (uint32_t mtu); 00298 00299 /** 00300 * \returns the address of the remote device connected to this device 00301 * through the point to point channel. 00302 */ 00303 Address GetRemote (void) const; 00304 00305 /** 00306 * Adds the necessary headers and trailers to a packet of data in order to 00307 * respect the protocol implemented by the agent. 00308 */ 00309 void AddHeader(Ptr<Packet> p, uint16_t protocolNumber); 00310 00311 /** 00312 * Removes, from a packet of data, all headers and trailers that 00313 * relate to the protocol implemented by the agent 00314 * \return Returns true if the packet should be forwarded up the 00315 * protocol stack. 00316 */ 00317 bool ProcessHeader(Ptr<Packet> p, uint16_t& param); 00318 00319 /** 00320 * Start Sending a Packet Down the Wire. 00321 * 00322 * The TransmitStart method is the method that is used internally in the 00323 * PointToPointNetDevice to begin the process of sending a packet out on 00324 * the channel. The corresponding method is called on the channel to let 00325 * it know that the physical device this class represents has virually 00326 * started sending signals. An event is scheduled for the time at which 00327 * the bits have been completely transmitted. 00328 * 00329 * @see PointToPointChannel::TransmitStart () 00330 * @see TransmitCompleteEvent () 00331 * @param p a reference to the packet to send 00332 * @returns true if success, false on failure 00333 */ 00334 bool TransmitStart (Ptr<Packet> p); 00335 00336 /** 00337 * Stop Sending a Packet Down the Wire and Begin the Interframe Gap. 00338 * 00339 * The TransmitComplete method is used internally to finish the process 00340 * of sending a packet out on the channel. 00341 */ 00342 void TransmitComplete(void); 00343 00344 void NotifyLinkUp (void); 00345 00346 /** 00347 * Enumeration of the states of the transmit machine of the net device. 00348 */ 00349 enum TxMachineState 00350 { 00351 READY, /**< The transmitter is ready to begin transmission of a packet */ 00352 BUSY /**< The transmitter is busy transmitting a packet */ 00353 }; 00354 /** 00355 * The state of the Net Device transmit state machine. 00356 * @see TxMachineState 00357 */ 00358 TxMachineState m_txMachineState; 00359 00360 /** 00361 * The data rate that the Net Device uses to simulate packet transmission 00362 * timing. 00363 * @see class DataRate 00364 */ 00365 DataRate m_bps; 00366 00367 /** 00368 * The interframe gap that the Net Device uses to throttle packet 00369 * transmission 00370 * @see class Time 00371 */ 00372 Time m_tInterframeGap; 00373 00374 /** 00375 * The PointToPointChannel to which this PointToPointNetDevice has been 00376 * attached. 00377 * @see class PointToPointChannel 00378 */ 00379 Ptr<PointToPointChannel> m_channel; 00380 00381 /** 00382 * The Queue which this PointToPointNetDevice uses as a packet source. 00383 * Management of this Queue has been delegated to the PointToPointNetDevice 00384 * and it has the responsibility for deletion. 00385 * @see class Queue 00386 * @see class DropTailQueue 00387 */ 00388 Ptr<Queue> m_queue; 00389 00390 /** 00391 * The trace source for the packet reception events that the device can 00392 * fire. 00393 * 00394 * @see class CallBackTraceSource 00395 */ 00396 TracedCallback<Ptr<const Packet> > m_rxTrace; 00397 00398 /** 00399 * The trace source for the packet drop events that the device can 00400 * fire. 00401 * 00402 * @see class CallBackTraceSource 00403 */ 00404 TracedCallback<Ptr<const Packet> > m_dropTrace; 00405 00406 /** 00407 * Error model for receive packet events 00408 */ 00409 Ptr<ErrorModel> m_receiveErrorModel; 00410 00411 Ptr<Node> m_node; 00412 Mac48Address m_address; 00413 NetDevice::ReceiveCallback m_rxCallback; 00414 NetDevice::PromiscReceiveCallback m_promiscCallback; 00415 uint32_t m_ifIndex; 00416 std::string m_name; 00417 bool m_linkUp; 00418 Callback<void> m_linkChangeCallback; 00419 00420 static const uint16_t DEFAULT_MTU = 1500; 00421 static const uint16_t PPP_OVERHEAD = 2; 00422 static const uint16_t DEFAULT_FRAME_SIZE = DEFAULT_MTU + PPP_OVERHEAD; 00423 00424 /** 00425 * The frame size/packet size. This corresponds to the maximum 00426 * number of bytes that can be transmitted as a packet without framing. 00427 * This corresponds to the 1518 byte packet size often seen on Ethernet. 00428 */ 00429 uint32_t m_frameSize; 00430 00431 /** 00432 * The Maxmimum Transmission Unit. This corresponds to the maximum 00433 * number of bytes that can be transmitted as seen from higher layers. 00434 * This corresponds to the 1500 byte MTU size often seen on IP over 00435 * Ethernet. 00436 */ 00437 uint32_t m_mtu; 00438 }; 00439 00440 } // namespace ns3 00441 00442 #endif // POINT_TO_POINT_NET_DEVICE_H 00443