A Discrete-Event Network Simulator
API
packet.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2005,2006 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
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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  */
20 #include "packet.h"
21 #include "ns3/assert.h"
22 #include "ns3/log.h"
23 #include "ns3/simulator.h"
24 #include <string>
25 #include <cstdarg>
26 
27 namespace ns3 {
28 
29 NS_LOG_COMPONENT_DEFINE ("Packet");
30 
31 uint32_t Packet::m_globalUid = 0;
32 
33 TypeId
35 {
36  return m_tid;
37 }
38 uint32_t
40 {
41  return m_start;
42 }
43 uint32_t
45 {
46  return m_end;
47 }
48 void
50 {
51  if (tag.GetInstanceTypeId () != GetTypeId ())
52  {
53  NS_FATAL_ERROR ("The tag you provided is not of the right type.");
54  }
55  tag.Deserialize (m_buffer);
56 }
57 ByteTagIterator::Item::Item (TypeId tid, uint32_t start, uint32_t end, TagBuffer buffer)
58  : m_tid (tid),
59  m_start (start),
60  m_end (end),
61  m_buffer (buffer)
62 {
63 }
64 bool
66 {
67  return m_current.HasNext ();
68 }
71 {
73  return ByteTagIterator::Item (i.tid,
76  i.buf);
77 }
79  : m_current (i)
80 {
81 }
82 
83 
85  : m_current (head)
86 {
87 }
88 bool
90 {
91  return m_current != 0;
92 }
95 {
96  NS_ASSERT (HasNext ());
97  const struct PacketTagList::TagData *prev = m_current;
99  return PacketTagIterator::Item (prev);
100 }
101 
103  : m_data (data)
104 {
105 }
106 TypeId
108 {
109  return m_data->tid;
110 }
111 void
113 {
114  NS_ASSERT (tag.GetInstanceTypeId () == m_data->tid);
115  tag.Deserialize (TagBuffer ((uint8_t*)m_data->data,
116  (uint8_t*)m_data->data + m_data->size));
117 }
118 
119 
121 Packet::Copy (void) const
122 {
123  // we need to invoke the copy constructor directly
124  // rather than calling Create because the copy constructor
125  // is private.
126  return Ptr<Packet> (new Packet (*this), false);
127 }
128 
130  : m_buffer (),
131  m_byteTagList (),
132  m_packetTagList (),
133  /* The upper 32 bits of the packet id in
134  * metadata is for the system id. For non-
135  * distributed simulations, this is simply
136  * zero. The lower 32 bits are for the
137  * global UID
138  */
139  m_metadata (static_cast<uint64_t> (Simulator::GetSystemId ()) << 32 | m_globalUid, 0),
140  m_nixVector (0)
141 {
142  m_globalUid++;
143 }
144 
146  : m_buffer (o.m_buffer),
147  m_byteTagList (o.m_byteTagList),
148  m_packetTagList (o.m_packetTagList),
149  m_metadata (o.m_metadata)
150 {
152  : m_nixVector = 0;
153 }
154 
155 Packet &
157 {
158  if (this == &o)
159  {
160  return *this;
161  }
162  m_buffer = o.m_buffer;
167  : m_nixVector = 0;
168  return *this;
169 }
170 
171 Packet::Packet (uint32_t size)
172  : m_buffer (size),
173  m_byteTagList (),
174  m_packetTagList (),
175  /* The upper 32 bits of the packet id in
176  * metadata is for the system id. For non-
177  * distributed simulations, this is simply
178  * zero. The lower 32 bits are for the
179  * global UID
180  */
181  m_metadata (static_cast<uint64_t> (Simulator::GetSystemId ()) << 32 | m_globalUid, size),
182  m_nixVector (0)
183 {
184  m_globalUid++;
185 }
186 Packet::Packet (uint8_t const *buffer, uint32_t size, bool magic)
187  : m_buffer (0, false),
188  m_byteTagList (),
189  m_packetTagList (),
190  m_metadata (0,0),
191  m_nixVector (0)
192 {
193  NS_ASSERT (magic);
194  Deserialize (buffer, size);
195 }
196 
197 Packet::Packet (uint8_t const*buffer, uint32_t size)
198  : m_buffer (),
199  m_byteTagList (),
200  m_packetTagList (),
201  /* The upper 32 bits of the packet id in
202  * metadata is for the system id. For non-
203  * distributed simulations, this is simply
204  * zero. The lower 32 bits are for the
205  * global UID
206  */
207  m_metadata (static_cast<uint64_t> (Simulator::GetSystemId ()) << 32 | m_globalUid, size),
208  m_nixVector (0)
209 {
210  m_globalUid++;
211  m_buffer.AddAtStart (size);
213  i.Write (buffer, size);
214 }
215 
216 Packet::Packet (const Buffer &buffer, const ByteTagList &byteTagList,
217  const PacketTagList &packetTagList, const PacketMetadata &metadata)
218  : m_buffer (buffer),
219  m_byteTagList (byteTagList),
220  m_packetTagList (packetTagList),
221  m_metadata (metadata),
222  m_nixVector (0)
223 {
224 }
225 
227 Packet::CreateFragment (uint32_t start, uint32_t length) const
228 {
229  NS_LOG_FUNCTION (this << start << length);
230  Buffer buffer = m_buffer.CreateFragment (start, length);
231  ByteTagList byteTagList = m_byteTagList;
232  byteTagList.Adjust (-start);
233  NS_ASSERT (m_buffer.GetSize () >= start + length);
234  uint32_t end = m_buffer.GetSize () - (start + length);
235  PacketMetadata metadata = m_metadata.CreateFragment (start, end);
236  // again, call the constructor directly rather than
237  // through Create because it is private.
238  Ptr<Packet> ret = Ptr<Packet> (new Packet (buffer, byteTagList, m_packetTagList, metadata), false);
239  ret->SetNixVector (GetNixVector ());
240  return ret;
241 }
242 
243 void
245 {
246  m_nixVector = nixVector;
247 }
248 
251 {
252  return m_nixVector;
253 }
254 
255 void
256 Packet::AddHeader (const Header &header)
257 {
258  uint32_t size = header.GetSerializedSize ();
259  NS_LOG_FUNCTION (this << header.GetInstanceTypeId ().GetName () << size);
260  m_buffer.AddAtStart (size);
261  m_byteTagList.Adjust (size);
262  m_byteTagList.AddAtStart (size);
263  header.Serialize (m_buffer.Begin ());
264  m_metadata.AddHeader (header, size);
265 }
266 uint32_t
267 Packet::RemoveHeader (Header &header, uint32_t size)
268 {
269  Buffer::Iterator end;
270  end = m_buffer.Begin ();
271  end.Next (size);
272  uint32_t deserialized = header.Deserialize (m_buffer.Begin (), end);
273  NS_LOG_FUNCTION (this << header.GetInstanceTypeId ().GetName () << deserialized);
274  m_buffer.RemoveAtStart (deserialized);
275  m_byteTagList.Adjust (-deserialized);
276  m_metadata.RemoveHeader (header, deserialized);
277  return deserialized;
278 }
279 uint32_t
281 {
282  uint32_t deserialized = header.Deserialize (m_buffer.Begin ());
283  NS_LOG_FUNCTION (this << header.GetInstanceTypeId ().GetName () << deserialized);
284  m_buffer.RemoveAtStart (deserialized);
285  m_byteTagList.Adjust (-deserialized);
286  m_metadata.RemoveHeader (header, deserialized);
287  return deserialized;
288 }
289 uint32_t
290 Packet::PeekHeader (Header &header) const
291 {
292  uint32_t deserialized = header.Deserialize (m_buffer.Begin ());
293  NS_LOG_FUNCTION (this << header.GetInstanceTypeId ().GetName () << deserialized);
294  return deserialized;
295 }
296 uint32_t
297 Packet::PeekHeader (Header &header, uint32_t size) const
298 {
299  Buffer::Iterator end;
300  end = m_buffer.Begin ();
301  end.Next (size);
302  uint32_t deserialized = header.Deserialize (m_buffer.Begin (), end);
303  NS_LOG_FUNCTION (this << header.GetInstanceTypeId ().GetName () << deserialized);
304  return deserialized;
305 }
306 void
307 Packet::AddTrailer (const Trailer &trailer)
308 {
309  uint32_t size = trailer.GetSerializedSize ();
310  NS_LOG_FUNCTION (this << trailer.GetInstanceTypeId ().GetName () << size);
312  m_buffer.AddAtEnd (size);
313  Buffer::Iterator end = m_buffer.End ();
314  trailer.Serialize (end);
315  m_metadata.AddTrailer (trailer, size);
316 }
317 uint32_t
319 {
320  uint32_t deserialized = trailer.Deserialize (m_buffer.End ());
321  NS_LOG_FUNCTION (this << trailer.GetInstanceTypeId ().GetName () << deserialized);
322  m_buffer.RemoveAtEnd (deserialized);
323  m_metadata.RemoveTrailer (trailer, deserialized);
324  return deserialized;
325 }
326 uint32_t
328 {
329  uint32_t deserialized = trailer.Deserialize (m_buffer.End ());
330  NS_LOG_FUNCTION (this << trailer.GetInstanceTypeId ().GetName () << deserialized);
331  return deserialized;
332 }
333 
334 void
336 {
337  NS_LOG_FUNCTION (this << packet << packet->GetSize ());
339  ByteTagList copy = packet->m_byteTagList;
340  copy.AddAtStart (0);
341  copy.Adjust (GetSize ());
342  m_byteTagList.Add (copy);
343  m_buffer.AddAtEnd (packet->m_buffer);
344  m_metadata.AddAtEnd (packet->m_metadata);
345 }
346 void
347 Packet::AddPaddingAtEnd (uint32_t size)
348 {
349  NS_LOG_FUNCTION (this << size);
351  m_buffer.AddAtEnd (size);
353 }
354 void
355 Packet::RemoveAtEnd (uint32_t size)
356 {
357  NS_LOG_FUNCTION (this << size);
358  m_buffer.RemoveAtEnd (size);
359  m_metadata.RemoveAtEnd (size);
360 }
361 void
362 Packet::RemoveAtStart (uint32_t size)
363 {
364  NS_LOG_FUNCTION (this << size);
365  m_buffer.RemoveAtStart (size);
366  m_byteTagList.Adjust (-size);
367  m_metadata.RemoveAtStart (size);
368 }
369 
370 void
372 {
373  NS_LOG_FUNCTION (this);
375 }
376 
377 uint32_t
378 Packet::CopyData (uint8_t *buffer, uint32_t size) const
379 {
380  return m_buffer.CopyData (buffer, size);
381 }
382 
383 void
384 Packet::CopyData (std::ostream *os, uint32_t size) const
385 {
386  return m_buffer.CopyData (os, size);
387 }
388 
389 uint64_t
390 Packet::GetUid (void) const
391 {
392  return m_metadata.GetUid ();
393 }
394 
395 void
396 Packet::PrintByteTags (std::ostream &os) const
397 {
399  while (i.HasNext ())
400  {
401  ByteTagIterator::Item item = i.Next ();
402  os << item.GetTypeId ().GetName () << " [" << item.GetStart () << "-" << item.GetEnd () << "]";
403  Callback<ObjectBase *> constructor = item.GetTypeId ().GetConstructor ();
404  if (constructor.IsNull ())
405  {
406  if (i.HasNext ())
407  {
408  os << " ";
409  }
410  continue;
411  }
412  Tag *tag = dynamic_cast<Tag *> (constructor ());
413  NS_ASSERT (tag != 0);
414  os << " ";
415  item.GetTag (*tag);
416  tag->Print (os);
417  if (i.HasNext ())
418  {
419  os << " ";
420  }
421  delete tag;
422  }
423 }
424 
425 std::string
427 {
428  std::ostringstream oss;
429  Print (oss);
430  return oss.str();
431 }
432 
433 void
434 Packet::Print (std::ostream &os) const
435 {
437  while (i.HasNext ())
438  {
439  PacketMetadata::Item item = i.Next ();
440  if (item.isFragment)
441  {
442  switch (item.type) {
444  os << "Payload";
445  break;
448  os << item.tid.GetName ();
449  break;
450  }
451  os << " Fragment [" << item.currentTrimedFromStart<<":"
452  << (item.currentTrimedFromStart + item.currentSize) << "]";
453  }
454  else
455  {
456  switch (item.type) {
458  os << "Payload (size=" << item.currentSize << ")";
459  break;
462  os << item.tid.GetName () << " (";
463  {
464  NS_ASSERT (item.tid.HasConstructor ());
465  Callback<ObjectBase *> constructor = item.tid.GetConstructor ();
466  NS_ASSERT (!constructor.IsNull ());
467  ObjectBase *instance = constructor ();
468  NS_ASSERT (instance != 0);
469  Chunk *chunk = dynamic_cast<Chunk *> (instance);
470  NS_ASSERT (chunk != 0);
472  {
473  Buffer::Iterator end = item.current;
474  end.Next (item.currentSize); // move from start
475  chunk->Deserialize (item.current, end);
476  }
477  else if (item.type == PacketMetadata::Item::TRAILER)
478  {
480  start.Prev (item.currentSize); // move from end
481  chunk->Deserialize (start, item.current);
482  }
483  else
484  {
485  chunk->Deserialize (item.current);
486  }
487  chunk->Print (os);
488  delete chunk;
489  }
490  os << ")";
491  break;
492  }
493  }
494  if (i.HasNext ())
495  {
496  os << " ";
497  }
498  }
499 #if 0
500  // The code below will work only if headers and trailers
501  // define the right attributes which is not the case for
502  // now. So, as a temporary measure, we use the
503  // headers' and trailers' Print method as shown above.
505  while (i.HasNext ())
506  {
507  PacketMetadata::Item item = i.Next ();
508  if (item.isFragment)
509  {
510  switch (item.type) {
512  os << "Payload";
513  break;
516  os << item.tid.GetName ();
517  break;
518  }
519  os << " Fragment [" << item.currentTrimedFromStart<<":"
520  << (item.currentTrimedFromStart + item.currentSize) << "]";
521  }
522  else
523  {
524  switch (item.type) {
526  os << "Payload (size=" << item.currentSize << ")";
527  break;
530  os << item.tid.GetName () << "(";
531  {
532  NS_ASSERT (item.tid.HasConstructor ());
533  Callback<ObjectBase *> constructor = item.tid.GetConstructor ();
534  NS_ASSERT (constructor.IsNull ());
535  ObjectBase *instance = constructor ();
536  NS_ASSERT (instance != 0);
537  Chunk *chunk = dynamic_cast<Chunk *> (instance);
538  NS_ASSERT (chunk != 0);
539  chunk->Deserialize (item.current);
540  for (uint32_t j = 0; j < item.tid.GetAttributeN (); j++)
541  {
542  std::string attrName = item.tid.GetAttributeName (j);
543  std::string value;
544  bool ok = chunk->GetAttribute (attrName, value);
545  NS_ASSERT (ok);
546  os << attrName << "=" << value;
547  if ((j + 1) < item.tid.GetAttributeN ())
548  {
549  os << ",";
550  }
551  }
552  }
553  os << ")";
554  break;
555  }
556  }
557  if (i.HasNext ())
558  {
559  os << " ";
560  }
561  }
562 #endif
563 }
564 
566 Packet::BeginItem (void) const
567 {
568  return m_metadata.BeginItem (m_buffer);
569 }
570 
571 void
573 {
576 }
577 
578 void
580 {
583 }
584 
585 uint32_t Packet::GetSerializedSize (void) const
586 {
587  uint32_t size = 0;
588 
589  if (m_nixVector)
590  {
591  // increment total size by the size of the nix-vector
592  // ensuring 4-byte boundary
593  size += ((m_nixVector->GetSerializedSize () + 3) & (~3));
594 
595  // add 4-bytes for entry of total length of nix-vector
596  size += 4;
597  }
598  else
599  {
600  // if no nix-vector, still have to add 4-bytes
601  // to account for the entry of total size for
602  // nix-vector in the buffer
603  size += 4;
604  }
605 
606  // increment total size by size of packet tag list
607  // ensuring 4-byte boundary
608  size += ((m_packetTagList.GetSerializedSize () + 3) & (~3));
609 
610  // add 4-bytes for entry of total length of packet tag list
611  size += 4;
612 
613  // increment total size by size of byte tag list
614  // ensuring 4-byte boundary
615  size += ((m_byteTagList.GetSerializedSize () + 3) & (~3));
616 
617  // add 4-bytes for entry of total length of byte tag list
618  size += 4;
619 
620  // increment total size by size of meta-data
621  // ensuring 4-byte boundary
622  size += ((m_metadata.GetSerializedSize () + 3) & (~3));
623 
624  // add 4-bytes for entry of total length of meta-data
625  size += 4;
626 
627  // increment total size by size of buffer
628  // ensuring 4-byte boundary
629  size += ((m_buffer.GetSerializedSize () + 3) & (~3));
630 
631  // add 4-bytes for entry of total length of buffer
632  size += 4;
633 
634  return size;
635 }
636 
637 uint32_t
638 Packet::Serialize (uint8_t* buffer, uint32_t maxSize) const
639 {
640  uint32_t* p = reinterpret_cast<uint32_t *> (buffer);
641  uint32_t size = 0;
642 
643  // if nix-vector exists, serialize it
644  if (m_nixVector)
645  {
646  uint32_t nixSize = m_nixVector->GetSerializedSize ();
647  if (size + nixSize <= maxSize)
648  {
649  // put the total length of nix-vector in the
650  // buffer. this includes 4-bytes for total
651  // length itself
652  *p++ = nixSize + 4;
653  size += nixSize;
654 
655  // serialize the nix-vector
656  uint32_t serialized =
657  m_nixVector->Serialize (p, nixSize);
658  if (serialized)
659  {
660  // increment p by nixSize bytes
661  // ensuring 4-byte boundary
662  p += ((nixSize+3) & (~3)) / 4;
663  }
664  else
665  {
666  return 0;
667  }
668  }
669  else
670  {
671  return 0;
672  }
673  }
674  else
675  {
676  // no nix vector, set zero length,
677  // ie 4-bytes, since it must include
678  // length for itself
679  if (size + 4 <= maxSize)
680  {
681  size += 4;
682  *p++ = 4;
683  }
684  else
685  {
686  return 0;
687  }
688  }
689 
690  // Serialize byte tag list
691  uint32_t byteTagSize = m_byteTagList.GetSerializedSize ();
692  if (size + byteTagSize <= maxSize)
693  {
694  // put the total length of byte tag list in the
695  // buffer. this includes 4-bytes for total
696  // length itself
697  *p++ = byteTagSize + 4;
698  size += byteTagSize;
699 
700  // serialize the byte tag list
701  uint32_t serialized = m_byteTagList.Serialize (p, byteTagSize);
702  if (serialized)
703  {
704  // increment p by byteTagSize bytes
705  // ensuring 4-byte boundary
706  p += ((byteTagSize+3) & (~3)) / 4;
707  }
708  else
709  {
710  return 0;
711  }
712  }
713  else
714  {
715  return 0;
716  }
717 
718  // Serialize packet tag list
719  uint32_t packetTagSize = m_packetTagList.GetSerializedSize ();
720  if (size + packetTagSize <= maxSize)
721  {
722  // put the total length of packet tag list in the
723  // buffer. this includes 4-bytes for total
724  // length itself
725  *p++ = packetTagSize + 4;
726  size += packetTagSize;
727 
728  // serialize the packet tag list
729  uint32_t serialized = m_packetTagList.Serialize (p, packetTagSize);
730  if (serialized)
731  {
732  // increment p by packetTagSize bytes
733  // ensuring 4-byte boundary
734  p += ((packetTagSize+3) & (~3)) / 4;
735  }
736  else
737  {
738  return 0;
739  }
740  }
741  else
742  {
743  return 0;
744  }
745 
746  // Serialize Metadata
747  uint32_t metaSize = m_metadata.GetSerializedSize ();
748  if (size + metaSize <= maxSize)
749  {
750  // put the total length of metadata in the
751  // buffer. this includes 4-bytes for total
752  // length itself
753  *p++ = metaSize + 4;
754  size += metaSize;
755 
756  // serialize the metadata
757  uint32_t serialized = m_metadata.Serialize (reinterpret_cast<uint8_t *> (p), metaSize);
758  if (serialized)
759  {
760  // increment p by metaSize bytes
761  // ensuring 4-byte boundary
762  p += ((metaSize+3) & (~3)) / 4;
763  }
764  else
765  {
766  return 0;
767  }
768  }
769  else
770  {
771  return 0;
772  }
773 
774  // Serialize the packet contents
775  uint32_t bufSize = m_buffer.GetSerializedSize ();
776  if (size + bufSize <= maxSize)
777  {
778  // put the total length of the buffer in the
779  // buffer. this includes 4-bytes for total
780  // length itself
781  *p++ = bufSize + 4;
782 
783  // serialize the buffer
784  uint32_t serialized = m_buffer.Serialize (reinterpret_cast<uint8_t *> (p), bufSize);
785  if (!serialized)
786  {
787  return 0;
788  }
789  }
790  else
791  {
792  return 0;
793  }
794 
795  // Serialized successfully
796  return 1;
797 }
798 
799 uint32_t
800 Packet::Deserialize (const uint8_t* buffer, uint32_t size)
801 {
802  NS_LOG_FUNCTION (this);
803 
804  const uint32_t* p = reinterpret_cast<const uint32_t *> (buffer);
805 
806  // read nix-vector
808  uint32_t nixSize = *p++;
809 
810  // if size less than nixSize, the buffer
811  // will be overrun, assert
812  NS_ASSERT (size >= nixSize);
813 
814  if (nixSize > 4)
815  {
816  Ptr<NixVector> nix = Create<NixVector> ();
817  uint32_t nixDeserialized = nix->Deserialize (p, nixSize);
818  if (!nixDeserialized)
819  {
820  // nix-vector not deserialized
821  // completely
822  return 0;
823  }
824  m_nixVector = nix;
825  // increment p by nixSize ensuring
826  // 4-byte boundary
827  p += ((((nixSize - 4) + 3) & (~3)) / 4);
828  }
829  size -= nixSize;
830 
831  // read byte tags
832  uint32_t byteTagSize = *p++;
833 
834  // if size less than byteTagSize, the buffer
835  // will be overrun, assert
836  NS_ASSERT (size >= byteTagSize);
837 
838  uint32_t byteTagDeserialized =
839  m_byteTagList.Deserialize (p, byteTagSize);
840  if (!byteTagDeserialized)
841  {
842  // byte tags not deserialized completely
843  return 0;
844  }
845  // increment p by byteTagSize ensuring
846  // 4-byte boundary
847  p += ((((byteTagSize - 4) + 3) & (~3)) / 4);
848  size -= byteTagSize;
849 
850  // read packet tags
851  uint32_t packetTagSize = *p++;
852 
853  // if size less than packetTagSize, the buffer
854  // will be overrun, assert
855  NS_ASSERT (size >= packetTagSize);
856 
857  uint32_t packetTagDeserialized =
858  m_packetTagList.Deserialize (p, packetTagSize);
859  if (!packetTagDeserialized)
860  {
861  // packet tags not deserialized completely
862  return 0;
863  }
864  // increment p by packetTagSize ensuring
865  // 4-byte boundary
866  p += ((((packetTagSize - 4) + 3) & (~3)) / 4);
867  size -= packetTagSize;
868 
869  // read metadata
870  uint32_t metaSize = *p++;
871 
872  // if size less than metaSize, the buffer
873  // will be overrun, assert
874  NS_ASSERT (size >= metaSize);
875 
876  uint32_t metadataDeserialized =
877  m_metadata.Deserialize (reinterpret_cast<const uint8_t *> (p), metaSize);
878  if (!metadataDeserialized)
879  {
880  // meta-data not deserialized
881  // completely
882  return 0;
883  }
884  // increment p by metaSize ensuring
885  // 4-byte boundary
886  p += ((((metaSize - 4) + 3) & (~3)) / 4);
887  size -= metaSize;
888 
889  // read buffer contents
890  uint32_t bufSize = *p++;
891 
892  // if size less than bufSize, the buffer
893  // will be overrun, assert
894  NS_ASSERT (size >= bufSize);
895 
896  uint32_t bufferDeserialized =
897  m_buffer.Deserialize (reinterpret_cast<const uint8_t *> (p), bufSize);
898  if (!bufferDeserialized)
899  {
900  // buffer not deserialized
901  // completely
902  return 0;
903  }
904  size -= bufSize;
905 
906  // return zero if did not deserialize the
907  // number of expected bytes
908  return (size == 0);
909 }
910 
911 void
912 Packet::AddByteTag (const Tag &tag) const
913 {
914  NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ().GetName () << tag.GetSerializedSize ());
915  ByteTagList *list = const_cast<ByteTagList *> (&m_byteTagList);
916  TagBuffer buffer = list->Add (tag.GetInstanceTypeId (), tag.GetSerializedSize (),
917  0,
918  GetSize ());
919  tag.Serialize (buffer);
920 }
921 void
922 Packet::AddByteTag (const Tag &tag, uint32_t start, uint32_t end) const
923 {
924  NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ().GetName () << tag.GetSerializedSize ());
925  NS_ABORT_MSG_IF (end < start, "Invalid byte range");
926  ByteTagList *list = const_cast<ByteTagList *> (&m_byteTagList);
927  TagBuffer buffer = list->Add (tag.GetInstanceTypeId (), tag.GetSerializedSize (),
928  static_cast<int32_t> (start),
929  static_cast<int32_t> (end));
930  tag.Serialize (buffer);
931 }
934 {
935  return ByteTagIterator (m_byteTagList.Begin (0, GetSize ()));
936 }
937 
938 bool
940 {
941  TypeId tid = tag.GetInstanceTypeId ();
943  while (i.HasNext ())
944  {
945  ByteTagIterator::Item item = i.Next ();
946  if (tid == item.GetTypeId ())
947  {
948  item.GetTag (tag);
949  return true;
950  }
951  }
952  return false;
953 }
954 
955 void
956 Packet::AddPacketTag (const Tag &tag) const
957 {
958  NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ().GetName () << tag.GetSerializedSize ());
959  m_packetTagList.Add (tag);
960 }
961 
962 bool
964 {
965  NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ().GetName () << tag.GetSerializedSize ());
966  bool found = m_packetTagList.Remove (tag);
967  return found;
968 }
969 bool
971 {
972  NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ().GetName () << tag.GetSerializedSize ());
973  bool found = m_packetTagList.Replace (tag);
974  return found;
975 }
976 
977 bool
979 {
980  bool found = m_packetTagList.Peek (tag);
981  return found;
982 }
983 void
985 {
986  NS_LOG_FUNCTION (this);
988 }
989 
990 void
991 Packet::PrintPacketTags (std::ostream &os) const
992 {
994  while (i.HasNext ())
995  {
996  PacketTagIterator::Item item = i.Next ();
997  NS_ASSERT (item.GetTypeId ().HasConstructor ());
998  Callback<ObjectBase *> constructor = item.GetTypeId ().GetConstructor ();
999  NS_ASSERT (!constructor.IsNull ());
1000  ObjectBase *instance = constructor ();
1001  Tag *tag = dynamic_cast<Tag *> (instance);
1002  NS_ASSERT (tag != 0);
1003  item.GetTag (*tag);
1004  tag->Print (os);
1005  delete tag;
1006  if (i.HasNext ())
1007  {
1008  os << " ";
1009  }
1010  }
1011 }
1012 
1015 {
1017 }
1018 
1019 std::ostream& operator<< (std::ostream& os, const Packet &packet)
1020 {
1021  packet.Print (os);
1022  return os;
1023 }
1024 
1025 } // namespace ns3
Protocol header serialization and deserialization.
Definition: header.h:42
uint32_t Deserialize(const uint32_t *buffer, uint32_t size)
Deserialize tag list from the provided buffer.
void RemoveAtEnd(uint32_t end)
Remove a chunk of metadata at the metadata end.
bool FindFirstMatchingByteTag(Tag &tag) const
Finds the first tag matching the parameter Tag type.
Definition: packet.cc:939
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:280
PacketMetadata m_metadata
the packet&#39;s metadata
Definition: packet.h:785
bool Remove(Tag &tag)
Remove (the first instance of) tag from the list.
Callback< ObjectBase * > GetConstructor(void) const
Get the constructor callback.
Definition: type-id.cc:1061
TypeId GetTypeId(void) const
Definition: packet.cc:34
std::string GetName(void) const
Get the name.
Definition: type-id.cc:977
void AddAtStart(uint32_t start)
Definition: buffer.cc:309
uint64_t GetUid(void) const
Returns the packet&#39;s Uid.
Definition: packet.cc:390
void Print(std::ostream &os) const
Print the packet contents.
Definition: packet.cc:434
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
bool HasConstructor(void) const
Check if this TypeId has a constructor.
Definition: type-id.cc:999
Control the scheduling of simulation events.
Definition: simulator.h:68
Callback template class.
Definition: callback.h:1278
void RemoveAtEnd(uint32_t end)
Definition: buffer.cc:483
struct TagData * next
Pointer to next in list.
Buffer::Iterator current
an iterator which can be fed to Deserialize.
uint32_t Deserialize(uint8_t const *buffer, uint32_t size)
Deserializes a packet.
Definition: packet.cc:800
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:852
void RemoveAtStart(uint32_t start)
Definition: buffer.cc:438
bool HasNext(void) const
Definition: packet.cc:65
virtual uint32_t GetSerializedSize(void) const =0
uint32_t GetSerializedSize(void) const
Returns number of bytes required for packet serialization.
Definition: packet.cc:585
TypeId GetTypeId(void) const
Definition: packet.cc:107
Item Next(void)
Retrieve the next metadata item.
automatically resized byte buffer
Definition: buffer.h:92
def start()
Definition: core.py:1855
structure describing a packet metadata item
List of the packet tags stored in a packet.
bool isFragment
true: this is a fragmented header, trailer, or, payload.
TypeId tid
TypeId of Header or Trailer.
uint32_t GetSerializedSize(void) const
Returns number of bytes required for packet serialization.
keep track of the byte tags stored in a packet.
Definition: byte-tag-list.h:63
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
static uint32_t m_globalUid
Global counter of packets Uid.
Definition: packet.h:790
static void EnableChecking(void)
Enable the packet metadata checking.
#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
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
TagBuffer Add(TypeId tid, uint32_t bufferSize, int32_t start, int32_t end)
uint32_t GetStart(void) const
The index is an offset from the start of the packet.
Definition: packet.cc:39
void Adjust(int32_t adjustment)
Adjust the offsets stored internally by the adjustment delta.
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
Buffer m_buffer
the packet buffer (it&#39;s actual contents)
Definition: packet.h:782
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Anchor the ns-3 type and attribute system.
Definition: object-base.h:119
Item(TypeId tid, uint32_t start, uint32_t end, TagBuffer buffer)
Constructor.
Definition: packet.cc:57
Packet & operator=(const Packet &o)
Basic assignment.
Definition: packet.cc:156
void PrintPacketTags(std::ostream &os) const
Print the list of packet tags.
Definition: packet.cc:991
network packets
Definition: packet.h:231
virtual uint32_t Deserialize(Buffer::Iterator start)=0
Deserialize the object from a buffer iterator.
Item Next(void)
Definition: packet.cc:94
void AddHeader(Header const &header, uint32_t size)
Add an header.
iterator in a Buffer instance
Definition: buffer.h:98
const struct PacketTagList::TagData * Head(void) const
ByteTagList::Iterator m_current
actual position over the set of byte tags in a packet
Definition: packet.h:122
Packet()
Create an empty packet with a new uid (as returned by getUid).
Definition: packet.cc:129
uint32_t Serialize(uint8_t *buffer, uint32_t maxSize) const
Serialization to raw uint8_t*.
uint32_t PeekTrailer(Trailer &trailer)
Deserialize but does not remove a trailer from the internal buffer.
Definition: packet.cc:327
void AddAtEnd(int32_t appendOffset)
Make sure that all offsets are smaller than appendOffset which represents the location where new byte...
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
Definition: packet.cc:335
void RemoveAll(void)
Removes all of the tags from the ByteTagList.
Tree node for sharing serialized tags.
uint32_t Deserialize(const uint8_t *buffer, uint32_t size)
Definition: buffer.cc:648
void RemoveAllPacketTags(void)
Remove all packet tags.
Definition: packet.cc:984
Identifies a byte tag and a set of bytes within a packet to which the tag applies.
Definition: packet.h:61
void AddTrailer(Trailer const &trailer, uint32_t size)
Add a trailer.
void RemoveAtStart(uint32_t size)
Remove size bytes from the start of the current packet.
Definition: packet.cc:362
void AddPaddingAtEnd(uint32_t end)
Add some padding at the end.
uint32_t GetSerializedSize(void) const
Returns number of bytes required for packet serialization.
bool Replace(Tag &tag)
Replace the value of a tag.
uint32_t Serialize(uint32_t *buffer, uint32_t maxSize) const
Definition: nix-vector.cc:225
ByteTagList::Iterator Begin(int32_t offsetStart, int32_t offsetEnd) const
static void EnablePrinting(void)
Enable printing packets metadata.
Definition: packet.cc:572
bool HasNext(void) const
Definition: packet.cc:89
TypeId m_tid
the ns3::TypeId associated to this tag.
Definition: packet.h:101
void SetNixVector(Ptr< NixVector > nixVector)
Set the packet nix-vector.
Definition: packet.cc:244
ItemIterator BeginItem(Buffer buffer) const
Initialize the item iterator to the buffer begin.
virtual void Print(std::ostream &os) const =0
Print the object contents.
ByteTagList m_byteTagList
the ByteTag list
Definition: packet.h:783
uint8_t data[writeSize]
enum ns3::PacketMetadata::Item::ItemType type
metadata type
void CopyData(std::ostream *os, uint32_t size) const
Copy the specified amount of data from the buffer to the given output stream.
Definition: buffer.cc:715
Iterator class for metadata items.
bool ReplacePacketTag(Tag &tag)
Replace the value of a packet tag.
Definition: packet.cc:970
uint32_t GetSerializedSize(void) const
Definition: nix-vector.cc:214
uint32_t GetSerializedSize(void) const
Return the number of bytes required for serialization.
Definition: buffer.cc:556
static void EnableChecking(void)
Enable packets metadata checking.
Definition: packet.cc:579
std::string ToString(void) const
Return a string representation of the packet.
Definition: packet.cc:426
void AddPaddingAtEnd(uint32_t size)
Add a zero-filled padding to the packet.
Definition: packet.cc:347
void Next(void)
go forward by one byte
Definition: buffer.h:845
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:290
int32_t start
offset to the start of the tag from the virtual byte buffer
Definition: byte-tag-list.h:85
virtual void Serialize(Buffer::Iterator start) const =0
virtual uint32_t Deserialize(Buffer::Iterator end)=0
Item Next(void)
Definition: packet.cc:70
Iterator over the set of packet tags in a packet.
Definition: packet.h:131
const struct PacketTagList::TagData * m_current
actual position over the set of tags in a packet
Definition: packet.h:179
void AddAtEnd(PacketMetadata const &o)
Add a metadata at the metadata start.
struct ByteTagList::Iterator::Item Next(void)
Returns the next Item from the ByteTagList.
bool HasNext(void) const
Checks if there is another metadata item.
#define list
virtual uint32_t Deserialize(Buffer::Iterator start)=0
std::ostream & operator<<(std::ostream &os, const Angles &a)
print a struct Angles to output
Definition: angles.cc:42
void AddAtEnd(uint32_t end)
Definition: buffer.cc:354
Protocol trailer serialization and deserialization.
Definition: trailer.h:40
virtual void Serialize(TagBuffer i) const =0
tag a set of bytes in a packet
Definition: tag.h:36
static void Enable(void)
Enable the packet metadata.
PacketTagIterator GetPacketTagIterator(void) const
Returns an object which can be used to iterate over the list of packet tags.
Definition: packet.cc:1014
Every class exported by the ns3 library is enclosed in the ns3 namespace.
virtual uint32_t GetSerializedSize(void) const =0
PacketMetadata CreateFragment(uint32_t start, uint32_t end) const
Creates a fragment.
PacketTagIterator(const struct PacketTagList::TagData *head)
Constructor.
Definition: packet.cc:84
void AddTrailer(const Trailer &trailer)
Add trailer to this packet.
Definition: packet.cc:307
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
void RemoveAtEnd(uint32_t size)
Remove size bytes from the end of the current packet.
Definition: packet.cc:355
friend class Packet
Friend class.
Definition: packet.h:173
Iterator over the set of byte tags in a packet.
Definition: packet.h:54
virtual void Deserialize(TagBuffer i)=0
uint32_t RemoveTrailer(Trailer &trailer)
Remove a deserialized trailer from the internal buffer.
Definition: packet.cc:318
bool Peek(Tag &tag) const
Find a tag and return its value.
PacketTagList m_packetTagList
the packet&#39;s Tag list
Definition: packet.h:784
Ptr< NixVector > Copy(void) const
Definition: nix-vector.cc:71
int32_t end
offset to the end of the tag from the virtual byte buffer
Definition: byte-tag-list.h:86
uint32_t Deserialize(const uint8_t *buffer, uint32_t size)
Deserialization from raw uint8_t*.
uint32_t Serialize(uint8_t *buffer, uint32_t maxSize) const
Definition: buffer.cc:576
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:396
Identifies a packet tag within a packet.
Definition: packet.h:137
PacketMetadata::ItemIterator BeginItem(void) const
Returns an iterator which points to the first &#39;item&#39; stored in this buffer.
Definition: packet.cc:566
void Add(Tag const &tag) const
Add a tag to the head of this branch.
void RemoveHeader(Header const &header, uint32_t size)
Remove an header.
Buffer::Iterator End(void) const
Definition: buffer.h:1075
TypeId tid
type of the tag
Definition: byte-tag-list.h:83
uint32_t currentSize
size of item.
Item(const struct PacketTagList::TagData *data)
Constructor.
Definition: packet.cc:102
uint32_t GetEnd(void) const
The index is an offset from the start of the packet.
Definition: packet.cc:44
TagBuffer buf
the data for the tag as generated by Tag::Serialize
Definition: byte-tag-list.h:87
An iterator for iterating through a byte tag list.
Definition: byte-tag-list.h:72
read and write tag data
Definition: tag-buffer.h:51
void GetTag(Tag &tag) const
Read the requested tag and store it in the user-provided tag instance.
Definition: packet.cc:112
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:956
void RemoveTrailer(Trailer const &trailer, uint32_t size)
Remove a trailer.
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Copy the packet contents to a byte buffer.
Definition: packet.cc:378
std::size_t GetAttributeN(void) const
Get the number of attributes.
Definition: type-id.cc:1077
virtual TypeId GetInstanceTypeId(void) const =0
Get the most derived TypeId for this Object.
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:963
void AddAtStart(int32_t prependOffset)
Make sure that all offsets are bigger than prependOffset which represents the location where new byte...
void RemoveAllByteTags(void)
Remove all byte tags stored in this packet.
Definition: packet.cc:371
virtual uint32_t GetSerializedSize(void) const =0
uint64_t GetUid(void) const
Get the packet Uid.
Ptr< NixVector > GetNixVector(void) const
Get the packet nix-vector.
Definition: packet.cc:250
Ptr< NixVector > m_nixVector
the packet&#39;s Nix vector
Definition: packet.h:788
uint32_t Deserialize(const uint32_t *buffer, uint32_t size)
Definition: nix-vector.cc:282
uint32_t GetSize(void) const
Definition: buffer.h:1063
Buffer CreateFragment(uint32_t start, uint32_t length) const
Definition: buffer.cc:519
void Write(uint8_t const *buffer, uint32_t size)
Definition: buffer.cc:953
uint32_t GetSerializedSize(void) const
Get the metadata serialized size.
virtual void Serialize(Buffer::Iterator start) const =0
uint32_t GetOffsetStart(void) const
Returns the offset from the start of the virtual byte buffer to the ByteTagList.
ByteTagIterator(ByteTagList::Iterator i)
Copy Constructor.
Definition: packet.cc:78
uint32_t Serialize(uint32_t *buffer, uint32_t maxSize) const
Serialize the tag list into a byte buffer.
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.
bool PeekPacketTag(Tag &tag) const
Search a matching tag and call Tag::Deserialize if it is found.
Definition: packet.cc:978
void GetTag(Tag &tag) const
Read the requested tag and store it in the user-provided tag instance.
Definition: packet.cc:49
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1386
void RemoveAll(void)
Remove all tags from this list (up to the first merge).
uint32_t Deserialize(const uint32_t *buffer, uint32_t size)
Deserialize tag list from the provided buffer.
a unique identifier for an interface.
Definition: type-id.h:58
uint32_t Serialize(uint32_t *buffer, uint32_t maxSize) const
Serialize the tag list into a byte buffer.
void GetAttribute(std::string name, AttributeValue &value) const
Get the value of an attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:223
void AddByteTag(const Tag &tag) const
Tag each byte included in this packet with a new byte tag.
Definition: packet.cc:912
abstract base class for ns3::Header and ns3::Trailer
Definition: chunk.h:34
Buffer::Iterator Begin(void) const
Definition: buffer.h:1069
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
ByteTagIterator GetByteTagIterator(void) const
Returns an iterator over the set of byte tags included in this packet.
Definition: packet.cc:933
virtual void Print(std::ostream &os) const =0
uint32_t Serialize(uint8_t *buffer, uint32_t maxSize) const
Serialize a packet, tags, and metadata into a byte buffer.
Definition: packet.cc:638
bool HasNext(void) const
Used to determine if the iterator is at the end of the byteTagList.
Handle packet metadata about packet headers and trailers.
An item specifies an individual tag within a byte buffer.
Definition: byte-tag-list.h:81