A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
packet-metadata-test.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2006,2007 INRIA
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
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 <stdarg.h>
21 #include <iostream>
22 #include <sstream>
23 #include "ns3/test.h"
24 #include "ns3/header.h"
25 #include "ns3/trailer.h"
26 #include "ns3/packet.h"
27 #include "ns3/packet-metadata.h"
28 
29 using namespace ns3;
30 
31 namespace {
32 
33 class HistoryHeaderBase : public Header
34 {
35 public:
36  static TypeId GetTypeId (void);
38  bool IsOk (void) const;
39 protected:
40  void ReportError (void);
41 private:
42  bool m_ok;
43 };
44 
45 TypeId
46 HistoryHeaderBase::GetTypeId (void)
47 {
48  static TypeId tid = TypeId ("ns3::HistoryHeaderBase")
49  .SetParent<Header> ()
50  ;
51  return tid;
52 }
53 
54 HistoryHeaderBase::HistoryHeaderBase ()
55  : m_ok (true)
56 {
57 }
58 
59 bool
61 {
62  return m_ok;
63 }
64 void
66 {
67  m_ok = false;
68 }
69 
70 
71 template <int N>
73 {
74 public:
75  HistoryHeader ();
76  static TypeId GetTypeId (void);
77  virtual TypeId GetInstanceTypeId (void) const;
78  virtual void Print (std::ostream &os) const;
79  virtual uint32_t GetSerializedSize (void) const;
80  virtual void Serialize (Buffer::Iterator start) const;
81  virtual uint32_t Deserialize (Buffer::Iterator start);
82 };
83 
84 template <int N>
87 {
88 }
89 
90 template <int N>
91 TypeId
93 {
94  std::ostringstream oss;
95  oss << "ns3::HistoryHeader<"<<N<<">";
96  static TypeId tid = TypeId (oss.str ().c_str ())
97  .SetParent<HistoryHeaderBase> ()
99  ;
100  return tid;
101 }
102 
103 template <int N>
104 TypeId
106 {
107  return GetTypeId ();
108 }
109 template <int N>
110 void
111 HistoryHeader<N>::Print (std::ostream &os) const
112 {
113  NS_ASSERT (false);
114 }
115 template <int N>
116 uint32_t
118 {
119  return N;
120 }
121 template <int N>
122 void
124 {
125  start.WriteU8 (N, N);
126 }
127 template <int N>
128 uint32_t
130 {
131  for (int i = 0; i < N; i++)
132  {
133  if (start.ReadU8 () != N)
134  {
135  ReportError ();
136  }
137  }
138  return N;
139 }
140 
142 {
143 public:
144  static TypeId GetTypeId (void);
146  bool IsOk (void) const;
147 protected:
148  void ReportError (void);
149 private:
150  bool m_ok;
151 };
152 
153 TypeId
155 {
156  static TypeId tid = TypeId ("ns3::HistoryTrailerBase")
157  .SetParent<Trailer> ()
158  ;
159  return tid;
160 }
162  : m_ok (true)
163 {
164 }
165 bool
167 {
168  return m_ok;
169 }
170 void
172 {
173  m_ok = false;
174 }
175 
176 
177 template <int N>
179 {
180 public:
181  HistoryTrailer ();
182 
183  static TypeId GetTypeId (void);
184  virtual TypeId GetInstanceTypeId (void) const;
185  virtual void Print (std::ostream &os) const;
186  virtual uint32_t GetSerializedSize (void) const;
187  virtual void Serialize (Buffer::Iterator start) const;
188  virtual uint32_t Deserialize (Buffer::Iterator start);
189 private:
190  bool m_ok;
191 };
192 
193 template <int N>
195 {
196 }
197 
198 template <int N>
199 TypeId
201 {
202  std::ostringstream oss;
203  oss << "ns3::HistoryTrailer<"<<N<<">";
204  static TypeId tid = TypeId (oss.str ().c_str ())
205  .SetParent<HistoryTrailerBase> ()
207  ;
208  return tid;
209 }
210 
211 template <int N>
212 TypeId
214 {
215  return GetTypeId ();
216 }
217 template <int N>
218 void
219 HistoryTrailer<N>::Print (std::ostream &os) const
220 {
221  NS_ASSERT (false);
222 }
223 template <int N>
224 uint32_t
226 {
227  return N;
228 }
229 template <int N>
230 void
232 {
233  start.Prev (N);
234  start.WriteU8 (N, N);
235 }
236 template <int N>
237 uint32_t
239 {
240  start.Prev (N);
241  for (int i = 0; i < N; i++)
242  {
243  if (start.ReadU8 () != N)
244  {
245  ReportError ();
246  }
247  }
248  return N;
249 }
250 
251 }
252 
253 namespace ns3 {
254 
255 class PacketMetadataTest : public TestCase {
256 public:
258  virtual ~PacketMetadataTest ();
259  void CheckHistory (Ptr<Packet> p, const char *file, int line, uint32_t n, ...);
260  virtual void DoRun (void);
261 private:
262  Ptr<Packet> DoAddHeader (Ptr<Packet> p);
263 };
264 
265 PacketMetadataTest::PacketMetadataTest ()
266  : TestCase ("Packet metadata")
267 {
268 }
269 
271 {
272 }
273 
274 void
275 PacketMetadataTest::CheckHistory (Ptr<Packet> p, const char *file, int line, uint32_t n, ...)
276 {
277  std::list<int> expected;
278  va_list ap;
279  va_start (ap, n);
280  for (uint32_t j = 0; j < n; j++)
281  {
282  int v = va_arg (ap, int);
283  expected.push_back (v);
284  }
285  va_end (ap);
286 
288  std::list<int> got;
289  while (k.HasNext ())
290  {
291  struct PacketMetadata::Item item = k.Next ();
292  if (item.isFragment || item.type == PacketMetadata::Item::PAYLOAD)
293  {
294  got.push_back (item.currentSize);
295  continue;
296  }
298  {
299  Callback<ObjectBase *> constructor = item.tid.GetConstructor ();
300  HistoryHeaderBase *header = dynamic_cast<HistoryHeaderBase *> (constructor ());
301  if (header == 0)
302  {
303  goto error;
304  }
305  header->Deserialize (item.current);
306  if (!header->IsOk ())
307  {
308  delete header;
309  goto error;
310  }
311  delete header;
312  }
313  else if (item.type == PacketMetadata::Item::TRAILER)
314  {
315  Callback<ObjectBase *> constructor = item.tid.GetConstructor ();
316  HistoryTrailerBase *trailer = dynamic_cast<HistoryTrailerBase *> (constructor ());
317  if (trailer == 0)
318  {
319  goto error;
320  }
321  trailer->Deserialize (item.current);
322  if (!trailer->IsOk ())
323  {
324  delete trailer;
325  goto error;
326  }
327  delete trailer;
328  }
329  got.push_back (item.currentSize);
330  }
331 
332  for (std::list<int>::iterator i = got.begin (),
333  j = expected.begin ();
334  i != got.end (); i++, j++)
335  {
336  NS_ASSERT (j != expected.end ());
337  if (*j != *i)
338  {
339  goto error;
340  }
341  }
342  return;
343 error:
344  std::ostringstream failure;
345  failure << "PacketMetadata error. Got:\"";
346  for (std::list<int>::iterator i = got.begin ();
347  i != got.end (); i++)
348  {
349  failure << *i << ", ";
350  }
351  failure << "\", expected: \"";
352  for (std::list<int>::iterator j = expected.begin ();
353  j != expected.end (); j++)
354  {
355  failure << *j << ", ";
356  }
357  failure << "\"";
358  NS_TEST_ASSERT_MSG_EQ_INTERNAL (false, true, failure.str (), file, line);
359 }
360 
361 #define ADD_HEADER(p, n) \
362  { \
363  HistoryHeader<n> header; \
364  p->AddHeader (header); \
365  }
366 #define ADD_TRAILER(p, n) \
367  { \
368  HistoryTrailer<n> trailer; \
369  p->AddTrailer (trailer); \
370  }
371 #define REM_HEADER(p, n) \
372  { \
373  HistoryHeader<n> header; \
374  p->RemoveHeader (header); \
375  }
376 #define REM_TRAILER(p, n) \
377  { \
378  HistoryTrailer<n> trailer; \
379  p->RemoveTrailer (trailer); \
380  }
381 #define CHECK_HISTORY(p, ...) \
382  { \
383  CheckHistory (p, __FILE__, __LINE__, __VA_ARGS__); \
384  uint32_t size = p->GetSerializedSize (); \
385  uint8_t* buffer = new uint8_t[size]; \
386  p->Serialize (buffer, size); \
387  Ptr<Packet> otherPacket = Create<Packet> (buffer, size, true); \
388  delete [] buffer; \
389  CheckHistory (otherPacket, __FILE__, __LINE__, __VA_ARGS__); \
390  }
391 
392 
395 {
396  ADD_HEADER (p, 10);
397  return p;
398 }
399 
400 void
402 {
404 
405  Ptr<Packet> p = Create<Packet> (0);
406  Ptr<Packet> p1 = Create<Packet> (0);
407 
408  p = Create<Packet> (10);
409  ADD_TRAILER (p, 100);
410  CHECK_HISTORY (p, 2, 10, 100);
411 
412 
413  p = Create<Packet> (10);
414  ADD_HEADER (p, 1);
415  ADD_HEADER (p, 2);
416  ADD_HEADER (p, 3);
417  CHECK_HISTORY (p, 4,
418  3, 2, 1, 10);
419  ADD_HEADER (p, 5);
420  CHECK_HISTORY (p, 5,
421  5, 3, 2, 1, 10);
422  ADD_HEADER (p, 6);
423  CHECK_HISTORY (p, 6,
424  6, 5, 3, 2, 1, 10);
425 
426  p = Create<Packet> (10);
427  ADD_HEADER (p, 1);
428  ADD_HEADER (p, 2);
429  ADD_HEADER (p, 3);
430  REM_HEADER (p, 3);
431  CHECK_HISTORY (p, 3,
432  2, 1, 10);
433 
434  p = Create<Packet> (10);
435  ADD_HEADER (p, 1);
436  ADD_HEADER (p, 2);
437  ADD_HEADER (p, 3);
438  REM_HEADER (p, 3);
439  REM_HEADER (p, 2);
440  CHECK_HISTORY (p, 2,
441  1, 10);
442 
443  p = Create<Packet> (10);
444  ADD_HEADER (p, 1);
445  ADD_HEADER (p, 2);
446  ADD_HEADER (p, 3);
447  REM_HEADER (p, 3);
448  REM_HEADER (p, 2);
449  REM_HEADER (p, 1);
450  CHECK_HISTORY (p, 1, 10);
451 
452  p = Create<Packet> (10);
453  ADD_HEADER (p, 1);
454  ADD_HEADER (p, 2);
455  ADD_HEADER (p, 3);
456  p1 = p->Copy ();
457  REM_HEADER (p1, 3);
458  REM_HEADER (p1, 2);
459  REM_HEADER (p1, 1);
460  CHECK_HISTORY (p1, 1, 10);
461  CHECK_HISTORY (p, 4,
462  3, 2, 1, 10);
463  ADD_HEADER (p1, 1);
464  ADD_HEADER (p1, 2);
465  CHECK_HISTORY (p1, 3,
466  2, 1, 10);
467  CHECK_HISTORY (p, 4,
468  3, 2, 1, 10);
469  ADD_HEADER (p, 3);
470  CHECK_HISTORY (p, 5,
471  3, 3, 2, 1, 10);
472  ADD_TRAILER (p, 4);
473  CHECK_HISTORY (p, 6,
474  3, 3, 2, 1, 10, 4);
475  ADD_TRAILER (p, 5);
476  CHECK_HISTORY (p, 7,
477  3, 3, 2, 1, 10, 4, 5);
478  REM_HEADER (p, 3);
479  CHECK_HISTORY (p, 6,
480  3, 2, 1, 10, 4, 5);
481  REM_TRAILER (p, 5);
482  CHECK_HISTORY (p, 5,
483  3, 2, 1, 10, 4);
484  p1 = p->Copy ();
485  REM_TRAILER (p, 4);
486  CHECK_HISTORY (p, 4,
487  3, 2, 1, 10);
488  CHECK_HISTORY (p1, 5,
489  3, 2, 1, 10, 4);
490  p1->RemoveAtStart (3);
491  CHECK_HISTORY (p1, 4,
492  2, 1, 10, 4);
493  p1->RemoveAtStart (1);
494  CHECK_HISTORY (p1, 4,
495  1, 1, 10, 4);
496  p1->RemoveAtStart (1);
497  CHECK_HISTORY (p1, 3,
498  1, 10, 4);
499  p1->RemoveAtEnd (4);
500  CHECK_HISTORY (p1, 2,
501  1, 10);
502  p1->RemoveAtStart (1);
503  CHECK_HISTORY (p1, 1, 10);
504 
505  p = Create<Packet> (10);
506  ADD_HEADER (p, 8);
507  ADD_TRAILER (p, 8);
508  ADD_TRAILER (p, 8);
509  p->RemoveAtStart (8+10+8);
510  CHECK_HISTORY (p, 1, 8);
511 
512  p = Create<Packet> (10);
513  ADD_HEADER (p, 10);
514  ADD_HEADER (p, 8);
515  ADD_TRAILER (p, 6);
516  ADD_TRAILER (p, 7);
517  ADD_TRAILER (p, 9);
518  p->RemoveAtStart (5);
519  p->RemoveAtEnd (12);
520  CHECK_HISTORY (p, 5, 3, 10, 10, 6, 4);
521 
522  p = Create<Packet> (10);
523  ADD_HEADER (p, 10);
524  ADD_TRAILER (p, 6);
525  p->RemoveAtEnd (18);
526  ADD_TRAILER (p, 5);
527  ADD_HEADER (p, 3);
528  CHECK_HISTORY (p, 3, 3, 8, 5);
529  p->RemoveAtStart (12);
530  CHECK_HISTORY (p, 1, 4);
531  p->RemoveAtEnd (2);
532  CHECK_HISTORY (p, 1, 2);
533  ADD_HEADER (p, 10);
534  CHECK_HISTORY (p, 2, 10, 2);
535  p->RemoveAtEnd (5);
536  CHECK_HISTORY (p, 1, 7);
537 
538  Ptr<Packet> p2 = Create<Packet> (0);
539  Ptr<Packet> p3 = Create<Packet> (0);
540 
541  p = Create<Packet> (40);
542  ADD_HEADER (p, 5);
543  ADD_HEADER (p, 8);
544  CHECK_HISTORY (p, 3, 8, 5, 40);
545  p1 = p->CreateFragment (0, 5);
546  p2 = p->CreateFragment (5, 5);
547  p3 = p->CreateFragment (10, 43);
548  CHECK_HISTORY (p1, 1, 5);
549  CHECK_HISTORY (p2, 2, 3, 2);
550  CHECK_HISTORY (p3, 2, 3, 40);
551  p1->AddAtEnd (p2);
552  CHECK_HISTORY (p1, 2, 8, 2);
553  CHECK_HISTORY (p2, 2, 3, 2);
554  p1->AddAtEnd (p3);
555  CHECK_HISTORY (p1, 3, 8, 5, 40);
556  CHECK_HISTORY (p2, 2, 3, 2);
557  CHECK_HISTORY (p3, 2, 3, 40);
558  p1 = p->CreateFragment (0, 5);
559  CHECK_HISTORY (p1, 1, 5);
560 
561  p3 = Create<Packet> (50);
562  ADD_HEADER (p3, 8);
563  CHECK_HISTORY (p3, 2, 8, 50);
564  CHECK_HISTORY (p1, 1, 5);
565  p1->AddAtEnd (p3);
566  CHECK_HISTORY (p1, 3, 5, 8, 50);
567  ADD_HEADER (p1, 5);
568  CHECK_HISTORY (p1, 4, 5, 5, 8, 50);
569  ADD_TRAILER (p1, 2);
570  CHECK_HISTORY (p1, 5, 5, 5, 8, 50, 2);
571  REM_HEADER (p1, 5);
572  CHECK_HISTORY (p1, 4, 5, 8, 50, 2);
573  p1->RemoveAtEnd (60);
574  CHECK_HISTORY (p1, 1, 5);
575  p1->AddAtEnd (p2);
576  CHECK_HISTORY (p1, 2, 8, 2);
577  CHECK_HISTORY (p2, 2, 3, 2);
578 
579  p3 = Create<Packet> (40);
580  ADD_HEADER (p3, 5);
581  ADD_HEADER (p3, 5);
582  CHECK_HISTORY (p3, 3, 5, 5, 40);
583  p1 = p3->CreateFragment (0, 5);
584  p2 = p3->CreateFragment (5, 5);
585  CHECK_HISTORY (p1, 1, 5);
586  CHECK_HISTORY (p2, 1, 5);
587  p1->AddAtEnd (p2);
588  CHECK_HISTORY (p1, 2, 5, 5);
589 
590  p = Create<Packet> (0);
591  CHECK_HISTORY (p, 0);
592 
593  p3 = Create<Packet> (0);
594  ADD_HEADER (p3, 5);
595  ADD_HEADER (p3, 5);
596  CHECK_HISTORY (p3, 2, 5, 5);
597  p1 = p3->CreateFragment (0, 4);
598  p2 = p3->CreateFragment (9, 1);
599  CHECK_HISTORY (p1, 1, 4);
600  CHECK_HISTORY (p2, 1, 1);
601  p1->AddAtEnd (p2);
602  CHECK_HISTORY (p1, 2, 4, 1);
603 
604 
605  p = Create<Packet> (2000);
606  CHECK_HISTORY (p, 1, 2000);
607 
608  p = Create<Packet> ();
609  ADD_TRAILER (p, 10);
610  ADD_HEADER (p, 5);
611  p1 = p->CreateFragment (0, 8);
612  p2 = p->CreateFragment (8, 7);
613  p1->AddAtEnd (p2);
614  CHECK_HISTORY (p, 2, 5, 10);
615 
616  p = Create<Packet> ();
617  ADD_TRAILER (p, 10);
618  REM_TRAILER (p, 10);
619  ADD_TRAILER (p, 10);
620  CHECK_HISTORY (p, 1, 10);
621 
622  p = Create<Packet> ();
623  ADD_HEADER (p, 10);
624  REM_HEADER (p, 10);
625  ADD_HEADER (p, 10);
626  CHECK_HISTORY (p, 1, 10);
627 
628  p = Create<Packet> ();
629  ADD_HEADER (p, 10);
630  p = DoAddHeader (p);
631  CHECK_HISTORY (p, 2, 10, 10);
632 
633  p = Create<Packet> (10);
634  ADD_HEADER (p, 8);
635  ADD_TRAILER (p, 8);
636  ADD_TRAILER (p, 8);
637  p->RemoveAtStart (8+10+8);
638  CHECK_HISTORY (p, 1, 8);
639 
640  p = Create<Packet> (0);
641  ADD_HEADER (p, 8);
642  REM_HEADER (p, 8);
643  CHECK_HISTORY (p, 0);
644 
645  p = Create<Packet> (0);
646  ADD_TRAILER (p, 8);
647  REM_TRAILER (p, 8);
648  CHECK_HISTORY (p, 0);
649 
650  p = Create<Packet> (0);
651  ADD_HEADER (p, 8);
652  p->RemoveAtStart (8);
653  CHECK_HISTORY (p, 0);
654 
655  p = Create<Packet> (0);
656  ADD_HEADER (p, 8);
657  ADD_TRAILER (p, 8);
658  REM_TRAILER (p, 8);
659  REM_HEADER (p, 8);
660  CHECK_HISTORY (p, 0);
661 
662  p = Create<Packet> (0);
663  ADD_HEADER (p, 8);
664  ADD_TRAILER (p, 8);
665  REM_HEADER (p, 8);
666  REM_TRAILER (p, 8);
667  CHECK_HISTORY (p, 0);
668 
669  p = Create<Packet> (0);
670  ADD_HEADER (p, 8);
671  ADD_TRAILER (p, 8);
672  REM_TRAILER (p, 8);
673  p->RemoveAtStart (8);
674  CHECK_HISTORY (p, 0);
675 
676  p = Create<Packet> (0);
677  ADD_HEADER (p, 8);
678  ADD_TRAILER (p, 8);
679  REM_HEADER (p, 8);
680  p->RemoveAtEnd (8);
681  CHECK_HISTORY (p, 0);
682 
683  p = Create<Packet> (0);
684  ADD_HEADER (p, 8);
685  ADD_TRAILER (p, 8);
686  REM_TRAILER (p, 8);
687  p->RemoveAtEnd (8);
688  CHECK_HISTORY (p, 0);
689 
690  p = Create<Packet> (0);
691  ADD_HEADER (p, 8);
692  ADD_TRAILER (p, 8);
693  REM_HEADER (p, 8);
694  p->RemoveAtStart (8);
695  CHECK_HISTORY (p, 0);
696 
697  p = Create<Packet> (16383);
698  p = Create<Packet> (16384);
699 
700 
701  // bug 179.
702  p = Create<Packet> (40);
703  p2 = p->CreateFragment (5, 5);
704  p3 = p->CreateFragment (10, 30);
705  ADD_HEADER (p2, 8);
706  ADD_HEADER (p3, 8);
707  REM_HEADER (p2, 8);
708  REM_HEADER (p3, 8);
709  p2->AddAtEnd (p3);
710 
711 
712  p = Create<Packet> (1000);
713  ADD_HEADER (p, 10);
714  ADD_TRAILER (p, 5);
715  p1 = p->Copy ();
716  ADD_HEADER (p1, 20);
717  REM_HEADER (p1, 20);
718  REM_TRAILER (p1, 5);
719  NS_TEST_EXPECT_MSG_EQ (p->GetSize (), 1015, "Correct size");
720 
721 
722  p = Create<Packet> (1510);
723  ADD_HEADER (p, 8);
724  ADD_HEADER (p, 25);
725  REM_HEADER (p, 25);
726  ADD_HEADER (p, 1);
727  p1 = p->CreateFragment (0, 1500);
728  p2 = p1->Copy ();
729  ADD_HEADER (p2, 24);
730  NS_TEST_EXPECT_MSG_EQ (p->GetSize (), 1519, "Correct size");
731 
732  p = Create<Packet> (1000);
733  ADD_HEADER (p, 2);
734  ADD_TRAILER (p, 3);
735  p1 = p->Copy ();
736  CHECK_HISTORY (p1, 3, 2, 1000, 3);
737  REM_HEADER (p, 2);
738  ADD_HEADER (p, 1);
739  CHECK_HISTORY (p, 3, 1, 1000, 3);
740  CHECK_HISTORY (p1, 3, 2, 1000, 3);
741 
742  p = Create<Packet> (200);
743  ADD_HEADER (p, 24);
744  p1 = p->CreateFragment (0, 100);
745  p2 = p->CreateFragment (100, 100);
746  p1->AddAtEnd (p2);
747 
748  p = Create<Packet> ();
749  ADD_HEADER (p, 10);
750  p1 = Create<Packet> ();
751  ADD_HEADER (p1, 11);
752  REM_HEADER (p1, 11);
753  p->AddAtEnd (p1);
754 
755  p = Create<Packet> (500);
756  CHECK_HISTORY (p, 1, 500);
757  ADD_HEADER (p, 10);
758  CHECK_HISTORY (p, 2, 10, 500);
759  REM_HEADER (p, 10);
760  CHECK_HISTORY (p, 1, 500);
761  p->RemoveAtEnd (10);
762  CHECK_HISTORY (p, 1, 490);
763 
764  p = Create<Packet> (500);
765  CHECK_HISTORY (p, 1, 500);
766  ADD_TRAILER (p, 10);
767  CHECK_HISTORY (p, 2, 500, 10);
768  REM_TRAILER (p, 10);
769  CHECK_HISTORY (p, 1, 500);
770  p->RemoveAtStart (10);
771  CHECK_HISTORY (p, 1, 490);
772 
773  // bug 1072
774  p = Create<Packet> (500);
775  ADD_HEADER (p, 10);
776  ADD_HEADER (p, 20);
777  ADD_HEADER (p, 5);
778  CHECK_HISTORY (p, 4, 5, 20, 10, 500);
779  p1 = p->CreateFragment (0,6);
780  p2 = p->CreateFragment (6,535-6);
781  p1->AddAtEnd (p2);
782 
783  // bug 1072#2
784  p = Create<Packet> (reinterpret_cast<const uint8_t*> ("hello world"), 11);
785  ADD_HEADER (p, 2);
786  CHECK_HISTORY (p, 2, 2, 11);
787  p1 = p->CreateFragment (0, 5);
788  CHECK_HISTORY (p1, 2, 2, 3);
789  p2 = p->CreateFragment (5, 8);
790  CHECK_HISTORY (p2, 1, 8);
791 
792  ADD_HEADER (p1, 8+2+2*6);
793  ADD_TRAILER (p1, 4);
794  CHECK_HISTORY (p1, 4, 22, 2, 3, 4);
795  ADD_HEADER (p2, 8+2+2*6);
796  ADD_TRAILER (p2, 4);
797  CHECK_HISTORY (p2, 3, 22, 8, 4);
798 
799  REM_TRAILER (p1, 4);
800  REM_HEADER (p1, 8+2+2*6);
801  CHECK_HISTORY (p1, 2, 2, 3);
802  REM_TRAILER (p2, 4);
803  REM_HEADER (p2, 8+2+2*6);
804  CHECK_HISTORY (p2, 1, 8);
805 
806  p3 = p1->Copy ();
807  CHECK_HISTORY (p3, 2, 2, 3);
808  p3->AddAtEnd (p2);
809  CHECK_HISTORY (p3, 2, 2, 11);
810 
811  CHECK_HISTORY (p, 2, 2, 11);
812  REM_HEADER (p, 2);
813  CHECK_HISTORY (p, 1, 11);
814  REM_HEADER (p3, 2);
815  CHECK_HISTORY (p3, 1, 11);
816 
817  uint8_t *buf = new uint8_t[p3->GetSize ()];
818  p3->CopyData (buf, p3->GetSize ());
819  std::string msg = std::string (reinterpret_cast<const char *>(buf),
820  p3->GetSize ());
821  delete [] buf;
822  NS_TEST_EXPECT_MSG_EQ (msg, std::string ("hello world"), "Could not find original data in received packet");
823 }
824 //-----------------------------------------------------------------------------
826 {
827 public:
829 };
830 
832  : TestSuite ("packet-metadata", UNIT)
833 {
835 }
836 
838 } // namespace ns3