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());
107  const struct PacketTagList::TagData* prev = m_current;
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.currentTrimedFromStart << ":"
475  << (item.currentTrimedFromStart + 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  Chunk* 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.currentTrimedFromStart<<":"
544  << (item.currentTrimedFromStart + 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  uint32_t* 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  if (size + nixSize <= maxSize)
673  {
674  // put the total length of nix-vector in the
675  // buffer. this includes 4-bytes for total
676  // length itself
677  *p++ = nixSize + 4;
678  size += nixSize;
679 
680  // serialize the nix-vector
681  uint32_t serialized = m_nixVector->Serialize(p, nixSize);
682  if (serialized)
683  {
684  // increment p by nixSize bytes
685  // ensuring 4-byte boundary
686  p += ((nixSize + 3) & (~3)) / 4;
687  }
688  else
689  {
690  return 0;
691  }
692  }
693  else
694  {
695  return 0;
696  }
697  }
698  else
699  {
700  // no nix vector, set zero length,
701  // ie 4-bytes, since it must include
702  // length for itself
703  if (size + 4 <= maxSize)
704  {
705  size += 4;
706  *p++ = 4;
707  }
708  else
709  {
710  return 0;
711  }
712  }
713 
714  // Serialize byte tag list
715  uint32_t byteTagSize = m_byteTagList.GetSerializedSize();
716  if (size + byteTagSize <= maxSize)
717  {
718  // put the total length of byte tag list in the
719  // buffer. this includes 4-bytes for total
720  // length itself
721  *p++ = byteTagSize + 4;
722  size += byteTagSize;
723 
724  // serialize the byte tag list
725  uint32_t serialized = m_byteTagList.Serialize(p, byteTagSize);
726  if (serialized)
727  {
728  // increment p by byteTagSize bytes
729  // ensuring 4-byte boundary
730  p += ((byteTagSize + 3) & (~3)) / 4;
731  }
732  else
733  {
734  return 0;
735  }
736  }
737  else
738  {
739  return 0;
740  }
741 
742  // Serialize packet tag list
743  uint32_t packetTagSize = m_packetTagList.GetSerializedSize();
744  if (size + packetTagSize <= maxSize)
745  {
746  // put the total length of packet tag list in the
747  // buffer. this includes 4-bytes for total
748  // length itself
749  *p++ = packetTagSize + 4;
750  size += packetTagSize;
751 
752  // serialize the packet tag list
753  uint32_t serialized = m_packetTagList.Serialize(p, packetTagSize);
754  if (serialized)
755  {
756  // increment p by packetTagSize bytes
757  // ensuring 4-byte boundary
758  p += ((packetTagSize + 3) & (~3)) / 4;
759  }
760  else
761  {
762  return 0;
763  }
764  }
765  else
766  {
767  return 0;
768  }
769 
770  // Serialize Metadata
771  uint32_t metaSize = m_metadata.GetSerializedSize();
772  if (size + metaSize <= maxSize)
773  {
774  // put the total length of metadata in the
775  // buffer. this includes 4-bytes for total
776  // length itself
777  *p++ = metaSize + 4;
778  size += metaSize;
779 
780  // serialize the metadata
781  uint32_t serialized = m_metadata.Serialize(reinterpret_cast<uint8_t*>(p), metaSize);
782  if (serialized)
783  {
784  // increment p by metaSize bytes
785  // ensuring 4-byte boundary
786  p += ((metaSize + 3) & (~3)) / 4;
787  }
788  else
789  {
790  return 0;
791  }
792  }
793  else
794  {
795  return 0;
796  }
797 
798  // Serialize the packet contents
799  uint32_t bufSize = m_buffer.GetSerializedSize();
800  if (size + bufSize <= maxSize)
801  {
802  // put the total length of the buffer in the
803  // buffer. this includes 4-bytes for total
804  // length itself
805  *p++ = bufSize + 4;
806 
807  // serialize the buffer
808  uint32_t serialized = m_buffer.Serialize(reinterpret_cast<uint8_t*>(p), bufSize);
809  if (!serialized)
810  {
811  return 0;
812  }
813  }
814  else
815  {
816  return 0;
817  }
818 
819  // Serialized successfully
820  return 1;
821 }
822 
823 uint32_t
824 Packet::Deserialize(const uint8_t* buffer, uint32_t size)
825 {
826  NS_LOG_FUNCTION(this);
827 
828  const uint32_t* p = reinterpret_cast<const uint32_t*>(buffer);
829 
830  // read nix-vector
832  uint32_t nixSize = *p++;
833 
834  // if size less than nixSize, the buffer
835  // will be overrun, assert
836  NS_ASSERT(size >= nixSize);
837 
838  if (nixSize > 4)
839  {
840  Ptr<NixVector> nix = Create<NixVector>();
841  uint32_t nixDeserialized = nix->Deserialize(p, nixSize);
842  if (!nixDeserialized)
843  {
844  // nix-vector not deserialized
845  // completely
846  return 0;
847  }
848  m_nixVector = nix;
849  // increment p by nixSize ensuring
850  // 4-byte boundary
851  p += ((((nixSize - 4) + 3) & (~3)) / 4);
852  }
853  size -= nixSize;
854 
855  // read byte tags
856  uint32_t byteTagSize = *p++;
857 
858  // if size less than byteTagSize, the buffer
859  // will be overrun, assert
860  NS_ASSERT(size >= byteTagSize);
861 
862  uint32_t byteTagDeserialized = m_byteTagList.Deserialize(p, byteTagSize);
863  if (!byteTagDeserialized)
864  {
865  // byte tags not deserialized completely
866  return 0;
867  }
868  // increment p by byteTagSize ensuring
869  // 4-byte boundary
870  p += ((((byteTagSize - 4) + 3) & (~3)) / 4);
871  size -= byteTagSize;
872 
873  // read packet tags
874  uint32_t packetTagSize = *p++;
875 
876  // if size less than packetTagSize, the buffer
877  // will be overrun, assert
878  NS_ASSERT(size >= packetTagSize);
879 
880  uint32_t packetTagDeserialized = m_packetTagList.Deserialize(p, packetTagSize);
881  if (!packetTagDeserialized)
882  {
883  // packet tags not deserialized completely
884  return 0;
885  }
886  // increment p by packetTagSize ensuring
887  // 4-byte boundary
888  p += ((((packetTagSize - 4) + 3) & (~3)) / 4);
889  size -= packetTagSize;
890 
891  // read metadata
892  uint32_t metaSize = *p++;
893 
894  // if size less than metaSize, the buffer
895  // will be overrun, assert
896  NS_ASSERT(size >= metaSize);
897 
898  uint32_t metadataDeserialized =
899  m_metadata.Deserialize(reinterpret_cast<const uint8_t*>(p), metaSize);
900  if (!metadataDeserialized)
901  {
902  // meta-data not deserialized
903  // completely
904  return 0;
905  }
906  // increment p by metaSize ensuring
907  // 4-byte boundary
908  p += ((((metaSize - 4) + 3) & (~3)) / 4);
909  size -= metaSize;
910 
911  // read buffer contents
912  uint32_t bufSize = *p++;
913 
914  // if size less than bufSize, the buffer
915  // will be overrun, assert
916  NS_ASSERT(size >= bufSize);
917 
918  uint32_t bufferDeserialized =
919  m_buffer.Deserialize(reinterpret_cast<const uint8_t*>(p), bufSize);
920  if (!bufferDeserialized)
921  {
922  // buffer not deserialized
923  // completely
924  return 0;
925  }
926  size -= bufSize;
927 
928  // return zero if did not deserialize the
929  // number of expected bytes
930  return (size == 0);
931 }
932 
933 void
934 Packet::AddByteTag(const Tag& tag) const
935 {
937  ByteTagList* list = const_cast<ByteTagList*>(&m_byteTagList);
938  TagBuffer buffer = list->Add(tag.GetInstanceTypeId(), tag.GetSerializedSize(), 0, GetSize());
939  tag.Serialize(buffer);
940 }
941 
942 void
943 Packet::AddByteTag(const Tag& tag, uint32_t start, uint32_t end) const
944 {
946  NS_ABORT_MSG_IF(end < start, "Invalid byte range");
947  ByteTagList* list = const_cast<ByteTagList*>(&m_byteTagList);
948  TagBuffer buffer = list->Add(tag.GetInstanceTypeId(),
949  tag.GetSerializedSize(),
950  static_cast<int32_t>(start),
951  static_cast<int32_t>(end));
952  tag.Serialize(buffer);
953 }
954 
957 {
959 }
960 
961 bool
963 {
964  TypeId tid = tag.GetInstanceTypeId();
966  while (i.HasNext())
967  {
968  ByteTagIterator::Item item = i.Next();
969  if (tid == item.GetTypeId())
970  {
971  item.GetTag(tag);
972  return true;
973  }
974  }
975  return false;
976 }
977 
978 void
979 Packet::AddPacketTag(const Tag& tag) const
980 {
982  m_packetTagList.Add(tag);
983 }
984 
985 bool
987 {
989  bool found = m_packetTagList.Remove(tag);
990  return found;
991 }
992 
993 bool
995 {
997  bool found = m_packetTagList.Replace(tag);
998  return found;
999 }
1000 
1001 bool
1003 {
1004  bool found = m_packetTagList.Peek(tag);
1005  return found;
1006 }
1007 
1008 void
1010 {
1011  NS_LOG_FUNCTION(this);
1013 }
1014 
1015 void
1016 Packet::PrintPacketTags(std::ostream& os) const
1017 {
1019  while (i.HasNext())
1020  {
1021  PacketTagIterator::Item item = i.Next();
1023  Callback<ObjectBase*> constructor = item.GetTypeId().GetConstructor();
1024  NS_ASSERT(!constructor.IsNull());
1025  ObjectBase* instance = constructor();
1026  Tag* tag = dynamic_cast<Tag*>(instance);
1027  NS_ASSERT(tag != nullptr);
1028  item.GetTag(*tag);
1029  tag->Print(os);
1030  delete tag;
1031  if (i.HasNext())
1032  {
1033  os << " ";
1034  }
1035  }
1036 }
1037 
1040 {
1042 }
1043 
1044 std::ostream&
1045 operator<<(std::ostream& os, const Packet& packet)
1046 {
1047  packet.Print(os);
1048  return os;
1049 }
1050 
1051 } // namespace ns3
iterator in a Buffer instance
Definition: buffer.h:100
void Write(const uint8_t *buffer, uint32_t size)
Definition: buffer.cc:951
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:563
Buffer CreateFragment(uint32_t start, uint32_t length) const
Definition: buffer.cc:526
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:716
void RemoveAtEnd(uint32_t end)
Definition: buffer.cc:490
uint32_t GetSize() const
Definition: buffer.h:1068
void AddAtStart(uint32_t start)
Definition: buffer.cc:311
Buffer::Iterator Begin() const
Definition: buffer.h:1074
void AddAtEnd(uint32_t end)
Definition: buffer.cc:357
Buffer::Iterator End() const
Definition: buffer.h:1081
uint32_t Deserialize(const uint8_t *buffer, uint32_t size)
Definition: buffer.cc:651
void RemoveAtStart(uint32_t start)
Definition: buffer.cc:444
uint32_t Serialize(uint8_t *buffer, uint32_t maxSize) const
Definition: buffer.cc:579
Identifies a byte tag and a set of bytes within a packet to which the tag applies.
Definition: packet.h:64
TypeId m_tid
the ns3::TypeId associated to this tag.
Definition: packet.h:104
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:57
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:127
An iterator for iterating through a byte tag list.
Definition: byte-tag-list.h:75
uint32_t GetOffsetStart() const
Returns the offset from the start of the virtual byte buffer to the ByteTagList.
struct ByteTagList::Iterator::Item Next()
Returns the next Item from 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:443
bool IsNull() const
Check for null implementation.
Definition: callback.h:572
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.
virtual void Print(std::ostream &os) const =0
Print the object contents.
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:240
network packets
Definition: packet.h:241
PacketTagIterator GetPacketTagIterator() const
Returns an object which can be used to iterate over the list of packet tags.
Definition: packet.cc:1039
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:986
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:792
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:793
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:863
static uint32_t m_globalUid
Global counter of packets Uid.
Definition: packet.h:800
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:824
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:794
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:1016
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:962
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:979
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:1009
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:934
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:1002
ByteTagIterator GetByteTagIterator() const
Returns an iterator over the set of byte tags included in this packet.
Definition: packet.cc:956
PacketMetadata m_metadata
the packet's metadata
Definition: packet.h:795
Ptr< NixVector > m_nixVector
the packet's Nix vector
Definition: packet.h:798
bool ReplacePacketTag(Tag &tag)
Replace the value of a packet tag.
Definition: packet.cc:994
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:143
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
Item(const struct PacketTagList::TagData *data)
Constructor.
Definition: packet.cc:112
Iterator over the set of packet tags in a packet.
Definition: packet.h:137
const struct PacketTagList::TagData * m_current
actual position over the set of tags in a packet
Definition: packet.h:187
bool HasNext() const
Definition: packet.cc:98
PacketTagIterator(const struct PacketTagList::TagData *head)
Constructor.
Definition: packet.cc:92
friend class Packet
Friend class.
Definition: packet.h:181
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).
const struct PacketTagList::TagData * Head() const
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.
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:60
Callback< ObjectBase * > GetConstructor() const
Get the constructor callback.
Definition: type-id.cc:1088
bool HasConstructor() const
Check if this TypeId has a constructor.
Definition: type-id.cc:1018
std::size_t GetAttributeN() const
Get the number of attributes.
Definition: type-id.cc:1104
std::string GetName() const
Get the name.
Definition: type-id.cc:995
#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:129
value
Definition: second.py:41
#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.
uint32_t currentTrimedFromStart
how many bytes were trimmed from the start of a fragment.
Buffer::Iterator current
an iterator which can be fed to Deserialize.
uint32_t currentSize
size of item.
Tree node for sharing serialized tags.
struct TagData * next
Pointer to next in list.
uint32_t prev