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