A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
packet.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2005,2006 INRIA
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
7 */
8#ifndef PACKET_H
9#define PACKET_H
10
11#include "buffer.h"
12#include "byte-tag-list.h"
13#include "header.h"
14#include "nix-vector.h"
15#include "packet-metadata.h"
16#include "packet-tag-list.h"
17#include "tag.h"
18#include "trailer.h"
19
20#include "ns3/assert.h"
21#include "ns3/callback.h"
22#include "ns3/mac48-address.h"
23#include "ns3/ptr.h"
24
25#include <stdint.h>
26
27namespace ns3
28{
29
30// Forward declaration
31class Address;
32
33/**
34 * @ingroup network
35 * @defgroup packet Packet
36 */
37
38/**
39 * @ingroup packet
40 * @brief Iterator over the set of byte tags in a packet
41 *
42 * This is a java-style iterator.
43 */
45{
46 public:
47 /**
48 * @brief Identifies a byte tag and a set of bytes within a packet
49 * to which the tag applies.
50 */
51 class Item
52 {
53 public:
54 /**
55 * @returns the ns3::TypeId associated to this tag.
56 */
57 TypeId GetTypeId() const;
58 /**
59 * @returns the index of the first byte tagged by this tag.
60 *
61 * @brief The index is an offset from the start of the packet.
62 */
63 uint32_t GetStart() const;
64 /**
65 * @returns the index of the last byte tagged by this tag.
66 *
67 * @brief The index is an offset from the start of the packet.
68 */
69 uint32_t GetEnd() const;
70 /**
71 * @brief Read the requested tag and store it in the user-provided tag instance.
72 *
73 * @param tag the user tag to which the data should be copied.
74 *
75 * This method will crash if the type of the tag provided
76 * by the user does not match the type of the underlying tag.
77 */
78 void GetTag(Tag& tag) const;
79
80 private:
81 /// Friend class
82 friend class ByteTagIterator;
83 /**
84 * @brief Constructor
85 * @param tid the ns3::TypeId associated to this tag.
86 * @param start the index of the first byte tagged by this tag.
87 * @param end the index of the last byte tagged by this tag.
88 * @param buffer the buffer associated with this tag.
89 */
90 Item(TypeId tid, uint32_t start, uint32_t end, TagBuffer buffer);
91
92 TypeId m_tid; //!< the ns3::TypeId associated to this tag.
93 uint32_t m_start; //!< the index of the first byte tagged by this tag.
94 uint32_t m_end; //!< the index of the last byte tagged by this tag.
95 TagBuffer m_buffer; //!< the buffer associated with this tag.
96 };
97
98 /**
99 * @returns true if calling Next is safe, false otherwise.
100 */
101 bool HasNext() const;
102 /**
103 * @returns the next item found and prepare for the next one.
104 */
105 Item Next();
106
107 private:
108 /// Friend class
109 friend class Packet;
110 /**
111 * Copy Constructor
112 * @param i object to copy
113 */
115 ByteTagList::Iterator m_current; //!< actual position over the set of byte tags in a packet
116};
117
118/**
119 * @ingroup packet
120 * @brief Iterator over the set of packet tags in a packet
121 *
122 * This is a java-style iterator.
123 */
125{
126 public:
127 /**
128 * Identifies a packet tag within a packet.
129 */
130 class Item
131 {
132 public:
133 /**
134 * @returns the ns3::TypeId associated to this tag.
135 */
136 TypeId GetTypeId() const;
137 /**
138 * Read the requested tag and store it in the user-provided tag instance.
139 *
140 * @param tag the user tag to which the data should be copied.
141 *
142 * This method will crash if the type of the tag provided
143 * by the user does not match the type of the underlying tag.
144 */
145 void GetTag(Tag& tag) const;
146
147 private:
148 /// Friend class
149 friend class PacketTagIterator;
150 /**
151 * Constructor
152 * @param data the data to copy.
153 */
155 const PacketTagList::TagData* m_data; //!< the tag data
156 };
157
158 /**
159 * @returns true if calling Next is safe, false otherwise.
160 */
161 bool HasNext() const;
162 /**
163 * @returns the next item found and prepare for the next one.
164 */
165 Item Next();
166
167 private:
168 /// Friend class
169 friend class Packet;
170 /**
171 * Constructor
172 * @param head head of the items
173 */
175 const PacketTagList::TagData* m_current; //!< actual position over the set of tags in a packet
176};
177
178/**
179 * @ingroup packet
180 * @brief network packets
181 *
182 * Each network packet contains a byte buffer, a set of byte tags, a set of
183 * packet tags, and metadata.
184 *
185 * - The byte buffer stores the serialized content of the headers and trailers
186 * added to a packet. The serialized representation of these headers is expected
187 * to match that of real network packets bit for bit (although nothing
188 * forces you to do this) which means that the content of a packet buffer
189 * is expected to be that of a real packet.
190 *
191 * - The metadata describes the type of the headers and trailers which
192 * were serialized in the byte buffer. The maintenance of metadata is
193 * optional and disabled by default. To enable it, you must call
194 * Packet::EnablePrinting and this will allow you to get non-empty
195 * output from Packet::Print. If you wish to only enable
196 * checking of metadata, and do not need any printing capability, you can
197 * call Packet::EnableChecking: its runtime cost is lower than
198 * Packet::EnablePrinting.
199 *
200 * - The set of tags contain simulation-specific information which cannot
201 * be stored in the packet byte buffer because the protocol headers or trailers
202 * have no standard-conformant field for this information. So-called
203 * 'byte' tags are used to tag a subset of the bytes in the packet byte buffer
204 * while 'packet' tags are used to tag the packet itself. The main difference
205 * between these two kinds of tags is what happens when packets are copied,
206 * fragmented, and reassembled: 'byte' tags follow bytes while 'packet' tags
207 * follow packets. Another important difference between these two kinds of tags
208 * is that byte tags cannot be removed and are expected to be written once,
209 * and read many times, while packet tags are expected to be written once,
210 * read many times, and removed exactly once. An example of a 'byte'
211 * tag is a FlowIdTag which contains a flow id and is set by the application
212 * generating traffic. An example of a 'packet' tag is a cross-layer
213 * qos class id set by an application and processed by a lower-level MAC
214 * layer.
215 *
216 * Implementing a new type of Header or Trailer for a new protocol is
217 * pretty easy and is a matter of creating a subclass of the ns3::Header
218 * or of the ns3::Trailer base class, and implementing the methods
219 * described in their respective API documentation.
220 *
221 * Implementing a new type of Tag requires roughly the same amount of
222 * work and this work is described in the ns3::Tag API documentation.
223 *
224 * The performance aspects copy-on-write semantics of the
225 * Packet API are discussed in \ref packetperf
226 */
227class Packet : public SimpleRefCount<Packet>
228{
229 public:
230 /**
231 * @brief Create an empty packet with a new uid (as returned
232 * by getUid).
233 */
234 Packet();
235 /**
236 * @brief Copy constructor
237 * @param o object to copy
238 */
239 Packet(const Packet& o);
240 /**
241 * @brief Basic assignment
242 * @param o object to copy
243 * @return the copied object
244 */
245 Packet& operator=(const Packet& o);
246 /**
247 * @brief Create a packet with a zero-filled payload.
248 *
249 * The memory necessary for the payload is not allocated:
250 * it will be allocated at any later point if you attempt
251 * to fragment this packet or to access the zero-filled
252 * bytes. The packet is allocated with a new uid (as
253 * returned by getUid).
254 *
255 * @param size the size of the zero-filled payload
256 */
257 Packet(uint32_t size);
258 /**
259 * @brief Create a new packet from the serialized buffer.
260 *
261 * This new packet
262 * is identical to the serialized packet contained in the buffer
263 * and is magically deserialized for you
264 *
265 * @param buffer the serialized packet to be created
266 * @param size the size of the packet for deserialization
267 * @param magic allows packet deserialization;
268 * asserts when set to false
269 */
270 Packet(const uint8_t* buffer, uint32_t size, bool magic);
271 /**
272 * @brief Create a packet with payload filled with the content
273 * of this buffer.
274 *
275 * The input data is copied: the input
276 * buffer is untouched.
277 *
278 * @param buffer the data to store in the packet.
279 * @param size the size of the input buffer.
280 */
281 Packet(const uint8_t* buffer, uint32_t size);
282 /**
283 * @brief Create a new packet which contains a fragment of the original
284 * packet.
285 *
286 * The returned packet shares the same uid as this packet.
287 *
288 * @param start offset from start of packet to start of fragment to create
289 * @param length length of fragment to create
290 * @returns a fragment of the original packet
291 */
292 Ptr<Packet> CreateFragment(uint32_t start, uint32_t length) const;
293 /**
294 * @brief Returns the the size in bytes of the packet (including the zero-filled
295 * initial payload).
296 *
297 * @returns the size in bytes of the packet
298 */
299 inline uint32_t GetSize() const;
300 /**
301 * @brief Add header to this packet.
302 *
303 * This method invokes the
304 * Header::GetSerializedSize and Header::Serialize
305 * methods to reserve space in the buffer and request the
306 * header to serialize itself in the packet buffer.
307 *
308 * @param header a reference to the header to add to this packet.
309 */
310 void AddHeader(const Header& header);
311 /**
312 * @brief Deserialize and remove the header from the internal buffer.
313 *
314 * This method invokes Header::Deserialize (begin) and should be used for
315 * fixed-length headers.
316 *
317 * @param header a reference to the header to remove from the internal buffer.
318 * @returns the number of bytes removed from the packet.
319 */
321 /**
322 * @brief Deserialize and remove the header from the internal buffer.
323 *
324 * This method invokes Header::Deserialize (begin, end) and should be
325 * used for variable-length headers (where the size is determined somehow
326 * by the caller).
327 *
328 * @param header a reference to the header to remove from the internal buffer.
329 * @param size number of bytes to deserialize
330 * @returns the number of bytes removed from the packet.
331 */
332 uint32_t RemoveHeader(Header& header, uint32_t size);
333 /**
334 * @brief Deserialize but does _not_ remove the header from the internal buffer.
335 * s
336 * This method invokes Header::Deserialize.
337 *
338 * @param header a reference to the header to read from the internal buffer.
339 * @returns the number of bytes read from the packet.
340 */
341 uint32_t PeekHeader(Header& header) const;
342 /**
343 * @brief Deserialize but does _not_ remove the header from the internal buffer.
344 * s
345 * This method invokes Header::Deserialize (begin, end) and should be used
346 * for variable-length headers (where the size is determined somehow
347 * by the caller).
348 *
349 * @param header a reference to the header to read from the internal buffer.
350 * @param size number of bytes to deserialize
351 * @returns the number of bytes read from the packet.
352 */
353 uint32_t PeekHeader(Header& header, uint32_t size) const;
354 /**
355 * @brief Add trailer to this packet.
356 *
357 * This method invokes the
358 * Trailer::GetSerializedSize and Trailer::Serialize
359 * methods to reserve space in the buffer and request the trailer
360 * to serialize itself in the packet buffer.
361 *
362 * @param trailer a reference to the trailer to add to this packet.
363 */
364 void AddTrailer(const Trailer& trailer);
365 /**
366 * @brief Remove a deserialized trailer from the internal buffer.
367 *
368 * This method invokes the Deserialize method.
369 *
370 * @param trailer a reference to the trailer to remove from the internal buffer.
371 * @returns the number of bytes removed from the end of the packet.
372 */
374 /**
375 * @brief Deserialize but does _not_ remove a trailer from the internal buffer.
376 *
377 * This method invokes the Trailer::Deserialize method.
378 *
379 * @param trailer a reference to the trailer to read from the internal buffer.
380 * @returns the number of bytes read from the end of the packet.
381 */
382 uint32_t PeekTrailer(Trailer& trailer);
383
384 /**
385 * @brief Concatenate the input packet at the end of the current
386 * packet.
387 *
388 * This does not alter the uid of either packet.
389 *
390 * @param packet packet to concatenate
391 */
392 void AddAtEnd(Ptr<const Packet> packet);
393 /**
394 * @brief Add a zero-filled padding to the packet.
395 *
396 * @param size number of padding bytes to add.
397 */
398 void AddPaddingAtEnd(uint32_t size);
399 /**
400 * @brief Remove size bytes from the end of the current packet.
401 *
402 * It is safe to remove more bytes than are present in
403 * the packet.
404 *
405 * @param size number of bytes from remove
406 */
407 void RemoveAtEnd(uint32_t size);
408 /**
409 * @brief Remove size bytes from the start of the current packet.
410 *
411 * It is safe to remove more bytes than are present in
412 * the packet.
413 *
414 * @param size number of bytes from remove
415 */
416 void RemoveAtStart(uint32_t size);
417
418 /**
419 * @brief Copy the packet contents to a byte buffer.
420 *
421 * @param buffer a pointer to a byte buffer where the packet data
422 * should be copied.
423 * @param size the size of the byte buffer.
424 * @returns the number of bytes read from the packet
425 *
426 * No more than \b size bytes will be copied by this function.
427 */
428 uint32_t CopyData(uint8_t* buffer, uint32_t size) const;
429
430 /**
431 * @brief Copy the packet contents to an output stream.
432 *
433 * @param os pointer to output stream in which we want
434 * to write the packet data.
435 * @param size the maximum number of bytes we want to write
436 * in the output stream.
437 */
438 void CopyData(std::ostream* os, uint32_t size) const;
439
440 /**
441 * @brief performs a COW copy of the packet.
442 *
443 * @returns a COW copy of the packet.
444 *
445 * The returns packet will behave like an independent copy of
446 * the original packet, even though they both share the
447 * same datasets internally.
448 */
449 Ptr<Packet> Copy() const;
450
451 /**
452 * @brief Returns the packet's Uid.
453 *
454 * A packet is allocated a new uid when it is created
455 * empty or with zero-filled payload.
456 *
457 * Note: This uid is an internal uid and cannot be counted on to
458 * provide an accurate counter of how many "simulated packets" of a
459 * particular protocol are in the system. It is not trivial to make
460 * this uid into such a counter, because of questions such as what
461 * should the uid be when the packet is sent over broadcast media, or
462 * when fragmentation occurs. If a user wants to trace actual packet
463 * counts, he or she should look at e.g. the IP ID field or transport
464 * sequence numbers, or other packet or frame counters at other
465 * protocol layers.
466 *
467 * @returns an integer identifier which uniquely
468 * identifies this packet.
469 */
470 uint64_t GetUid() const;
471
472 /**
473 * @brief Print the packet contents.
474 *
475 * @param os output stream in which the data should be printed.
476 *
477 * Iterate over the headers and trailers present in this packet,
478 * from the first header to the last trailer and invoke, for
479 * each of them, the user-provided method Header::DoPrint or
480 * Trailer::DoPrint methods.
481 */
482 void Print(std::ostream& os) const;
483
484 /**
485 * @brief Return a string representation of the packet
486 *
487 * An empty string is returned if you haven't called EnablePrinting ()
488 *
489 * @return String representation
490 */
491 std::string ToString() const;
492
493 /**
494 * @brief Returns an iterator which points to the first 'item'
495 * stored in this buffer.
496 *
497 * Note that this iterator will point
498 * to an empty array of items if you don't call EnablePrinting
499 * or EnableChecking before.
500 *
501 * @returns an iterator
502 *
503 * \sa EnablePrinting EnableChecking
504 */
506
507 /**
508 * @brief Enable printing packets metadata.
509 *
510 * By default, packets do not keep around enough metadata to
511 * perform the operations requested by the Print methods. If you
512 * want to be able the Packet::Print method,
513 * you need to invoke this method at least once during the
514 * simulation setup and before any packet is created.
515 */
516 static void EnablePrinting();
517 /**
518 * @brief Enable packets metadata checking.
519 *
520 * The packet metadata is also used to perform extensive
521 * sanity checks at runtime when performing operations on a
522 * Packet. For example, this metadata is used to verify that
523 * when you remove a header from a packet, this same header
524 * was actually present at the front of the packet. These
525 * errors will be detected and will abort the program.
526 */
527 static void EnableChecking();
528
529 /**
530 * @brief Returns number of bytes required for packet
531 * serialization.
532 *
533 * @returns number of bytes required for packet
534 * serialization
535 *
536 * For packet serialization, the total size is checked
537 * in order to determine the size of the buffer
538 * required for serialization
539 */
541
542 /**
543 * @brief Serialize a packet, tags, and metadata into a byte buffer.
544 *
545 * @param buffer a raw byte buffer to which the packet will be serialized
546 * @param maxSize the max size of the buffer for bounds checking
547 *
548 * @returns one if all data were serialized, zero if buffer size was too small.
549 */
550 uint32_t Serialize(uint8_t* buffer, uint32_t maxSize) const;
551
552 /**
553 * @brief Tag each byte included in this packet with a new byte tag.
554 *
555 * @param tag the new tag to add to this packet
556 *
557 * Note that adding a tag is a const operation which is pretty
558 * un-intuitive. The rationale is that the content and behavior of
559 * a packet is _not_ changed when a tag is added to a packet: any
560 * code which was not aware of the new tag is going to work just
561 * the same if the new tag is added. The real reason why adding a
562 * tag was made a const operation is to allow a trace sink which gets
563 * a packet to tag the packet, even if the packet is const (and most
564 * trace sources should use const packets because it would be
565 * totally evil to allow a trace sink to modify the content of a
566 * packet).
567 */
568 void AddByteTag(const Tag& tag) const;
569
570 /**
571 * @brief Tag the indicated byte range of this packet with a new byte tag.
572 *
573 * As parameters for this method, we do not use indexes, but byte position.
574 * Moreover, as there is no 0-th position, the first position is 1.
575 *
576 * As example, if you want to tag the first 10 bytes, you have to call
577 * the method in this way:
578 *
579 * \code{.cpp}
580 Ptr<Packet> p = ... ;
581 SomeTag tag;
582 p->AddByteTag (tag, 1, 10);
583 \endcode
584 *
585 * @param tag the new tag to add to this packet
586 * @param start the position of the first byte tagged by this tag
587 * @param end the position of the last byte tagged by this tag
588 */
589 void AddByteTag(const Tag& tag, uint32_t start, uint32_t end) const;
590 /**
591 * @brief Returns an iterator over the set of byte tags included in this packet
592 *
593 * @returns an iterator over the set of byte tags included in this packet.
594 */
596 /**
597 * @brief Finds the first tag matching the parameter Tag type
598 *
599 * @param tag the byte tag type to search in this packet
600 * @returns true if the requested tag type was found, false otherwise.
601 *
602 * If the requested tag type is found, it is copied in the user's
603 * provided tag instance.
604 */
605 bool FindFirstMatchingByteTag(Tag& tag) const;
606
607 /**
608 * @brief Remove all byte tags stored in this packet.
609 */
610 void RemoveAllByteTags();
611
612 /**
613 * @param os output stream in which the data should be printed.
614 *
615 * @brief Iterate over the byte tags present in this packet, and
616 * invoke the Print method of each tag stored in the packet.
617 */
618 void PrintByteTags(std::ostream& os) const;
619
620 /**
621 * @brief Add a packet tag.
622 *
623 * @param tag the packet tag type to add.
624 *
625 * Note that this method is const, that is, it does not
626 * modify the state of this packet, which is fairly
627 * un-intuitive. See AddByteTag"()" discussion.
628 */
629 void AddPacketTag(const Tag& tag) const;
630 /**
631 * @brief Remove a packet tag.
632 *
633 * @param tag the packet tag type to remove from this packet.
634 * The tag parameter is set to the value of the tag found.
635 * @returns true if the requested tag is found, false
636 * otherwise.
637 */
638 bool RemovePacketTag(Tag& tag);
639 /**
640 * @brief Replace the value of a packet tag.
641 *
642 * @param tag the packet tag type to replace. To get the old
643 * value of the tag, use PeekPacketTag first.
644 * @returns true if the requested tag is found, false otherwise.
645 * If the tag isn't found, Add is performed instead (so
646 * the packet is guaranteed to have the new tag value
647 * either way).
648 */
649 bool ReplacePacketTag(Tag& tag);
650 /**
651 * @brief Search a matching tag and call Tag::Deserialize if it is found.
652 *
653 * @param tag the tag to search in this packet
654 * @returns true if the requested tag is found, false
655 * otherwise.
656 */
657 bool PeekPacketTag(Tag& tag) const;
658 /**
659 * @brief Remove all packet tags.
660 */
661 void RemoveAllPacketTags();
662
663 /**
664 * @brief Print the list of packet tags.
665 *
666 * @param os the stream on which to print the tags.
667 *
668 * \sa Packet::AddPacketTag, Packet::RemovePacketTag, Packet::PeekPacketTag,
669 * Packet::RemoveAllPacketTags
670 */
671 void PrintPacketTags(std::ostream& os) const;
672
673 /**
674 * @brief Returns an object which can be used to iterate over the list of
675 * packet tags.
676 *
677 * @returns an object which can be used to iterate over the list of
678 * packet tags.
679 */
681
682 /**
683 * @brief Set the packet nix-vector.
684 *
685 * @note Note: This function supports a temporary solution
686 * to a specific problem in this generic class, i.e.
687 * how to associate something specific like nix-vector
688 * with a packet. This design methodology
689 * should _not_ be followed, and is only here as an
690 * impetus to fix this general issue.
691 *
692 * @warning For real this function is not const, as it is the
693 * setter for a mutable variable member. The const qualifier
694 * is needed to set a private mutable variable of const objects.
695 *
696 * @param nixVector the nix vector
697 */
698 void SetNixVector(Ptr<NixVector> nixVector) const;
699 /**
700 * @brief Get the packet nix-vector.
701 *
702 * See the comment on SetNixVector
703 *
704 * @returns the Nix vector
705 */
707
708 /**
709 * TracedCallback signature for Ptr<Packet>
710 *
711 * @param [in] packet The packet.
712 */
713 typedef void (*TracedCallback)(Ptr<const Packet> packet);
714
715 /**
716 * TracedCallback signature for packet and Address.
717 *
718 * @param [in] packet The packet.
719 * @param [in] address The address.
720 */
721 typedef void (*AddressTracedCallback)(Ptr<const Packet> packet, const Address& address);
722
723 /**
724 * TracedCallback signature for packet and source/destination addresses.
725 *
726 * @param [in] packet The packet.
727 * @param [in] srcAddress The source address.
728 * @param [in] destAddress The destination address.
729 */
730 typedef void (*TwoAddressTracedCallback)(const Ptr<const Packet> packet,
731 const Address& srcAddress,
732 const Address& destAddress);
733
734 /**
735 * TracedCallback signature for packet and Mac48Address.
736 *
737 * @param [in] packet The packet.
738 * @param [in] mac The Mac48Address.
739 */
741
742 /**
743 * TracedCallback signature for changes in packet size.
744 *
745 * @param [in] oldSize The previous packet's size.
746 * @param [in] newSize The actual packet's size.
747 */
748 typedef void (*SizeTracedCallback)(uint32_t oldSize, uint32_t newSize);
749
750 /**
751 * TracedCallback signature for packet and SINR.
752 *
753 * @param [in] packet The packet.
754 * @param [in] sinr The received SINR.
755 */
756 typedef void (*SinrTracedCallback)(Ptr<const Packet> packet, double sinr);
757
758 private:
759 /**
760 * @brief Constructor
761 * @param buffer the packet buffer
762 * @param byteTagList the ByteTag list
763 * @param packetTagList the packet's Tag list
764 * @param metadata the packet's metadata
765 */
766 Packet(const Buffer& buffer,
767 const ByteTagList& byteTagList,
768 const PacketTagList& packetTagList,
769 const PacketMetadata& metadata);
770
771 /**
772 * @brief Deserializes a packet.
773 * @param [in] buffer the input buffer.
774 * @param [in] size the buffer size.
775 * @returns the number of deserialized bytes.
776 */
777 uint32_t Deserialize(const uint8_t* buffer, uint32_t size);
778
779 Buffer m_buffer; //!< the packet buffer (it's actual contents)
780 ByteTagList m_byteTagList; //!< the ByteTag list
781 PacketTagList m_packetTagList; //!< the packet's Tag list
782 PacketMetadata m_metadata; //!< the packet's metadata
783
784 /* Please see comments above about nix-vector */
785 mutable Ptr<NixVector> m_nixVector; //!< the packet's Nix vector
786
787 static uint32_t m_globalUid; //!< Global counter of packets Uid
788};
789
790/**
791 * @brief Stream insertion operator.
792 *
793 * @param os the stream
794 * @param packet the packet
795 * @returns a reference to the stream
796 */
797std::ostream& operator<<(std::ostream& os, const Packet& packet);
798
799/**
800 * @ingroup network
801 * @defgroup packetperf Packet Performance
802 * The current implementation of the byte buffers and tag list is based
803 * on COW (Copy On Write. An introduction to COW can be found in Scott
804 * Meyer's "More Effective C++", items 17 and 29). What this means is that
805 * copying packets without modifying them is very cheap (in terms of cpu
806 * and memory usage) and modifying them can be also very cheap. What is
807 * key for proper COW implementations is being
808 * able to detect when a given modification of the state of a packet triggers
809 * a full copy of the data prior to the modification: COW systems need
810 * to detect when an operation is "dirty".
811 *
812 * Dirty operations:
813 * - ns3::Packet::AddHeader
814 * - ns3::Packet::AddTrailer
815 * - both versions of ns3::Packet::AddAtEnd
816 * - ns3::Packet::RemovePacketTag
817 * - ns3::Packet::ReplacePacketTag
818 *
819 * Non-dirty operations:
820 * - ns3::Packet::AddPacketTag
821 * - ns3::Packet::PeekPacketTag
822 * - ns3::Packet::RemoveAllPacketTags
823 * - ns3::Packet::AddByteTag
824 * - ns3::Packet::FindFirstMatchingByteTag
825 * - ns3::Packet::RemoveAllByteTags
826 * - ns3::Packet::RemoveHeader
827 * - ns3::Packet::RemoveTrailer
828 * - ns3::Packet::CreateFragment
829 * - ns3::Packet::RemoveAtStart
830 * - ns3::Packet::RemoveAtEnd
831 * - ns3::Packet::CopyData
832 *
833 * Dirty operations will always be slower than non-dirty operations,
834 * sometimes by several orders of magnitude. However, even the
835 * dirty operations have been optimized for common use-cases which
836 * means that most of the time, these operations will not trigger
837 * data copies and will thus be still very fast.
838 */
839
840} // namespace ns3
841
842/****************************************************
843 * Implementation of inline methods for performance
844 ****************************************************/
845
846namespace ns3
847{
848
851{
852 return m_buffer.GetSize();
853}
854
855} // namespace ns3
856
857#endif /* PACKET_H */
a polymophic address class
Definition address.h:90
automatically resized byte buffer
Definition buffer.h:83
uint32_t GetSize() const
Definition buffer.h:1057
Identifies a byte tag and a set of bytes within a packet to which the tag applies.
Definition packet.h:52
TypeId m_tid
the ns3::TypeId associated to this tag.
Definition packet.h:92
uint32_t m_start
the index of the first byte tagged by this tag.
Definition packet.h:93
uint32_t GetEnd() const
The index is an offset from the start of the packet.
Definition packet.cc:37
TagBuffer m_buffer
the buffer associated with this tag.
Definition packet.h:95
Item(TypeId tid, uint32_t start, uint32_t end, TagBuffer buffer)
Constructor.
Definition packet.cc:52
void GetTag(Tag &tag) const
Read the requested tag and store it in the user-provided tag instance.
Definition packet.cc:43
uint32_t GetStart() const
The index is an offset from the start of the packet.
Definition packet.cc:31
uint32_t m_end
the index of the last byte tagged by this tag.
Definition packet.h:94
TypeId GetTypeId() const
Definition packet.cc:25
Iterator over the set of byte tags in a packet.
Definition packet.h:45
ByteTagIterator(ByteTagList::Iterator i)
Copy Constructor.
Definition packet.cc:76
bool HasNext() const
Definition packet.cc:61
ByteTagList::Iterator m_current
actual position over the set of byte tags in a packet
Definition packet.h:115
An iterator for iterating through a byte tag list.
keep track of the byte tags stored in a packet.
Protocol header serialization and deserialization.
Definition header.h:33
an EUI-48 address
network packets
Definition packet.h:228
void(* SizeTracedCallback)(uint32_t oldSize, uint32_t newSize)
TracedCallback signature for changes in packet size.
Definition packet.h:748
PacketTagIterator GetPacketTagIterator() const
Returns an object which can be used to iterate over the list of packet tags.
Definition packet.cc:1009
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition packet.cc:956
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition packet.cc:283
Buffer m_buffer
the packet buffer (it's actual contents)
Definition packet.h:779
static void EnableChecking()
Enable packets metadata checking.
Definition packet.cc:592
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
Definition packet.cc:343
void(* Mac48AddressTracedCallback)(Ptr< const Packet > packet, Mac48Address mac)
TracedCallback signature for packet and Mac48Address.
Definition packet.h:740
uint32_t RemoveTrailer(Trailer &trailer)
Remove a deserialized trailer from the internal buffer.
Definition packet.cc:325
PacketMetadata::ItemIterator BeginItem() const
Returns an iterator which points to the first 'item' stored in this buffer.
Definition packet.cc:579
void SetNixVector(Ptr< NixVector > nixVector) const
Set the packet nix-vector.
Definition packet.cc:245
ByteTagList m_byteTagList
the ByteTag list
Definition packet.h:780
void(* AddressTracedCallback)(Ptr< const Packet > packet, const Address &address)
TracedCallback signature for packet and Address.
Definition packet.h:721
void(* TwoAddressTracedCallback)(const Ptr< const Packet > packet, const Address &srcAddress, const Address &destAddress)
TracedCallback signature for packet and source/destination addresses.
Definition packet.h:730
Ptr< NixVector > GetNixVector() const
Get the packet nix-vector.
Definition packet.cc:251
void PrintByteTags(std::ostream &os) const
Iterate over the byte tags present in this packet, and invoke the Print method of each tag stored in ...
Definition packet.cc:407
void(* SinrTracedCallback)(Ptr< const Packet > packet, double sinr)
TracedCallback signature for packet and SINR.
Definition packet.h:756
void AddHeader(const Header &header)
Add header to this packet.
Definition packet.cc:257
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition packet.h:850
static uint32_t m_globalUid
Global counter of packets Uid.
Definition packet.h:787
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Copy the packet contents to a byte buffer.
Definition packet.cc:389
void RemoveAtEnd(uint32_t size)
Remove size bytes from the end of the current packet.
Definition packet.cc:365
uint32_t Deserialize(const uint8_t *buffer, uint32_t size)
Deserializes a packet.
Definition packet.cc:794
uint32_t GetSerializedSize() const
Returns number of bytes required for packet serialization.
Definition packet.cc:599
void RemoveAtStart(uint32_t size)
Remove size bytes from the start of the current packet.
Definition packet.cc:373
PacketTagList m_packetTagList
the packet's Tag list
Definition packet.h:781
Ptr< Packet > Copy() const
performs a COW copy of the packet.
Definition packet.cc:120
void PrintPacketTags(std::ostream &os) const
Print the list of packet tags.
Definition packet.cc:986
Packet & operator=(const Packet &o)
Basic assignment.
Definition packet.cc:154
bool FindFirstMatchingByteTag(Tag &tag) const
Finds the first tag matching the parameter Tag type.
Definition packet.cc:932
uint32_t Serialize(uint8_t *buffer, uint32_t maxSize) const
Serialize a packet, tags, and metadata into a byte buffer.
Definition packet.cc:652
void RemoveAllByteTags()
Remove all byte tags stored in this packet.
Definition packet.cc:382
Packet()
Create an empty packet with a new uid (as returned by getUid).
Definition packet.cc:128
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition packet.cc:949
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition packet.cc:294
void RemoveAllPacketTags()
Remove all packet tags.
Definition packet.cc:979
Ptr< Packet > CreateFragment(uint32_t start, uint32_t length) const
Create a new packet which contains a fragment of the original packet.
Definition packet.cc:227
uint32_t PeekTrailer(Trailer &trailer)
Deserialize but does not remove a trailer from the internal buffer.
Definition packet.cc:335
void Print(std::ostream &os) const
Print the packet contents.
Definition packet.cc:445
uint64_t GetUid() const
Returns the packet's Uid.
Definition packet.cc:401
void AddByteTag(const Tag &tag) const
Tag each byte included in this packet with a new byte tag.
Definition packet.cc:904
std::string ToString() const
Return a string representation of the packet.
Definition packet.cc:437
static void EnablePrinting()
Enable printing packets metadata.
Definition packet.cc:585
void AddTrailer(const Trailer &trailer)
Add trailer to this packet.
Definition packet.cc:313
void AddPaddingAtEnd(uint32_t size)
Add a zero-filled padding to the packet.
Definition packet.cc:356
bool PeekPacketTag(Tag &tag) const
Search a matching tag and call Tag::Deserialize if it is found.
Definition packet.cc:972
ByteTagIterator GetByteTagIterator() const
Returns an iterator over the set of byte tags included in this packet.
Definition packet.cc:926
PacketMetadata m_metadata
the packet's metadata
Definition packet.h:782
Ptr< NixVector > m_nixVector
the packet's Nix vector
Definition packet.h:785
bool ReplacePacketTag(Tag &tag)
Replace the value of a packet tag.
Definition packet.cc:964
Iterator class for metadata items.
Handle packet metadata about packet headers and trailers.
Identifies a packet tag within a packet.
Definition packet.h:131
Item(const PacketTagList::TagData *data)
Constructor.
Definition packet.cc:101
TypeId GetTypeId() const
Definition packet.cc:107
void GetTag(Tag &tag) const
Read the requested tag and store it in the user-provided tag instance.
Definition packet.cc:113
const PacketTagList::TagData * m_data
the tag data
Definition packet.h:155
Iterator over the set of packet tags in a packet.
Definition packet.h:125
const PacketTagList::TagData * m_current
actual position over the set of tags in a packet
Definition packet.h:175
bool HasNext() const
Definition packet.cc:87
PacketTagIterator(const PacketTagList::TagData *head)
Constructor.
Definition packet.cc:81
List of the packet tags stored in a packet.
Smart pointer class similar to boost::intrusive_ptr.
A template-based reference counting class.
read and write tag data
Definition tag-buffer.h:41
tag a set of bytes in a packet
Definition tag.h:28
Forward calls to a chain of Callback.
Protocol trailer serialization and deserialization.
Definition trailer.h:30
a unique identifier for an interface.
Definition type-id.h:48
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition angles.cc:148
Defines a linked list of Packet tags, including copy-on-write semantics.
uint8_t data[writeSize]
Tree node for sharing serialized tags.