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