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