A Discrete-Event Network Simulator
API
pcap-file-test-suite.cc
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License version 2 as
4  * published by the Free Software Foundation;
5  *
6  * This program is distributed in the hope that it will be useful,
7  * but WITHOUT ANY WARRANTY; without even the implied warranty of
8  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9  * GNU General Public License for more details.
10  *
11  * You should have received a copy of the GNU General Public License
12  * along with this program; if not, write to the Free Software
13  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14  *
15  * Author: Craig Dowell (craigdo@ee.washington.edu)
16  */
17 
18 #include "ns3/log.h"
19 #include "ns3/pcap-file.h"
20 #include "ns3/test.h"
21 
22 #include <cstdio>
23 #include <cstdlib>
24 #include <cstring>
25 #include <iostream>
26 #include <sstream>
27 
28 using namespace ns3;
29 
30 NS_LOG_COMPONENT_DEFINE("pcap-file-test-suite");
31 
32 // ===========================================================================
33 // Some utility functions for the tests.
34 // ===========================================================================
35 
36 static uint16_t
37 Swap(uint16_t val)
38 {
39  return ((val >> 8) & 0x00ff) | ((val << 8) & 0xff00);
40 }
41 
42 static uint32_t
43 Swap(uint32_t val)
44 {
45  return ((val >> 24) & 0x000000ff) | ((val >> 8) & 0x0000ff00) | ((val << 8) & 0x00ff0000) |
46  ((val << 24) & 0xff000000);
47 }
48 
49 static bool
50 CheckFileExists(std::string filename)
51 {
52  FILE* p = std::fopen(filename.c_str(), "rb");
53  if (p == nullptr)
54  {
55  return false;
56  }
57 
58  std::fclose(p);
59  return true;
60 }
61 
62 static bool
63 CheckFileLength(std::string filename, long sizeExpected)
64 {
65  FILE* p = std::fopen(filename.c_str(), "rb");
66  if (p == nullptr)
67  {
68  return false;
69  }
70 
71  std::fseek(p, 0, SEEK_END);
72 
73  auto sizeActual = std::ftell(p);
74  std::fclose(p);
75 
76  return sizeActual == sizeExpected;
77 }
78 
87 {
88  public:
90  ~WriteModeCreateTestCase() override;
91 
92  private:
93  void DoSetup() override;
94  void DoRun() override;
95  void DoTeardown() override;
96 
97  std::string m_testFilename;
98 };
99 
101  : TestCase("Check to see that PcapFile::Open with mode std::ios::out works")
102 {
103 }
104 
106 {
107 }
108 
109 void
111 {
112  std::stringstream filename;
113  uint32_t n = rand();
114  filename << n;
115  m_testFilename = CreateTempDirFilename(filename.str() + ".pcap");
116 }
117 
118 void
120 {
121  if (remove(m_testFilename.c_str()))
122  {
123  NS_LOG_ERROR("Failed to delete file " << m_testFilename);
124  }
125 }
126 
127 void
129 {
130  PcapFile f;
131 
132  //
133  // Opening a new file in write mode should result in an empty file of the
134  // given name.
135  //
136  f.Open(m_testFilename, std::ios::out);
137 
138  NS_TEST_ASSERT_MSG_EQ(f.Fail(), false, "Open (" << m_testFilename << ", \"w\") returns error");
139  f.Close();
140 
142  true,
143  "Open (" << m_testFilename
144  << ", \"std::ios::out\") does not create file");
146  true,
147  "Open (" << m_testFilename
148  << ", \"std::ios::out\") does not result in an empty file");
149 
150  //
151  // Calling Init() on a file created with "std::ios::out" should result in a file just
152  // long enough to contain the pcap file header.
153  //
154  f.Open(m_testFilename, std::ios::out);
155  NS_TEST_ASSERT_MSG_EQ(f.Fail(),
156  false,
157  "Open (" << m_testFilename << ", \"std::ios::out\") returns error");
158 
159  f.Init(1234, 5678, 7);
160  NS_TEST_ASSERT_MSG_EQ(f.Fail(), false, "Init (1234, 5678, 7) returns error");
161 
162  f.Close();
163 
165  true,
166  "Init () does not result in a file with a pcap file header");
167 
168  //
169  // Opening an existing file in write mode should result in that file being
170  // emptied.
171  //
172  f.Open(m_testFilename, std::ios::out);
173  NS_TEST_ASSERT_MSG_EQ(f.Fail(),
174  false,
175  "Open (" << m_testFilename << ", \"std::ios::out\") returns error");
176 
177  f.Close();
178 
180  true,
181  "Open (" << m_testFilename
182  << ", \"w\") does not result in an empty file");
183 
184  //
185  // Initialize the file again.
186  //
187  f.Open(m_testFilename, std::ios::out);
188  NS_TEST_ASSERT_MSG_EQ(f.Fail(), false, "Open (" << m_testFilename << ", \"w\") returns error");
189 
190  f.Init(1234, 5678, 7);
191  NS_TEST_ASSERT_MSG_EQ(f.Fail(), false, "Init (1234, 5678, 7) returns error");
192 
193  //
194  // Now we should be able to write to it since it was opened in std::ios::out mode.
195  // This is just a permissions check so we don't actually look at the
196  // data.
197  //
198  uint8_t buffer[128];
199  memset(buffer, 0, sizeof(buffer));
200  f.Write(0, 0, buffer, 128);
201  NS_TEST_ASSERT_MSG_EQ(f.Fail(),
202  false,
203  "Write (write-only-file " << m_testFilename << ") returns error");
204 }
205 
214 {
215  public:
217  ~ReadModeCreateTestCase() override;
218 
219  private:
220  void DoSetup() override;
221  void DoRun() override;
222  void DoTeardown() override;
223 
224  std::string m_testFilename;
225 };
226 
228  : TestCase("Check to see that PcapFile::Open with mode std::ios::in works")
229 {
230 }
231 
233 {
234 }
235 
236 void
238 {
239  std::stringstream filename;
240  uint32_t n = rand();
241  filename << n;
242  m_testFilename = CreateTempDirFilename(filename.str() + ".pcap");
243 }
244 
245 void
247 {
248  if (remove(m_testFilename.c_str()))
249  {
250  NS_LOG_ERROR("Failed to delete file " << m_testFilename);
251  }
252 }
253 
254 void
256 {
257  PcapFile f;
258 
259  //
260  // Opening a non-existing file in read mode should result in an error.
261  //
262  f.Open(m_testFilename, std::ios::in);
263  NS_TEST_ASSERT_MSG_EQ(f.Fail(),
264  true,
265  "Open (non-existing-filename "
266  << m_testFilename << ", \"std::ios::in\") does not return error");
267  f.Close();
268  f.Clear();
270  false,
271  "Open (" << m_testFilename
272  << ", \"std::ios::in\") unexpectedly created a file");
273 
274  //
275  // Okay, now create an uninitialized file using previously tested operations
276  //
277  f.Open(m_testFilename, std::ios::out);
278  NS_TEST_ASSERT_MSG_EQ(f.Fail(), false, "Open (filename, \"std::ios::out\") returns error");
279  f.Close();
280 
281  //
282  // Opening this file should result in an error since it has no pcap file header.
283  //
284  f.Open(m_testFilename, std::ios::in);
285  NS_TEST_ASSERT_MSG_EQ(f.Fail(),
286  true,
287  "Open (non-initialized-filename "
288  << m_testFilename << ", \"std::ios::in\") does not return error");
289  f.Close();
290  f.Clear();
291 
292  //
293  // Okay, now open that non-initialized file in write mode and initialize it
294  // Note that we open it in write mode to initialize it.
295  //
296  f.Open(m_testFilename, std::ios::out);
297  NS_TEST_ASSERT_MSG_EQ(f.Fail(),
298  false,
299  "Open (" << m_testFilename << ", \"std::ios::out\") returns error");
300 
301  f.Init(1234, 5678, 7);
302  NS_TEST_ASSERT_MSG_EQ(f.Fail(), false, "Init (1234, 5678, 7) returns error");
303  f.Close();
304 
305  //
306  // Opening this file should now work since it has a pcap file header.
307  //
308  f.Open(m_testFilename, std::ios::in);
309  NS_TEST_ASSERT_MSG_EQ(f.Fail(),
310  false,
311  "Open (initialized-filename " << m_testFilename
312  << ", \"std::ios::in\") returns error");
313 
314  //
315  // Now we should not be able to write to it since it was opened in "r" mode
316  // even if it has been initialized..
317  //
318  uint8_t buffer[128];
319  f.Write(0, 0, buffer, 128);
320  NS_TEST_ASSERT_MSG_EQ(f.Fail(),
321  true,
322  "Write (read-only-file " << m_testFilename << ") does not return error");
323  f.Close();
324  f.Clear();
325 }
326 
327 #if 0
328 // ===========================================================================
329 // Test case to make sure that the Pcap File Object can open an existing pcap
330 // file for appending.
331 // ===========================================================================
332 class AppendModeCreateTestCase : public TestCase
333 {
334 public:
335  AppendModeCreateTestCase ();
336  virtual ~AppendModeCreateTestCase ();
337 
338 private:
339  virtual void DoSetup ();
340  virtual void DoRun ();
341  virtual void DoTeardown ();
342 
343  std::string m_testFilename;
344 };
345 
346 AppendModeCreateTestCase::AppendModeCreateTestCase ()
347  : TestCase ("Check to see that PcapFile::Open with mode std::ios::app works")
348 {
349 }
350 
351 AppendModeCreateTestCase::~AppendModeCreateTestCase ()
352 {
353 }
354 
355 void
356 AppendModeCreateTestCase::DoSetup ()
357 {
358  std::stringstream filename;
359  uint32_t n = rand ();
360  filename << n;
361  m_testFilename = CreateTempDirFilename (filename.str () + ".pcap");
362 }
363 
364 void
365 AppendModeCreateTestCase::DoTeardown ()
366 {
367  if (remove (m_testFilename.c_str ()))
368  {
369  NS_LOG_ERROR ("Failed to delete file " << m_testFilename);
370  }
371 }
372 
373 void
374 AppendModeCreateTestCase::DoRun ()
375 {
376  PcapFile f;
377 
378  //
379  // Opening a non-existing file in append mode should result in an error.
380  //
381  f.Open (m_testFilename, std::ios::out | std::ios::app);
382  NS_TEST_ASSERT_MSG_EQ (f.Fail (), true, "Open (non-existing-filename " << m_testFilename <<
383  ", \"std::ios::app\") does not return error");
384  f.Close ();
385  f.Clear ();
386 
387  NS_TEST_ASSERT_MSG_EQ (CheckFileExists (m_testFilename), false,
388  "Open (" << m_testFilename << ", \"std::ios::app\") unexpectedly created a file");
389 
390  //
391  // Okay, now create an uninitialized file using previously tested operations
392  //
393  f.Open (m_testFilename, std::ios::out);
394  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (" << m_testFilename <<
395  ", \"std::ios::out\") returns error");
396  f.Close ();
397 
398  //
399  // Opening this file should result in an error since it has no pcap file header.
400  //
401  f.Open (m_testFilename, std::ios::out | std::ios::app);
402  NS_TEST_ASSERT_MSG_EQ (f.Fail (), true, "Open (non-initialized-filename " << m_testFilename <<
403  ", \"std::ios::app\") does not return error");
404  f.Close ();
405  f.Clear ();
406 
407  //
408  // Okay, now open that non-initialized file in write mode and initialize it.
409  //
410  f.Open (m_testFilename, std::ios::out);
411  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (non-initialized-filename " << m_testFilename <<
412  ", \"std::ios::out\") returns error");
413 
414  f.Init (1234, 5678, 7);
415  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Init (1234, 5678, 7) returns error");
416  f.Close ();
417 
418  //
419  // Opening this file should now work since it has a pcap file header.
420  //
421  f.Open (m_testFilename, std::ios::out | std::ios::app);
422  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (initialized-filename " << m_testFilename <<
423  ", \"std::ios::app\") returns error");
424 
425  //
426  // We should be able to write to it since it was opened in "std::ios::app" mode.
427  //
428  uint8_t buffer[128];
429  memset (buffer, 0, sizeof(buffer));
430  f.Write (0, 0, buffer, 128);
431  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Write (append-mode-file " << m_testFilename << ") returns error");
432 
433  f.Close ();
434 }
435 #endif
436 
446 {
447  public:
449  ~FileHeaderTestCase() override;
450 
451  private:
452  void DoSetup() override;
453  void DoRun() override;
454  void DoTeardown() override;
455 
456  std::string m_testFilename;
457 };
458 
460  : TestCase("Check to see that PcapFileHeader is managed correctly")
461 {
462 }
463 
465 {
466 }
467 
468 void
470 {
471  std::stringstream filename;
472  uint32_t n = rand();
473  filename << n;
474  m_testFilename = CreateTempDirFilename(filename.str() + ".pcap");
475 }
476 
477 void
479 {
480  if (remove(m_testFilename.c_str()))
481  {
482  NS_LOG_ERROR("Failed to delete file " << m_testFilename);
483  }
484 }
485 
486 void
488 {
489  PcapFile f;
490 
491  //
492  // Create an uninitialized file using previously tested operations
493  //
494  f.Open(m_testFilename, std::ios::out);
495  NS_TEST_ASSERT_MSG_EQ(f.Fail(),
496  false,
497  "Open (" << m_testFilename << ", \"std::ios::out\") returns error");
498 
499  //
500  // Initialize the pcap file header.
501  //
502  f.Init(1234, 5678, 7);
503  NS_TEST_ASSERT_MSG_EQ(f.Fail(), false, "Init (1234, 5678, 7) returns error");
504  f.Close();
505 
506  //
507  // Take a look and see what was done to the file
508  //
509  FILE* p = std::fopen(m_testFilename.c_str(), "r+b");
511  nullptr,
512  "fopen("
513  << m_testFilename
514  << ") should have been able to open a correctly created pcap file");
515 
516  uint32_t val32;
517  uint16_t val16;
518 
519  //
520  // Because the regression tests require that pcap file output be compared
521  // byte-by-byte, we had to decide on a single format for written pcap files.
522  // This was little endian. So we have to do something special with big-
523  // endian machines here.
524  //
525  // When a big endian machine writes a pcap file, it is forced into swap
526  // mode and actually writes little endian files. This is automagically
527  // fixed up when using a PcapFile to read the values, but when a big-
528  // endian machine reads these values directly, they will be swapped.
529  //
530  // We can remove this nonsense when we get rid of the pcap-file-comparison
531  // regression tests.
532  //
533  // So, determine the endian-ness of the running system, and if we're on
534  // a big-endian machine, swap all of the results below before checking.
535  //
536  union {
537  uint32_t a;
538  uint8_t b[4];
539  } u;
540 
541  u.a = 1;
542  bool bigEndian = u.b[3];
543 
544  size_t result = std::fread(&val32, sizeof(val32), 1, p);
545  NS_TEST_ASSERT_MSG_EQ(result, 1, "Unable to fread() magic number");
546  if (bigEndian)
547  {
548  val32 = Swap(val32);
549  }
550  NS_TEST_ASSERT_MSG_EQ(val32, 0xa1b2c3d4, "Magic number written incorrectly");
551 
552  result = std::fread(&val16, sizeof(val16), 1, p);
553  NS_TEST_ASSERT_MSG_EQ(result, 1, "Unable to fread() version major");
554  if (bigEndian)
555  {
556  val16 = Swap(val16);
557  }
558  NS_TEST_ASSERT_MSG_EQ(val16, 2, "Version major written incorrectly");
559 
560  result = std::fread(&val16, sizeof(val16), 1, p);
561  NS_TEST_ASSERT_MSG_EQ(result, 1, "Unable to fread() version minor");
562  if (bigEndian)
563  {
564  val16 = Swap(val16);
565  }
566  NS_TEST_ASSERT_MSG_EQ(val16, 4, "Version minor written incorrectly");
567 
568  result = std::fread(&val32, sizeof(val32), 1, p);
569  NS_TEST_ASSERT_MSG_EQ(result, 1, "Unable to fread() time zone correction");
570  if (bigEndian)
571  {
572  val32 = Swap(val32);
573  }
574  NS_TEST_ASSERT_MSG_EQ(val32, 7, "Version minor written incorrectly");
575 
576  result = std::fread(&val32, sizeof(val32), 1, p);
577  NS_TEST_ASSERT_MSG_EQ(result, 1, "Unable to fread() sig figs");
578  if (bigEndian)
579  {
580  val32 = Swap(val32);
581  }
582  NS_TEST_ASSERT_MSG_EQ(val32, 0, "Sig figs written incorrectly");
583 
584  result = std::fread(&val32, sizeof(val32), 1, p);
585  NS_TEST_ASSERT_MSG_EQ(result, 1, "Unable to fread() snap length");
586  if (bigEndian)
587  {
588  val32 = Swap(val32);
589  }
590  NS_TEST_ASSERT_MSG_EQ(val32, 5678, "Snap length written incorrectly");
591 
592  result = std::fread(&val32, sizeof(val32), 1, p);
593  NS_TEST_ASSERT_MSG_EQ(result, 1, "Unable to fread() data link type");
594  if (bigEndian)
595  {
596  val32 = Swap(val32);
597  }
598  NS_TEST_ASSERT_MSG_EQ(val32, 1234, "Data length type written incorrectly");
599 
600  std::fclose(p);
601  p = nullptr;
602 
603  //
604  // We wrote a little-endian file out correctly, now let's see if we can read
605  // it back in correctly.
606  //
607  // As mentioned above, when a big endian machine writes a pcap file, it is
608  // forced into swap mode and actually writes little endian files. This is
609  // automagically fixed up when using a PcapFile to read the values, so we
610  // don't have to do anything special here.
611  //
612  f.Open(m_testFilename, std::ios::in);
613  NS_TEST_ASSERT_MSG_EQ(f.Fail(),
614  false,
615  "Open (existing-initialized-file "
616  << m_testFilename << ", \"std::ios::in\") returns error");
617 
618  NS_TEST_ASSERT_MSG_EQ(f.GetMagic(), 0xa1b2c3d4, "Read back magic number incorrectly");
619  NS_TEST_ASSERT_MSG_EQ(f.GetVersionMajor(), 2, "Read back version major incorrectly");
620  NS_TEST_ASSERT_MSG_EQ(f.GetVersionMinor(), 4, "Read back version minor incorrectly");
621  NS_TEST_ASSERT_MSG_EQ(f.GetTimeZoneOffset(), 7, "Read back time zone offset incorrectly");
622  NS_TEST_ASSERT_MSG_EQ(f.GetSigFigs(), 0, "Read back sig figs incorrectly");
623  NS_TEST_ASSERT_MSG_EQ(f.GetSnapLen(), 5678, "Read back snap len incorrectly");
624  NS_TEST_ASSERT_MSG_EQ(f.GetDataLinkType(), 1234, "Read back data link type incorrectly");
625  f.Close();
626 
627  //
628  // Re-open the file to erase its contents.
629  //
630  f.Open(m_testFilename, std::ios::out);
631  NS_TEST_ASSERT_MSG_EQ(f.Fail(),
632  false,
633  "Open (" << m_testFilename << ", \"std::ios::out\") returns error");
634 
635  //
636  // Initialize the pcap file header, turning on swap mode manually to force
637  // the pcap file header to be written out in foreign-endian form, whichever
638  // endian-ness that might be. Since big-endian machines are automatically
639  // forced into swap mode, the <true> parameter to f.Init() below is actually
640  // a no-op and we're always writing foreign-endian files. In that case,
641  // this test case is really just a duplicate of the previous.
642  //
643  f.Init(1234, 5678, 7, true);
644  NS_TEST_ASSERT_MSG_EQ(f.Fail(), false, "Init (1234, 5678, 7) returns error");
645  f.Close();
646 
647  //
648  // Take a look and see what was done to the file. Everything should now
649  // appear byte-swapped.
650  //
651  p = std::fopen(m_testFilename.c_str(), "r+b");
653  nullptr,
654  "fopen("
655  << m_testFilename
656  << ") should have been able to open a correctly created pcap file");
657 
658  result = std::fread(&val32, sizeof(val32), 1, p);
659  NS_TEST_ASSERT_MSG_EQ(result, 1, "Unable to fread() magic number");
660  NS_TEST_ASSERT_MSG_EQ(val32, Swap(uint32_t(0xa1b2c3d4)), "Magic number written incorrectly");
661 
662  result = std::fread(&val16, sizeof(val16), 1, p);
663  NS_TEST_ASSERT_MSG_EQ(result, 1, "Unable to fread() version major");
664  NS_TEST_ASSERT_MSG_EQ(val16, Swap(uint16_t(2)), "Version major written incorrectly");
665 
666  result = std::fread(&val16, sizeof(val16), 1, p);
667  NS_TEST_ASSERT_MSG_EQ(result, 1, "Unable to fread() version minor");
668  NS_TEST_ASSERT_MSG_EQ(val16, Swap(uint16_t(4)), "Version minor written incorrectly");
669 
670  result = std::fread(&val32, sizeof(val32), 1, p);
671  NS_TEST_ASSERT_MSG_EQ(result, 1, "Unable to fread() time zone correction");
672  NS_TEST_ASSERT_MSG_EQ(val32, Swap(uint32_t(7)), "Version minor written incorrectly");
673 
674  result = std::fread(&val32, sizeof(val32), 1, p);
675  NS_TEST_ASSERT_MSG_EQ(result, 1, "Unable to fread() sig figs");
676  NS_TEST_ASSERT_MSG_EQ(val32, 0, "Sig figs written incorrectly");
677 
678  result = std::fread(&val32, sizeof(val32), 1, p);
679  NS_TEST_ASSERT_MSG_EQ(result, 1, "Unable to fread() snap length");
680  NS_TEST_ASSERT_MSG_EQ(val32, Swap(uint32_t(5678)), "Snap length written incorrectly");
681 
682  result = std::fread(&val32, sizeof(val32), 1, p);
683  NS_TEST_ASSERT_MSG_EQ(result, 1, "Unable to fread() data link type");
684  NS_TEST_ASSERT_MSG_EQ(val32, Swap(uint32_t(1234)), "Data length type written incorrectly");
685 
686  std::fclose(p);
687  p = nullptr;
688 
689  //
690  // We wrote an opposite-endian file out correctly, now let's see if we can read
691  // it back in correctly. Again, in the case of a big-endian machine, we already
692  // did this test and it is just a duplicate. What we don't test on a big endian
693  // machine is writing out a big-endian file by default, but we can't do that
694  // since it breaks regression testing.
695  //
696  f.Open(m_testFilename, std::ios::in);
697  NS_TEST_ASSERT_MSG_EQ(f.Fail(),
698  false,
699  "Open (existing-initialized-file "
700  << m_testFilename << ", \"std::ios::in\") returns error");
701 
702  NS_TEST_ASSERT_MSG_EQ(f.GetSwapMode(), true, "Byte-swapped file not correctly indicated");
703 
704  NS_TEST_ASSERT_MSG_EQ(f.GetMagic(), 0xa1b2c3d4, "Read back magic number incorrectly");
705  NS_TEST_ASSERT_MSG_EQ(f.GetVersionMajor(), 2, "Read back version major incorrectly");
706  NS_TEST_ASSERT_MSG_EQ(f.GetVersionMinor(), 4, "Read back version minor incorrectly");
707  NS_TEST_ASSERT_MSG_EQ(f.GetTimeZoneOffset(), 7, "Read back time zone offset incorrectly");
708  NS_TEST_ASSERT_MSG_EQ(f.GetSigFigs(), 0, "Read back sig figs incorrectly");
709  NS_TEST_ASSERT_MSG_EQ(f.GetSnapLen(), 5678, "Read back snap len incorrectly");
710  NS_TEST_ASSERT_MSG_EQ(f.GetDataLinkType(), 1234, "Read back data link type incorrectly");
711 
712  f.Close();
713 }
714 
724 {
725  public:
727  ~RecordHeaderTestCase() override;
728 
729  private:
730  void DoSetup() override;
731  void DoRun() override;
732  void DoTeardown() override;
733 
734  std::string m_testFilename;
735 };
736 
738  : TestCase("Check to see that PcapRecordHeader is managed correctly")
739 {
740 }
741 
743 {
744 }
745 
746 void
748 {
749  std::stringstream filename;
750  uint32_t n = rand();
751  filename << n;
752  m_testFilename = CreateTempDirFilename(filename.str() + ".pcap");
753 }
754 
755 void
757 {
758  if (remove(m_testFilename.c_str()))
759  {
760  NS_LOG_ERROR("Failed to delete file " << m_testFilename);
761  }
762 }
763 
764 void
766 {
767  PcapFile f;
768 
769  //
770  // Create an uninitialized file using previously tested operations
771  //
772  f.Open(m_testFilename, std::ios::out);
773  NS_TEST_ASSERT_MSG_EQ(f.Fail(),
774  false,
775  "Open (" << m_testFilename << ", \"std::ios::out\") returns error");
776 
777  //
778  // Initialize the pcap file header.
779  //
780  f.Init(37, 43, -7);
781  NS_TEST_ASSERT_MSG_EQ(f.Fail(), false, "Init (37, 43, -7) returns error");
782 
783  //
784  // Initialize a buffer with a counting pattern to check the data later.
785  //
786  uint8_t bufferOut[128];
787  for (uint32_t i = 0; i < 128; ++i)
788  {
789  bufferOut[i] = i;
790  }
791 
792  //
793  // Now we should be able to write a packet to it since it was opened in "w"
794  // mode. The packet data written should be limited to 43 bytes in length
795  // by the Init() call above.
796  //
797  f.Write(1234, 5678, bufferOut, 128);
798  NS_TEST_ASSERT_MSG_EQ(f.Fail(),
799  false,
800  "Write (write-only-file " << m_testFilename << ") returns error");
801  f.Close();
802 
803  //
804  // Let's peek into the file and see what actually went out for that
805  // packet.
806  //
807  FILE* p = std::fopen(m_testFilename.c_str(), "r+b");
809  nullptr,
810  "fopen() should have been able to open a correctly created pcap file");
811 
812  //
813  // A pcap file header takes up 24 bytes, a pcap record header takes up 16 bytes
814  // and we wrote in 43 bytes, so the file must be 83 bytes long. Let's just
815  // double check that this is exactly what happened.
816  //
817  std::fseek(p, 0, SEEK_END);
818  auto size = std::ftell(p);
819  NS_TEST_ASSERT_MSG_EQ(size, 83, "Pcap file with one 43 byte packet is incorrect size");
820 
821  //
822  // A pcap file header takes up 24 bytes, so we should see a pcap record header
823  // starting there in the file. We've tested this all before so we just assume
824  // it's all right and just seek to just past that point..
825  //
826  std::fseek(p, 24, SEEK_SET);
827 
828  uint32_t val32;
829 
830  //
831  // Because the regression tests require that pcap file output be compared
832  // byte-by-byte, we had to decide on a single format for written pcap files.
833  // This was little endian. So we have to do something special with big-
834  // endian machines here.
835  //
836  // When a big endian machine writes a pcap file, it is forced into swap
837  // mode and actually writes little endian files. This is automagically
838  // fixed up when using a PcapFile to read the values, but when a big-
839  // endian machine reads these values directly, they will be swapped.
840  //
841  // We can remove this nonsense when we get rid of the pcap-file-comparison
842  // regression tests.
843  //
844  // So, determine the endian-ness of the running system, and if we're on
845  // a big-endian machine, swap all of the results below before checking.
846  //
847  union {
848  uint32_t a;
849  uint8_t b[4];
850  } u;
851 
852  u.a = 1;
853  bool bigEndian = u.b[3];
854 
855  size_t result = std::fread(&val32, sizeof(val32), 1, p);
856  NS_TEST_ASSERT_MSG_EQ(result, 1, "Unable to fread() seconds timestamp");
857  if (bigEndian)
858  {
859  val32 = Swap(val32);
860  }
861  NS_TEST_ASSERT_MSG_EQ(val32, 1234, "Seconds timestamp written incorrectly");
862 
863  result = std::fread(&val32, sizeof(val32), 1, p);
864  NS_TEST_ASSERT_MSG_EQ(result, 1, "Unable to fread() microseconds timestamp");
865  if (bigEndian)
866  {
867  val32 = Swap(val32);
868  }
869  NS_TEST_ASSERT_MSG_EQ(val32, 5678, "Microseconds timestamp written incorrectly");
870 
871  result = std::fread(&val32, sizeof(val32), 1, p);
872  NS_TEST_ASSERT_MSG_EQ(result, 1, "Unable to fread() included length");
873  if (bigEndian)
874  {
875  val32 = Swap(val32);
876  }
877  NS_TEST_ASSERT_MSG_EQ(val32, 43, "Included length written incorrectly");
878 
879  result = std::fread(&val32, sizeof(val32), 1, p);
880  NS_TEST_ASSERT_MSG_EQ(result, 1, "Unable to fread() actual length");
881  if (bigEndian)
882  {
883  val32 = Swap(val32);
884  }
885  NS_TEST_ASSERT_MSG_EQ(val32, 128, "Actual length written incorrectly");
886 
887  //
888  // Take a look and see what went out into the file. The packet data
889  // should be unchanged (unswapped).
890  //
891  uint8_t bufferIn[128];
892 
893  result = std::fread(bufferIn, 1, 43, p);
894  NS_TEST_ASSERT_MSG_EQ(result, 43, "Unable to fread() packet data of expected length");
895 
896  for (uint32_t i = 0; i < 43; ++i)
897  {
898  NS_TEST_ASSERT_MSG_EQ(bufferIn[i], bufferOut[i], "Incorrect packet data written");
899  }
900 
901  std::fclose(p);
902  p = nullptr;
903 
904  //
905  // Let's see if the PcapFile object can figure out how to do the same thing and
906  // correctly read in a packet.
907  //
908  f.Open(m_testFilename, std::ios::in);
909  NS_TEST_ASSERT_MSG_EQ(f.Fail(),
910  false,
911  "Open (" << m_testFilename
912  << ", \"std::ios::in\") of existing good file returns error");
913 
914  uint32_t tsSec;
915  uint32_t tsUsec;
916  uint32_t inclLen;
917  uint32_t origLen;
918  uint32_t readLen;
919 
920  f.Read(bufferIn, sizeof(bufferIn), tsSec, tsUsec, inclLen, origLen, readLen);
921  NS_TEST_ASSERT_MSG_EQ(f.Fail(), false, "Read() of known good packet returns error");
922  NS_TEST_ASSERT_MSG_EQ(tsSec, 1234, "Incorrectly read seconds timestamp from known good packet");
923  NS_TEST_ASSERT_MSG_EQ(tsUsec,
924  5678,
925  "Incorrectly read microseconds timestamp from known good packet");
926  NS_TEST_ASSERT_MSG_EQ(inclLen, 43, "Incorrectly read included length from known good packet");
927  NS_TEST_ASSERT_MSG_EQ(origLen, 128, "Incorrectly read original length from known good packet");
929  readLen,
930  43,
931  "Incorrectly constructed actual read length from known good packet given buffer size");
932  f.Close();
933 
934  //
935  // Did the data come back correctly?
936  //
937  for (uint32_t i = 0; i < 43; ++i)
938  {
939  NS_TEST_ASSERT_MSG_EQ(bufferIn[i],
940  bufferOut[i],
941  "Incorrect packet data read from known good packet");
942  }
943 
944  //
945  // We have to check to make sure that the pcap record header is swapped
946  // correctly. Since big-endian machines are automatically forced into
947  // swap mode, the <true> parameter to f.Init() below is actually
948  // a no-op and we're always writing foreign-endian files. In that case,
949  // this test case is really just a duplicate of the previous.
950  //
951  // Open the file in write mode to clear the data.
952  //
953  f.Open(m_testFilename, std::ios::out);
954  NS_TEST_ASSERT_MSG_EQ(f.Fail(),
955  false,
956  "Open (" << m_testFilename << ", \"std::ios::out\") returns error");
957 
958  //
959  // Initialize the pcap file header, forcing the object into swap mode.
960  //
961  f.Init(37, 43, -7, true);
962  NS_TEST_ASSERT_MSG_EQ(f.Fail(), false, "Init (37, 43, -7) returns error");
963 
964  //
965  // Now we should be able to write a packet to it since it was opened in "w"
966  // mode. The packet data written should be limited to 43 bytes in length
967  // by the Init() call above.
968  //
969  f.Write(1234, 5678, bufferOut, 128);
970  NS_TEST_ASSERT_MSG_EQ(f.Fail(),
971  false,
972  "Write (write-only-file " << m_testFilename << ") returns error");
973  f.Close();
974 
975  //
976  // Let's peek into the file and see what actually went out for that
977  // packet.
978  //
979  p = std::fopen(m_testFilename.c_str(), "r+b");
981  nullptr,
982  "fopen() should have been able to open a correctly created pcap file");
983 
984  //
985  // A pcap file header takes up 24 bytes, a pcap record header takes up 16 bytes
986  // and we wrote in 43 bytes, so the file must be 83 bytes long. Let's just
987  // double check that this is exactly what happened.
988  //
989  std::fseek(p, 0, SEEK_END);
990  size = std::ftell(p);
991  NS_TEST_ASSERT_MSG_EQ(size, 83, "Pcap file with one 43 byte packet is incorrect size");
992 
993  //
994  // A pcap file header takes up 24 bytes, so we should see a pcap record header
995  // starting there in the file. We've tested this all before so we just assume
996  // it's all right and just seek past it.
997  //
998  result = std::fseek(p, 24, SEEK_SET);
999  NS_TEST_ASSERT_MSG_EQ(result, 0, "Failed seeking past pcap header");
1000 
1001  result = std::fread(&val32, sizeof(val32), 1, p);
1002  NS_TEST_ASSERT_MSG_EQ(result, 1, "Unable to fread() seconds timestamp");
1003  NS_TEST_ASSERT_MSG_EQ(val32,
1004  Swap(uint32_t(1234)),
1005  "Swapped seconds timestamp written incorrectly");
1006 
1007  result = std::fread(&val32, sizeof(val32), 1, p);
1008  NS_TEST_ASSERT_MSG_EQ(result, 1, "Unable to fread() microseconds timestamp");
1009  NS_TEST_ASSERT_MSG_EQ(val32,
1010  Swap(uint32_t(5678)),
1011  "Swapped microseconds timestamp written incorrectly");
1012 
1013  result = std::fread(&val32, sizeof(val32), 1, p);
1014  NS_TEST_ASSERT_MSG_EQ(result, 1, "Unable to fread() included length");
1015  NS_TEST_ASSERT_MSG_EQ(val32, Swap(uint32_t(43)), "Swapped included length written incorrectly");
1016 
1017  result = std::fread(&val32, sizeof(val32), 1, p);
1018  NS_TEST_ASSERT_MSG_EQ(result, 1, "Unable to fread() actual length");
1019  NS_TEST_ASSERT_MSG_EQ(val32, Swap(uint32_t(128)), "Swapped Actual length written incorrectly");
1020 
1021  //
1022  // Take a look and see what went out into the file. The packet data
1023  // should be unchanged (unswapped).
1024  //
1025  result = std::fread(bufferIn, 1, 43, p);
1026  NS_TEST_ASSERT_MSG_EQ(result, 43, "Unable to fread() packet data of expected length");
1027 
1028  for (uint32_t i = 0; i < 43; ++i)
1029  {
1030  NS_TEST_ASSERT_MSG_EQ(bufferIn[i], bufferOut[i], "Incorrect packet data written");
1031  }
1032 
1033  std::fclose(p);
1034  p = nullptr;
1035 
1036  //
1037  // Let's see if the PcapFile object can figure out how to do the same thing and
1038  // correctly read in a packet. The record header info should come back to us
1039  // swapped back into correct form.
1040  //
1041  f.Open(m_testFilename, std::ios::in);
1042  NS_TEST_ASSERT_MSG_EQ(f.Fail(),
1043  false,
1044  "Open (" << m_testFilename
1045  << ", \"std::ios::in\") of existing good file returns error");
1046 
1047  f.Read(bufferIn, sizeof(bufferIn), tsSec, tsUsec, inclLen, origLen, readLen);
1048  NS_TEST_ASSERT_MSG_EQ(f.Fail(), false, "Read() of known good packet returns error");
1049  NS_TEST_ASSERT_MSG_EQ(tsSec, 1234, "Incorrectly read seconds timestamp from known good packet");
1050  NS_TEST_ASSERT_MSG_EQ(tsUsec,
1051  5678,
1052  "Incorrectly read microseconds timestamp from known good packet");
1053  NS_TEST_ASSERT_MSG_EQ(inclLen, 43, "Incorrectly read included length from known good packet");
1054  NS_TEST_ASSERT_MSG_EQ(origLen, 128, "Incorrectly read original length from known good packet");
1056  readLen,
1057  43,
1058  "Incorrectly constructed actual read length from known good packet given buffer size");
1059 
1060  //
1061  // Did the data come back correctly (unchanged / unswapped)?
1062  //
1063  for (uint32_t i = 0; i < 43; ++i)
1064  {
1065  NS_TEST_ASSERT_MSG_EQ(bufferIn[i],
1066  bufferOut[i],
1067  "Incorrect packet data read from known good packet");
1068  }
1069 
1070  f.Close();
1071 }
1072 
1081 {
1082  public:
1083  ReadFileTestCase();
1084  ~ReadFileTestCase() override;
1085 
1086  private:
1087  void DoSetup() override;
1088  void DoRun() override;
1089  void DoTeardown() override;
1090 
1091  std::string m_testFilename;
1092 };
1093 
1095  : TestCase("Check to see that PcapFile can read out a known good pcap file")
1096 {
1097 }
1098 
1100 {
1101 }
1102 
1103 void
1105 {
1106 }
1107 
1108 void
1110 {
1111 }
1112 
1113 static const uint32_t N_KNOWN_PACKETS = 6;
1114 static const uint32_t N_PACKET_BYTES = 16;
1115 
1120 {
1121  uint32_t tsSec;
1122  uint32_t tsUsec;
1123  uint32_t inclLen;
1124  uint32_t origLen;
1125  uint16_t data[N_PACKET_BYTES];
1126 };
1127 
1128 static const PacketEntry knownPackets[] = {
1129  {2,
1130  3696,
1131  46,
1132  46,
1133  {0x0001,
1134  0x0800,
1135  0x0604,
1136  0x0001,
1137  0x0000,
1138  0x0000,
1139  0x0003,
1140  0x0a01,
1141  0x0201,
1142  0xffff,
1143  0xffff,
1144  0xffff,
1145  0x0a01,
1146  0x0204,
1147  0x0000,
1148  0x0000}},
1149  {2,
1150  3707,
1151  46,
1152  46,
1153  {0x0001,
1154  0x0800,
1155  0x0604,
1156  0x0002,
1157  0x0000,
1158  0x0000,
1159  0x0006,
1160  0x0a01,
1161  0x0204,
1162  0x0000,
1163  0x0000,
1164  0x0003,
1165  0x0a01,
1166  0x0201,
1167  0x0000,
1168  0x0000}},
1169  {2,
1170  3801,
1171  1070,
1172  1070,
1173  {0x4500,
1174  0x041c,
1175  0x0000,
1176  0x0000,
1177  0x3f11,
1178  0x0000,
1179  0x0a01,
1180  0x0101,
1181  0x0a01,
1182  0x0204,
1183  0xc001,
1184  0x0009,
1185  0x0408,
1186  0x0000,
1187  0x0000,
1188  0x0000}},
1189  {2,
1190  3811,
1191  46,
1192  46,
1193  {0x0001,
1194  0x0800,
1195  0x0604,
1196  0x0001,
1197  0x0000,
1198  0x0000,
1199  0x0006,
1200  0x0a01,
1201  0x0204,
1202  0xffff,
1203  0xffff,
1204  0xffff,
1205  0x0a01,
1206  0x0201,
1207  0x0000,
1208  0x0000}},
1209  {2,
1210  3822,
1211  46,
1212  46,
1213  {0x0001,
1214  0x0800,
1215  0x0604,
1216  0x0002,
1217  0x0000,
1218  0x0000,
1219  0x0003,
1220  0x0a01,
1221  0x0201,
1222  0x0000,
1223  0x0000,
1224  0x0006,
1225  0x0a01,
1226  0x0204,
1227  0x0000,
1228  0x0000}},
1229  {2,
1230  3915,
1231  1070,
1232  1070,
1233  {0x4500,
1234  0x041c,
1235  0x0000,
1236  0x0000,
1237  0x4011,
1238  0x0000,
1239  0x0a01,
1240  0x0204,
1241  0x0a01,
1242  0x0101,
1243  0x0009,
1244  0xc001,
1245  0x0408,
1246  0x0000,
1247  0x0000,
1248  0x0000}},
1249 };
1250 
1251 void
1253 {
1254  PcapFile f;
1255 
1256  //
1257  //
1258  std::string filename = CreateDataDirFilename("known.pcap");
1259  f.Open(filename, std::ios::in);
1260  NS_TEST_ASSERT_MSG_EQ(f.Fail(),
1261  false,
1262  "Open (" << filename << ", \"std::ios::in\") returns error");
1263 
1264  //
1265  // We are going to read out the file header and all of the packets to make
1266  // sure that we read what we know, a priori, to be there.
1267  //
1268  // The packet data was gotten using "tcpdump -nn -tt -r known.pcap -x"
1269  // and the timestamp and first 32 bytes of the resulting dump were
1270  // duplicated in the structure above.
1271  //
1272  uint8_t data[N_PACKET_BYTES];
1273  uint32_t tsSec;
1274  uint32_t tsUsec;
1275  uint32_t inclLen;
1276  uint32_t origLen;
1277  uint32_t readLen;
1278 
1279  for (uint32_t i = 0; i < N_KNOWN_PACKETS; ++i)
1280  {
1281  const PacketEntry& p = knownPackets[i];
1282 
1283  f.Read(data, sizeof(data), tsSec, tsUsec, inclLen, origLen, readLen);
1284  NS_TEST_ASSERT_MSG_EQ(f.Fail(), false, "Read() of known good pcap file returns error");
1285  NS_TEST_ASSERT_MSG_EQ(tsSec,
1286  p.tsSec,
1287  "Incorrectly read seconds timestamp from known good pcap file");
1288  NS_TEST_ASSERT_MSG_EQ(tsUsec,
1289  p.tsUsec,
1290  "Incorrectly read microseconds timestamp from known good pcap file");
1291  NS_TEST_ASSERT_MSG_EQ(inclLen,
1292  p.inclLen,
1293  "Incorrectly read included length from known good packet");
1294  NS_TEST_ASSERT_MSG_EQ(origLen,
1295  p.origLen,
1296  "Incorrectly read original length from known good packet");
1298  readLen,
1300  "Incorrect actual read length from known good packet given buffer size");
1301  }
1302 
1303  //
1304  // The file should now be at EOF since we've read all of the packets.
1305  // Another packet read should return an error.
1306  //
1307  f.Read(data, 1, tsSec, tsUsec, inclLen, origLen, readLen);
1308  NS_TEST_ASSERT_MSG_EQ(f.Eof(),
1309  true,
1310  "Read() of known good pcap file at EOF does not return error");
1311 
1312  f.Close();
1313 }
1314 
1321 class DiffTestCase : public TestCase
1322 {
1323  public:
1324  DiffTestCase();
1325 
1326  private:
1327  void DoRun() override;
1328 };
1329 
1331  : TestCase("Check that PcapFile::Diff works as expected")
1332 {
1333 }
1334 
1335 void
1337 {
1338  //
1339  // Check that PcapDiff(file, file) is false
1340  //
1341  std::string filename = CreateDataDirFilename("known.pcap");
1342  uint32_t sec(0);
1343  uint32_t usec(0);
1344  uint32_t packets(0);
1345  bool diff = PcapFile::Diff(filename, filename, sec, usec, packets);
1346  NS_TEST_EXPECT_MSG_EQ(diff, false, "PcapDiff(file, file) must always be false");
1347 
1348  //
1349  // Create different PCAP file (with the same timestamps, but different packets) and check that
1350  // it is indeed different
1351  //
1352  std::string filename2 = CreateTempDirFilename("different.pcap");
1353  PcapFile f;
1354 
1355  f.Open(filename2, std::ios::out);
1356  NS_TEST_ASSERT_MSG_EQ(f.Fail(),
1357  false,
1358  "Open (" << filename2 << ", \"std::ios::out\") returns error");
1359  f.Init(1, N_PACKET_BYTES);
1360  NS_TEST_ASSERT_MSG_EQ(f.Fail(), false, "Init (1, " << N_PACKET_BYTES << ") returns error");
1361 
1362  for (uint32_t i = 0; i < N_KNOWN_PACKETS; ++i)
1363  {
1364  const PacketEntry& p = knownPackets[i];
1365 
1366  f.Write(p.tsSec, p.tsUsec, (const uint8_t*)p.data, p.origLen);
1367  NS_TEST_EXPECT_MSG_EQ(f.Fail(), false, "Write must not fail");
1368  }
1369  f.Close();
1370 
1371  packets = 0;
1372  diff = PcapFile::Diff(filename, filename2, sec, usec, packets);
1373  NS_TEST_EXPECT_MSG_EQ(diff, true, "PcapDiff(file, file2) must be true");
1374  NS_TEST_EXPECT_MSG_EQ(sec, 2, "Files are different from 2.3696 seconds");
1375  NS_TEST_EXPECT_MSG_EQ(usec, 3696, "Files are different from 2.3696 seconds");
1376 }
1377 
1385 {
1386  public:
1388 };
1389 
1391  : TestSuite("pcap-file", UNIT)
1392 {
1393  SetDataDir(NS_TEST_SOURCEDIR);
1394  AddTestCase(new WriteModeCreateTestCase, TestCase::QUICK);
1395  AddTestCase(new ReadModeCreateTestCase, TestCase::QUICK);
1396  // AddTestCase (new AppendModeCreateTestCase, TestCase::QUICK);
1397  AddTestCase(new FileHeaderTestCase, TestCase::QUICK);
1398  AddTestCase(new RecordHeaderTestCase, TestCase::QUICK);
1399  AddTestCase(new ReadFileTestCase, TestCase::QUICK);
1400  AddTestCase(new DiffTestCase, TestCase::QUICK);
1401 }
1402 
double f(double x, void *params)
Definition: 80211b.c:70
Test case to make sure that the Pcap::Diff method works as expected.
void DoRun() override
Implementation to actually run this TestCase.
Test case to make sure that the Pcap File Object can write out correct pcap file headers in both endi...
void DoSetup() override
Implementation to do any local setup required for this TestCase.
std::string m_testFilename
File name.
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
void DoRun() override
Implementation to actually run this TestCase.
PCAP file utils TestSuite.
Test case to make sure that the Pcap File Object can read out the contents of a known good pcap file.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
std::string m_testFilename
File name.
void DoRun() override
Implementation to actually run this TestCase.
Test case to make sure that the Pcap File Object can open an existing pcap file.
std::string m_testFilename
File name.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
void DoRun() override
Implementation to actually run this TestCase.
Test case to make sure that the Pcap File Object can write pcap packet records in both endian cases,...
std::string m_testFilename
File name.
void DoRun() override
Implementation to actually run this TestCase.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
Test case to make sure that the Pcap File Object can do its most basic job and create an empty pcap f...
std::string m_testFilename
File name.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
void DoTeardown() override
Implementation to do any local setup required for this TestCase.
void DoRun() override
Implementation to actually run this TestCase.
A class representing a pcap file.
Definition: pcap-file.h:43
encapsulates test code
Definition: test.h:1060
std::string CreateDataDirFilename(std::string filename)
Construct the full path to a file in the data directory.
Definition: test.cc:419
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
virtual void DoSetup()
Implementation to do any local setup required for this TestCase.
Definition: test.cc:485
std::string CreateTempDirFilename(std::string filename)
Construct the full path to a file in a temporary directory.
Definition: test.cc:438
void SetDataDir(std::string directory)
Set the data directory where reference trace files can be found.
Definition: test.cc:478
virtual void DoTeardown()
Implementation to do any local setup required for this TestCase.
Definition: test.cc:491
virtual void DoRun()=0
Implementation to actually run this TestCase.
A suite of tests to run.
Definition: test.h:1256
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:254
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:144
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition: test.h:251
#define NS_TEST_ASSERT_MSG_NE(actual, limit, msg)
Test that an actual and expected (limit) value are not equal and report and abort if not.
Definition: test.h:564
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static bool CheckFileLength(std::string filename, long sizeExpected)
static const uint32_t N_KNOWN_PACKETS
static bool CheckFileExists(std::string filename)
static uint16_t Swap(uint16_t val)
static const PacketEntry knownPackets[]
static PcapFileTestSuite pcapFileTestSuite
Static variable for test initialization.
static const uint32_t N_PACKET_BYTES
uint8_t data[writeSize]
PCAP Packet structure.
uint32_t tsUsec
Time (micro seconds part)
uint32_t origLen
length of the original packet
uint16_t data[N_PACKET_BYTES]
Packet data.
uint32_t tsSec
Time (seconds part)
uint32_t inclLen
Length of the entry in the PCAP.