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
Swap(uint16_t val)38 Swap (uint16_t val)
39 {
40 return ((val >> 8) & 0x00ff) | ((val << 8) & 0xff00);
41 }
42
43 static uint32_t
Swap(uint32_t val)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
CheckFileExists(std::string filename)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
CheckFileLength(std::string filename,uint64_t sizeExpected)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 * \ingroup network-test
82 * \ingroup tests
83 *
84 * \brief Test case to make sure that the Pcap File Object can do its
85 * most basic job and create an empty pcap file.
86 */
87 class WriteModeCreateTestCase : public TestCase
88 {
89 public:
90 WriteModeCreateTestCase ();
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; //!< File name
99 };
100
WriteModeCreateTestCase()101 WriteModeCreateTestCase::WriteModeCreateTestCase ()
102 : TestCase ("Check to see that PcapFile::Open with mode std::ios::out works")
103 {
104 }
105
~WriteModeCreateTestCase()106 WriteModeCreateTestCase::~WriteModeCreateTestCase ()
107 {
108 }
109
110 void
DoSetup(void)111 WriteModeCreateTestCase::DoSetup (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
DoTeardown(void)120 WriteModeCreateTestCase::DoTeardown (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
DoRun(void)129 WriteModeCreateTestCase::DoRun (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
142 NS_TEST_ASSERT_MSG_EQ (CheckFileExists (m_testFilename), true,
143 "Open (" << m_testFilename << ", \"std::ios::out\") does not create file");
144 NS_TEST_ASSERT_MSG_EQ (CheckFileLength (m_testFilename, 0), true,
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
160 NS_TEST_ASSERT_MSG_EQ (CheckFileLength (m_testFilename, 24), true,
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
173 NS_TEST_ASSERT_MSG_EQ (CheckFileLength (m_testFilename, 0), true,
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
198 /**
199 * \ingroup network-test
200 * \ingroup tests
201 *
202 * \brief Test case to make sure that the Pcap File Object can open an
203 * existing pcap file.
204 */
205 class ReadModeCreateTestCase : public TestCase
206 {
207 public:
208 ReadModeCreateTestCase ();
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; //!< File name
217 };
218
ReadModeCreateTestCase()219 ReadModeCreateTestCase::ReadModeCreateTestCase ()
220 : TestCase ("Check to see that PcapFile::Open with mode std::ios::in works")
221 {
222 }
223
~ReadModeCreateTestCase()224 ReadModeCreateTestCase::~ReadModeCreateTestCase ()
225 {
226 }
227
228 void
DoSetup(void)229 ReadModeCreateTestCase::DoSetup (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
DoTeardown(void)238 ReadModeCreateTestCase::DoTeardown (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
DoRun(void)247 ReadModeCreateTestCase::DoRun (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 ();
259 NS_TEST_ASSERT_MSG_EQ (CheckFileExists (m_testFilename), false, "Open (" << m_testFilename <<
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
419 /**
420 * \ingroup network-test
421 * \ingroup tests
422 *
423 * \brief Test case to make sure that the Pcap File Object can
424 * write out correct pcap file headers in both endian cases,
425 * and then read them in correctly.
426 */
427 class FileHeaderTestCase : public TestCase
428 {
429 public:
430 FileHeaderTestCase ();
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; //!< File name
439 };
440
FileHeaderTestCase()441 FileHeaderTestCase::FileHeaderTestCase ()
442 : TestCase ("Check to see that PcapFileHeader is managed correctly")
443 {
444 }
445
~FileHeaderTestCase()446 FileHeaderTestCase::~FileHeaderTestCase ()
447 {
448 }
449
450 void
DoSetup(void)451 FileHeaderTestCase::DoSetup (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
DoTeardown(void)460 FileHeaderTestCase::DoTeardown (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
DoRun(void)469 FileHeaderTestCase::DoRun (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
663 /**
664 * \ingroup network-test
665 * \ingroup tests
666 *
667 * \brief Test case to make sure that the Pcap File Object can
668 * write pcap packet records in both endian cases, and then read
669 * them in correctly.
670 */
671 class RecordHeaderTestCase : public TestCase
672 {
673 public:
674 RecordHeaderTestCase ();
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; //!< File name
683 };
684
RecordHeaderTestCase()685 RecordHeaderTestCase::RecordHeaderTestCase ()
686 : TestCase ("Check to see that PcapRecordHeader is managed correctly")
687 {
688 }
689
~RecordHeaderTestCase()690 RecordHeaderTestCase::~RecordHeaderTestCase ()
691 {
692 }
693
694 void
DoSetup(void)695 RecordHeaderTestCase::DoSetup (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
DoTeardown(void)704 RecordHeaderTestCase::DoTeardown (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
DoRun(void)713 RecordHeaderTestCase::DoRun (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
973 /**
974 * \ingroup network-test
975 * \ingroup tests
976 *
977 * \brief Test case to make sure that the Pcap File Object can read
978 * out the contents of a known good pcap file.
979 */
980 class ReadFileTestCase : public TestCase
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; //!< File name
992 };
993
ReadFileTestCase()994 ReadFileTestCase::ReadFileTestCase ()
995 : TestCase ("Check to see that PcapFile can read out a known good pcap file")
996 {
997 }
998
~ReadFileTestCase()999 ReadFileTestCase::~ReadFileTestCase ()
1000 {
1001 }
1002
1003 void
DoSetup(void)1004 ReadFileTestCase::DoSetup (void)
1005 {
1006 }
1007
1008 void
DoTeardown(void)1009 ReadFileTestCase::DoTeardown (void)
1010 {
1011 }
1012
1013 static const uint32_t N_KNOWN_PACKETS = 6;
1014 static const uint32_t N_PACKET_BYTES = 16;
1015
1016 /**
1017 * PCAP Packet structure
1018 */
1019 typedef struct PACKET_ENTRY {
1020 uint32_t tsSec; //!< Time (seconds part)
1021 uint32_t tsUsec; //!< Time (micro seconds part)
1022 uint32_t inclLen; //!< Length of the entry in the PCAP
1023 uint32_t origLen; //!< length of the original packet
1024 uint16_t data[N_PACKET_BYTES]; //!< Packet data
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
DoRun(void)1044 ReadFileTestCase::DoRun (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
1089 /**
1090 * \ingroup network-test
1091 * \ingroup tests
1092 *
1093 * \brief Test case to make sure that the Pcap::Diff method works as expected.
1094 */
1095 class DiffTestCase : public TestCase
1096 {
1097 public:
1098 DiffTestCase ();
1099
1100 private:
1101 virtual void DoRun (void);
1102 };
1103
DiffTestCase()1104 DiffTestCase::DiffTestCase ()
1105 : TestCase ("Check that PcapFile::Diff works as expected")
1106 {
1107 }
1108
1109 void
DoRun(void)1110 DiffTestCase::DoRun (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
1147 /**
1148 * \ingroup network-test
1149 * \ingroup tests
1150 *
1151 * \brief PCAP file utils TestSuite
1152 */
1153 class PcapFileTestSuite : public TestSuite
1154 {
1155 public:
1156 PcapFileTestSuite ();
1157 };
1158
PcapFileTestSuite()1159 PcapFileTestSuite::PcapFileTestSuite ()
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
1172 static PcapFileTestSuite pcapFileTestSuite; //!< Static variable for test initialization
1173