View | Details | Raw Unified | Return to bug 872
Collapse All | Expand All

(-)a/examples/tutorial/sixth.cc (-1 / +1 lines)
 Lines 219-225    Link Here 
219
  ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow", MakeBoundCallback (&CwndChange, stream));
219
  ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow", MakeBoundCallback (&CwndChange, stream));
220
220
221
  PcapHelper pcapHelper;
221
  PcapHelper pcapHelper;
222
  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile ("sixth.pcap", "w", PcapHelper::DLT_PPP);
222
  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile ("sixth.pcap", std::ios::out, PcapHelper::DLT_PPP);
223
  devices.Get (1)->TraceConnectWithoutContext("PhyRxDrop", MakeBoundCallback (&RxDrop, file));
223
  devices.Get (1)->TraceConnectWithoutContext("PhyRxDrop", MakeBoundCallback (&RxDrop, file));
224
224
225
  Simulator::Stop (Seconds(20));
225
  Simulator::Stop (Seconds(20));
(-)a/src/common/pcap-file-test-suite.cc (-105 / +137 lines)
 Lines 31-49    Link Here 
31
// Some utility functions for the tests.
31
// Some utility functions for the tests.
32
// ===========================================================================
32
// ===========================================================================
33
33
34
uint16_t
34
static uint16_t
35
Swap (uint16_t val)
35
Swap (uint16_t val)
36
{
36
{
37
  return ((val >> 8) & 0x00ff) | ((val << 8) & 0xff00);
37
  return ((val >> 8) & 0x00ff) | ((val << 8) & 0xff00);
38
}
38
}
39
39
40
uint32_t 
40
static uint32_t 
41
Swap (uint32_t val)
41
Swap (uint32_t val)
42
{
42
{
43
  return ((val >> 24) & 0x000000ff) | ((val >> 8) & 0x0000ff00) | ((val << 8) & 0x00ff0000) | ((val << 24) & 0xff000000);
43
  return ((val >> 24) & 0x000000ff) | ((val >> 8) & 0x0000ff00) | ((val << 8) & 0x00ff0000) | ((val << 24) & 0xff000000);
44
}
44
}
45
45
46
bool
46
static bool
47
CheckFileExists (std::string filename)
47
CheckFileExists (std::string filename)
48
{
48
{
49
  FILE * p = fopen (filename.c_str (), "rb");
49
  FILE * p = fopen (filename.c_str (), "rb");
 Lines 57-63    Link Here 
57
}
57
}
58
58
59
59
60
bool
60
static bool
61
CheckFileLength (std::string filename, uint64_t sizeExpected)
61
CheckFileLength (std::string filename, uint64_t sizeExpected)
62
{
62
{
63
  FILE * p = fopen (filename.c_str (), "rb");
63
  FILE * p = fopen (filename.c_str (), "rb");
 Lines 93-99    Link Here 
93
};
93
};
94
94
95
WriteModeCreateTestCase::WriteModeCreateTestCase ()
95
WriteModeCreateTestCase::WriteModeCreateTestCase ()
96
  : TestCase ("Check to see that PcapFile::Open with mode \"w\" works")
96
  : TestCase ("Check to see that PcapFile::Open with mode std::ios::out works")
97
{
97
{
98
}
98
}
99
99
 Lines 125-149    Link Here 
125
  // Opening a new file in write mode should result in an empty file of the
125
  // Opening a new file in write mode should result in an empty file of the
126
  // given name.
126
  // given name.
127
  //
127
  //
128
  bool err = f.Open (m_testFilename, "w");
128
  f.Open (m_testFilename, std::ios::out);
129
129
130
  NS_TEST_ASSERT_MSG_EQ (err, false, "Open (" << m_testFilename << ", \"w\") returns error");
130
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (" << m_testFilename << ", \"w\") returns error");
131
  f.Close ();
131
  f.Close ();
132
132
133
  NS_TEST_ASSERT_MSG_EQ (CheckFileExists (m_testFilename), true, 
133
  NS_TEST_ASSERT_MSG_EQ (CheckFileExists (m_testFilename), true, 
134
                         "Open (" << m_testFilename << ", \"w\") does not create file");
134
                         "Open (" << m_testFilename << ", \"std::ios::out\") does not create file");
135
  NS_TEST_ASSERT_MSG_EQ (CheckFileLength (m_testFilename, 0), true,
135
  NS_TEST_ASSERT_MSG_EQ (CheckFileLength (m_testFilename, 0), true,
136
                         "Open (" << m_testFilename << ", \"w\") does not result in an empty file");
136
                         "Open (" << m_testFilename << ", \"std::ios::out\") does not result in an empty file");
137
137
138
  //
138
  //
139
  // Calling Init() on a file created with "w" should result in a file just 
139
  // Calling Init() on a file created with "std::ios::out" should result in a file just 
140
  // long enough to contain the pcap file header.
140
  // long enough to contain the pcap file header.
141
  //
141
  //
142
  err = f.Open (m_testFilename, "w");
142
  f.Open (m_testFilename, std::ios::out);
143
  NS_TEST_ASSERT_MSG_EQ (err, false, "Open (" << m_testFilename << ", \"w\") returns error");
143
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (" << m_testFilename << 
144
                         ", \"std::ios::out\") returns error");
144
145
145
  err = f.Init (1234, 5678, 7);
146
  f.Init (1234, 5678, 7);
146
  NS_TEST_ASSERT_MSG_EQ (err, false, "Init (1234, 5678, 7) returns error");
147
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Init (1234, 5678, 7) returns error");
147
148
148
  f.Close ();
149
  f.Close ();
149
150
 Lines 154-161    Link Here 
154
  // Opening an existing file in write mode should result in that file being
155
  // Opening an existing file in write mode should result in that file being
155
  // emptied.
156
  // emptied.
156
  //
157
  //
157
  err = f.Open (m_testFilename, "w");
158
  f.Open (m_testFilename, std::ios::out);
158
  NS_TEST_ASSERT_MSG_EQ (err, false, "Open (" << m_testFilename << ", \"w\") returns error");
159
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (" << m_testFilename << 
160
                         ", \"std::ios::out\") returns error");
159
161
160
  f.Close ();
162
  f.Close ();
161
163
 Lines 165-186    Link Here 
165
  //
167
  //
166
  // Initialize the file again.
168
  // Initialize the file again.
167
  //
169
  //
168
  err = f.Open (m_testFilename, "w");
170
  f.Open (m_testFilename, std::ios::out);
169
  NS_TEST_ASSERT_MSG_EQ (err, false, 
171
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, 
170
                         "Open (" << m_testFilename << ", \"w\") returns error");
172
                         "Open (" << m_testFilename << ", \"w\") returns error");
171
173
172
  err = f.Init (1234, 5678, 7);
174
  f.Init (1234, 5678, 7);
173
  NS_TEST_ASSERT_MSG_EQ (err, false, "Init (1234, 5678, 7) returns error");
175
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Init (1234, 5678, 7) returns error");
174
176
175
  //
177
  //
176
  // Now we should be able to write to it since it was opened in "w" mode.
178
  // Now we should be able to write to it since it was opened in std::ios::out mode.
177
  // This is just a permissions check so we don't actually look at the 
179
  // This is just a permissions check so we don't actually look at the 
178
  // data.
180
  // data.
179
  //
181
  //
180
  uint8_t buffer[128];
182
  uint8_t buffer[128];
181
  memset(buffer, 0, sizeof(buffer));
183
  memset(buffer, 0, sizeof(buffer));
182
  err = f.Write (0, 0, buffer, 128);
184
  f.Write (0, 0, buffer, 128);
183
  NS_TEST_ASSERT_MSG_EQ (err, false, "Write (write-only-file " << m_testFilename << ") returns error");
185
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Write (write-only-file " << m_testFilename << 
186
                         ") returns error");
184
187
185
  return false;
188
  return false;
186
}
189
}
 Lines 204-210    Link Here 
204
};
207
};
205
208
206
ReadModeCreateTestCase::ReadModeCreateTestCase ()
209
ReadModeCreateTestCase::ReadModeCreateTestCase ()
207
  : TestCase ("Check to see that PcapFile::Open with mode \"r\" works")
210
  : TestCase ("Check to see that PcapFile::Open with mode \"std::ios::in\" works")
208
{
211
{
209
}
212
}
210
213
 Lines 235-289    Link Here 
235
  //
238
  //
236
  // Opening a non-existing file in read mode should result in an error.
239
  // Opening a non-existing file in read mode should result in an error.
237
  //
240
  //
238
  bool err = f.Open (m_testFilename, "r");
241
  f.Open (m_testFilename, std::ios::in);
239
  NS_TEST_ASSERT_MSG_EQ (err, true, "Open (non-existing-filename " << m_testFilename << ", \"r\") does not return error");
242
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), true, "Open (non-existing-filename " << m_testFilename << 
240
243
                         ", \"std::ios::in\") does not return error");
241
  NS_TEST_ASSERT_MSG_EQ (CheckFileExists (m_testFilename), false, 
244
  f.Close ();
242
                         "Open (" << m_testFilename << ", \"r\") unexpectedly created a file");
245
  f.Clear ();
246
  NS_TEST_ASSERT_MSG_EQ (CheckFileExists (m_testFilename), false, "Open (" << m_testFilename << 
247
                         ", \"std::ios::in\") unexpectedly created a file");
243
248
244
  //
249
  //
245
  // Okay, now create an uninitialized file using previously tested operations
250
  // Okay, now create an uninitialized file using previously tested operations
246
  //
251
  //
247
  err = f.Open (m_testFilename, "w");
252
  f.Open (m_testFilename, std::ios::out);
248
  NS_TEST_ASSERT_MSG_EQ (err, false, "Open (filename, \"w\") returns error");
253
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (filename, \"std::ios::out\") returns error");
249
  f.Close ();
254
  f.Close ();
250
255
251
  //
256
  //
252
  // Opening this file should result in an error since it has no pcap file header.
257
  // Opening this file should result in an error since it has no pcap file header.
253
  //
258
  //
254
  err = f.Open (m_testFilename, "r");
259
  f.Open (m_testFilename, std::ios::in);
255
  NS_TEST_ASSERT_MSG_EQ (err, true, "Open (non-initialized-filename " << m_testFilename << ", \"r\") does not return error");
260
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), true, "Open (non-initialized-filename " << m_testFilename << 
261
                         ", \"std::ios::in\") does not return error");
262
  f.Close ();
263
  f.Clear ();
256
264
257
  //
265
  //
258
  // Okay, now open that non-initialized file in write mode and initialize it
266
  // Okay, now open that non-initialized file in write mode and initialize it
259
  // Note that we open it in write mode to initialize it.
267
  // Note that we open it in write mode to initialize it.
260
  //
268
  //
261
  err = f.Open (m_testFilename, "w");
269
  f.Open (m_testFilename, std::ios::out);
262
  NS_TEST_ASSERT_MSG_EQ (err, false, "Open (" << m_testFilename << ", \"w\") returns error");
270
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (" << m_testFilename << 
271
                         ", \"std::ios::out\") returns error");
263
272
264
  err = f.Init (1234, 5678, 7);
273
  f.Init (1234, 5678, 7);
265
  NS_TEST_ASSERT_MSG_EQ (err, false, "Init (1234, 5678, 7) returns error");
274
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Init (1234, 5678, 7) returns error");
266
  f.Close ();
275
  f.Close ();
267
276
268
  //
277
  //
269
  // Opening this file should now work since it has a pcap file header.
278
  // Opening this file should now work since it has a pcap file header.
270
  //
279
  //
271
  err = f.Open (m_testFilename, "r");
280
  f.Open (m_testFilename, std::ios::in);
272
  NS_TEST_ASSERT_MSG_EQ (err, false, "Open (initialized-filename " << m_testFilename << ", \"r\") returns error");
281
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (initialized-filename " << m_testFilename << 
282
                         ", \"std::ios::in\") returns error");
273
283
274
  //
284
  //
275
  // Now we should not be able to write to it since it was opened in "r" mode
285
  // Now we should not be able to write to it since it was opened in "r" mode
276
  // even if it has been initialized..
286
  // even if it has been initialized..
277
  //
287
  //
278
  uint8_t buffer[128];
288
  uint8_t buffer[128];
279
  err = f.Write (0, 0, buffer, 128);
289
  f.Write (0, 0, buffer, 128);
