A Discrete-Event Network Simulator
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2006,2007 INRIA
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
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  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
23 #include <stdint.h>
24 #include <vector>
25 #include <limits>
26 #include "ns3/callback.h"
27 #include "ns3/assert.h"
28 #include "ns3/type-id.h"
29 #include "buffer.h"
31 namespace ns3 {
33 class Chunk;
34 class Buffer;
35 class Header;
36 class Trailer;
79 {
80 public:
85  struct Item
86  {
88  enum ItemType {
92  } type;
97  bool isFragment;
107  uint32_t currentSize;
123  };
129  {
130 public:
136  ItemIterator (const PacketMetadata *metadata, Buffer buffer);
141  bool HasNext (void) const;
146  Item Next (void);
147 private:
150  uint16_t m_current;
151  uint32_t m_offset;
153  };
158  static void Enable (void);
162  static void EnableChecking (void);
169  inline PacketMetadata (uint64_t uid, uint32_t size);
174  inline PacketMetadata (PacketMetadata const &o);
180  inline PacketMetadata &operator = (PacketMetadata const& o);
181  inline ~PacketMetadata ();
188  void AddHeader (Header const &header, uint32_t size);
194  void RemoveHeader (Header const &header, uint32_t size);
201  void AddTrailer (Trailer const &trailer, uint32_t size);
207  void RemoveTrailer (Trailer const &trailer, uint32_t size);
219  PacketMetadata CreateFragment (uint32_t start, uint32_t end) const;
225  void AddAtEnd (PacketMetadata const&o);
230  void AddPaddingAtEnd (uint32_t end);
235  void RemoveAtStart (uint32_t start);
240  void RemoveAtEnd (uint32_t end);
246  uint64_t GetUid (void) const;
252  uint32_t GetSerializedSize (void) const;
259  ItemIterator BeginItem (Buffer buffer) const;
267  uint32_t Serialize (uint8_t* buffer, uint32_t maxSize) const;
274  uint32_t Deserialize (const uint8_t* buffer, uint32_t size);
276 private:
286  static uint8_t* AddToRawU8 (const uint8_t& data,
287  uint8_t* start,
288  uint8_t* current,
289  uint32_t maxSize);
300  static uint8_t* AddToRawU16 (const uint16_t& data,
301  uint8_t* start,
302  uint8_t* current,
303  uint32_t maxSize);
314  static uint8_t* AddToRawU32 (const uint32_t& data,
315  uint8_t* start,
316  uint8_t* current,
317  uint32_t maxSize);
328  static uint8_t* AddToRawU64 (const uint64_t& data,
329  uint8_t* start,
330  uint8_t* current,
331  uint32_t maxSize);
343  static uint8_t* AddToRaw (const uint8_t* data,
344  uint32_t dataSize,
345  uint8_t* start,
346  uint8_t* current,
347  uint32_t maxSize);
358  static uint8_t* ReadFromRawU8 (uint8_t& data,
359  const uint8_t* start,
360  const uint8_t* current,
361  uint32_t maxSize);
372  static uint8_t* ReadFromRawU16 (uint16_t& data,
373  const uint8_t* start,
374  const uint8_t* current,
375  uint32_t maxSize);
386  static uint8_t* ReadFromRawU32 (uint32_t& data,
387  const uint8_t* start,
388  const uint8_t* current,
389  uint32_t maxSize);
400  static uint8_t* ReadFromRawU64 (uint64_t& data,
401  const uint8_t* start,
402  const uint8_t* current,
403  uint32_t maxSize);
414  struct Data {
416  uint32_t m_count;
418  uint16_t m_size;
421  uint16_t m_dirtyEnd;
424  };
425  /* Note that since the next and prev fields are 16 bit integers
426  and since the value 0xffff is reserved to identify the
427  fact that the end or the start of the list is reached,
428  only a limited number of elements can be stored in
429  a m_data byte buffer.
430  */
434  struct SmallItem {
440  uint16_t next;
446  uint16_t prev;
454  uint32_t typeUid;
459  uint32_t size;
472  uint16_t chunkUid;
473  };
478  struct ExtraItem {
483  uint32_t fragmentStart;
488  uint32_t fragmentEnd;
494  uint64_t packetUid;
495  };
500  class DataFreeList : public std::vector<struct Data *>
501  {
502 public:
503  ~DataFreeList ();
504  };
506  friend DataFreeList::~DataFreeList ();
508  friend class ItemIterator;
510  PacketMetadata ();
517  inline uint16_t AddSmall (const PacketMetadata::SmallItem *item);
526  uint16_t AddBig (uint32_t head, uint32_t tail,
527  const PacketMetadata::SmallItem *item,
528  const PacketMetadata::ExtraItem *extraItem);
537  PacketMetadata::ExtraItem *extraItem,
538  uint32_t available);
543  inline void UpdateHead (uint16_t written);
548  inline void UpdateTail (uint16_t written);
555  inline uint32_t GetUleb128Size (uint32_t value) const;
561  uint32_t ReadUleb128 (const uint8_t **pBuffer) const;
567  inline void Append16 (uint16_t value, uint8_t *buffer);
573  inline void Append32 (uint32_t value, uint8_t *buffer);
579  inline void AppendValue (uint32_t value, uint8_t *buffer);
588  void AppendValueExtra (uint32_t value, uint8_t *buffer);
594  inline void Reserve (uint32_t n);
599  void ReserveCopy (uint32_t n);
605  uint32_t GetTotalSize (void) const;
614  uint32_t ReadItems (uint16_t current,
615  struct PacketMetadata::SmallItem *item,
616  struct PacketMetadata::ExtraItem *extraItem) const;
622  void DoAddHeader (uint32_t uid, uint32_t size);
627  bool IsStateOk (void) const;
633  bool IsPointerOk (uint16_t pointer) const;
639  bool IsSharedPointerOk (uint16_t pointer) const;
645  static void Recycle (struct PacketMetadata::Data *data);
651  static struct PacketMetadata::Data *Create (uint32_t size);
657  static struct PacketMetadata::Data *Allocate (uint32_t n);
662  static void Deallocate (struct PacketMetadata::Data *data);
665  static bool m_enable;
666  static bool m_enableChecking;
673  static bool m_metadataSkipped;
675  static uint32_t m_maxSize;
676  static uint16_t m_chunkUid;
678  struct Data *m_data;
679  /*
680  head -(next)-> tail
681  ^ |
682  \---(prev)---|
683  */
684  uint16_t m_head;
685  uint16_t m_tail;
686  uint16_t m_used;
687  uint64_t m_packetUid;
688 };
690 } // namespace ns3
692 namespace ns3 {
694 PacketMetadata::PacketMetadata (uint64_t uid, uint32_t size)
695  : m_data (PacketMetadata::Create (10)),
696  m_head (0xffff),
697  m_tail (0xffff),
698  m_used (0),
699  m_packetUid (uid)
700 {
701  memset (m_data->m_data, 0xff, 4);
702  if (size > 0)
703  {
704  DoAddHeader (0, size);
705  }
706 }
708  : m_data (o.m_data),
709  m_head (o.m_head),
710  m_tail (o.m_tail),
711  m_used (o.m_used),
713 {
714  NS_ASSERT (m_data != 0);
716  m_data->m_count++;
717 }
720 {
721  if (m_data != o.m_data)
722  {
723  // not self assignment
724  NS_ASSERT (m_data != 0);
725  m_data->m_count--;
726  if (m_data->m_count == 0)
727  {
729  }
730  m_data = o.m_data;
731  NS_ASSERT (m_data != 0);
732  m_data->m_count++;
733  }
734  m_head = o.m_head;
735  m_tail = o.m_tail;
736  m_used = o.m_used;
738  return *this;
739 }
741 {
742  NS_ASSERT (m_data != 0);
743  m_data->m_count--;
744  if (m_data->m_count == 0)
745  {
747  }
748 }
750 } // namespace ns3
753 #endif /* PACKET_METADATA_H */
Protocol header serialization and deserialization.
Definition: header.h:42
void RemoveAtEnd(uint32_t end)
Remove a chunk of metadata at the metadata end.
static void Recycle(struct PacketMetadata::Data *data)
Recycle the buffer memory.
friend class ItemIterator
Friend class.
Buffer::Iterator current
an iterator which can be fed to Deserialize.
static uint8_t * ReadFromRawU8(uint8_t &data, const uint8_t *start, const uint8_t *current, uint32_t maxSize)
Helper for the raw deserialization.
static bool m_enableChecking
Enable the packet metadata checking.
static bool m_enable
Enable the packet metadata.
uint64_t GetUid(void) const
Get the packet Uid.
void ReserveCopy(uint32_t n)
Reserve space and make a metadata copy.
automatically resized byte buffer
Definition: buffer.h:92
def start()
Definition: core.py:1806
structure describing a packet metadata item
bool isFragment
true: this is a fragmented header, trailer, or, payload.
static void Deallocate(struct PacketMetadata::Data *data)
Deallocate the buffer memory.
TypeId tid
TypeId of Header or Trailer.
static void EnableChecking(void)
Enable the packet metadata checking.
static uint8_t * ReadFromRawU16(uint16_t &data, const uint8_t *start, const uint8_t *current, uint32_t maxSize)
Helper for the raw deserialization.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
struct Data * m_data
Metadata storage.
uint32_t GetSerializedSize(void) const
Get the metadata serialized size.
uint16_t AddSmall(const PacketMetadata::SmallItem *item)
Add a SmallItem.
void UpdateHead(uint16_t written)
Update the head.
uint32_t currentTrimedFromEnd
how many bytes were trimmed from the end of a fragment.
Class to hold all the metadata.
bool IsSharedPointerOk(uint16_t pointer) const
Check if the position is valid.
void AddHeader(Header const &header, uint32_t size)
Add an header.
void AppendValueExtra(uint32_t value, uint8_t *buffer)
Append a value to the buffer - extra.
iterator in a Buffer instance
Definition: buffer.h:98
void DoAddHeader(uint32_t uid, uint32_t size)
Add an header.
const PacketMetadata * m_metadata
pointer to the metadata
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.
bool IsPointerOk(uint16_t pointer) const
Check if the position is valid.
void AddTrailer(Trailer const &trailer, uint32_t size)
Add a trailer.
void AddPaddingAtEnd(uint32_t end)
Add some padding at the end.
#define max(a, b)
Definition: 80211b.c:43
PacketMetadata CreateFragment(uint32_t start, uint32_t end) const
Creates a fragment.
uint8_t data[writeSize]
static uint8_t * AddToRawU16(const uint16_t &data, uint8_t *start, uint8_t *current, uint32_t maxSize)
Helper for the raw serialization.
enum ns3::PacketMetadata::Item::ItemType type
metadata type
Iterator class for metadata items.
uint16_t next
offset (in bytes) from start of m_data buffer to next element in linked list.
static DataFreeList m_freeList
the metadata data storage
void AppendValue(uint32_t value, uint8_t *buffer)
Append a value to the buffer.
static struct PacketMetadata::Data * Allocate(uint32_t n)
Allocate a buffer data storage.
void AddAtEnd(PacketMetadata const &o)
Add a metadata at the metadata start.
Protocol trailer serialization and deserialization.
Definition: trailer.h:40
uint64_t m_packetUid
packet Uid
uint32_t GetUleb128Size(uint32_t value) const
Get the ULEB128 (Unsigned Little Endian Base 128) size.
static void Enable(void)
Enable the packet metadata.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Buffer m_buffer
buffer the metadata refers to
uint32_t size
the size (in bytes) of the header or trailer represented by this element.
uint16_t m_tail
list tail
static uint8_t * AddToRawU64(const uint64_t &data, uint8_t *start, uint8_t *current, uint32_t maxSize)
Helper for the raw serialization.
void Append32(uint32_t value, uint8_t *buffer)
Append a 32-bit value to the buffer.
uint16_t m_size
size (in bytes) of m_data buffer below
void Append16(uint16_t value, uint8_t *buffer)
Append a 16-bit value to the buffer.
uint32_t Deserialize(const uint8_t *buffer, uint32_t size)
Deserialization from raw uint8_t*.
static uint32_t m_maxSize
maximum metadata size
bool IsStateOk(void) const
Check if the metadata state is ok.
void RemoveHeader(Header const &header, uint32_t size)
Remove an header.
static uint8_t * AddToRawU32(const uint32_t &data, uint8_t *start, uint8_t *current, uint32_t maxSize)
Helper for the raw serialization.
uint16_t prev
offset (in bytes) from start of m_data buffer to previous element in linked list. ...
static uint16_t m_chunkUid
Chunk Uid.
uint16_t m_used
used portion
uint32_t currentSize
size of item.
uint32_t GetTotalSize(void) const
Get the total size used by the metadata.
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)
uint32_t m_count
number of references to this struct Data instance.
static struct PacketMetadata::Data * Create(uint32_t size)
Create a buffer data storage.
void RemoveTrailer(Trailer const &trailer, uint32_t size)
Remove a trailer.
PacketMetadata & operator=(PacketMetadata const &o)
Basic assignment.
ItemIterator BeginItem(Buffer buffer) const
Initialize the item iterator to the buffer begin.
static uint8_t * ReadFromRawU64(uint64_t &data, const uint8_t *start, const uint8_t *current, uint32_t maxSize)
Helper for the raw deserialization.
uint16_t m_dirtyEnd
max of the m_used field over all objects which reference this struct Data instance ...
static bool m_metadataSkipped
Set to true when adding metadata to a packet is skipped because m_enable is false; used to detect ena...
uint32_t fragmentEnd
offset (in bytes) from start of original header to the end of the fragment still present.
uint32_t typeUid
the high 31 bits of this field identify the type of the header or trailer represented by this item: t...
uint16_t chunkUid
this field tries to uniquely identify each header or trailer instance while the typeUid field uniquel...
bool m_hasReadTail
true if the metadata tail has been read
void UpdateTail(uint16_t written)
Update the tail.
uint64_t packetUid
the packetUid of the packet in which this header or trailer was first added.
void RemoveAtStart(uint32_t start)
Remove a chunk of metadata at the metadata start.
uint32_t currentTrimedFromStart
how many bytes were trimmed from the start of a fragment.
uint16_t m_current
current position
Type of data in the packet.
void Reserve(uint32_t n)
Reserve space.
void ReplaceTail(PacketMetadata::SmallItem *item, PacketMetadata::ExtraItem *extraItem, uint32_t available)
Replace the tail.
static uint8_t * AddToRawU8(const uint8_t &data, uint8_t *start, uint8_t *current, uint32_t maxSize)
Helper for the raw serialization.
variable-sized buffer of bytes
a unique identifier for an interface.
Definition: type-id.h:58
uint32_t ReadUleb128(const uint8_t **pBuffer) const
Read a ULEB128 (Unsigned Little Endian Base 128) coded number.
uint32_t fragmentStart
offset (in bytes) from start of original header to the start of the fragment still present...
uint16_t m_head
list head
uint32_t ReadItems(uint16_t current, struct PacketMetadata::SmallItem *item, struct PacketMetadata::ExtraItem *extraItem) const
Read items.
the size of PacketMetadata::Data::m_data such that the total size of PacketMetadata::Data is 16 bytes...
static uint8_t * ReadFromRawU32(uint32_t &data, const uint8_t *start, const uint8_t *current, uint32_t maxSize)
Helper for the raw deserialization.
uint32_t Serialize(uint8_t *buffer, uint32_t maxSize) const
Serialization to raw uint8_t*.
Handle packet metadata about packet headers and trailers.