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