280
  NS_TEST_ASSERT_MSG_EQ (err, true, "Write (read-only-file " << m_testFilename << ") does not return error");
290
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), true, "Write (read-only-file " << m_testFilename << 
281
291
                         ") does not return error");
282
  f.Close ();
292
  f.Close ();
293
  f.Clear ();
283
294
284
  return false;
295
  return false;
285
}
296
}
286
297
298
#if 0
287
// ===========================================================================
299
// ===========================================================================
288
// Test case to make sure that the Pcap File Object can open an existing pcap
300
// Test case to make sure that the Pcap File Object can open an existing pcap
289
// file for appending.
301
// file for appending.
 Lines 303-309    Link Here 
303
};
315
};
304
316
305
AppendModeCreateTestCase::AppendModeCreateTestCase ()
317
AppendModeCreateTestCase::AppendModeCreateTestCase ()
306
  : TestCase ("Check to see that PcapFile::Open with mode \"a\" works")
318
  : TestCase ("Check to see that PcapFile::Open with mode \"std::ios::app\" works")
307
{
319
{
308
}
320
}
309
321
 Lines 334-387    Link Here 
334
  //
346
  //
335
  // Opening a non-existing file in append mode should result in an error.
347
  // Opening a non-existing file in append mode should result in an error.
336
  //
348
  //
337
  bool err = f.Open (m_testFilename, "a");
349
  f.Open (m_testFilename, std::ios::out | std::ios::app);
338
  NS_TEST_ASSERT_MSG_EQ (err, true, "Open (non-existing-filename " << m_testFilename << ", \"a\") does not return error");
350
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), true, "Open (non-existing-filename " << m_testFilename << 
351
                         ", \"std::ios::app\") does not return error");
339
  f.Close ();
352
  f.Close ();
353
  f.Clear ();
340
354
341
  NS_TEST_ASSERT_MSG_EQ (CheckFileExists (m_testFilename), false, 
355
  NS_TEST_ASSERT_MSG_EQ (CheckFileExists (m_testFilename), false, 
342
                         "Open (" << m_testFilename << ", \"a\") unexpectedly created a file");
356
                         "Open (" << m_testFilename << ", \"std::ios::app\") unexpectedly created a file");
343
357
344
  //
358
  //
345
  // Okay, now create an uninitialized file using previously tested operations
359
  // Okay, now create an uninitialized file using previously tested operations
346
  //
360
  //
347
  err = f.Open (m_testFilename, "w");
361
  f.Open (m_testFilename, std::ios::out);
348
  NS_TEST_ASSERT_MSG_EQ (err, false, "Open (" << m_testFilename << ", \"w\") returns error");
362
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (" << m_testFilename << 
363
                         ", \"std::ios::out\") returns error");
349
  f.Close ();
364
  f.Close ();
350
365
351
  //
366
  //
352
  // Opening this file should result in an error since it has no pcap file header.
367
  // Opening this file should result in an error since it has no pcap file header.
353
  //
368
  //
354
  err = f.Open (m_testFilename, "a");
369
  f.Open (m_testFilename, std::ios::out | std::ios::app);
355
  NS_TEST_ASSERT_MSG_EQ (err, true, "Open (non-initialized-filename " << m_testFilename << ", \"a\") does not return error");
370
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), true, "Open (non-initialized-filename " << m_testFilename << 
371
                         ", \"std::ios::app\") does not return error");
372
  f.Close ();
373
  f.Clear ();
356
374
357
  //
375
  //
358
  // Okay, now open that non-initialized file in write mode and initialize it.
376
  // Okay, now open that non-initialized file in write mode and initialize it.
359
  //
377
  //
360
  err = f.Open (m_testFilename, "w");
378
  f.Open (m_testFilename, std::ios::out);
361
  NS_TEST_ASSERT_MSG_EQ (err, false, "Open (non-initialized-filename " << m_testFilename << ", \"w\") returns error");
379
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (non-initialized-filename " << m_testFilename << 
380
                         ", \"std::ios::out\") returns error");
362
381
363
  err = f.Init (1234, 5678, 7);
382
  f.Init (1234, 5678, 7);
364
  NS_TEST_ASSERT_MSG_EQ (err, false, "Init (1234, 5678, 7) returns error");
383
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Init (1234, 5678, 7) returns error");
365
  f.Close ();
384
  f.Close ();
366
385
367
  //
386
  //
368
  // Opening this file should now work since it has a pcap file header.
387
  // Opening this file should now work since it has a pcap file header.
369
  //
388
  //
370
  err = f.Open (m_testFilename, "a");
389
  f.Open (m_testFilename, std::ios::out | std::ios::app);
371
  NS_TEST_ASSERT_MSG_EQ (err, false, "Open (initialized-filename " << m_testFilename << ", \"r\") returns error");
390
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (initialized-filename " << m_testFilename << 
391
                         ", \"std::ios::app\") returns error");
372
392
373
  //
393
  //
374
  // We should be able to write to it since it was opened in "a" mode.
394
  // We should be able to write to it since it was opened in "std::ios::app" mode.
375
  //
395
  //
376
  uint8_t buffer[128];
396
  uint8_t buffer[128];
377
  memset(buffer, 0, sizeof(buffer));
397
  memset(buffer, 0, sizeof(buffer));
378
  err = f.Write (0, 0, buffer, 128);
398
  f.Write (0, 0, buffer, 128);
379
  NS_TEST_ASSERT_MSG_EQ (err, false, "Write (append-mode-file " << m_testFilename << ") returns error");
399
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Write (append-mode-file " << m_testFilename << ") returns error");
380
400
381
  f.Close ();
401
  f.Close ();
382
402
383
  return false;
403
  return false;
384
}
404
}
405
#endif
385
406
386
// ===========================================================================
407
// ===========================================================================
387
// Test case to make sure that the Pcap File Object can write out correct pcap
408
// Test case to make sure that the Pcap File Object can write out correct pcap
 Lines 433-446    Link Here 
433
  //
454
  //
434
  // Create an uninitialized file using previously tested operations
455
  // Create an uninitialized file using previously tested operations
435
  //
456
  //
436
  bool err = f.Open (m_testFilename, "w");
457
  f.Open (m_testFilename, std::ios::out);
437
  NS_TEST_ASSERT_MSG_EQ (err, false, "Open (" << m_testFilename << ", \"w\") returns error");
458
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (" << m_testFilename << 
438
459
                         ", \"std::ios::out\") returns error");
460
  
439
  //
461
  //
440
  // Initialize the pcap file header.
462
  // Initialize the pcap file header.
441
  //
463
  //
442
  err = f.Init (1234, 5678, 7);
464
  f.Init (1234, 5678, 7);
443
  NS_TEST_ASSERT_MSG_EQ (err, false, 
465
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, 
444
                         "Init (1234, 5678, 7) returns error");
466
                         "Init (1234, 5678, 7) returns error");
445
  f.Close ();
467
  f.Close ();
446
468
 Lines 525-532    Link Here 
525
  // automagically fixed up when using a PcapFile to read the values, so we 
547
  // automagically fixed up when using a PcapFile to read the values, so we 
526
  // don't have to do anything special here.
548
  // don't have to do anything special here.
527
  //
549
  //
528
  err = f.Open (m_testFilename, "r");
550
  f.Open (m_testFilename, std::ios::in);
529
  NS_TEST_ASSERT_MSG_EQ (err, false, "Open (existing-initialized-file " << m_testFilename << ", \"r\") returns error");
551
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (existing-initialized-file " << m_testFilename << 
552
                         ", \"std::ios::in\") returns error");
530
553
531
  NS_TEST_ASSERT_MSG_EQ (f.GetMagic (), 0xa1b2c3d4, "Read back magic number incorrectly");
554
  NS_TEST_ASSERT_MSG_EQ (f.GetMagic (), 0xa1b2c3d4, "Read back magic number incorrectly");
532
  NS_TEST_ASSERT_MSG_EQ (f.GetVersionMajor (), 2, "Read back version major incorrectly");
555
  NS_TEST_ASSERT_MSG_EQ (f.GetVersionMajor (), 2, "Read back version major incorrectly");
 Lines 535-546    Link Here 
535
  NS_TEST_ASSERT_MSG_EQ (f.GetSigFigs (), 0, "Read back sig figs incorrectly");
558
  NS_TEST_ASSERT_MSG_EQ (f.GetSigFigs (), 0, "Read back sig figs incorrectly");
536
  NS_TEST_ASSERT_MSG_EQ (f.GetSnapLen (), 5678, "Read back snap len incorrectly");
559
  NS_TEST_ASSERT_MSG_EQ (f.GetSnapLen (), 5678, "Read back snap len incorrectly");
537
  NS_TEST_ASSERT_MSG_EQ (f.GetDataLinkType (), 1234, "Read back data link type incorrectly");
560
  NS_TEST_ASSERT_MSG_EQ (f.GetDataLinkType (), 1234, "Read back data link type incorrectly");
561
  f.Close ();
538
  
562
  
539
  //
563
  //
540
  // Re-open the file to erase its contents.
564
  // Re-open the file to erase its contents.
541
  //
565
  //
542
  err = f.Open (m_testFilename, "w");
566
  f.Open (m_testFilename, std::ios::out);
543
  NS_TEST_ASSERT_MSG_EQ (err, false, "Open (" << m_testFilename << ", \"w\") returns error");
567
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (" << m_testFilename << 
568
                         ", \"std::ios::out\") returns error");
544
569
545
  //
570
  //
546
  // Initialize the pcap file header, turning on swap mode manually to force
571
  // Initialize the pcap file header, turning on swap mode manually to force
 Lines 550-557    Link Here 
550
  // a no-op and we're always writing foreign-endian files.  In that case, 
575
  // a no-op and we're always writing foreign-endian files.  In that case, 
551
  // this test case is really just a duplicate of the previous.
576
  // this test case is really just a duplicate of the previous.
552
  //
577
  //
553
  err = f.Init (1234, 5678, 7, true);
578
  f.Init (1234, 5678, 7, true);
554
  NS_TEST_ASSERT_MSG_EQ (err, false, "Init (1234, 5678, 7) returns error");
579
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Init (1234, 5678, 7) returns error");
555
  f.Close ();
580
  f.Close ();
556
581
557
  //
582
  //
 Lines 599-606    Link Here 
599
  // machine is writing out a big-endian file by default, but we can't do that 
624
  // machine is writing out a big-endian file by default, but we can't do that 
600
  // since it breaks regression testing.
625
  // since it breaks regression testing.
601
  //
626
  //
602
  err = f.Open (m_testFilename, "r");
627
  f.Open (m_testFilename, std::ios::in);
603
  NS_TEST_ASSERT_MSG_EQ (err, false, "Open (existing-initialized-file " << m_testFilename << ", \"r\") returns error");
628
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (existing-initialized-file " << m_testFilename << 
629
                         ", \"std::ios::in\") returns error");
604
630
605
  NS_TEST_ASSERT_MSG_EQ (f.GetSwapMode (), true, "Byte-swapped file not correctly indicated");
631
  NS_TEST_ASSERT_MSG_EQ (f.GetSwapMode (), true, "Byte-swapped file not correctly indicated");
606
632
 Lines 667-680    Link Here 
667
  //
693
  //
668
  // Create an uninitialized file using previously tested operations
694
  // Create an uninitialized file using previously tested operations
669
  //
695
  //
670
  bool err = f.Open (m_testFilename, "w");
696
  f.Open (m_testFilename, std::ios::out);
671
  NS_TEST_ASSERT_MSG_EQ (err, false, "Open (" << m_testFilename << ", \"w\") returns error");
697
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (" << m_testFilename << 
698
                         ", \"std::ios::out\") returns error");
672
699
673
  //
700
  //
674
  // Initialize the pcap file header.
701
  // Initialize the pcap file header.
675
  //
702
  //
676
  err = f.Init (37, 43, -7);
703
  f.Init (37, 43, -7);
677
  NS_TEST_ASSERT_MSG_EQ (err, false, "Init (37, 43, -7) returns error");
704
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Init (37, 43, -7) returns error");
678
705
679
  //
706
  //
680
  // Initialize a buffer with a counting pattern to check the data later.
707
  // Initialize a buffer with a counting pattern to check the data later.
 Lines 690-697    Link Here 
690
  // mode.  The packet data written should be limited to 43 bytes in length 
717
  // mode.  The packet data written should be limited to 43 bytes in length 
691
  // by the Init() call above.
