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