A Discrete-Event Network Simulator
API
packet-metadata.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2006,2007 INRIA
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18  */
19 #ifndef PACKET_METADATA_H
20 #define PACKET_METADATA_H
21 
22 #include "buffer.h"
23 
24 #include "ns3/assert.h"
25 #include "ns3/callback.h"
26 #include "ns3/type-id.h"
27 
28 #include <limits>
29 #include <stdint.h>
30 #include <vector>
31 
32 namespace ns3
33 {
34 
35 class Chunk;
36 class Buffer;
37 class Header;
38 class Trailer;
39 
81 {
82  public:
86  struct Item
87  {
89  enum ItemType
90  {
93  TRAILER
94  };
95 
100 
115  uint32_t currentSize;
131  };
132 
137  {
138  public:
144  ItemIterator(const PacketMetadata* metadata, Buffer buffer);
149  bool HasNext() const;
154  Item Next();
155 
156  private:
159  uint16_t m_current;
160  uint32_t m_offset;
162  };
163 
167  static void Enable();
171  static void EnableChecking();
172 
178  inline PacketMetadata(uint64_t uid, uint32_t size);
183  inline PacketMetadata(const PacketMetadata& o);
189  inline PacketMetadata& operator=(const PacketMetadata& o);
190  inline ~PacketMetadata();
191 
192  // Delete default constructor to avoid misuse
193  PacketMetadata() = delete;
194 
200  void AddHeader(const Header& header, uint32_t size);
206  void RemoveHeader(const Header& header, uint32_t size);
207 
213  void AddTrailer(const Trailer& trailer, uint32_t size);
219  void RemoveTrailer(const Trailer& trailer, uint32_t size);
220 
231  PacketMetadata CreateFragment(uint32_t start, uint32_t end) const;
232 
237  void AddAtEnd(const PacketMetadata& o);
242  void AddPaddingAtEnd(uint32_t end);
247  void RemoveAtStart(uint32_t start);
252  void RemoveAtEnd(uint32_t end);
253 
258  uint64_t GetUid() const;
259 
264  uint32_t GetSerializedSize() const;
265 
271  ItemIterator BeginItem(Buffer buffer) const;
272 
279  uint32_t Serialize(uint8_t* buffer, uint32_t maxSize) const;
286  uint32_t Deserialize(const uint8_t* buffer, uint32_t size);
287 
288  private:
298  static uint8_t* AddToRawU8(const uint8_t& data,
299  uint8_t* start,
300  uint8_t* current,
301  uint32_t maxSize);
302 
312  static uint8_t* AddToRawU16(const uint16_t& data,
313  uint8_t* start,
314  uint8_t* current,
315  uint32_t maxSize);
316 
326  static uint8_t* AddToRawU32(const uint32_t& data,
327  uint8_t* start,
328  uint8_t* current,
329  uint32_t maxSize);
330 
340  static uint8_t* AddToRawU64(const uint64_t& data,
341  uint8_t* start,
342  uint8_t* current,
343  uint32_t maxSize);
344 
355  static uint8_t* AddToRaw(const uint8_t* data,
356  uint32_t dataSize,
357  uint8_t* start,
358  uint8_t* current,
359  uint32_t maxSize);
360 
370  static uint8_t* ReadFromRawU8(uint8_t& data,
371  const uint8_t* start,
372  const uint8_t* current,
373  uint32_t maxSize);
374 
384  static uint8_t* ReadFromRawU16(uint16_t& data,
385  const uint8_t* start,
386  const uint8_t* current,
387  uint32_t maxSize);
388 
398  static uint8_t* ReadFromRawU32(uint32_t& data,
399  const uint8_t* start,
400  const uint8_t* current,
401  uint32_t maxSize);
402 
412  static uint8_t* ReadFromRawU64(uint64_t& data,
413  const uint8_t* start,
414  const uint8_t* current,
415  uint32_t maxSize);
416 
421 #define PACKET_METADATA_DATA_M_DATA_SIZE 8
422 
426  struct Data
427  {
429  uint32_t m_count;
431  uint32_t m_size;
433  uint16_t m_dirtyEnd;
436  };
437 
438  /* Note that since the next and prev fields are 16 bit integers
439  and since the value 0xffff is reserved to identify the
440  fact that the end or the start of the list is reached,
441  only a limited number of elements can be stored in
442  a m_data byte buffer.
443  */
447  struct SmallItem
448  {
454  uint16_t next;
460  uint16_t prev;
468  uint32_t typeUid;
473  uint32_t size;
486  uint16_t chunkUid;
487  };
488 
492  struct ExtraItem
493  {
498  uint32_t fragmentStart;
503  uint32_t fragmentEnd;
509  uint64_t packetUid;
510  };
511 
515  class DataFreeList : public std::vector<Data*>
516  {
517  public:
518  ~DataFreeList();
519  };
520 
523  friend class ItemIterator;
524 
530  inline uint16_t AddSmall(const PacketMetadata::SmallItem* item);
539  uint16_t AddBig(uint32_t head,
540  uint32_t tail,
541  const PacketMetadata::SmallItem* item,
542  const PacketMetadata::ExtraItem* extraItem);
551  PacketMetadata::ExtraItem* extraItem,
552  uint32_t available);
557  inline void UpdateHead(uint16_t written);
562  inline void UpdateTail(uint16_t written);
563 
569  inline uint32_t GetUleb128Size(uint32_t value) const;
575  uint32_t ReadUleb128(const uint8_t** pBuffer) const;
581  inline void Append16(uint16_t value, uint8_t* buffer);
587  inline void Append32(uint32_t value, uint8_t* buffer);
593  inline void AppendValue(uint32_t value, uint8_t* buffer);
602  void AppendValueExtra(uint32_t value, uint8_t* buffer);
603 
608  inline void Reserve(uint32_t n);
613  void ReserveCopy(uint32_t n);
614 
619  uint32_t GetTotalSize() const;
620 
628  uint32_t ReadItems(uint16_t current,
630  PacketMetadata::ExtraItem* extraItem) const;
636  void DoAddHeader(uint32_t uid, uint32_t size);
641  bool IsStateOk() const;
647  bool IsPointerOk(uint16_t pointer) const;
653  bool IsSharedPointerOk(uint16_t pointer) const;
654 
659  static void Recycle(PacketMetadata::Data* data);
665  static PacketMetadata::Data* Create(uint32_t size);
671  static PacketMetadata::Data* Allocate(uint32_t n);
676  static void Deallocate(PacketMetadata::Data* data);
677 
679  static bool m_enable;
680  static bool m_enableChecking;
681 
687  static bool m_metadataSkipped;
688 
689  static uint32_t m_maxSize;
690  static uint16_t m_chunkUid;
691 
693  /*
694  head -(next)-> tail
695  ^ |
696  \---(prev)---|
697  */
698  uint16_t m_head;
699  uint16_t m_tail;
700  uint32_t m_used;
701  uint64_t m_packetUid;
702 };
703 
704 } // namespace ns3
705 
706 namespace ns3
707 {
708 
709 PacketMetadata::PacketMetadata(uint64_t uid, uint32_t size)
710  : m_data(PacketMetadata::Create(10)),
711  m_head(0xffff),
712  m_tail(0xffff),
713  m_used(0),
714  m_packetUid(uid)
715 {
716  memset(m_data->m_data, 0xff, 4);
717  if (size > 0)
718  {
719  DoAddHeader(0, size);
720  }
721 }
722 
724  : m_data(o.m_data),
725  m_head(o.m_head),
726  m_tail(o.m_tail),
727  m_used(o.m_used),
728  m_packetUid(o.m_packetUid)
729 {
730  NS_ASSERT(m_data != nullptr);
732  m_data->m_count++;
733 }
734 
737 {
738  if (m_data != o.m_data)
739  {
740  // not self assignment
741  NS_ASSERT(m_data != nullptr);
742  m_data->m_count--;
743  if (m_data->m_count == 0)
744  {
746  }
747  m_data = o.m_data;
748  NS_ASSERT(m_data != nullptr);
749  m_data->m_count++;
750  }
751  m_head = o.m_head;
752  m_tail = o.m_tail;
753  m_used = o.m_used;
755  return *this;
756 }
757 
759 {
760  NS_ASSERT(m_data != nullptr);
761  m_data->m_count--;
762  if (m_data->m_count == 0)
763  {
765  }
766 }
767 
768 } // namespace ns3
769 
770 #endif /* PACKET_METADATA_H */
#define max(a, b)
Definition: 80211b.c:42
iterator in a Buffer instance
Definition: buffer.h:100
automatically resized byte buffer
Definition: buffer.h:94
Protocol header serialization and deserialization.
Definition: header.h:44
Class to hold all the metadata.
Iterator class for metadata items.
uint16_t m_current
current position
Buffer m_buffer
buffer the metadata refers to
const PacketMetadata * m_metadata
pointer to the metadata
bool m_hasReadTail
true if the metadata tail has been read
bool HasNext() const
Checks if there is another metadata item.
Item Next()
Retrieve the next metadata item.
ItemIterator(const PacketMetadata *metadata, Buffer buffer)
Constructor.
Handle packet metadata about packet headers and trailers.
uint32_t m_used
used portion
static uint8_t * ReadFromRawU64(uint64_t &data, const uint8_t *start, const uint8_t *current, uint32_t maxSize)
Helper for the raw deserialization.
uint32_t GetSerializedSize() const
Get the metadata serialized size.
void ReplaceTail(PacketMetadata::SmallItem *item, PacketMetadata::ExtraItem *extraItem, uint32_t available)
Replace the tail.
PacketMetadata CreateFragment(uint32_t start, uint32_t end) const
Creates a fragment.
Data * m_data
Metadata storage.
PacketMetadata & operator=(const PacketMetadata &o)
Basic assignment.
void ReserveCopy(uint32_t n)
Reserve space and make a metadata copy.
void AddHeader(const Header &header, uint32_t size)
Add an header.
uint32_t ReadItems(uint16_t current, PacketMetadata::SmallItem *item, PacketMetadata::ExtraItem *extraItem) const
Read items.
static void Deallocate(PacketMetadata::Data *data)
Deallocate the buffer memory.
void AppendValueExtra(uint32_t value, uint8_t *buffer)
Append a value to the buffer - extra.
static PacketMetadata::Data * Create(uint32_t size)
Create a buffer data storage.
void Append32(uint32_t value, uint8_t *buffer)
Append a 32-bit value to the buffer.
static uint32_t m_maxSize
maximum metadata size
static bool m_enableChecking
Enable the packet metadata checking.
void UpdateHead(uint16_t written)
Update the head.
uint64_t GetUid() const
Get the packet Uid.
uint16_t m_head
list head
void AppendValue(uint32_t value, uint8_t *buffer)
Append a value to the buffer.
static void Recycle(PacketMetadata::Data *data)
Recycle the buffer memory.
static uint8_t * ReadFromRawU32(uint32_t &data, const uint8_t *start, const uint8_t *current, uint32_t maxSize)
Helper for the raw deserialization.
static uint8_t * AddToRawU32(const uint32_t &data, uint8_t *start, uint8_t *current, uint32_t maxSize)
Helper for the raw serialization.
static bool m_enable
Enable the packet metadata.
void AddAtEnd(const PacketMetadata &o)
Add a metadata at the metadata start.
void Reserve(uint32_t n)
Reserve space.
uint32_t ReadUleb128(const uint8_t **pBuffer) const
Read a ULEB128 (Unsigned Little Endian Base 128) coded number.
ItemIterator BeginItem(Buffer buffer) const
Initialize the item iterator to the buffer begin.
static void EnableChecking()
Enable the packet metadata checking.
void RemoveAtEnd(uint32_t end)
Remove a chunk of metadata at the metadata end.
void RemoveHeader(const Header &header, uint32_t size)
Remove an header.
uint32_t Deserialize(const uint8_t *buffer, uint32_t size)
Deserialization from raw uint8_t*.
void AddPaddingAtEnd(uint32_t end)
Add some padding at the end.
static uint8_t * ReadFromRawU16(uint16_t &data, const uint8_t *start, const uint8_t *current, uint32_t maxSize)
Helper for the raw deserialization.
static uint16_t m_chunkUid
Chunk Uid.
static PacketMetadata::Data * Allocate(uint32_t n)
Allocate a buffer data storage.
void RemoveAtStart(uint32_t start)
Remove a chunk of metadata at the metadata start.
uint16_t AddSmall(const PacketMetadata::SmallItem *item)
Add a SmallItem.
static DataFreeList m_freeList
the metadata data storage
uint32_t GetUleb128Size(uint32_t value) const
Get the ULEB128 (Unsigned Little Endian Base 128) size.
uint32_t GetTotalSize() const
Get the total size used by the metadata.
void Append16(uint16_t value, uint8_t *buffer)
Append a 16-bit value to the buffer.
void RemoveTrailer(const Trailer &trailer, uint32_t size)
Remove a trailer.
static bool m_metadataSkipped
Set to true when adding metadata to a packet is skipped because m_enable is false; used to detect ena...
bool IsPointerOk(uint16_t pointer) const
Check if the position is valid.
bool IsStateOk() const
Check if the metadata state is ok.
uint32_t Serialize(uint8_t *buffer, uint32_t maxSize) const
Serialization to raw uint8_t*.
bool IsSharedPointerOk(uint16_t pointer) const
Check if the position is valid.
static uint8_t * AddToRawU8(const uint8_t &data, uint8_t *start, uint8_t *current, uint32_t maxSize)
Helper for the raw serialization.
uint16_t m_tail
list tail
void UpdateTail(uint16_t written)
Update the tail.
uint64_t m_packetUid
packet Uid
static uint8_t * AddToRaw(const uint8_t *data, uint32_t dataSize, uint8_t *start, uint8_t *current, uint32_t maxSize)
Helper for the raw serialization.
void DoAddHeader(uint32_t uid, uint32_t size)
Add an header.
uint16_t AddBig(uint32_t head, uint32_t tail, const PacketMetadata::SmallItem *item, const PacketMetadata::ExtraItem *extraItem)
Add a "Big" Item (a SmallItem plus an ExtraItem)
static uint8_t * ReadFromRawU8(uint8_t &data, const uint8_t *start, const uint8_t *current, uint32_t maxSize)
Helper for the raw deserialization.
void AddTrailer(const Trailer &trailer, uint32_t size)
Add a trailer.
static uint8_t * AddToRawU16(const uint16_t &data, uint8_t *start, uint8_t *current, uint32_t maxSize)
Helper for the raw serialization.
static uint8_t * AddToRawU64(const uint64_t &data, uint8_t *start, uint8_t *current, uint32_t maxSize)
Helper for the raw serialization.
static void Enable()
Enable the packet metadata.
Protocol trailer serialization and deserialization.
Definition: trailer.h:41
a unique identifier for an interface.
Definition: type-id.h:59
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition: ptr.h:442
Every class exported by the ns3 library is enclosed in the ns3 namespace.
value
Definition: second.py:48
#define PACKET_METADATA_DATA_M_DATA_SIZE
the size of PacketMetadata::Data::m_data such that the total size of PacketMetadata::Data is 16 bytes
uint8_t data[writeSize]
uint32_t m_size
size (in bytes) of m_data buffer below
uint8_t m_data[PACKET_METADATA_DATA_M_DATA_SIZE]
variable-sized buffer of bytes
uint32_t m_count
number of references to this struct Data instance.
uint16_t m_dirtyEnd
max of the m_used field over all objects which reference this struct Data instance
uint32_t fragmentEnd
offset (in bytes) from start of original header to the end of the fragment still present.
uint64_t packetUid
the packetUid of the packet in which this header or trailer was first added.
uint32_t fragmentStart
offset (in bytes) from start of original header to the start of the fragment still present.
structure describing a packet metadata item
ItemType type
metadata type
TypeId tid
TypeId of Header or Trailer.
bool isFragment
true: this is a fragmented header, trailer, or, payload.
uint32_t currentTrimmedFromEnd
how many bytes were trimmed from the end of a fragment.
Buffer::Iterator current
an iterator which can be fed to Deserialize.
ItemType
Type of data in the packet.
uint32_t currentTrimmedFromStart
how many bytes were trimmed from the start of a fragment.
uint32_t currentSize
size of item.
uint16_t next
offset (in bytes) from start of m_data buffer to next element in linked list.
uint16_t chunkUid
this field tries to uniquely identify each header or trailer instance while the typeUid field uniquel...
uint32_t typeUid
the high 31 bits of this field identify the type of the header or trailer represented by this item: t...
uint32_t size
the size (in bytes) of the header or trailer represented by this element.
uint16_t prev
offset (in bytes) from start of m_data buffer to previous element in linked list.