718
  // by the Init() call above.
692
  //
719
  //
693
  err = f.Write (1234, 5678, bufferOut, 128);
720
  f.Write (1234, 5678, bufferOut, 128);
694
  NS_TEST_ASSERT_MSG_EQ (err, false, "Write (write-only-file " << m_testFilename << ") returns error");
721
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Write (write-only-file " << m_testFilename << ") returns error");
695
  f.Close ();
722
  f.Close ();
696
723
697
  //
724
  //
 Lines 785-802    Link Here 
785
  // Let's see if the PcapFile object can figure out how to do the same thing and
812
  // Let's see if the PcapFile object can figure out how to do the same thing and
786
  // correctly read in a packet.
813
  // correctly read in a packet.
787
  //
814
  //
788
  err = f.Open (m_testFilename, "r");
815
  f.Open (m_testFilename, std::ios::in);
789
  NS_TEST_ASSERT_MSG_EQ (err, false, "Open (" << m_testFilename << ", \"r\") of existing good file returns error");
816
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (" << m_testFilename << 
817
                         ", \"std::ios::in\") of existing good file returns error");
790
818
791
  uint32_t tsSec, tsUsec, inclLen, origLen, readLen;
819
  uint32_t tsSec, tsUsec, inclLen, origLen, readLen;
792
820
793
  err = f.Read (bufferIn, sizeof(bufferIn), tsSec, tsUsec, inclLen, origLen, readLen);
821
  f.Read (bufferIn, sizeof(bufferIn), tsSec, tsUsec, inclLen, origLen, readLen);
794
  NS_TEST_ASSERT_MSG_EQ (err, false, "Read() of known good packet returns error");
822
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Read() of known good packet returns error");
795
  NS_TEST_ASSERT_MSG_EQ (tsSec, 1234, "Incorrectly read seconds timestap from known good packet");
823
  NS_TEST_ASSERT_MSG_EQ (tsSec, 1234, "Incorrectly read seconds timestap from known good packet");
796
  NS_TEST_ASSERT_MSG_EQ (tsUsec, 5678, "Incorrectly read microseconds timestap from known good packet");
824
  NS_TEST_ASSERT_MSG_EQ (tsUsec, 5678, "Incorrectly read microseconds timestap from known good packet");
797
  NS_TEST_ASSERT_MSG_EQ (inclLen, 43, "Incorrectly read included length from known good packet");
825
  NS_TEST_ASSERT_MSG_EQ (inclLen, 43, "Incorrectly read included length from known good packet");
798
  NS_TEST_ASSERT_MSG_EQ (origLen, 128, "Incorrectly read original length from known good packet");
826
  NS_TEST_ASSERT_MSG_EQ (origLen, 128, "Incorrectly read original length from known good packet");
799
  NS_TEST_ASSERT_MSG_EQ (readLen, 43, "Incorrectly constructed actual read length from known good packet given buffer size");
827
  NS_TEST_ASSERT_MSG_EQ (readLen, 43, "Incorrectly constructed actual read length from known good packet given buffer size");
828
  f.Close ();
800
829
801
  //
830
  //
802
  // Did the data come back correctly?
831
  // Did the data come back correctly?
 Lines 815-836    Link Here 
815
  //
844
  //
816
  // Open the file in write mode to clear the data.
845
  // Open the file in write mode to clear the data.
817
  //
846
  //
818
  err = f.Open (m_testFilename, "w");
847
  f.Open (m_testFilename, std::ios::out);
819
  NS_TEST_ASSERT_MSG_EQ (err, false, "Open (" << m_testFilename << ", \"w\") returns error");
848
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (" << m_testFilename << 
849
                         ", \"std::ios::out\") returns error");
820
850
821
  //
851
  //
822
  // Initialize the pcap file header, forcing the object into swap mode.
852
  // Initialize the pcap file header, forcing the object into swap mode.
823
  //
853
  //
824
  err = f.Init (37, 43, -7, true);
854
  f.Init (37, 43, -7, true);
825
  NS_TEST_ASSERT_MSG_EQ (err, false, "Init (37, 43, -7) returns error");
855
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Init (37, 43, -7) returns error");
826
856
827
  //
857
  //
828
  // Now we should be able to write a packet to it since it was opened in "w" 
858
  // Now we should be able to write a packet to it since it was opened in "w" 
829
  // mode.  The packet data written should be limited to 43 bytes in length 
859
  // mode.  The packet data written should be limited to 43 bytes in length 
830
  // by the Init() call above.
860
  // by the Init() call above.
831
  //
861
  //
832
  err = f.Write (1234, 5678, bufferOut, 128);
862
  f.Write (1234, 5678, bufferOut, 128);
833
  NS_TEST_ASSERT_MSG_EQ (err, false, "Write (write-only-file " << m_testFilename << ") returns error");
863
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Write (write-only-file " << m_testFilename << ") returns error");
834
  f.Close ();
864
  f.Close ();
835
865
836
  //
866
  //
 Lines 892-902    Link Here 
892
  // correctly read in a packet.  The record header info should come back to us
922
  // correctly read in a packet.  The record header info should come back to us
893
  // swapped back into correct form.
923
  // swapped back into correct form.
894
  //
924
  //
895
  err = f.Open (m_testFilename, "r");
925
  f.Open (m_testFilename, std::ios::in);
896
  NS_TEST_ASSERT_MSG_EQ (err, false, "Open (" << m_testFilename << ", \"r\") of existing good file returns error");
926
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (" << m_testFilename << 
927
                         ", \"std::ios::in\") of existing good file returns error");
897
928
898
  err = f.Read (bufferIn, sizeof(bufferIn), tsSec, tsUsec, inclLen, origLen, readLen);
929
  f.Read (bufferIn, sizeof(bufferIn), tsSec, tsUsec, inclLen, origLen, readLen);
899
  NS_TEST_ASSERT_MSG_EQ (err, false, "Read() of known good packet returns error");
930
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Read() of known good packet returns error");
900
  NS_TEST_ASSERT_MSG_EQ (tsSec, 1234, "Incorrectly read seconds timestap from known good packet");
931
  NS_TEST_ASSERT_MSG_EQ (tsSec, 1234, "Incorrectly read seconds timestap from known good packet");
901
  NS_TEST_ASSERT_MSG_EQ (tsUsec, 5678, "Incorrectly read microseconds timestap from known good packet");
932
  NS_TEST_ASSERT_MSG_EQ (tsUsec, 5678, "Incorrectly read microseconds timestap from known good packet");
902
  NS_TEST_ASSERT_MSG_EQ (inclLen, 43, "Incorrectly read included length from known good packet");
933
  NS_TEST_ASSERT_MSG_EQ (inclLen, 43, "Incorrectly read included length from known good packet");
 Lines 988-995    Link Here 
988
  //
1019
  //
989
  //
1020
  //
990
  std::string filename = NS_TEST_SOURCEDIR + "known.pcap";
1021
  std::string filename = NS_TEST_SOURCEDIR + "known.pcap";
991
  bool err = f.Open (filename, "r");
1022
  f.Open (filename, std::ios::in);
992
  NS_TEST_ASSERT_MSG_EQ (err, false, "Open (" << filename << ", \"w\") returns error");
1023
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (" << filename << 
1024
                         ", \"std::ios::in\") returns error");
993
 
1025
 
994
  //
1026
  //
995
  // We are going to read out the file header and all of the packets to make 
1027
  // We are going to read out the file header and all of the packets to make 
 Lines 1006-1013    Link Here 
1006
1038
1007
  for (uint32_t i = 0; i < N_KNOWN_PACKETS; ++i, ++p)
1039
  for (uint32_t i = 0; i < N_KNOWN_PACKETS; ++i, ++p)
