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