00001 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ 00002 /* 00003 * Copyright (c) 2005,2006 INRIA 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 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr> 00019 */ 00020 #ifndef PACKET_H 00021 #define PACKET_H 00022 00023 #include <stdint.h> 00024 #include "buffer.h" 00025 #include "header.h" 00026 #include "trailer.h" 00027 #include "packet-metadata.h" 00028 #include "tag.h" 00029 #include "tag-list.h" 00030 #include "ns3/callback.h" 00031 #include "ns3/assert.h" 00032 #include "ns3/ptr.h" 00033 #include "ns3/deprecated.h" 00034 00035 namespace ns3 { 00036 00037 /** 00038 * \ingroup common 00039 * \defgroup packet Packet 00040 */ 00041 00042 /** 00043 * \ingroup packet 00044 * \brief Iterator over the set of tags in a packet 00045 * 00046 * This is a java-style iterator. 00047 */ 00048 class TagIterator 00049 { 00050 public: 00051 /** 00052 * Identifies a tag and a set of bytes within a packet 00053 * to which the tag applies. 00054 */ 00055 class Item 00056 { 00057 public: 00058 /** 00059 * \returns the ns3::TypeId associated to this tag. 00060 */ 00061 TypeId GetTypeId (void) const; 00062 /** 00063 * \returns the index of the first byte tagged by this tag. 00064 * 00065 * The index is an offset from the start of the packet. 00066 */ 00067 uint32_t GetStart (void) const; 00068 /** 00069 * \returns the index of the last byte tagged by this tag. 00070 * 00071 * The index is an offset from the start of the packet. 00072 */ 00073 uint32_t GetEnd (void) const; 00074 /** 00075 * \param tag the user tag to which the data should be copied. 00076 * 00077 * Read the requested tag and store it in the user-provided 00078 * tag instance. This method will crash if the type of the 00079 * tag provided by the user does not match the type of 00080 * the underlying tag. 00081 */ 00082 void GetTag (Tag &tag) const; 00083 private: 00084 friend class TagIterator; 00085 Item (TypeId tid, uint32_t start, uint32_t end, TagBuffer buffer); 00086 TypeId m_tid; 00087 uint32_t m_start; 00088 uint32_t m_end; 00089 TagBuffer m_buffer; 00090 }; 00091 /** 00092 * \returns true if calling Next is safe, false otherwise. 00093 */ 00094 bool HasNext (void) const; 00095 /** 00096 * \returns the next item found and prepare for the next one. 00097 */ 00098 Item Next (void); 00099 private: 00100 friend class Packet; 00101 TagIterator (TagList::Iterator i); 00102 TagList::Iterator m_current; 00103 }; 00104 00105 /** 00106 * \ingroup packet 00107 * \brief network packets 00108 * 00109 * Each network packet contains a byte buffer, a set of tags, and 00110 * metadata. 00111 * 00112 * - The byte buffer stores the serialized content of the headers and trailers 00113 * added to a packet. The serialized representation of these headers is expected 00114 * to match that of real network packets bit for bit (although nothing 00115 * forces you to do this) which means that the content of a packet buffer 00116 * is expected to be that of a real packet. 00117 * 00118 * - Each tag tags a subset of the bytes in the packet byte buffer with the 00119 * information stored in the tag. A classic example of a tag is a FlowIdTag 00120 * which contains a flow id: the set of bytes tagged by this tag implicitely 00121 * belong to the attached flow id. 00122 * 00123 * - The metadata describes the type of the headers and trailers which 00124 * were serialized in the byte buffer. The maintenance of metadata is 00125 * optional and disabled by default. To enable it, you must call 00126 * Packet::EnableMetadata and this will allow you to get non-empty 00127 * output from Packet::Print and Packet::Print. 00128 * 00129 * Implementing a new type of Header or Trailer for a new protocol is 00130 * pretty easy and is a matter of creating a subclass of the ns3::Header 00131 * or of the ns3::Trailer base class, and implementing the methods 00132 * described in their respective API documentation. 00133 * 00134 * Implementing a new type of Tag requires roughly the same amount of 00135 * work and this work is described in the ns3::Tag API documentation. 00136 * 00137 * The performance aspects of the Packet API are discussed in 00138 * \ref packetperf 00139 */ 00140 class Packet 00141 { 00142 public: 00143 void Ref (void) const; 00144 void Unref (void) const; 00145 00146 Ptr<Packet> Copy (void) const; 00147 00148 /** 00149 * Create an empty packet with a new uid (as returned 00150 * by getUid). 00151 */ 00152 Packet (); 00153 Packet (const Packet &o); 00154 Packet &operator = (const Packet &o); 00155 /** 00156 * Create a packet with a zero-filled payload. 00157 * The memory necessary for the payload is not allocated: 00158 * it will be allocated at any later point if you attempt 00159 * to fragment this packet or to access the zero-filled 00160 * bytes. The packet is allocated with a new uid (as 00161 * returned by getUid). 00162 * 00163 * \param size the size of the zero-filled payload 00164 */ 00165 Packet (uint32_t size); 00166 /** 00167 * Create a packet with payload filled with the content 00168 * of this buffer. The input data is copied: the input 00169 * buffer is untouched. 00170 * 00171 * \param buffer the data to store in the packet. 00172 * \param size the size of the input buffer. 00173 */ 00174 Packet (uint8_t const*buffer, uint32_t size); 00175 /** 00176 * Create a new packet which contains a fragment of the original 00177 * packet. The returned packet shares the same uid as this packet. 00178 * 00179 * \param start offset from start of packet to start of fragment to create 00180 * \param length length of fragment to create 00181 * \returns a fragment of the original packet 00182 */ 00183 Ptr<Packet> CreateFragment (uint32_t start, uint32_t length) const; 00184 /** 00185 * \returns the size in bytes of the packet (including the zero-filled 00186 * initial payload) 00187 */ 00188 uint32_t GetSize (void) const; 00189 /** 00190 * Add header to this packet. This method invokes the 00191 * Header::GetSerializedSize and Header::Serialize 00192 * methods to reserve space in the buffer and request the 00193 * header to serialize itself in the packet buffer. 00194 * 00195 * \param header a reference to the header to add to this packet. 00196 */ 00197 void AddHeader (const Header & header); 00198 /** 00199 * Deserialize and remove the header from the internal buffer. 00200 * This method invokes Header::Deserialize. 00201 * 00202 * \param header a reference to the header to remove from the internal buffer. 00203 * \returns the number of bytes removed from the packet. 00204 */ 00205 uint32_t RemoveHeader (Header &header); 00206 /** 00207 * Deserialize but does _not_ remove the header from the internal buffer. 00208 * This method invokes Header::Deserialize. 00209 * 00210 * \param header a reference to the header to read from the internal buffer. 00211 * \returns the number of bytes read from the packet. 00212 */ 00213 uint32_t PeekHeader (Header &header) const; 00214 /** 00215 * Add trailer to this packet. This method invokes the 00216 * Trailer::GetSerializedSize and Trailer::Serialize 00217 * methods to reserve space in the buffer and request the trailer 00218 * to serialize itself in the packet buffer. 00219 * 00220 * \param trailer a reference to the trailer to add to this packet. 00221 */ 00222 void AddTrailer (const Trailer &trailer); 00223 /** 00224 * Remove a deserialized trailer from the internal buffer. 00225 * This method invokes the Deserialize method. 00226 * 00227 * \param trailer a reference to the trailer to remove from the internal buffer. 00228 * \returns the number of bytes removed from the end of the packet. 00229 */ 00230 uint32_t RemoveTrailer (Trailer &trailer); 00231 /** 00232 * Deserialize but does _not_ remove a trailer from the internal buffer. 00233 * This method invokes the Trailer::Deserialize method. 00234 * 00235 * \param trailer a reference to the trailer to read from the internal buffer. 00236 * \returns the number of bytes read from the end of the packet. 00237 */ 00238 uint32_t PeekTrailer (Trailer &trailer); 00239 /** 00240 * \param os output stream in which the data should be printed. 00241 * 00242 * Iterate over the tags present in this packet, and 00243 * invoke the Print method of each tag stored in the packet. 00244 */ 00245 void PrintTags (std::ostream &os) const; 00246 00247 /** 00248 * Concatenate the input packet at the end of the current 00249 * packet. This does not alter the uid of either packet. 00250 * 00251 * \param packet packet to concatenate 00252 */ 00253 void AddAtEnd (Ptr<const Packet> packet); 00254 /** 00255 * \param size number of padding bytes to add. 00256 */ 00257 void AddPaddingAtEnd (uint32_t size); 00258 /** 00259 * Remove size bytes from the end of the current packet 00260 * It is safe to remove more bytes that what is present in 00261 * the packet. 00262 * 00263 * \param size number of bytes from remove 00264 */ 00265 void RemoveAtEnd (uint32_t size); 00266 /** 00267 * Remove size bytes from the start of the current packet. 00268 * It is safe to remove more bytes that what is present in 00269 * the packet. 00270 * 00271 * \param size number of bytes from remove 00272 */ 00273 void RemoveAtStart (uint32_t size); 00274 00275 /** 00276 * If you try to change the content of the buffer 00277 * returned by this method, you will die. 00278 * 00279 * \returns a pointer to the internal buffer of the packet. 00280 */ 00281 uint8_t const *PeekData (void) const; 00282 00283 /** 00284 * \param buffer a pointer to a byte buffer where the packet data 00285 * should be copied. 00286 * \param size the size of the byte buffer. 00287 * \returns the number of bytes read from the packet 00288 * 00289 * No more than \b size bytes will be copied by this function. 00290 */ 00291 uint32_t CopyData (uint8_t *buffer, uint32_t size) const; 00292 00293 /** 00294 * A packet is allocated a new uid when it is created 00295 * empty or with zero-filled payload. 00296 * 00297 * Note: This uid is an internal uid and cannot be counted on to 00298 * provide an accurate counter of how many "simulated packets" of a 00299 * particular protocol are in the system. It is not trivial to make 00300 * this uid into such a counter, because of questions such as what 00301 * should the uid be when the packet is sent over broadcast media, or 00302 * when fragmentation occurs. If a user wants to trace actual packet 00303 * counts, he or she should look at e.g. the IP ID field or transport 00304 * sequence numbers, or other packet or frame counters at other 00305 * protocol layers. 00306 * 00307 * \returns an integer identifier which uniquely 00308 * identifies this packet. 00309 */ 00310 uint32_t GetUid (void) const; 00311 00312 /** 00313 * \param os output stream in which the data should be printed. 00314 * 00315 * Iterate over the headers and trailers present in this packet, 00316 * from the first header to the last trailer and invoke, for 00317 * each of them, the user-provided method Header::DoPrint or 00318 * Trailer::DoPrint methods. 00319 */ 00320 void Print (std::ostream &os) const; 00321 00322 PacketMetadata::ItemIterator BeginItem (void) const; 00323 00324 static void EnableMetadata (void) NS_DEPRECATED; 00325 00326 /** 00327 * By default, packets do not keep around enough metadata to 00328 * perform the operations requested by the Print methods. If you 00329 * want to be able to invoke any of the two ::Print methods, 00330 * you need to invoke this method at least once during the 00331 * simulation setup and before any packet is created. 00332 */ 00333 static void EnablePrinting (void); 00334 /** 00335 * The packet metadata is also used to perform extensive 00336 * sanity checks at runtime when performing operations on a 00337 * Packet. For example, this metadata is used to verify that 00338 * when you remove a header from a packet, this same header 00339 * was actually present at the front of the packet. These 00340 * errors will be detected and will abort the program. 00341 */ 00342 static void EnableChecking (void); 00343 00344 /** 00345 * \returns a byte buffer 00346 * 00347 * This method creates a serialized representation of a Packet object 00348 * ready to be transmitted over a network to another system. This 00349 * serialized representation contains a copy of the packet byte buffer, 00350 * the tag list, and the packet metadata (if there is one). 00351 * 00352 * This method will trigger calls to the Serialize and GetSerializedSize 00353 * methods of each tag stored in this packet. 00354 * 00355 * This method will typically be used by parallel simulations where 00356 * the simulated system is partitioned and each partition runs on 00357 * a different CPU. 00358 */ 00359 Buffer Serialize (void) const; 00360 /** 00361 * \param buffer a byte buffer 00362 * 00363 * This method reads a byte buffer as created by Packet::Serialize 00364 * and restores the state of the Packet to what it was prior to 00365 * calling Serialize. 00366 * 00367 * This method will trigger calls to the Deserialize method 00368 * of each tag stored in this packet. 00369 * 00370 * This method will typically be used by parallel simulations where 00371 * the simulated system is partitioned and each partition runs on 00372 * a different CPU. 00373 */ 00374 void Deserialize (Buffer buffer); 00375 00376 /** 00377 * \param tag the new tag to add to this packet 00378 * 00379 * Tag each byte included in this packet with the 00380 * new tag. 00381 * 00382 * Note that adding a tag is a const operation which is pretty 00383 * un-intuitive. The rationale is that the content and behavior of 00384 * a packet is _not_ changed when a tag is added to a packet: any 00385 * code which was not aware of the new tag is going to work just 00386 * the same if the new tag is added. The real reason why adding a 00387 * tag was made a const operation is to allow a trace sink which gets 00388 * a packet to tag the packet, even if the packet is const (and most 00389 * trace sources should use const packets because it would be 00390 * totally evil to allow a trace sink to modify the content of a 00391 * packet). 00392 */ 00393 void AddTag (const Tag &tag) const; 00394 /** 00395 * \returns an iterator over the set of tags included in this packet. 00396 */ 00397 TagIterator GetTagIterator (void) const; 00398 /** 00399 * \param tag the tag to search in this packet 00400 * \returns true if the requested tag type was found, false otherwise. 00401 * 00402 * If the requested tag type is found, it is copied in the user's 00403 * provided tag instance. 00404 */ 00405 bool FindFirstMatchingTag (Tag &tag) const; 00406 00407 /** 00408 * Remove all the tags stored in this packet. 00409 */ 00410 void RemoveAllTags (void); 00411 00412 private: 00413 Packet (const Buffer &buffer, const TagList &tagList, const PacketMetadata &metadata); 00414 Buffer m_buffer; 00415 TagList m_tagList; 00416 PacketMetadata m_metadata; 00417 mutable uint32_t m_refCount; 00418 static uint32_t m_globalUid; 00419 }; 00420 00421 std::ostream& operator<< (std::ostream& os, const Packet &packet); 00422 00423 /** 00424 * \ingroup common 00425 * \defgroup packetperf Packet Performance 00426 * The current implementation of the byte buffers and tag list is based 00427 * on COW (Copy On Write. An introduction to COW can be found in Scott 00428 * Meyer's "More Effective C++", items 17 and 29). What this means is that 00429 * copying packets without modifying them is very cheap (in terms of cpu 00430 * and memory usage) and modifying them can be also very cheap. What is 00431 * key for proper COW implementations is being 00432 * able to detect when a given modification of the state of a packet triggers 00433 * a full copy of the data prior to the modification: COW systems need 00434 * to detect when an operation is "dirty". 00435 * 00436 * Dirty operations: 00437 * - ns3::Packet::AddHeader 00438 * - ns3::Packet::AddTrailer 00439 * - both versions of ns3::Packet::AddAtEnd 00440 * 00441 * Non-dirty operations: 00442 * - ns3::Packet::AddTag 00443 * - ns3::Packet::RemoveAllTags 00444 * - ns3::Packet::PeekTag 00445 * - ns3::Packet::RemoveHeader 00446 * - ns3::Packet::RemoveTrailer 00447 * - ns3::Packet::CreateFragment 00448 * - ns3::Packet::RemoveAtStart 00449 * - ns3::Packet::RemoveAtEnd 00450 * - ns3::Packet::CopyData 00451 * 00452 * Dirty operations will always be slower than non-dirty operations, 00453 * sometimes by several orders of magnitude. However, even the 00454 * dirty operations have been optimized for common use-cases which 00455 * means that most of the time, these operations will not trigger 00456 * data copies and will thus be still very fast. 00457 */ 00458 00459 } // namespace ns3 00460 00461 #endif /* PACKET_H */