1008
    {
1040
    {
1009
      err = f.Read (data, sizeof(data), tsSec, tsUsec, inclLen, origLen, readLen);
1041
      f.Read (data, sizeof(data), tsSec, tsUsec, inclLen, origLen, readLen);
1010
      NS_TEST_ASSERT_MSG_EQ (err, false, "Read() of known good pcap file returns error");
1042
      NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Read() of known good pcap file returns error");
1011
      NS_TEST_ASSERT_MSG_EQ (tsSec, p->tsSec, "Incorrectly read seconds timestap from known good pcap file");
1043
      NS_TEST_ASSERT_MSG_EQ (tsSec, p->tsSec, "Incorrectly read seconds timestap from known good pcap file");
1012
      NS_TEST_ASSERT_MSG_EQ (tsUsec, p->tsUsec, "Incorrectly read microseconds timestap from known good pcap file");
1044
      NS_TEST_ASSERT_MSG_EQ (tsUsec, p->tsUsec, "Incorrectly read microseconds timestap from known good pcap file");
1013
      NS_TEST_ASSERT_MSG_EQ (inclLen, p->inclLen, "Incorrectly read included length from known good packet");
1045
      NS_TEST_ASSERT_MSG_EQ (inclLen, p->inclLen, "Incorrectly read included length from known good packet");
 Lines 1019-1026    Link Here 
1019
  // The file should now be at EOF since we've read all of the packets.
1051
  // The file should now be at EOF since we've read all of the packets.
1020
  // Another packet read should return an error.
1052
  // Another packet read should return an error.
1021
  //
1053
  //
1022
  err = f.Read (data, 1, tsSec, tsUsec, inclLen, origLen, readLen);
1054
  f.Read (data, 1, tsSec, tsUsec, inclLen, origLen, readLen);
1023
  NS_TEST_ASSERT_MSG_EQ (err, true, "Read() of known good pcap file at EOF does not return error");
1055
  NS_TEST_ASSERT_MSG_EQ (f.Eof (), true, "Read() of known good pcap file at EOF does not return error");
1024
1056
1025
  f.Close ();
1057
  f.Close ();
1026
1058
 Lines 1061-1077    Link Here 
1061
  std::string filename2 = "different.pcap";
1093
  std::string filename2 = "different.pcap";
1062
  PcapFile f;
1094
  PcapFile f;
1063
  
1095
  
1064
  bool err = f.Open (filename2, "w");
1096
  f.Open (filename2, std::ios::out);
1065
  NS_TEST_ASSERT_MSG_EQ (err, false, "Open (" << filename2 << ", \"w\") returns error");
1097
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (" << filename2 << ", \"std::ios::out\") returns error");
1066
  err = f.Init (1, N_PACKET_BYTES);
1098
  f.Init (1, N_PACKET_BYTES);
1067
  NS_TEST_ASSERT_MSG_EQ (err, false, "Init (1, " << N_PACKET_BYTES << ") returns error");
1099
  NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Init (1, " << N_PACKET_BYTES << ") returns error");
1068
  
1100
  
1069
  for (uint32_t i = 0; i < N_KNOWN_PACKETS; ++i)
1101
  for (uint32_t i = 0; i < N_KNOWN_PACKETS; ++i)
1070
    {
1102
    {
1071
      PacketEntry const & p = knownPackets[i];
1103
      PacketEntry const & p = knownPackets[i];
1072
      
1104
      
1073
      err = f.Write (p.tsSec, p.tsUsec, (uint8_t const *)p.data, p.origLen);
1105
      f.Write (p.tsSec, p.tsUsec, (uint8_t const *)p.data, p.origLen);
1074
      NS_TEST_EXPECT_MSG_EQ (err, false, "Write must not fail");
1106
      NS_TEST_EXPECT_MSG_EQ (f.Fail (), false, "Write must not fail");
1075
    }
1107
    }
1076
  f.Close ();
1108
  f.Close ();
1077
1109
 Lines 1094-1100    Link Here 
1094
{
1126
{
1095
  AddTestCase (new WriteModeCreateTestCase);
1127
  AddTestCase (new WriteModeCreateTestCase);
1096
  AddTestCase (new ReadModeCreateTestCase);
1128
  AddTestCase (new ReadModeCreateTestCase);
1097
  AddTestCase (new AppendModeCreateTestCase);
1129
  //AddTestCase (new AppendModeCreateTestCase);
1098
  AddTestCase (new FileHeaderTestCase);
1130
  AddTestCase (new FileHeaderTestCase);
1099
  AddTestCase (new RecordHeaderTestCase);
1131
  AddTestCase (new RecordHeaderTestCase);
1100
  AddTestCase (new ReadFileTestCase);
1132
  AddTestCase (new ReadFileTestCase);
(-)a/src/common/pcap-file-wrapper.cc (-36 / +29 lines)
 Lines 54-72    Link Here 
54
  Close ();
54
  Close ();
55
}
55
}
56
56
57
58
bool 
59
PcapFileWrapper::Fail (void) const
60
{
61
  return m_file.Fail ();
62
}
63
bool 
64
PcapFileWrapper::Eof (void) const
65
{
66
  return m_file.Eof ();
67
}
68
void 
69
PcapFileWrapper::Clear (void)
70
{
71
  m_file.Clear ();
72
}
73
57
void
74
void
58
PcapFileWrapper::Close (void)
75
PcapFileWrapper::Close (void)
59
{
76
{
60
  m_file.Close ();
77
  m_file.Close ();
61
}
78
}
62
79
63
bool
80
void
64
PcapFileWrapper::Open (std::string const &filename, std::string const &mode)
81
PcapFileWrapper::Open (std::string const &filename, std::ios::openmode mode)
65
{
82
{
66
  return m_file.Open (filename, mode);
83
  m_file.Open (filename, mode);
67
}
84
}
68
85
69
bool
86
void
70
PcapFileWrapper::Init (uint32_t dataLinkType, uint32_t snapLen, int32_t tzCorrection)
87
PcapFileWrapper::Init (uint32_t dataLinkType, uint32_t snapLen, int32_t tzCorrection)
71
{
88
{
72
  //
89
  //
 Lines 76-141    Link Here 
76
  //
93
  //
77
  if (snapLen != std::numeric_limits<uint32_t>::max ())
94
  if (snapLen != std::numeric_limits<uint32_t>::max ())
78
    {
95
    {
79
      return m_file.Init (dataLinkType, snapLen, tzCorrection);
96
      m_file.Init (dataLinkType, snapLen, tzCorrection);
80
    } 
97
    } 
81
  else
98
  else
82
    {
99
    {
83
      return m_file.Init (dataLinkType, m_snapLen, tzCorrection);
100
      m_file.Init (dataLinkType, m_snapLen, tzCorrection);
84
    } 
101
    } 
85
86
  //
87
  // Quiet the compiler
88
  //
89
  return true;
90
}
102
}
91
103
92
bool
104
void
93
PcapFileWrapper::Write (Time t, Ptr<const Packet> p)
105
PcapFileWrapper::Write (Time t, Ptr<const Packet> p)
94
{
106
{
95
  uint8_t buffer[PcapFile::SNAPLEN_DEFAULT];
96
97
  uint64_t current = t.GetMicroSeconds ();
107
  uint64_t current = t.GetMicroSeconds ();
98
  uint64_t s = current / 1000000;
108
  uint64_t s = current / 1000000;
99
  uint64_t us = current % 1000000;
109
  uint64_t us = current % 1000000;
100
110
101
  uint32_t bufferSize = p->GetSize ();
111
  m_file.Write (s, us, p);
102
  p->CopyData (buffer, bufferSize);
103
  bool rc = m_file.Write (s, us, buffer, bufferSize);
104
  return rc;
105
}
112
}
106
113
107
bool
114
void
108
PcapFileWrapper::Write (Time t, Header &header, Ptr<const Packet> p)
115
PcapFileWrapper::Write (Time t, Header &header, Ptr<const Packet> p)
109
{
116
{
110
  uint8_t buffer[PcapFile::SNAPLEN_DEFAULT];
111
112
  uint64_t current = t.GetMicroSeconds ();
117
  uint64_t current = t.GetMicroSeconds ();
113
  uint64_t s = current / 1000000;
118
  uint64_t s = current / 1000000;
114
  uint64_t us = current % 1000000;
119
  uint64_t us = current % 1000000;
115
120
116
  Buffer headerBuffer;
121
  m_file.Write (s, us, header, p);
117
  uint32_t headerSize = header.GetSerializedSize ();
118
  uint32_t packetSize = p->GetSize ();
119
  uint32_t bufferSize = headerSize + packetSize;
120
121
  headerBuffer.AddAtStart (headerSize);
122
  header.Serialize (headerBuffer.Begin ());
123
124
  headerBuffer.Begin ().Read (buffer, headerSize);
125
  p->CopyData (&buffer[headerSize], packetSize);
126
  bool rc = m_file.Write (s, us, buffer, bufferSize);
127
128
  return rc;
129
}
122
}
130
123
131
bool
124
void
132
PcapFileWrapper::Write (Time t, uint8_t const *buffer, uint32_t length)
125
PcapFileWrapper::Write (Time t, uint8_t const *buffer, uint32_t length)
133
{
126
{
134
  uint64_t current = t.GetMicroSeconds ();
127
  uint64_t current = t.GetMicroSeconds ();
135
  uint64_t s = current / 1000000;
128
  uint64_t s = current / 1000000;
136
  uint64_t us = current % 1000000;
129
  uint64_t us = current % 1000000;
137
130
138
  return m_file.Write (s, us, buffer, length);
131
  m_file.Write (s, us, buffer, length);
139
}
132
}
140
133
141
uint32_t
134
uint32_t
(-)a/src/common/pcap-file-wrapper.h (-58 / +24 lines)
 Lines 21-26    Link Here 
21
21
22
#include <string.h>
22
#include <string.h>
23
#include <limits>
23
#include <limits>
24
#include <fstream>
24
#include "ns3/ptr.h"
25
#include "ns3/ptr.h"
25
#include "ns3/packet.h"
26
#include "ns3/packet.h"
26
#include "ns3/nstime.h"
27
#include "ns3/nstime.h"
 Lines 42-105    Link Here 
42
  PcapFileWrapper ();
43
  PcapFileWrapper ();
43
  ~PcapFileWrapper ();
44
  ~PcapFileWrapper ();
44
45
46
45
  /**
47
  /**
46
   * Create a new pcap file wrapper representing a new or existing pcap file.
48
   * \return true if the 'fail' bit is set in the underlying iostream, false otherwise.
47
   * Semantics are similar to the C standard library function \c fopen
49
   */
48
   *
50
  bool Fail (void) const;
49
   * Possible modes are:
51
  /**
50
   *
52
   * \return true if the 'eof' bit is set in the underlying iostream, false otherwise.
51
   * \verbatim
53
   */
52
   * "r":   Open a file for reading.  The file must exist.  The pcap header
54
  bool Eof (void) const;
53
   *        is assumed to exist in the file and will be read and checked.
55
  /**
54
   *        The file seek position indicator is set to point to the first 
56
   * Clear all state bits of the underlying iostream.
55
   *        packet on exit.
57
   */
56
   *
58
  void Clear (void);
57
   * "w":   Create an empty file for writing. If a file with the same name 
59
58
   *        already exists its content is erased and the file is treated as a 
60
  /**
59
   *        new empty pcap file.  The file is assumed not to have a pcap 
61
   * Create a new pcap file or open an existing pcap file.  Semantics are
60
   *        header and the caller is responsible for calling Init before saving
62
   * similar to the stdc++ io stream classes.
61
   *        any packet data.  The file seek position indicator is set to point 
62
   *        to the beginning of the file on exit since there will be no pcap
63
   *        header.
64
   *
65
   * "a":   Append to an existing file. This mode allows for adding packet data
66
   *        to the end of an existing pcap file.  The file must exist and have a
67
   *        valid pcap header written (N.B. this is different from standard fopen
68
   *        semantics).  The file seek position indicator is set to point 
69
   *        to the end of the file on exit.
70
   *
71
   * "r+":  Open a file for update -- both reading and writing. The file must 
72
   *        exist.  The pcap header is assumed to have been written to the 
73
   *        file and will be read and checked.  The file seek position indicator
74
   *        is set to point to the first packet on exit.
75
   *
76
   * "w+":  Create an empty file for both reading and writing.  If a file with
77
   *        the same name already exists, its content is erased and the file is 
78
   *        treated as a new empty pcap file.  Since this new file will not have
79
   *        a pcap header, the caller is responsible for calling Init before 
80
   *        saving any packet data.  On exit, the file seek position indicator is
81
   *        set to point to the beginning of the file.
82
   *
83
   * "a+"   Open a file for reading and appending.  The file must exist and have a
84
   *        valid pcap header written (N.B. this is different from standard fopen
85
   *        semantics).  The file seek position indicator is set to point 
86
   *        to the end of the file on exit.  Existing content is preserved.
87
   * \endverbatim
88
   *
63
   *
89
   * Since a pcap file is always a binary file, the file type is automatically 
64
   * Since a pcap file is always a binary file, the file type is automatically 
90
   * selected as a binary file.  For example, providing a mode string "a+" 
65
   * selected as a binary file (fstream::binary is automatically ored with the mode
91
   * results in the underlying OS file being opened in "a+b" mode.
66
   * field).
92
   *
67
   *
93
   * \param filename String containing the name of the file.
68
   * \param filename String containing the name of the file.
94
   *
69
   *
95
   * \param mode String containing the access mode for the file.
70
   * \param mode String containing the access mode for the file.
96
   *
71
   *
97
   * \returns Error indication that should be interpreted as, "did an error 
98
   * happen"?  That is, the method returns false if the open succeeds, true 
99
   * otherwise.  The errno variable will be set by the OS to to provide a 
100
   * more descriptive failure indication.
101
   */
72
   */
102
  bool Open (std::string const &filename, std::string const &mode);
73
  void Open (std::string const &filename, std::ios::openmode mode);
103
74
104
  /**
75
  /**
105
   * Close the underlying pcap file.
76
   * Close the underlying pcap file.
 Lines 126-137    Link Here 
126
   * time zone from UTC/GMT.  For example, Pacific Standard Time in the US is
97
   * time zone from UTC/GMT.  For example, Pacific Standard Time in the US is
127
   * GMT-8, so one would enter -8 for that correction.  Defaults to 0 (UTC).
98
   * GMT-8, so one would enter -8 for that correction.  Defaults to 0 (UTC).
128
   *
99
   *
129
   * \return false if the open succeeds, true otherwise.
130
   *
131
   * \warning Calling this method on an existing file will result in the loss
100
   * \warning Calling this method on an existing file will result in the loss
132
   * any existing data.
101
   * any existing data.
133
   */
102
   */
134
  bool Init (uint32_t dataLinkType, 
103
  void Init (uint32_t dataLinkType, 
135
             uint32_t snapLen = std::numeric_limits<uint32_t>::max (), 
104
             uint32_t snapLen = std::numeric_limits<uint32_t>::max (), 
136
             int32_t tzCorrection = PcapFile::ZONE_DEFAULT);
105
             int32_t tzCorrection = PcapFile::ZONE_DEFAULT);
137
106
 Lines 141-149    Link Here 
141
   * \param t Packet timestamp as ns3::Time.
110
   * \param t Packet timestamp as ns3::Time.
142
   * \param p Packet to write to the pcap file.
111
   * \param p Packet to write to the pcap file.
143
   * 
112
   * 
144
   * \return true on error, false otherwise
145
   */
113
   */
146
  bool Write (Time t, Ptr<const Packet> p);
114
  void Write (Time t, Ptr<const Packet> p);
147
115
148
  /**
116
  /**
149
   * \brief Write the provided header along with the packet to the pcap file.
117
   * \brief Write the provided header along with the packet to the pcap file.
 Lines 156-164    Link Here 
156
   * \param header The Header to prepend to the packet.
124
   * \param header The Header to prepend to the packet.
157
   * \param p Packet to write to the pcap file.
125
   * \param p Packet to write to the pcap file.
158
   * 
126
   * 
159
   * \return true on error, false otherwise
160
   */
127
   */
161
  bool Write (Time t, Header &header, Ptr<const Packet> p);
128
  void Write (Time t, Header &header, Ptr<const Packet> p);
162
129
163
  /**
130
  /**
164
   * \brief Write the provided data buffer to the pcap file.
131
   * \brief Write the provided data buffer to the pcap file.
 Lines 167-175    Link Here 
167
   * \param buffer The buffer to write.
134
   * \param buffer The buffer to write.
168
   * \param length The size of the buffer.
135
   * \param length The size of the buffer.
169
   * 
136
   * 
170
   * \return true on error, false otherwise
171
   */
137
   */
172
  bool Write (Time t, uint8_t const *buffer, uint32_t length);
138
  void Write (Time t, uint8_t const *buffer, uint32_t length);
173
139
174
  /*
140
  /*
175
   * \brief Returns the magic number of the pcap file as defined by the magic_number
141
   * \brief Returns the magic number of the pcap file as defined by the magic_number
(-)a/src/common/pcap-file.cc (-240 / +142 lines)
 Lines 19-28    Link Here 
19
 */
19
 */
20
20
21
#include <iostream>
21
#include <iostream>
22
#include <stdio.h>
23
#include <stdlib.h>
24
#include <cstring>
22
#include <cstring>
25
23
#include "ns3/assert.h"
24
#include "ns3/packet.h"
25
#include "ns3/fatal-error.h"
26
#include "ns3/header.h"
27
#include "ns3/buffer.h"
26
#include "pcap-file.h"
28
#include "pcap-file.h"
27
//
29
//
28
// This file is used as part of the ns-3 test framework, so please refrain from 
30
// This file is used as part of the ns-3 test framework, so please refrain from 
 Lines 41-68    Link Here 
41
const int32_t  SIGFIGS_DEFAULT = 0;           /**< Significant figures for timestamps (libpcap doesn't even bother) */
43
const int32_t  SIGFIGS_DEFAULT = 0;           /**< Significant figures for timestamps (libpcap doesn't even bother) */
42
44
43
PcapFile::PcapFile ()
45
PcapFile::PcapFile ()
44
  : m_filename (""),
46
  : m_file (),
45
    m_filePtr (0),
46
    m_haveFileHeader (false),
47
    m_swapMode (false)
47
    m_swapMode (false)
48
{
48
{}
49
}
50
49
51
PcapFile::~PcapFile ()
50
PcapFile::~PcapFile ()
52
{
51
{
53
  Close ();
52
  Close ();
54
}
53
}
55
54
55
56
bool 
57
PcapFile::Fail (void) const
58
{
59
  return m_file.fail ();
60
}
61
bool 
62
PcapFile::Eof (void) const
63
{
64
  return m_file.eof ();
65
}
66
void 
67
PcapFile::Clear (void)
68
{
69
  m_file.clear ();
70
}
71
72
56
void
73
void
57
PcapFile::Close (void)
74
PcapFile::Close (void)
58
{
75
{
59
  if (m_filePtr)
76
  m_file.close ();
60
    {
61
      fclose (m_filePtr);
62
    }
63
  m_filePtr = 0;
64
  m_filename = "";
65
  m_haveFileHeader = false;
66
}
77
}
67
78
68
uint32_t
79
uint32_t
 Lines 152-169    Link Here 
152
  to->m_origLen = Swap (from->m_origLen);
163
  to->m_origLen = Swap (from->m_origLen);
153
}
164
}
154
165
155
bool
166
void
156
PcapFile::WriteFileHeader (void)
167
PcapFile::WriteFileHeader (void)
157
{
168
{
158
  //
169
  //
159
  // If we're initializing the file, we need to write the pcap file header
170
  // If we're initializing the file, we need to write the pcap file header
160
  // at the start of the file.
171
  // at the start of the file.
161
  //
172
  //
162
  int result = fseek (m_filePtr, 0, SEEK_SET);
173
  m_file.seekp (0, std::ios::beg);
163
  if (result)
164
    {
165
      return true;
166
    }
167
 
174
 
168
  //
175
  //
169
  // We have the ability to write out the pcap file header in a foreign endian
176
  // We have the ability to write out the pcap file header in a foreign endian
 Lines 191-247    Link Here 
191
  // Watch out for memory alignment differences between machines, so write
198
  // Watch out for memory alignment differences between machines, so write
192
  // them all individually.
199
  // them all individually.
193
  //
200
  //
194
  result = 0;
201
  m_file.write ((const char *)&headerOut->m_magicNumber, sizeof(headerOut->m_magicNumber));
195
202
  m_file.write ((const char *)&headerOut->m_versionMajor, sizeof(headerOut->m_versionMajor));
196
  result |= (fwrite (&headerOut->m_magicNumber, sizeof(headerOut->m_magicNumber), 1, m_filePtr) != 1);
203
  m_file.write ((const char *)&headerOut->m_versionMinor, sizeof(headerOut->m_versionMinor));
197
  result |= (fwrite (&headerOut->m_versionMajor, sizeof(headerOut->m_versionMajor), 1, m_filePtr) != 1);
204
  m_file.write ((const char *)&headerOut->m_zone, sizeof(headerOut->m_zone));
198
  result |= (fwrite (&headerOut->m_versionMinor, sizeof(headerOut->m_versionMinor), 1, m_filePtr) != 1);
205
  m_file.write ((const char *)&headerOut->m_sigFigs, sizeof(headerOut->m_sigFigs));
199
  result |= (fwrite (&headerOut->m_zone, sizeof(headerOut->m_zone), 1, m_filePtr) != 1);
206
  m_file.write ((const char *)&headerOut->m_snapLen, sizeof(headerOut->m_snapLen));
200
  result |= (fwrite (&headerOut->m_sigFigs, sizeof(headerOut->m_sigFigs), 1, m_filePtr) != 1);
207
  m_file.write ((const char *)&headerOut->m_type, sizeof(headerOut->m_type));
201
  result |= (fwrite (&headerOut->m_snapLen, sizeof(headerOut->m_snapLen), 1, m_filePtr) != 1);
202
  result |= (fwrite (&headerOut->m_type, sizeof(headerOut->m_type), 1, m_filePtr) != 1);
203
204
  //
205
  // If any of the fwrites above did not succeed in writinging the correct
206
  // number of objects, result will be nonzero and will indicate an error.
207
  //
208
  return result != 0;
209
}
208
}
210
209
211
bool
210
void
212
PcapFile::ReadAndVerifyFileHeader (void)
211
PcapFile::ReadAndVerifyFileHeader (void)
213
{
212
{
214
  //
213
  //
215
  // Pcap file header is always at the start of the file
214
  // Pcap file header is always at the start of the file
216
  //
215
  //
217
  int result = fseek (m_filePtr, 0, SEEK_SET);
216
  m_file.seekg (0, std::ios::beg);
218
  if (result)
219
    {
220
      return true;
221
    }
222
217
223
  //
218
  //
224
  // Watch out for memory alignment differences between machines, so read
219
  // Watch out for memory alignment differences between machines, so read
225
  // them all individually.
220
  // them all individually.
226
  //
221
  //
227
  result = 0;
222
  m_file.read ((char *)&m_fileHeader.m_magicNumber, sizeof(m_fileHeader.m_magicNumber));
228
223
  m_file.read ((char *)&m_fileHeader.m_versionMajor, sizeof(m_fileHeader.m_versionMajor));
229
  result |= (fread (&m_fileHeader.m_magicNumber, sizeof(m_fileHeader.m_magicNumber), 1, m_filePtr) != 1);
224
  m_file.read ((char *)&m_fileHeader.m_versionMinor, sizeof(m_fileHeader.m_versionMinor));
230
  result |= (fread (&m_fileHeader.m_versionMajor, sizeof(m_fileHeader.m_versionMajor), 1, m_filePtr) != 1);
225
  m_file.read ((char *)&m_fileHeader.m_zone, sizeof(m_fileHeader.m_zone));
231
  result |= (fread (&m_fileHeader.m_versionMinor, sizeof(m_fileHeader.m_versionMinor), 1, m_filePtr) != 1);
226
  m_file.read ((char *)&m_fileHeader.m_sigFigs, sizeof(m_fileHeader.m_sigFigs));
232
  result |= (fread (&m_fileHeader.m_zone, sizeof(m_fileHeader.m_zone), 1, m_filePtr) != 1);
227
  m_file.read ((char *)&m_fileHeader.m_snapLen, sizeof(m_fileHeader.m_snapLen));
233
  result |= (fread (&m_fileHeader.m_sigFigs, sizeof(m_fileHeader.m_sigFigs), 1, m_filePtr) != 1);
228
  m_file.read ((char *)&m_fileHeader.m_type, sizeof(m_fileHeader.m_type));
234
  result |= (fread (&m_fileHeader.m_snapLen, sizeof(m_fileHeader.m_snapLen), 1, m_filePtr) != 1);
235
  result |= (fread (&m_fileHeader.m_type, sizeof(m_fileHeader.m_type), 1, m_filePtr) != 1);
236
237
  //
238
  // If any of the freads above did not succeed in reading the correct number of 
239
  // objects, result will be nonzero.
240
  //
241
  if (result)
242
    {
243
      return true;
244
    }
245
229
246
  //
230
  //
247
  // There are four possible magic numbers that can be there.  Normal and byte
231
  // There are four possible magic numbers that can be there.  Normal and byte
 Lines 251-264    Link Here 
251
  if (m_fileHeader.m_magicNumber != MAGIC && m_fileHeader.m_magicNumber != SWAPPED_MAGIC && 
235
  if (m_fileHeader.m_magicNumber != MAGIC && m_fileHeader.m_magicNumber != SWAPPED_MAGIC && 
252
      m_fileHeader.m_magicNumber != NS_MAGIC && m_fileHeader.m_magicNumber != NS_SWAPPED_MAGIC)
236
      m_fileHeader.m_magicNumber != NS_MAGIC && m_fileHeader.m_magicNumber != NS_SWAPPED_MAGIC)
253
    {
237
    {
254
      return true;
238
      m_file.setstate (std::ios::failbit);
255
    }
239
    }
256
240
257
  //
241
  //
258
  // If the magic number is swapped, then we can assume that everything else we read
242
  // If the magic number is swapped, then we can assume that everything else we read
259
  // is swapped.
243
  // is swapped.
260
  //
244
  //
261
  m_swapMode = (m_fileHeader.m_magicNumber == SWAPPED_MAGIC || m_fileHeader.m_magicNumber == NS_SWAPPED_MAGIC) ? true : false;
245
  m_swapMode = (m_fileHeader.m_magicNumber == SWAPPED_MAGIC 
246
                || m_fileHeader.m_magicNumber == NS_SWAPPED_MAGIC) ? true : false;
262
247
263
  if (m_swapMode)
248
  if (m_swapMode)
264
    {
249
    {
 Lines 270-276    Link Here 
270
  //
255
  //
271
  if (m_fileHeader.m_versionMajor != VERSION_MAJOR || m_fileHeader.m_versionMinor != VERSION_MINOR)
256
  if (m_fileHeader.m_versionMajor != VERSION_MAJOR || m_fileHeader.m_versionMinor != VERSION_MINOR)
272
    {
257
    {
273
      return true;
258
      m_file.setstate (std::ios::failbit);
274
    }
259
    }
275
260
276
  //
261
  //
 Lines 279-389    Link Here 
279
  //
264
  //
280
  if (m_fileHeader.m_zone < -12 || m_fileHeader.m_zone > 12)
265
  if (m_fileHeader.m_zone < -12 || m_fileHeader.m_zone > 12)
281
    {
266
    {
282
      return true;
267
      m_file.setstate (std::ios::failbit);
283
    }
268
    }
284
269
285
  m_haveFileHeader = true;
270
  if (m_file.fail ())
286
  return false;
271
    {
272
      m_file.close ();
273
    }
287
}
274
}
288
275
289
bool
276
void
290
PcapFile::Open (std::string const &filename, std::string const &mode)
277
PcapFile::Open (std::string const &filename, std::ios::openmode mode)
291
{
278
{
292
  //
279
  NS_ASSERT ((mode & std::ios::app) == 0);
293
  // If opening a new file, implicit close of any existing file required.
280
  NS_ASSERT (!m_file.fail ());
294
  //
295
  Close ();
296
        
297
  //
281
  //
298
  // All pcap files are binary files, so we just do this automatically.
282
  // All pcap files are binary files, so we just do this automatically.
299
  //
283
  //
300
  std::string realMode = mode + "b";
284
  mode |= std::ios::binary;
301
285
302
  //
286
  m_file.open (filename.c_str (), mode);
303
  // Our modes may be subtly different from the standard fopen semantics since
287
  if (mode & std::ios::in)
304
  // we need to have a pcap file header to succeed in some cases; so we need 
305
  // to process different modes according to our own definitions of the modes.
306
  //
307
  // In the case of read modes, we must read, check and save the pcap file
308
  // header as well as just opening the file.
309
  //
310
  // In the case of write modes, we just pass the call on through to the 
311
  // library.
312
  //
313
  // In the case of append modes, we change the semantics to require the
314
  // given file to exist.  We can't just create a file since we can't make up
315
  // a pcap file header on our own.
316
  //
317
  if (realMode == "rb" || realMode == "r+b")
318
    {
288
    {
319
      m_filePtr = fopen (filename.c_str (), realMode.c_str ());
289
      // will set the fail bit if file header is invalid.
320
      if (m_filePtr == 0)
290
      ReadAndVerifyFileHeader ();
321
        {
322
          return true;
323
        }
324
      m_filename = filename;
325
      return ReadAndVerifyFileHeader ();
326
    }
327
  else if (realMode == "wb" || realMode == "w+b")
328
    {
329
      m_filePtr = fopen (filename.c_str (), realMode.c_str ());
330
      if (m_filePtr)
331
        {
332
          m_filename = filename;
333
          return false;
334
        }
335
      else
336
        {
337
          return true;
338
        }
339
    }
340
  else if (realMode == "ab" || realMode == "a+b")
341
    {
342
      //
343
      // Remember that semantics for append are different here.  We never create
344
      // a file since we can't make up a pcap file header.  We first have to 
345
      // open the file in read-only mode and check to see that it exists and
346
      // read the file header.  If this all works out, then we can go ahead and
347
      // open the file in append mode and seek to the end (imlicitly).
348
      //
349
      m_filePtr = fopen (filename.c_str (), "rb");
350
      if (m_filePtr == 0)
351
        {
352
          return true;
353
        }
354
355
      bool result = ReadAndVerifyFileHeader ();
356
      if (result == true)
357
        {
358
          Close ();
359
          return true;
360
        }
361
362
      //
363
      // We have a properly initialized file and have the pcap file header
364
      // loaded and checked.  This means that the file meets all of the 
365
      // critera for opening in append mode, but the file is in read-only mode
366
      // now -- we must close it and open it in the correct mode.
367
      //
368
      fclose (m_filePtr);
369
      m_filePtr = 0;
370
371
      m_filePtr = fopen (filename.c_str (), realMode.c_str ());
372
      if (m_filePtr == 0)
373
        {
374
          return true;
375
        }
376
377
      m_filename = filename;
378
      return false;
379
    }
380
  else
381
    {
382
      return true;
383
    }
291
    }
384
}
292
}
385
293
386
bool
294
void
387
PcapFile::Init (uint32_t dataLinkType, uint32_t snapLen, int32_t timeZoneCorrection, bool swapMode)
295
PcapFile::Init (uint32_t dataLinkType, uint32_t snapLen, int32_t timeZoneCorrection, bool swapMode)
388
{
296
{
389
  //
297
  //
 Lines 397-404    Link Here 
397
  m_fileHeader.m_snapLen = snapLen;
305
  m_fileHeader.m_snapLen = snapLen;
398
  m_fileHeader.m_type = dataLinkType;
306
  m_fileHeader.m_type = dataLinkType;
399
307
400
  m_haveFileHeader = true;
401
402
  //
308
  //
403
  // We use pcap files for regression testing.  We do byte-for-byte comparisons
309
  // We use pcap files for regression testing.  We do byte-for-byte comparisons
404
  // in those tests to determine pass or fail.  If we allow big endian systems
310
  // in those tests to determine pass or fail.  If we allow big endian systems
 Lines 426-441    Link Here 
426
  //
332
  //
427
  m_swapMode = swapMode | bigEndian;
333
  m_swapMode = swapMode | bigEndian;
428
334
429
  return WriteFileHeader ();
335
  WriteFileHeader ();
430
}
336
}
431
337
432
bool
338
uint32_t
433
PcapFile::Write (uint32_t tsSec, uint32_t tsUsec, uint8_t const * const data, uint32_t totalLen)
339
PcapFile::WritePacketHeader (uint32_t tsSec, uint32_t tsUsec, uint32_t totalLen)
434
{
340
{
435
  if (m_haveFileHeader == false)
341
  NS_ASSERT (m_file.good ());
436
    {
437
      return true;
438
    }
439
342
440
  uint32_t inclLen = totalLen > m_fileHeader.m_snapLen ? m_fileHeader.m_snapLen : totalLen;
343
  uint32_t inclLen = totalLen > m_fileHeader.m_snapLen ? m_fileHeader.m_snapLen : totalLen;
441
344
 Lines 454-472    Link Here 
454
  // Watch out for memory alignment differences between machines, so write
357
  // Watch out for memory alignment differences between machines, so write
455
  // them all individually.
358
  // them all individually.
456
  //
359
  //
457
  uint32_t result = 0;
360
  m_file.write ((const char *)&header.m_tsSec, sizeof(header.m_tsSec));
458
361
  m_file.write ((const char *)&header.m_tsUsec, sizeof(header.m_tsUsec));
459
  result |= (fwrite (&header.m_tsSec, sizeof(header.m_tsSec), 1, m_filePtr) != 1);
362
  m_file.write ((const char *)&header.m_inclLen, sizeof(header.m_inclLen));
460
  result |= (fwrite (&header.m_tsUsec, sizeof(header.m_tsUsec), 1, m_filePtr) != 1);
363
  m_file.write ((const char *)&header.m_origLen, sizeof(header.m_origLen));
461
  result |= (fwrite (&header.m_inclLen, sizeof(header.m_inclLen), 1, m_filePtr) != 1);
364
  return inclLen;
462
  result |= (fwrite (&header.m_origLen, sizeof(header.m_origLen), 1, m_filePtr) != 1);
463
464
  result |= fwrite (data, 1, inclLen, m_filePtr) != inclLen;
465
466
  return result != 0;
467
}
365
}
468
366
469
bool
367
void
368
PcapFile::Write (uint32_t tsSec, uint32_t tsUsec, uint8_t const * const data, uint32_t totalLen)
369
{
370
  uint32_t inclLen = WritePacketHeader (tsSec, tsUsec, totalLen);
371
  m_file.write ((const char *)data, inclLen);
372
}
373
374
void 
375
PcapFile::Write (uint32_t tsSec, uint32_t tsUsec, Ptr<const Packet> p)
376
{
377
  uint32_t inclLen = WritePacketHeader (tsSec, tsUsec, p->GetSize ());
378
  p->CopyData (&m_file, inclLen);
379
}
380
381
void 
382
PcapFile::Write (uint32_t tsSec, uint32_t tsUsec, Header &header, Ptr<const Packet> p)
383
{
384
  uint32_t headerSize = header.GetSerializedSize ();
385
  uint32_t totalSize = headerSize + p->GetSize ();
386
  uint32_t inclLen = WritePacketHeader (tsSec, tsUsec, totalSize);
387
388
  Buffer headerBuffer;
389
  headerBuffer.AddAtStart (headerSize);
390
  header.Serialize (headerBuffer.Begin ());
391
  uint32_t toCopy = std::min (headerSize, inclLen);
392
  headerBuffer.CopyData (&m_file, toCopy);
393
  inclLen -= toCopy;
394
  p->CopyData (&m_file, inclLen);
395
}
396
397
void
470
PcapFile::Read (
398
PcapFile::Read (
471
  uint8_t * const data, 
399
  uint8_t * const data, 
472
  uint32_t maxBytes,
400
  uint32_t maxBytes,
 Lines 476-485    Link Here 
476
  uint32_t &origLen,
404
  uint32_t &origLen,
477
  uint32_t &readLen)
405
  uint32_t &readLen)
478
{
406
{
479
  if (m_haveFileHeader == false)
407
  NS_ASSERT (m_file.good ());
480
    {
481
      return true;
482
    }
483
408
484
  PcapRecordHeader header;
409
  PcapRecordHeader header;
485
410
 Lines 487-507    Link Here 
487
  // Watch out for memory alignment differences between machines, so read
412
  // Watch out for memory alignment differences between machines, so read
488
  // them all individually.
413
  // them all individually.
489
  //
414
  //
490
  uint32_t result = 0;
415
  m_file.read ((char *)&header.m_tsSec, sizeof(header.m_tsSec));
491
416
  m_file.read ((char *)&header.m_tsUsec, sizeof(header.m_tsUsec));
492
  result |= (fread (&header.m_tsSec, sizeof(header.m_tsSec), 1, m_filePtr) != 1);
417
  m_file.read ((char *)&header.m_inclLen, sizeof(header.m_inclLen));
493
  result |= (fread (&header.m_tsUsec, sizeof(header.m_tsUsec), 1, m_filePtr) != 1);
418
  m_file.read ((char *)&header.m_origLen, sizeof(header.m_origLen));
494
  result |= (fread (&header.m_inclLen, sizeof(header.m_inclLen), 1, m_filePtr) != 1);
495
  result |= (fread (&header.m_origLen, sizeof(header.m_origLen), 1, m_filePtr) != 1);
496
497
  //
498
  // If any of the freads above did not succeed in reading the correct number of 
499
  // objects, result will be nonzero.
500
  //
501
  if (result)
502
    {
503
      return true;
504
    }
505
419
506
  if (m_swapMode)
420
  if (m_swapMode)
507
    {
421
    {
 Lines 521-531    Link Here 
521
  // for example, to figure out what is going on.
435
  // for example, to figure out what is going on.
522
  //
436
  //
523
  readLen = maxBytes < header.m_inclLen ? maxBytes : header.m_inclLen;
437
  readLen = maxBytes < header.m_inclLen ? maxBytes : header.m_inclLen;
524
  result = fread (data, 1, readLen, m_filePtr) != readLen;
438
  m_file.read ((char *)data, readLen);
525
  if (result)
526
    {
527
      return result;
528
    }
529
439
530
  //
440
  //
531
  // To keep the file pointer pointed in the right place, however, we always
441
  // To keep the file pointer pointed in the right place, however, we always
 Lines 533-547    Link Here 
533
  //
443
  //
534
  if (readLen < header.m_inclLen)
444
  if (readLen < header.m_inclLen)
535
    {
445
    {
536
      uint64_t pos = ftell (m_filePtr);
446
      m_file.seekg (header.m_inclLen - readLen, std::ios::cur);
537
      int result = fseek (m_filePtr, pos + header.m_inclLen - readLen, SEEK_SET);
538
      if (result)
539
        {
540
          return true;
541
        }
542
    }
447
    }
543
544
  return false;
545
}
448
}
546
449
547
bool
450
bool
 Lines 549-607    Link Here 
549
                uint32_t & sec, uint32_t & usec, 
452
                uint32_t & sec, uint32_t & usec, 
550
                uint32_t snapLen)
453
                uint32_t snapLen)
551
{
454
{
552
  PcapFile pcap[2];
455
  PcapFile pcap1, pcap2;
553
  for (int i = 0; i < 2; ++i)
456
  pcap1.Open (f1, std::ios::in);
457
  pcap2.Open (f2, std::ios::in);
458
  bool bad = pcap1.Fail () || pcap2.Fail ();
459
  if (bad)
554
    {
460
    {
555
      std::string const & file = (i == 0) ? f1 : f2;
461
      return true;
556
      bool err = pcap[i].Open (file, "r");
557
      if (err)
558
        {
559
          // Can't open file
560
          return true;
561
        }
562
    }
462
    }
563
  
463
  
564
  uint8_t data[2][snapLen];
464
  uint8_t *data1 = new uint8_t [snapLen] ();
565
  uint32_t tsSec[2], tsUsec[2], inclLen[2], origLen[2], readLen[2];
465
  uint8_t *data2 = new uint8_t [snapLen] ();
566
  bool err[2];
466
  uint32_t tsSec1, tsSec2;
567
  bool diff(false);
467
  uint32_t tsUsec1, tsUsec2;
468
  uint32_t inclLen1, inclLen2;
469
  uint32_t origLen1, origLen2;
470
  uint32_t readLen1, readLen2;
471
  bool diff = false;
568
  
472
  
569
  while (1)
473
  while (!pcap1.Eof () && !pcap2.Eof ()
474
         && !pcap1.Fail () && !pcap2.Fail ())
570
    {
475
    {
571
      for (int i = 0; i < 2; ++i)
476
      pcap1.Read (data1, snapLen, tsSec1, tsUsec1, inclLen1, origLen1, readLen1);
572
        err[i] = pcap[i].Read (data[i], snapLen, tsSec[i], tsUsec[i], inclLen[i], origLen[i], readLen[i]);
477
      pcap2.Read (data2, snapLen, tsSec2, tsUsec2, inclLen2, origLen2, readLen2);
573
    
478
574
      sec = tsSec[0];
479
      if (tsSec1 != tsSec2 || tsUsec1 != tsUsec2)
575
      usec = tsUsec[0];
576
      
577
      if (err[0] != err[1])
578
        {
579
          diff = true; // Read status doesn't match
580
          break;
581
        }
582
      
583
      if (err[0]) break; // nothing left
584
      
585
      if (tsSec[0] != tsSec[1] || tsUsec[0] != tsUsec[1])
586
        {
480
        {
587
          diff = true; // Next packet timestamps do not match
481
          diff = true; // Next packet timestamps do not match
588
          break;
482
          break;
589
        }
483
        }
590
      
484
      
591
      if (readLen[0] != readLen[1])
485
      if (readLen1 != readLen2)
592
        {
486
        {
593
          diff = true; // Packet lengths do not match
487
          diff = true; // Packet lengths do not match
594
          break;
488
          break;
595
        }
489
        }
596
      
490
      
597
      if (std::memcmp(data[0], data[1], readLen[0]) != 0)
491
      if (std::memcmp(data1, data2, readLen1) != 0)
598
        {
492
        {
599
          diff = true; // Packet data do not match
493
          diff = true; // Packet data do not match
600
          break;
494
          break;
601
        }
495
        }
602
    }  
496
    }  
603
  pcap[0].Close ();
497
  sec = tsSec1;
604
  pcap[1].Close ();
498
  usec = tsUsec1;
499
500
  bad = pcap1.Fail () || pcap2.Fail ();
501
  bool eof = pcap1.Eof () && pcap2.Eof ();
502
  if (bad && !eof)
503
    {
504
      diff = true;
505
    }
506
605
  return diff;
507
  return diff;
606
}
508
}
607
509
(-)a/src/common/pcap-file.h (-59 / +51 lines)
 Lines 22-31    Link Here 
22
#define PCAP_FILE_H
22
#define PCAP_FILE_H
23
23
24
#include <string>
24
#include <string>
25
#include <fstream>
25
#include <stdint.h>
26
#include <stdint.h>
27
#include "ns3/ptr.h"
26
28
27
namespace ns3 {
29
namespace ns3 {
28
30
31
class Packet;
32
class Header;
33
29
/*
34
/*
30
 * A class representing a pcap file.  This allows easy creation, writing and 
35
 * A class representing a pcap file.  This allows easy creation, writing and 
31
 * reading of files composed of stored packets; which may be viewed using
36
 * reading of files composed of stored packets; which may be viewed using
 Lines 43-109    Link Here 
43
  ~PcapFile ();
48
  ~PcapFile ();
44
49
45
  /**
50
  /**
51
   * \return true if the 'fail' bit is set in the underlying iostream, false otherwise.
52
   */
53
  bool Fail (void) const;
54
  /**
55
   * \return true if the 'eof' bit is set in the underlying iostream, false otherwise.
56
   */
57
  bool Eof (void) const;
58
  /**
59
   * Clear all state bits of the underlying iostream.
60
   */
61
  void Clear (void);
62
63
  /**
46
   * Create a new pcap file or open an existing pcap file.  Semantics are
64
   * Create a new pcap file or open an existing pcap file.  Semantics are
47
   * similar to the C standard library function \c fopen, but differ in that
65
   * similar to the stdc++ io stream classes, but differ in that
48
   * positions in the file are based on packets not characters.  For example
66
   * positions in the file are based on packets not characters.  For example
49
   * if the file is opened for reading, the file position indicator (seek
67
   * if the file is opened for reading, the file position indicator (seek
50
   * position) points to the beginning of the first packet in the file, not
68
   * position) points to the beginning of the first packet in the file, not
51
   * zero (which would point to the start of the pcap header).
69
   * zero (which would point to the start of the pcap header).
52
   *
70
   *
53
   * Possible modes are:
54
   *
55
   * \verbatim
56
   * "r":   Open a file for reading.  The file must exist.  The pcap header
57
   *        is assumed to exist in the file and will be read and checked.
58
   *        The file seek position indicator is set to point to the first 
59
   *        packet on exit.
60
   *
61
   * "w":   Create an empty file for writing. If a file with the same name 
62
   *        already exists its content is erased and the file is treated as a 
63
   *        new empty pcap file.  The file is assumed not to have a pcap 
64
   *        header and the caller is responsible for calling Init before saving
65
   *        any packet data.  The file seek position indicator is set to point 
66
   *        to the beginning of the file on exit since there will be no pcap
67
   *        header.
68
   *
69
   * "a":   Append to an existing file. This mode allows for adding packet data
70
   *        to the end of an existing pcap file.  The file must exist and have a
71
   *        valid pcap header written (N.B. this is different from standard fopen
72
   *        semantics).  The file seek position indicator is set to point 
73
   *        to the end of the file on exit.
74
   *
75
   * "r+":  Open a file for update -- both reading and writing. The file must 
76
   *        exist.  The pcap header is assumed to have been written to the 
77
   *        file and will be read and checked.  The file seek position indicator
78
   *        is set to point to the first packet on exit.
79
   *
80
   * "w+":  Create an empty file for both reading and writing.  If a file with
81
   *        the same name already exists, its content is erased and the file is 
82
   *        treated as a new empty pcap file.  Since this new file will not have
83
   *        a pcap header, the caller is responsible for calling Init before 
84
   *        saving any packet data.  On exit, the file seek position indicator is
85
   *        set to point to the beginning of the file.
86
   *
87
   * "a+"   Open a file for reading and appending.  The file must exist and have a
88
   *        valid pcap header written (N.B. this is different from standard fopen
89
   *        semantics).  The file seek position indicator is set to point 
90
   *        to the end of the file on exit.  Existing content is preserved.
91
   * \endverbatim
92
   *
93
   * Since a pcap file is always a binary file, the file type is automatically 
71
   * Since a pcap file is always a binary file, the file type is automatically 
94
   * selected as a binary file.  For example, providing a mode string "a+" 
72
   * selected as a binary file (fstream::binary is automatically ored with the mode
95
   * results in the underlying OS file being opened in "a+b" mode.
73
   * field).
96
   *
74
   *
97
   * \param filename String containing the name of the file.
75
   * \param filename String containing the name of the file.
98
   *
76
   *
99
   * \param mode String containing the access mode for the file.
77
   * \param mode the access mode for the file.
100
   *
101
   * \returns Error indication that should be interpreted as, "did an error 
102
   * happen"?  That is, the method returns false if the open succeeds, true 
103
   * otherwise.  The errno variable will be set by the OS to to provide a 
104
   * more descriptive failure indication.
105
   */
78
   */
106
  bool Open (std::string const &filename, std::string const &mode);
79
  void Open (std::string const &filename, std::ios::openmode mode);
107
80
108
  /**
81
  /**
109
   * Close the underlying file.
82
   * Close the underlying file.
 Lines 138-144    Link Here 
138
   * \warning Calling this method on an existing file will result in the loss
111
   * \warning Calling this method on an existing file will result in the loss
139
   * any existing data.
112
   * any existing data.
140
   */
113
   */
141
  bool Init (uint32_t dataLinkType, 
114
  void Init (uint32_t dataLinkType, 
142
             uint32_t snapLen = SNAPLEN_DEFAULT, 
115
             uint32_t snapLen = SNAPLEN_DEFAULT, 
143
             int32_t timeZoneCorrection = ZONE_DEFAULT,
116
             int32_t timeZoneCorrection = ZONE_DEFAULT,
144
             bool swapMode = false);
117
             bool swapMode = false);
 Lines 151-159    Link Here 
151
   * \param data        Data buffer
124
   * \param data        Data buffer
152
   * \param totalLen    Total packet length
125
   * \param totalLen    Total packet length
153
   * 
126
   * 
154
   * \return true on error, false otherwise
155
   */
127
   */
156
  bool Write (uint32_t tsSec, uint32_t tsUsec, uint8_t const * const data, uint32_t totalLen);
128
  void Write (uint32_t tsSec, uint32_t tsUsec, uint8_t const * const data, uint32_t totalLen);
129
130
  /**
131
   * \brief Write next packet to file
132
   * 
133
   * \param tsSec       Packet timestamp, seconds 
134
   * \param tsUsec      Packet timestamp, microseconds
135
   * \param p           Packet to write
136
   * 
137
   */
138
  void Write (uint32_t tsSec, uint32_t tsUsec, Ptr<const Packet> p);
139
  /**
140
   * \brief Write next packet to file
141
   * 
142
   * \param tsSec       Packet timestamp, seconds 
143
   * \param tsUsec      Packet timestamp, microseconds
144
   * \param header      Header to write, in front of packet
145
   * \param p           Packet to write
146
   * 
147
   */
148
  void Write (uint32_t tsSec, uint32_t tsUsec, Header &header, Ptr<const Packet> p);
149
157
150
158
  /**
151
  /**
159
   * \brief Read next packet from file
152
   * \brief Read next packet from file
 Lines 166-174    Link Here 
166
   * \param origLen     [out] Original length
159
   * \param origLen     [out] Original length
167
   * \param readLen     [out] Number of bytes read
160
   * \param readLen     [out] Number of bytes read
168
   * 
161
   * 
169
   * \return true if read failed, false otherwise
170
   */
162
   */
171
  bool Read (uint8_t * const data, 
163
  void Read (uint8_t * const data, 
172
             uint32_t maxBytes,
164
             uint32_t maxBytes,
173
             uint32_t &tsSec, 
165
             uint32_t &tsSec, 
174
             uint32_t &tsUsec, 
166
             uint32_t &tsUsec, 
 Lines 290-302    Link Here 
290
  void Swap (PcapFileHeader *from, PcapFileHeader *to);
282
  void Swap (PcapFileHeader *from, PcapFileHeader *to);
291
  void Swap (PcapRecordHeader *from, PcapRecordHeader *to);
283
  void Swap (PcapRecordHeader *from, PcapRecordHeader *to);
292
284
293
  bool WriteFileHeader (void);
285
  void WriteFileHeader (void);
294
  bool ReadAndVerifyFileHeader (void);
286
  uint32_t WritePacketHeader (uint32_t tsSec, uint32_t tsUsec, uint32_t totalLen);
287
  void ReadAndVerifyFileHeader (void);
295
288
296
  std::string    m_filename;
289
  std::string    m_filename;
297
  FILE          *m_filePtr;
290
  std::fstream   m_file;
298
  PcapFileHeader m_fileHeader;
291
  PcapFileHeader m_fileHeader;
299
  bool m_haveFileHeader;
300
  bool m_swapMode;
292
  bool m_swapMode;
301
};
293
};
302
294
(-)a/src/helper/csma-helper.cc (-2 / +3 lines)
 Lines 98-104    Link Here 
98
      filename = pcapHelper.GetFilenameFromDevice (prefix, device);
98
      filename = pcapHelper.GetFilenameFromDevice (prefix, device);
99
    }
99
    }
100
100
101
  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, "w", PcapHelper::DLT_EN10MB);
101
  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, std::ios::out, 
102
                                                     PcapHelper::DLT_EN10MB);
102
  if (promiscuous)
103
  if (promiscuous)
103
    {
104
    {
104
      pcapHelper.HookDefaultSink<CsmaNetDevice> (device, "PromiscSniffer", file);
105
      pcapHelper.HookDefaultSink<CsmaNetDevice> (device, "PromiscSniffer", file);
 Lines 159-165    Link Here 
159
          filename = asciiTraceHelper.GetFilenameFromDevice (prefix, device);
160
          filename = asciiTraceHelper.GetFilenameFromDevice (prefix, device);
160
        }
161
        }
161
162
162
      Ptr<OutputStreamWrapper> theStream = asciiTraceHelper.CreateFileStream (filename, "w");
163
      Ptr<OutputStreamWrapper> theStream = asciiTraceHelper.CreateFileStream (filename);
163
164
164
      //
165
      //
165
      // The MacRx trace source provides our "r" event.
166
      // The MacRx trace source provides our "r" event.
(-)a/src/helper/emu-helper.cc (-2 / +2 lines)
 Lines 91-97    Link Here 
91
      filename = pcapHelper.GetFilenameFromDevice (prefix, device);
91
      filename = pcapHelper.GetFilenameFromDevice (prefix, device);
92
    }
92
    }
93
93
94
  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, "w", PcapHelper::DLT_EN10MB);
94
  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, std::ios::out, PcapHelper::DLT_EN10MB);
95
  if (promiscuous)
95
  if (promiscuous)
96
    {
96
    {
97
      pcapHelper.HookDefaultSink<EmuNetDevice> (device, "PromiscSniffer", file);
97
      pcapHelper.HookDefaultSink<EmuNetDevice> (device, "PromiscSniffer", file);
 Lines 152-158    Link Here 
152
          filename = asciiTraceHelper.GetFilenameFromDevice (prefix, device);
152
          filename = asciiTraceHelper.GetFilenameFromDevice (prefix, device);
153
        }
153
        }
154
154
155
      Ptr<OutputStreamWrapper> theStream = asciiTraceHelper.CreateFileStream (filename, "w");
155
      Ptr<OutputStreamWrapper> theStream = asciiTraceHelper.CreateFileStream (filename);
156
156
157
      //
157
      //
158
      // The MacRx trace source provides our "r" event.
158
      // The MacRx trace source provides our "r" event.
(-)a/src/helper/internet-stack-helper.cc (-4 / +4 lines)
 Lines 470-476    Link Here 
470
      filename = pcapHelper.GetFilenameFromInterfacePair (prefix, ipv4, interface);
470
      filename = pcapHelper.GetFilenameFromInterfacePair (prefix, ipv4, interface);
471
    }
471
    }
472
472
473
  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, "w", PcapHelper::DLT_RAW);
473
  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, std::ios::out, PcapHelper::DLT_RAW);
474
474
475
  //
475
  //
476
  // However, we only hook the trace source once to avoid multiple trace sink
476
  // However, we only hook the trace source once to avoid multiple trace sink
 Lines 562-568    Link Here 
562
      filename = pcapHelper.GetFilenameFromInterfacePair (prefix, ipv6, interface);
562
      filename = pcapHelper.GetFilenameFromInterfacePair (prefix, ipv6, interface);
563
    }
563
    }
564
564
565
  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, "w", PcapHelper::DLT_RAW);
565
  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, std::ios::out, PcapHelper::DLT_RAW);
566
566
567
  //
567
  //
568
  // However, we only hook the trace source once to avoid multiple trace sink
568
  // However, we only hook the trace source once to avoid multiple trace sink
 Lines 714-720    Link Here 
714
          filename = asciiTraceHelper.GetFilenameFromInterfacePair (prefix, ipv4, interface);
714
          filename = asciiTraceHelper.GetFilenameFromInterfacePair (prefix, ipv4, interface);
715
        }
715
        }
716
716
717
      Ptr<OutputStreamWrapper> theStream = asciiTraceHelper.CreateFileStream (filename, "w");
717
      Ptr<OutputStreamWrapper> theStream = asciiTraceHelper.CreateFileStream (filename);
718
718
719
      //
719
      //
720
      // However, we only hook the trace sources once to avoid multiple trace sink
720
      // However, we only hook the trace sources once to avoid multiple trace sink
 Lines 909-915    Link Here 
909
          filename = asciiTraceHelper.GetFilenameFromInterfacePair (prefix, ipv6, interface);
909
          filename = asciiTraceHelper.GetFilenameFromInterfacePair (prefix, ipv6, interface);
910
        }
910
        }
911
911
912
      Ptr<OutputStreamWrapper> theStream = asciiTraceHelper.CreateFileStream (filename, "w");
912
      Ptr<OutputStreamWrapper> theStream = asciiTraceHelper.CreateFileStream (filename);
913
913
914
      //
914
      //
915
      // However, we only hook the trace sources once to avoid multiple trace sink
915
      // However, we only hook the trace sources once to avoid multiple trace sink
(-)a/src/helper/point-to-point-helper.cc (-2 / +3 lines)
 Lines 99-105    Link Here 
99
      filename = pcapHelper.GetFilenameFromDevice (prefix, device);
99
      filename = pcapHelper.GetFilenameFromDevice (prefix, device);
100
    }
100
    }
101
101
102
  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, "w", PcapHelper::DLT_PPP);
102
  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, std::ios::out, 
103
                                                     PcapHelper::DLT_PPP);
103
  pcapHelper.HookDefaultSink<PointToPointNetDevice> (device, "PromiscSniffer", file);
104
  pcapHelper.HookDefaultSink<PointToPointNetDevice> (device, "PromiscSniffer", file);
104
}
105
}
105
106
 Lines 154-160    Link Here 
154
          filename = asciiTraceHelper.GetFilenameFromDevice (prefix, device);
155
          filename = asciiTraceHelper.GetFilenameFromDevice (prefix, device);
155
        }
156
        }
156
157
157
      Ptr<OutputStreamWrapper> theStream = asciiTraceHelper.CreateFileStream (filename, "w");
158
      Ptr<OutputStreamWrapper> theStream = asciiTraceHelper.CreateFileStream (filename);
158
159
159
      //
160
      //
160
      // The MacRx trace source provides our "r" event.
161
      // The MacRx trace source provides our "r" event.
(-)a/src/helper/trace-helper.cc (-21 / +7 lines)
 Lines 48-54    Link Here 
48
Ptr<PcapFileWrapper>
48
Ptr<PcapFileWrapper>
49
PcapHelper::CreateFile (
49
PcapHelper::CreateFile (
50
  std::string filename, 
50
  std::string filename, 
51
  std::string filemode,  
51
  std::ios::openmode filemode,
52
  uint32_t    dataLinkType, 
52
  uint32_t    dataLinkType, 
53
  uint32_t    snapLen, 
53
  uint32_t    snapLen, 
54
  int32_t     tzCorrection)
54
  int32_t     tzCorrection)
 Lines 56-66    Link Here 
56
  NS_LOG_FUNCTION (filename << filemode << dataLinkType << snapLen << tzCorrection);
56
  NS_LOG_FUNCTION (filename << filemode << dataLinkType << snapLen << tzCorrection);
57
57
58
  Ptr<PcapFileWrapper> file = CreateObject<PcapFileWrapper> ();
58
  Ptr<PcapFileWrapper> file = CreateObject<PcapFileWrapper> ();
59
  bool err = file->Open (filename, filemode);
59
  file->Open (filename, filemode);
60
  NS_ABORT_MSG_IF (err, "Unable to Open " << filename << " for mode " << filemode);
60
  NS_ABORT_MSG_IF (file->Fail (), "Unable to Open " << filename << " for mode " << filemode);
61
61
62
  err = file->Init (dataLinkType, snapLen, tzCorrection);
62
  file->Init (dataLinkType, snapLen, tzCorrection);
63
  NS_ABORT_MSG_IF (err, "Unable to Init " << filename);
63
  NS_ABORT_MSG_IF (file->Fail (), "Unable to Init " << filename);
64
64
65
  //
65
  //
66
  // Note that the pcap helper promptly forgets all about the pcap file.  We
66
  // Note that the pcap helper promptly forgets all about the pcap file.  We
 Lines 181-207    Link Here 
181
}
181
}
182
182
183
Ptr<OutputStreamWrapper>
183
Ptr<OutputStreamWrapper>
184
AsciiTraceHelper::CreateFileStream (std::string filename, std::string filemode)
184
AsciiTraceHelper::CreateFileStream (std::string filename, std::ios::openmode filemode)
185
{
185
{
186
  NS_LOG_FUNCTION (filename << filemode);
186
  NS_LOG_FUNCTION (filename << filemode);
187
187
188
  std::ofstream *ofstream = new std::ofstream;
188
  std::ofstream *ofstream = new std::ofstream;
189
  std::ios_base::openmode mode = std::ios_base::out | std::ios_base::trunc;
190
189
191
  if (filemode == "a")
190
  ofstream->open (filename.c_str (), filemode);
192
    {
193
      mode = std::ios_base::out | std::ios_base::app;
194
    }
195
  else if (filemode == "w")
196
    {
197
      mode = std::ios_base::out | std::ios_base::trunc;
198
    }
199
  else
200
    {
201
      NS_ABORT_MSG ("AsciiTraceHelper::CreateFileStream(): Unexpected file mode");
202
    }
203
204
  ofstream->open (filename.c_str (), mode);
205
  NS_ABORT_MSG_UNLESS (ofstream->is_open (), "AsciiTraceHelper::CreateFileStream():  Unable to Open " << 
191
  NS_ABORT_MSG_UNLESS (ofstream->is_open (), "AsciiTraceHelper::CreateFileStream():  Unable to Open " << 
206
                       filename << " for mode " << filemode);
192
                       filename << " for mode " << filemode);
207
  
193
  
(-)a/src/helper/trace-helper.h (-2 / +3 lines)
 Lines 84-90    Link Here 
84
  /**
84
  /**
85
   * @brief Create and initialize a pcap file.
85
   * @brief Create and initialize a pcap file.
86
   */
86
   */
87
  Ptr<PcapFileWrapper> CreateFile (std::string filename, std::string filemode,
87
  Ptr<PcapFileWrapper> CreateFile (std::string filename, std::ios::openmode filemode,
88
                                  uint32_t dataLinkType,  uint32_t snapLen = 65535, int32_t tzCorrection = 0);
88
                                  uint32_t dataLinkType,  uint32_t snapLen = 65535, int32_t tzCorrection = 0);
89
  /**
89
  /**
90
   * @brief Hook a trace source to the default trace sink
90
   * @brief Hook a trace source to the default trace sink
 Lines 156-162    Link Here 
156
   * that can solve the problem so we use one of those to carry the stream
156
   * that can solve the problem so we use one of those to carry the stream
157
   * around and deal with the lifetime issues.
157
   * around and deal with the lifetime issues.
158
   */
158
   */
159
  Ptr<OutputStreamWrapper> CreateFileStream (std::string filename, std::string filemode = "w");
159
  Ptr<OutputStreamWrapper> CreateFileStream (std::string filename, 
160
                                             std::ios::openmode filemode = std::ios::out);
160
161
161
  /**
162
  /**
162
   * @brief Hook a trace source to the default enqueue operation trace sink that
163
   * @brief Hook a trace source to the default enqueue operation trace sink that
(-)a/src/helper/wimax-helper.cc (-2 / +2 lines)
 Lines 480-486    Link Here 
480
        {
480
        {
481
          filename = asciiTraceHelper.GetFilenameFromDevice (prefix, device);
481
          filename = asciiTraceHelper.GetFilenameFromDevice (prefix, device);
482
        }
482
        }
483
      Ptr<OutputStreamWrapper> theStream = asciiTraceHelper.CreateFileStream (filename, "w");
483
      Ptr<OutputStreamWrapper> theStream = asciiTraceHelper.CreateFileStream (filename);
484
484
485
      uint32_t nodeid = nd->GetNode ()->GetId ();
485
      uint32_t nodeid = nd->GetNode ()->GetId ();
486
      uint32_t deviceid = nd->GetIfIndex ();
486
      uint32_t deviceid = nd->GetIfIndex ();
 Lines 586-592    Link Here 
586
      filename = pcapHelper.GetFilenameFromDevice (prefix, device);
586
      filename = pcapHelper.GetFilenameFromDevice (prefix, device);
587
    }
587
    }
588
588
589
  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, "w", PcapHelper::DLT_EN10MB);
589
  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, std::ios::out, PcapHelper::DLT_EN10MB);
590
590
591
  phy->TraceConnectWithoutContext ("Tx", MakeBoundCallback (&PcapSniffTxEvent, file));
591
  phy->TraceConnectWithoutContext ("Tx", MakeBoundCallback (&PcapSniffTxEvent, file));
592
  phy->TraceConnectWithoutContext ("Rx", MakeBoundCallback (&PcapSniffRxEvent, file));
592
  phy->TraceConnectWithoutContext ("Rx", MakeBoundCallback (&PcapSniffRxEvent, file));
(-)a/src/helper/yans-wifi-helper.cc (-1 / +1 lines)
 Lines 409-415    Link Here 
409
      filename = pcapHelper.GetFilenameFromDevice (prefix, device);
409
      filename = pcapHelper.GetFilenameFromDevice (prefix, device);
410
    }
410
    }
411
411
412
  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, "w", m_pcapDlt);
412
  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, std::ios::out, m_pcapDlt);
413
413
414
  phy->TraceConnectWithoutContext ("PromiscSnifferTx", MakeBoundCallback (&PcapSniffTxEvent, file));
414
  phy->TraceConnectWithoutContext ("PromiscSnifferTx", MakeBoundCallback (&PcapSniffTxEvent, file));
415
  phy->TraceConnectWithoutContext ("PromiscSnifferRx", MakeBoundCallback (&PcapSniffRxEvent, file));
415
  phy->TraceConnectWithoutContext ("PromiscSnifferRx", MakeBoundCallback (&PcapSniffRxEvent, file));

Return to bug 872