diff -r cd0d8ba00e6c examples/tutorial/sixth.cc --- a/examples/tutorial/sixth.cc Thu Apr 08 13:39:07 2010 +0200 +++ b/examples/tutorial/sixth.cc Wed Apr 14 08:47:33 2010 +0200 @@ -219,7 +219,7 @@ ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow", MakeBoundCallback (&CwndChange, stream)); PcapHelper pcapHelper; - Ptr file = pcapHelper.CreateFile ("sixth.pcap", "w", PcapHelper::DLT_PPP); + Ptr file = pcapHelper.CreateFile ("sixth.pcap", std::ios::out, PcapHelper::DLT_PPP); devices.Get (1)->TraceConnectWithoutContext("PhyRxDrop", MakeBoundCallback (&RxDrop, file)); Simulator::Stop (Seconds(20)); diff -r cd0d8ba00e6c src/common/pcap-file-test-suite.cc --- a/src/common/pcap-file-test-suite.cc Thu Apr 08 13:39:07 2010 +0200 +++ b/src/common/pcap-file-test-suite.cc Wed Apr 14 08:47:33 2010 +0200 @@ -31,19 +31,19 @@ // Some utility functions for the tests. // =========================================================================== -uint16_t +static uint16_t Swap (uint16_t val) { return ((val >> 8) & 0x00ff) | ((val << 8) & 0xff00); } -uint32_t +static uint32_t Swap (uint32_t val) { return ((val >> 24) & 0x000000ff) | ((val >> 8) & 0x0000ff00) | ((val << 8) & 0x00ff0000) | ((val << 24) & 0xff000000); } -bool +static bool CheckFileExists (std::string filename) { FILE * p = fopen (filename.c_str (), "rb"); @@ -57,7 +57,7 @@ } -bool +static bool CheckFileLength (std::string filename, uint64_t sizeExpected) { FILE * p = fopen (filename.c_str (), "rb"); @@ -93,7 +93,7 @@ }; WriteModeCreateTestCase::WriteModeCreateTestCase () - : TestCase ("Check to see that PcapFile::Open with mode \"w\" works") + : TestCase ("Check to see that PcapFile::Open with mode std::ios::out works") { } @@ -125,25 +125,26 @@ // Opening a new file in write mode should result in an empty file of the // given name. // - bool err = f.Open (m_testFilename, "w"); + f.Open (m_testFilename, std::ios::out); - NS_TEST_ASSERT_MSG_EQ (err, false, "Open (" << m_testFilename << ", \"w\") returns error"); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (" << m_testFilename << ", \"w\") returns error"); f.Close (); NS_TEST_ASSERT_MSG_EQ (CheckFileExists (m_testFilename), true, - "Open (" << m_testFilename << ", \"w\") does not create file"); + "Open (" << m_testFilename << ", \"std::ios::out\") does not create file"); NS_TEST_ASSERT_MSG_EQ (CheckFileLength (m_testFilename, 0), true, - "Open (" << m_testFilename << ", \"w\") does not result in an empty file"); + "Open (" << m_testFilename << ", \"std::ios::out\") does not result in an empty file"); // - // Calling Init() on a file created with "w" should result in a file just + // Calling Init() on a file created with "std::ios::out" should result in a file just // long enough to contain the pcap file header. // - err = f.Open (m_testFilename, "w"); - NS_TEST_ASSERT_MSG_EQ (err, false, "Open (" << m_testFilename << ", \"w\") returns error"); + f.Open (m_testFilename, std::ios::out); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (" << m_testFilename << + ", \"std::ios::out\") returns error"); - err = f.Init (1234, 5678, 7); - NS_TEST_ASSERT_MSG_EQ (err, false, "Init (1234, 5678, 7) returns error"); + f.Init (1234, 5678, 7); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Init (1234, 5678, 7) returns error"); f.Close (); @@ -154,8 +155,9 @@ // Opening an existing file in write mode should result in that file being // emptied. // - err = f.Open (m_testFilename, "w"); - NS_TEST_ASSERT_MSG_EQ (err, false, "Open (" << m_testFilename << ", \"w\") returns error"); + f.Open (m_testFilename, std::ios::out); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (" << m_testFilename << + ", \"std::ios::out\") returns error"); f.Close (); @@ -165,22 +167,23 @@ // // Initialize the file again. // - err = f.Open (m_testFilename, "w"); - NS_TEST_ASSERT_MSG_EQ (err, false, + f.Open (m_testFilename, std::ios::out); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (" << m_testFilename << ", \"w\") returns error"); - err = f.Init (1234, 5678, 7); - NS_TEST_ASSERT_MSG_EQ (err, false, "Init (1234, 5678, 7) returns error"); + f.Init (1234, 5678, 7); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Init (1234, 5678, 7) returns error"); // - // Now we should be able to write to it since it was opened in "w" mode. + // Now we should be able to write to it since it was opened in std::ios::out mode. // This is just a permissions check so we don't actually look at the // data. // uint8_t buffer[128]; memset(buffer, 0, sizeof(buffer)); - err = f.Write (0, 0, buffer, 128); - NS_TEST_ASSERT_MSG_EQ (err, false, "Write (write-only-file " << m_testFilename << ") returns error"); + f.Write (0, 0, buffer, 128); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Write (write-only-file " << m_testFilename << + ") returns error"); return false; } @@ -204,7 +207,7 @@ }; ReadModeCreateTestCase::ReadModeCreateTestCase () - : TestCase ("Check to see that PcapFile::Open with mode \"r\" works") + : TestCase ("Check to see that PcapFile::Open with mode \"std::ios::in\" works") { } @@ -235,55 +238,64 @@ // // Opening a non-existing file in read mode should result in an error. // - bool err = f.Open (m_testFilename, "r"); - NS_TEST_ASSERT_MSG_EQ (err, true, "Open (non-existing-filename " << m_testFilename << ", \"r\") does not return error"); - - NS_TEST_ASSERT_MSG_EQ (CheckFileExists (m_testFilename), false, - "Open (" << m_testFilename << ", \"r\") unexpectedly created a file"); + f.Open (m_testFilename, std::ios::in); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), true, "Open (non-existing-filename " << m_testFilename << + ", \"std::ios::in\") does not return error"); + f.Close (); + f.Clear (); + NS_TEST_ASSERT_MSG_EQ (CheckFileExists (m_testFilename), false, "Open (" << m_testFilename << + ", \"std::ios::in\") unexpectedly created a file"); // // Okay, now create an uninitialized file using previously tested operations // - err = f.Open (m_testFilename, "w"); - NS_TEST_ASSERT_MSG_EQ (err, false, "Open (filename, \"w\") returns error"); + f.Open (m_testFilename, std::ios::out); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (filename, \"std::ios::out\") returns error"); f.Close (); // // Opening this file should result in an error since it has no pcap file header. // - err = f.Open (m_testFilename, "r"); - NS_TEST_ASSERT_MSG_EQ (err, true, "Open (non-initialized-filename " << m_testFilename << ", \"r\") does not return error"); + f.Open (m_testFilename, std::ios::in); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), true, "Open (non-initialized-filename " << m_testFilename << + ", \"std::ios::in\") does not return error"); + f.Close (); + f.Clear (); // // Okay, now open that non-initialized file in write mode and initialize it // Note that we open it in write mode to initialize it. // - err = f.Open (m_testFilename, "w"); - NS_TEST_ASSERT_MSG_EQ (err, false, "Open (" << m_testFilename << ", \"w\") returns error"); + f.Open (m_testFilename, std::ios::out); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (" << m_testFilename << + ", \"std::ios::out\") returns error"); - err = f.Init (1234, 5678, 7); - NS_TEST_ASSERT_MSG_EQ (err, false, "Init (1234, 5678, 7) returns error"); + f.Init (1234, 5678, 7); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Init (1234, 5678, 7) returns error"); f.Close (); // // Opening this file should now work since it has a pcap file header. // - err = f.Open (m_testFilename, "r"); - NS_TEST_ASSERT_MSG_EQ (err, false, "Open (initialized-filename " << m_testFilename << ", \"r\") returns error"); + f.Open (m_testFilename, std::ios::in); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (initialized-filename " << m_testFilename << + ", \"std::ios::in\") returns error"); // // Now we should not be able to write to it since it was opened in "r" mode // even if it has been initialized.. // uint8_t buffer[128]; - err = f.Write (0, 0, buffer, 128); - NS_TEST_ASSERT_MSG_EQ (err, true, "Write (read-only-file " << m_testFilename << ") does not return error"); - + f.Write (0, 0, buffer, 128); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), true, "Write (read-only-file " << m_testFilename << + ") does not return error"); f.Close (); + f.Clear (); return false; } +#if 0 // =========================================================================== // Test case to make sure that the Pcap File Object can open an existing pcap // file for appending. @@ -303,7 +315,7 @@ }; AppendModeCreateTestCase::AppendModeCreateTestCase () - : TestCase ("Check to see that PcapFile::Open with mode \"a\" works") + : TestCase ("Check to see that PcapFile::Open with mode \"std::ios::app\" works") { } @@ -334,54 +346,63 @@ // // Opening a non-existing file in append mode should result in an error. // - bool err = f.Open (m_testFilename, "a"); - NS_TEST_ASSERT_MSG_EQ (err, true, "Open (non-existing-filename " << m_testFilename << ", \"a\") does not return error"); + f.Open (m_testFilename, std::ios::out | std::ios::app); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), true, "Open (non-existing-filename " << m_testFilename << + ", \"std::ios::app\") does not return error"); f.Close (); + f.Clear (); NS_TEST_ASSERT_MSG_EQ (CheckFileExists (m_testFilename), false, - "Open (" << m_testFilename << ", \"a\") unexpectedly created a file"); + "Open (" << m_testFilename << ", \"std::ios::app\") unexpectedly created a file"); // // Okay, now create an uninitialized file using previously tested operations // - err = f.Open (m_testFilename, "w"); - NS_TEST_ASSERT_MSG_EQ (err, false, "Open (" << m_testFilename << ", \"w\") returns error"); + f.Open (m_testFilename, std::ios::out); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (" << m_testFilename << + ", \"std::ios::out\") returns error"); f.Close (); // // Opening this file should result in an error since it has no pcap file header. // - err = f.Open (m_testFilename, "a"); - NS_TEST_ASSERT_MSG_EQ (err, true, "Open (non-initialized-filename " << m_testFilename << ", \"a\") does not return error"); + f.Open (m_testFilename, std::ios::out | std::ios::app); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), true, "Open (non-initialized-filename " << m_testFilename << + ", \"std::ios::app\") does not return error"); + f.Close (); + f.Clear (); // // Okay, now open that non-initialized file in write mode and initialize it. // - err = f.Open (m_testFilename, "w"); - NS_TEST_ASSERT_MSG_EQ (err, false, "Open (non-initialized-filename " << m_testFilename << ", \"w\") returns error"); + f.Open (m_testFilename, std::ios::out); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (non-initialized-filename " << m_testFilename << + ", \"std::ios::out\") returns error"); - err = f.Init (1234, 5678, 7); - NS_TEST_ASSERT_MSG_EQ (err, false, "Init (1234, 5678, 7) returns error"); + f.Init (1234, 5678, 7); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Init (1234, 5678, 7) returns error"); f.Close (); // // Opening this file should now work since it has a pcap file header. // - err = f.Open (m_testFilename, "a"); - NS_TEST_ASSERT_MSG_EQ (err, false, "Open (initialized-filename " << m_testFilename << ", \"r\") returns error"); + f.Open (m_testFilename, std::ios::out | std::ios::app); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (initialized-filename " << m_testFilename << + ", \"std::ios::app\") returns error"); // - // We should be able to write to it since it was opened in "a" mode. + // We should be able to write to it since it was opened in "std::ios::app" mode. // uint8_t buffer[128]; memset(buffer, 0, sizeof(buffer)); - err = f.Write (0, 0, buffer, 128); - NS_TEST_ASSERT_MSG_EQ (err, false, "Write (append-mode-file " << m_testFilename << ") returns error"); + f.Write (0, 0, buffer, 128); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Write (append-mode-file " << m_testFilename << ") returns error"); f.Close (); return false; } +#endif // =========================================================================== // Test case to make sure that the Pcap File Object can write out correct pcap @@ -433,14 +454,15 @@ // // Create an uninitialized file using previously tested operations // - bool err = f.Open (m_testFilename, "w"); - NS_TEST_ASSERT_MSG_EQ (err, false, "Open (" << m_testFilename << ", \"w\") returns error"); - + f.Open (m_testFilename, std::ios::out); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (" << m_testFilename << + ", \"std::ios::out\") returns error"); + // // Initialize the pcap file header. // - err = f.Init (1234, 5678, 7); - NS_TEST_ASSERT_MSG_EQ (err, false, + f.Init (1234, 5678, 7); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Init (1234, 5678, 7) returns error"); f.Close (); @@ -525,8 +547,9 @@ // automagically fixed up when using a PcapFile to read the values, so we // don't have to do anything special here. // - err = f.Open (m_testFilename, "r"); - NS_TEST_ASSERT_MSG_EQ (err, false, "Open (existing-initialized-file " << m_testFilename << ", \"r\") returns error"); + f.Open (m_testFilename, std::ios::in); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (existing-initialized-file " << m_testFilename << + ", \"std::ios::in\") returns error"); NS_TEST_ASSERT_MSG_EQ (f.GetMagic (), 0xa1b2c3d4, "Read back magic number incorrectly"); NS_TEST_ASSERT_MSG_EQ (f.GetVersionMajor (), 2, "Read back version major incorrectly"); @@ -535,12 +558,14 @@ NS_TEST_ASSERT_MSG_EQ (f.GetSigFigs (), 0, "Read back sig figs incorrectly"); NS_TEST_ASSERT_MSG_EQ (f.GetSnapLen (), 5678, "Read back snap len incorrectly"); NS_TEST_ASSERT_MSG_EQ (f.GetDataLinkType (), 1234, "Read back data link type incorrectly"); + f.Close (); // // Re-open the file to erase its contents. // - err = f.Open (m_testFilename, "w"); - NS_TEST_ASSERT_MSG_EQ (err, false, "Open (" << m_testFilename << ", \"w\") returns error"); + f.Open (m_testFilename, std::ios::out); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (" << m_testFilename << + ", \"std::ios::out\") returns error"); // // Initialize the pcap file header, turning on swap mode manually to force @@ -550,8 +575,8 @@ // a no-op and we're always writing foreign-endian files. In that case, // this test case is really just a duplicate of the previous. // - err = f.Init (1234, 5678, 7, true); - NS_TEST_ASSERT_MSG_EQ (err, false, "Init (1234, 5678, 7) returns error"); + f.Init (1234, 5678, 7, true); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Init (1234, 5678, 7) returns error"); f.Close (); // @@ -599,8 +624,9 @@ // machine is writing out a big-endian file by default, but we can't do that // since it breaks regression testing. // - err = f.Open (m_testFilename, "r"); - NS_TEST_ASSERT_MSG_EQ (err, false, "Open (existing-initialized-file " << m_testFilename << ", \"r\") returns error"); + f.Open (m_testFilename, std::ios::in); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (existing-initialized-file " << m_testFilename << + ", \"std::ios::in\") returns error"); NS_TEST_ASSERT_MSG_EQ (f.GetSwapMode (), true, "Byte-swapped file not correctly indicated"); @@ -667,14 +693,15 @@ // // Create an uninitialized file using previously tested operations // - bool err = f.Open (m_testFilename, "w"); - NS_TEST_ASSERT_MSG_EQ (err, false, "Open (" << m_testFilename << ", \"w\") returns error"); + f.Open (m_testFilename, std::ios::out); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (" << m_testFilename << + ", \"std::ios::out\") returns error"); // // Initialize the pcap file header. // - err = f.Init (37, 43, -7); - NS_TEST_ASSERT_MSG_EQ (err, false, "Init (37, 43, -7) returns error"); + f.Init (37, 43, -7); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Init (37, 43, -7) returns error"); // // Initialize a buffer with a counting pattern to check the data later. @@ -690,8 +717,8 @@ // mode. The packet data written should be limited to 43 bytes in length // by the Init() call above. // - err = f.Write (1234, 5678, bufferOut, 128); - NS_TEST_ASSERT_MSG_EQ (err, false, "Write (write-only-file " << m_testFilename << ") returns error"); + f.Write (1234, 5678, bufferOut, 128); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Write (write-only-file " << m_testFilename << ") returns error"); f.Close (); // @@ -785,18 +812,20 @@ // Let's see if the PcapFile object can figure out how to do the same thing and // correctly read in a packet. // - err = f.Open (m_testFilename, "r"); - NS_TEST_ASSERT_MSG_EQ (err, false, "Open (" << m_testFilename << ", \"r\") of existing good file returns error"); + f.Open (m_testFilename, std::ios::in); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (" << m_testFilename << + ", \"std::ios::in\") of existing good file returns error"); uint32_t tsSec, tsUsec, inclLen, origLen, readLen; - err = f.Read (bufferIn, sizeof(bufferIn), tsSec, tsUsec, inclLen, origLen, readLen); - NS_TEST_ASSERT_MSG_EQ (err, false, "Read() of known good packet returns error"); + f.Read (bufferIn, sizeof(bufferIn), tsSec, tsUsec, inclLen, origLen, readLen); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Read() of known good packet returns error"); NS_TEST_ASSERT_MSG_EQ (tsSec, 1234, "Incorrectly read seconds timestap from known good packet"); NS_TEST_ASSERT_MSG_EQ (tsUsec, 5678, "Incorrectly read microseconds timestap from known good packet"); NS_TEST_ASSERT_MSG_EQ (inclLen, 43, "Incorrectly read included length from known good packet"); NS_TEST_ASSERT_MSG_EQ (origLen, 128, "Incorrectly read original length from known good packet"); NS_TEST_ASSERT_MSG_EQ (readLen, 43, "Incorrectly constructed actual read length from known good packet given buffer size"); + f.Close (); // // Did the data come back correctly? @@ -815,22 +844,23 @@ // // Open the file in write mode to clear the data. // - err = f.Open (m_testFilename, "w"); - NS_TEST_ASSERT_MSG_EQ (err, false, "Open (" << m_testFilename << ", \"w\") returns error"); + f.Open (m_testFilename, std::ios::out); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (" << m_testFilename << + ", \"std::ios::out\") returns error"); // // Initialize the pcap file header, forcing the object into swap mode. // - err = f.Init (37, 43, -7, true); - NS_TEST_ASSERT_MSG_EQ (err, false, "Init (37, 43, -7) returns error"); + f.Init (37, 43, -7, true); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Init (37, 43, -7) returns error"); // // Now we should be able to write a packet to it since it was opened in "w" // mode. The packet data written should be limited to 43 bytes in length // by the Init() call above. // - err = f.Write (1234, 5678, bufferOut, 128); - NS_TEST_ASSERT_MSG_EQ (err, false, "Write (write-only-file " << m_testFilename << ") returns error"); + f.Write (1234, 5678, bufferOut, 128); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Write (write-only-file " << m_testFilename << ") returns error"); f.Close (); // @@ -892,11 +922,12 @@ // correctly read in a packet. The record header info should come back to us // swapped back into correct form. // - err = f.Open (m_testFilename, "r"); - NS_TEST_ASSERT_MSG_EQ (err, false, "Open (" << m_testFilename << ", \"r\") of existing good file returns error"); + f.Open (m_testFilename, std::ios::in); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (" << m_testFilename << + ", \"std::ios::in\") of existing good file returns error"); - err = f.Read (bufferIn, sizeof(bufferIn), tsSec, tsUsec, inclLen, origLen, readLen); - NS_TEST_ASSERT_MSG_EQ (err, false, "Read() of known good packet returns error"); + f.Read (bufferIn, sizeof(bufferIn), tsSec, tsUsec, inclLen, origLen, readLen); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Read() of known good packet returns error"); NS_TEST_ASSERT_MSG_EQ (tsSec, 1234, "Incorrectly read seconds timestap from known good packet"); NS_TEST_ASSERT_MSG_EQ (tsUsec, 5678, "Incorrectly read microseconds timestap from known good packet"); NS_TEST_ASSERT_MSG_EQ (inclLen, 43, "Incorrectly read included length from known good packet"); @@ -988,8 +1019,9 @@ // // std::string filename = NS_TEST_SOURCEDIR + "known.pcap"; - bool err = f.Open (filename, "r"); - NS_TEST_ASSERT_MSG_EQ (err, false, "Open (" << filename << ", \"w\") returns error"); + f.Open (filename, std::ios::in); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (" << filename << + ", \"std::ios::in\") returns error"); // // We are going to read out the file header and all of the packets to make @@ -1006,8 +1038,8 @@ for (uint32_t i = 0; i < N_KNOWN_PACKETS; ++i, ++p) { - err = f.Read (data, sizeof(data), tsSec, tsUsec, inclLen, origLen, readLen); - NS_TEST_ASSERT_MSG_EQ (err, false, "Read() of known good pcap file returns error"); + f.Read (data, sizeof(data), tsSec, tsUsec, inclLen, origLen, readLen); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Read() of known good pcap file returns error"); NS_TEST_ASSERT_MSG_EQ (tsSec, p->tsSec, "Incorrectly read seconds timestap from known good pcap file"); NS_TEST_ASSERT_MSG_EQ (tsUsec, p->tsUsec, "Incorrectly read microseconds timestap from known good pcap file"); NS_TEST_ASSERT_MSG_EQ (inclLen, p->inclLen, "Incorrectly read included length from known good packet"); @@ -1019,8 +1051,8 @@ // The file should now be at EOF since we've read all of the packets. // Another packet read should return an error. // - err = f.Read (data, 1, tsSec, tsUsec, inclLen, origLen, readLen); - NS_TEST_ASSERT_MSG_EQ (err, true, "Read() of known good pcap file at EOF does not return error"); + f.Read (data, 1, tsSec, tsUsec, inclLen, origLen, readLen); + NS_TEST_ASSERT_MSG_EQ (f.Eof (), true, "Read() of known good pcap file at EOF does not return error"); f.Close (); @@ -1061,17 +1093,17 @@ std::string filename2 = "different.pcap"; PcapFile f; - bool err = f.Open (filename2, "w"); - NS_TEST_ASSERT_MSG_EQ (err, false, "Open (" << filename2 << ", \"w\") returns error"); - err = f.Init (1, N_PACKET_BYTES); - NS_TEST_ASSERT_MSG_EQ (err, false, "Init (1, " << N_PACKET_BYTES << ") returns error"); + f.Open (filename2, std::ios::out); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Open (" << filename2 << ", \"std::ios::out\") returns error"); + f.Init (1, N_PACKET_BYTES); + NS_TEST_ASSERT_MSG_EQ (f.Fail (), false, "Init (1, " << N_PACKET_BYTES << ") returns error"); for (uint32_t i = 0; i < N_KNOWN_PACKETS; ++i) { PacketEntry const & p = knownPackets[i]; - err = f.Write (p.tsSec, p.tsUsec, (uint8_t const *)p.data, p.origLen); - NS_TEST_EXPECT_MSG_EQ (err, false, "Write must not fail"); + f.Write (p.tsSec, p.tsUsec, (uint8_t const *)p.data, p.origLen); + NS_TEST_EXPECT_MSG_EQ (f.Fail (), false, "Write must not fail"); } f.Close (); @@ -1094,7 +1126,7 @@ { AddTestCase (new WriteModeCreateTestCase); AddTestCase (new ReadModeCreateTestCase); - AddTestCase (new AppendModeCreateTestCase); + //AddTestCase (new AppendModeCreateTestCase); AddTestCase (new FileHeaderTestCase); AddTestCase (new RecordHeaderTestCase); AddTestCase (new ReadFileTestCase); diff -r cd0d8ba00e6c src/common/pcap-file-wrapper.cc --- a/src/common/pcap-file-wrapper.cc Thu Apr 08 13:39:07 2010 +0200 +++ b/src/common/pcap-file-wrapper.cc Wed Apr 14 08:47:33 2010 +0200 @@ -54,19 +54,36 @@ Close (); } + +bool +PcapFileWrapper::Fail (void) const +{ + return m_file.Fail (); +} +bool +PcapFileWrapper::Eof (void) const +{ + return m_file.Eof (); +} +void +PcapFileWrapper::Clear (void) +{ + m_file.Clear (); +} + void PcapFileWrapper::Close (void) { m_file.Close (); } -bool -PcapFileWrapper::Open (std::string const &filename, std::string const &mode) +void +PcapFileWrapper::Open (std::string const &filename, std::ios::openmode mode) { - return m_file.Open (filename, mode); + m_file.Open (filename, mode); } -bool +void PcapFileWrapper::Init (uint32_t dataLinkType, uint32_t snapLen, int32_t tzCorrection) { // @@ -76,66 +93,42 @@ // if (snapLen != std::numeric_limits::max ()) { - return m_file.Init (dataLinkType, snapLen, tzCorrection); + m_file.Init (dataLinkType, snapLen, tzCorrection); } else { - return m_file.Init (dataLinkType, m_snapLen, tzCorrection); + m_file.Init (dataLinkType, m_snapLen, tzCorrection); } - - // - // Quiet the compiler - // - return true; } -bool +void PcapFileWrapper::Write (Time t, Ptr p) { - uint8_t buffer[PcapFile::SNAPLEN_DEFAULT]; - uint64_t current = t.GetMicroSeconds (); uint64_t s = current / 1000000; uint64_t us = current % 1000000; - uint32_t bufferSize = p->GetSize (); - p->CopyData (buffer, bufferSize); - bool rc = m_file.Write (s, us, buffer, bufferSize); - return rc; + m_file.Write (s, us, p); } -bool +void PcapFileWrapper::Write (Time t, Header &header, Ptr p) { - uint8_t buffer[PcapFile::SNAPLEN_DEFAULT]; - uint64_t current = t.GetMicroSeconds (); uint64_t s = current / 1000000; uint64_t us = current % 1000000; - Buffer headerBuffer; - uint32_t headerSize = header.GetSerializedSize (); - uint32_t packetSize = p->GetSize (); - uint32_t bufferSize = headerSize + packetSize; - - headerBuffer.AddAtStart (headerSize); - header.Serialize (headerBuffer.Begin ()); - - headerBuffer.Begin ().Read (buffer, headerSize); - p->CopyData (&buffer[headerSize], packetSize); - bool rc = m_file.Write (s, us, buffer, bufferSize); - - return rc; + m_file.Write (s, us, header, p); } -bool +void PcapFileWrapper::Write (Time t, uint8_t const *buffer, uint32_t length) { uint64_t current = t.GetMicroSeconds (); uint64_t s = current / 1000000; uint64_t us = current % 1000000; - return m_file.Write (s, us, buffer, length); + m_file.Write (s, us, buffer, length); } uint32_t diff -r cd0d8ba00e6c src/common/pcap-file-wrapper.h --- a/src/common/pcap-file-wrapper.h Thu Apr 08 13:39:07 2010 +0200 +++ b/src/common/pcap-file-wrapper.h Wed Apr 14 08:47:33 2010 +0200 @@ -21,6 +21,7 @@ #include #include +#include #include "ns3/ptr.h" #include "ns3/packet.h" #include "ns3/nstime.h" @@ -42,64 +43,34 @@ PcapFileWrapper (); ~PcapFileWrapper (); + /** - * Create a new pcap file wrapper representing a new or existing pcap file. - * Semantics are similar to the C standard library function \c fopen - * - * Possible modes are: - * - * \verbatim - * "r": Open a file for reading. The file must exist. The pcap header - * is assumed to exist in the file and will be read and checked. - * The file seek position indicator is set to point to the first - * packet on exit. - * - * "w": Create an empty file for writing. If a file with the same name - * already exists its content is erased and the file is treated as a - * new empty pcap file. The file is assumed not to have a pcap - * header and the caller is responsible for calling Init before saving - * any packet data. The file seek position indicator is set to point - * to the beginning of the file on exit since there will be no pcap - * header. - * - * "a": Append to an existing file. This mode allows for adding packet data - * to the end of an existing pcap file. The file must exist and have a - * valid pcap header written (N.B. this is different from standard fopen - * semantics). The file seek position indicator is set to point - * to the end of the file on exit. - * - * "r+": Open a file for update -- both reading and writing. The file must - * exist. The pcap header is assumed to have been written to the - * file and will be read and checked. The file seek position indicator - * is set to point to the first packet on exit. - * - * "w+": Create an empty file for both reading and writing. If a file with - * the same name already exists, its content is erased and the file is - * treated as a new empty pcap file. Since this new file will not have - * a pcap header, the caller is responsible for calling Init before - * saving any packet data. On exit, the file seek position indicator is - * set to point to the beginning of the file. - * - * "a+" Open a file for reading and appending. The file must exist and have a - * valid pcap header written (N.B. this is different from standard fopen - * semantics). The file seek position indicator is set to point - * to the end of the file on exit. Existing content is preserved. - * \endverbatim + * \return true if the 'fail' bit is set in the underlying iostream, false otherwise. + */ + bool Fail (void) const; + /** + * \return true if the 'eof' bit is set in the underlying iostream, false otherwise. + */ + bool Eof (void) const; + /** + * Clear all state bits of the underlying iostream. + */ + void Clear (void); + + /** + * Create a new pcap file or open an existing pcap file. Semantics are + * similar to the stdc++ io stream classes. * * Since a pcap file is always a binary file, the file type is automatically - * selected as a binary file. For example, providing a mode string "a+" - * results in the underlying OS file being opened in "a+b" mode. + * selected as a binary file (fstream::binary is automatically ored with the mode + * field). * * \param filename String containing the name of the file. * * \param mode String containing the access mode for the file. * - * \returns Error indication that should be interpreted as, "did an error - * happen"? That is, the method returns false if the open succeeds, true - * otherwise. The errno variable will be set by the OS to to provide a - * more descriptive failure indication. */ - bool Open (std::string const &filename, std::string const &mode); + void Open (std::string const &filename, std::ios::openmode mode); /** * Close the underlying pcap file. @@ -126,12 +97,10 @@ * time zone from UTC/GMT. For example, Pacific Standard Time in the US is * GMT-8, so one would enter -8 for that correction. Defaults to 0 (UTC). * - * \return false if the open succeeds, true otherwise. - * * \warning Calling this method on an existing file will result in the loss * any existing data. */ - bool Init (uint32_t dataLinkType, + void Init (uint32_t dataLinkType, uint32_t snapLen = std::numeric_limits::max (), int32_t tzCorrection = PcapFile::ZONE_DEFAULT); @@ -141,9 +110,8 @@ * \param t Packet timestamp as ns3::Time. * \param p Packet to write to the pcap file. * - * \return true on error, false otherwise */ - bool Write (Time t, Ptr p); + void Write (Time t, Ptr p); /** * \brief Write the provided header along with the packet to the pcap file. @@ -156,9 +124,8 @@ * \param header The Header to prepend to the packet. * \param p Packet to write to the pcap file. * - * \return true on error, false otherwise */ - bool Write (Time t, Header &header, Ptr p); + void Write (Time t, Header &header, Ptr p); /** * \brief Write the provided data buffer to the pcap file. @@ -167,9 +134,8 @@ * \param buffer The buffer to write. * \param length The size of the buffer. * - * \return true on error, false otherwise */ - bool Write (Time t, uint8_t const *buffer, uint32_t length); + void Write (Time t, uint8_t const *buffer, uint32_t length); /* * \brief Returns the magic number of the pcap file as defined by the magic_number diff -r cd0d8ba00e6c src/common/pcap-file.cc --- a/src/common/pcap-file.cc Thu Apr 08 13:39:07 2010 +0200 +++ b/src/common/pcap-file.cc Wed Apr 14 08:47:33 2010 +0200 @@ -19,10 +19,12 @@ */ #include -#include -#include #include - +#include "ns3/assert.h" +#include "ns3/packet.h" +#include "ns3/fatal-error.h" +#include "ns3/header.h" +#include "ns3/buffer.h" #include "pcap-file.h" // // This file is used as part of the ns-3 test framework, so please refrain from @@ -41,28 +43,37 @@ const int32_t SIGFIGS_DEFAULT = 0; /**< Significant figures for timestamps (libpcap doesn't even bother) */ PcapFile::PcapFile () - : m_filename (""), - m_filePtr (0), - m_haveFileHeader (false), + : m_file (), m_swapMode (false) -{ -} +{} PcapFile::~PcapFile () { Close (); } + +bool +PcapFile::Fail (void) const +{ + return m_file.fail (); +} +bool +PcapFile::Eof (void) const +{ + return m_file.eof (); +} +void +PcapFile::Clear (void) +{ + m_file.clear (); +} + + void PcapFile::Close (void) { - if (m_filePtr) - { - fclose (m_filePtr); - } - m_filePtr = 0; - m_filename = ""; - m_haveFileHeader = false; + m_file.close (); } uint32_t @@ -152,18 +163,14 @@ to->m_origLen = Swap (from->m_origLen); } -bool +void PcapFile::WriteFileHeader (void) { // // If we're initializing the file, we need to write the pcap file header // at the start of the file. // - int result = fseek (m_filePtr, 0, SEEK_SET); - if (result) - { - return true; - } + m_file.seekp (0, std::ios::beg); // // We have the ability to write out the pcap file header in a foreign endian @@ -191,57 +198,34 @@ // Watch out for memory alignment differences between machines, so write // them all individually. // - result = 0; - - result |= (fwrite (&headerOut->m_magicNumber, sizeof(headerOut->m_magicNumber), 1, m_filePtr) != 1); - result |= (fwrite (&headerOut->m_versionMajor, sizeof(headerOut->m_versionMajor), 1, m_filePtr) != 1); - result |= (fwrite (&headerOut->m_versionMinor, sizeof(headerOut->m_versionMinor), 1, m_filePtr) != 1); - result |= (fwrite (&headerOut->m_zone, sizeof(headerOut->m_zone), 1, m_filePtr) != 1); - result |= (fwrite (&headerOut->m_sigFigs, sizeof(headerOut->m_sigFigs), 1, m_filePtr) != 1); - result |= (fwrite (&headerOut->m_snapLen, sizeof(headerOut->m_snapLen), 1, m_filePtr) != 1); - result |= (fwrite (&headerOut->m_type, sizeof(headerOut->m_type), 1, m_filePtr) != 1); - - // - // If any of the fwrites above did not succeed in writinging the correct - // number of objects, result will be nonzero and will indicate an error. - // - return result != 0; + m_file.write ((const char *)&headerOut->m_magicNumber, sizeof(headerOut->m_magicNumber)); + m_file.write ((const char *)&headerOut->m_versionMajor, sizeof(headerOut->m_versionMajor)); + m_file.write ((const char *)&headerOut->m_versionMinor, sizeof(headerOut->m_versionMinor)); + m_file.write ((const char *)&headerOut->m_zone, sizeof(headerOut->m_zone)); + m_file.write ((const char *)&headerOut->m_sigFigs, sizeof(headerOut->m_sigFigs)); + m_file.write ((const char *)&headerOut->m_snapLen, sizeof(headerOut->m_snapLen)); + m_file.write ((const char *)&headerOut->m_type, sizeof(headerOut->m_type)); } -bool +void PcapFile::ReadAndVerifyFileHeader (void) { // // Pcap file header is always at the start of the file // - int result = fseek (m_filePtr, 0, SEEK_SET); - if (result) - { - return true; - } + m_file.seekg (0, std::ios::beg); // // Watch out for memory alignment differences between machines, so read // them all individually. // - result = 0; - - result |= (fread (&m_fileHeader.m_magicNumber, sizeof(m_fileHeader.m_magicNumber), 1, m_filePtr) != 1); - result |= (fread (&m_fileHeader.m_versionMajor, sizeof(m_fileHeader.m_versionMajor), 1, m_filePtr) != 1); - result |= (fread (&m_fileHeader.m_versionMinor, sizeof(m_fileHeader.m_versionMinor), 1, m_filePtr) != 1); - result |= (fread (&m_fileHeader.m_zone, sizeof(m_fileHeader.m_zone), 1, m_filePtr) != 1); - result |= (fread (&m_fileHeader.m_sigFigs, sizeof(m_fileHeader.m_sigFigs), 1, m_filePtr) != 1); - result |= (fread (&m_fileHeader.m_snapLen, sizeof(m_fileHeader.m_snapLen), 1, m_filePtr) != 1); - result |= (fread (&m_fileHeader.m_type, sizeof(m_fileHeader.m_type), 1, m_filePtr) != 1); - - // - // If any of the freads above did not succeed in reading the correct number of - // objects, result will be nonzero. - // - if (result) - { - return true; - } + m_file.read ((char *)&m_fileHeader.m_magicNumber, sizeof(m_fileHeader.m_magicNumber)); + m_file.read ((char *)&m_fileHeader.m_versionMajor, sizeof(m_fileHeader.m_versionMajor)); + m_file.read ((char *)&m_fileHeader.m_versionMinor, sizeof(m_fileHeader.m_versionMinor)); + m_file.read ((char *)&m_fileHeader.m_zone, sizeof(m_fileHeader.m_zone)); + m_file.read ((char *)&m_fileHeader.m_sigFigs, sizeof(m_fileHeader.m_sigFigs)); + m_file.read ((char *)&m_fileHeader.m_snapLen, sizeof(m_fileHeader.m_snapLen)); + m_file.read ((char *)&m_fileHeader.m_type, sizeof(m_fileHeader.m_type)); // // There are four possible magic numbers that can be there. Normal and byte @@ -251,14 +235,15 @@ if (m_fileHeader.m_magicNumber != MAGIC && m_fileHeader.m_magicNumber != SWAPPED_MAGIC && m_fileHeader.m_magicNumber != NS_MAGIC && m_fileHeader.m_magicNumber != NS_SWAPPED_MAGIC) { - return true; + m_file.setstate (std::ios::failbit); } // // If the magic number is swapped, then we can assume that everything else we read // is swapped. // - m_swapMode = (m_fileHeader.m_magicNumber == SWAPPED_MAGIC || m_fileHeader.m_magicNumber == NS_SWAPPED_MAGIC) ? true : false; + m_swapMode = (m_fileHeader.m_magicNumber == SWAPPED_MAGIC + || m_fileHeader.m_magicNumber == NS_SWAPPED_MAGIC) ? true : false; if (m_swapMode) { @@ -270,7 +255,7 @@ // if (m_fileHeader.m_versionMajor != VERSION_MAJOR || m_fileHeader.m_versionMinor != VERSION_MINOR) { - return true; + m_file.setstate (std::ios::failbit); } // @@ -279,111 +264,34 @@ // if (m_fileHeader.m_zone < -12 || m_fileHeader.m_zone > 12) { - return true; + m_file.setstate (std::ios::failbit); } - m_haveFileHeader = true; - return false; + if (m_file.fail ()) + { + m_file.close (); + } } -bool -PcapFile::Open (std::string const &filename, std::string const &mode) +void +PcapFile::Open (std::string const &filename, std::ios::openmode mode) { - // - // If opening a new file, implicit close of any existing file required. - // - Close (); - + NS_ASSERT ((mode & std::ios::app) == 0); + NS_ASSERT (!m_file.fail ()); // // All pcap files are binary files, so we just do this automatically. // - std::string realMode = mode + "b"; + mode |= std::ios::binary; - // - // Our modes may be subtly different from the standard fopen semantics since - // we need to have a pcap file header to succeed in some cases; so we need - // to process different modes according to our own definitions of the modes. - // - // In the case of read modes, we must read, check and save the pcap file - // header as well as just opening the file. - // - // In the case of write modes, we just pass the call on through to the - // library. - // - // In the case of append modes, we change the semantics to require the - // given file to exist. We can't just create a file since we can't make up - // a pcap file header on our own. - // - if (realMode == "rb" || realMode == "r+b") + m_file.open (filename.c_str (), mode); + if (mode & std::ios::in) { - m_filePtr = fopen (filename.c_str (), realMode.c_str ()); - if (m_filePtr == 0) - { - return true; - } - m_filename = filename; - return ReadAndVerifyFileHeader (); - } - else if (realMode == "wb" || realMode == "w+b") - { - m_filePtr = fopen (filename.c_str (), realMode.c_str ()); - if (m_filePtr) - { - m_filename = filename; - return false; - } - else - { - return true; - } - } - else if (realMode == "ab" || realMode == "a+b") - { - // - // Remember that semantics for append are different here. We never create - // a file since we can't make up a pcap file header. We first have to - // open the file in read-only mode and check to see that it exists and - // read the file header. If this all works out, then we can go ahead and - // open the file in append mode and seek to the end (imlicitly). - // - m_filePtr = fopen (filename.c_str (), "rb"); - if (m_filePtr == 0) - { - return true; - } - - bool result = ReadAndVerifyFileHeader (); - if (result == true) - { - Close (); - return true; - } - - // - // We have a properly initialized file and have the pcap file header - // loaded and checked. This means that the file meets all of the - // critera for opening in append mode, but the file is in read-only mode - // now -- we must close it and open it in the correct mode. - // - fclose (m_filePtr); - m_filePtr = 0; - - m_filePtr = fopen (filename.c_str (), realMode.c_str ()); - if (m_filePtr == 0) - { - return true; - } - - m_filename = filename; - return false; - } - else - { - return true; + // will set the fail bit if file header is invalid. + ReadAndVerifyFileHeader (); } } -bool +void PcapFile::Init (uint32_t dataLinkType, uint32_t snapLen, int32_t timeZoneCorrection, bool swapMode) { // @@ -397,8 +305,6 @@ m_fileHeader.m_snapLen = snapLen; m_fileHeader.m_type = dataLinkType; - m_haveFileHeader = true; - // // We use pcap files for regression testing. We do byte-for-byte comparisons // in those tests to determine pass or fail. If we allow big endian systems @@ -426,16 +332,13 @@ // m_swapMode = swapMode | bigEndian; - return WriteFileHeader (); + WriteFileHeader (); } -bool -PcapFile::Write (uint32_t tsSec, uint32_t tsUsec, uint8_t const * const data, uint32_t totalLen) +uint32_t +PcapFile::WritePacketHeader (uint32_t tsSec, uint32_t tsUsec, uint32_t totalLen) { - if (m_haveFileHeader == false) - { - return true; - } + NS_ASSERT (m_file.good ()); uint32_t inclLen = totalLen > m_fileHeader.m_snapLen ? m_fileHeader.m_snapLen : totalLen; @@ -454,19 +357,44 @@ // Watch out for memory alignment differences between machines, so write // them all individually. // - uint32_t result = 0; - - result |= (fwrite (&header.m_tsSec, sizeof(header.m_tsSec), 1, m_filePtr) != 1); - result |= (fwrite (&header.m_tsUsec, sizeof(header.m_tsUsec), 1, m_filePtr) != 1); - result |= (fwrite (&header.m_inclLen, sizeof(header.m_inclLen), 1, m_filePtr) != 1); - result |= (fwrite (&header.m_origLen, sizeof(header.m_origLen), 1, m_filePtr) != 1); - - result |= fwrite (data, 1, inclLen, m_filePtr) != inclLen; - - return result != 0; + m_file.write ((const char *)&header.m_tsSec, sizeof(header.m_tsSec)); + m_file.write ((const char *)&header.m_tsUsec, sizeof(header.m_tsUsec)); + m_file.write ((const char *)&header.m_inclLen, sizeof(header.m_inclLen)); + m_file.write ((const char *)&header.m_origLen, sizeof(header.m_origLen)); + return inclLen; } -bool +void +PcapFile::Write (uint32_t tsSec, uint32_t tsUsec, uint8_t const * const data, uint32_t totalLen) +{ + uint32_t inclLen = WritePacketHeader (tsSec, tsUsec, totalLen); + m_file.write ((const char *)data, inclLen); +} + +void +PcapFile::Write (uint32_t tsSec, uint32_t tsUsec, Ptr p) +{ + uint32_t inclLen = WritePacketHeader (tsSec, tsUsec, p->GetSize ()); + p->CopyData (&m_file, inclLen); +} + +void +PcapFile::Write (uint32_t tsSec, uint32_t tsUsec, Header &header, Ptr p) +{ + uint32_t headerSize = header.GetSerializedSize (); + uint32_t totalSize = headerSize + p->GetSize (); + uint32_t inclLen = WritePacketHeader (tsSec, tsUsec, totalSize); + + Buffer headerBuffer; + headerBuffer.AddAtStart (headerSize); + header.Serialize (headerBuffer.Begin ()); + uint32_t toCopy = std::min (headerSize, inclLen); + headerBuffer.CopyData (&m_file, toCopy); + inclLen -= toCopy; + p->CopyData (&m_file, inclLen); +} + +void PcapFile::Read ( uint8_t * const data, uint32_t maxBytes, @@ -476,10 +404,7 @@ uint32_t &origLen, uint32_t &readLen) { - if (m_haveFileHeader == false) - { - return true; - } + NS_ASSERT (m_file.good ()); PcapRecordHeader header; @@ -487,21 +412,10 @@ // Watch out for memory alignment differences between machines, so read // them all individually. // - uint32_t result = 0; - - result |= (fread (&header.m_tsSec, sizeof(header.m_tsSec), 1, m_filePtr) != 1); - result |= (fread (&header.m_tsUsec, sizeof(header.m_tsUsec), 1, m_filePtr) != 1); - result |= (fread (&header.m_inclLen, sizeof(header.m_inclLen), 1, m_filePtr) != 1); - result |= (fread (&header.m_origLen, sizeof(header.m_origLen), 1, m_filePtr) != 1); - - // - // If any of the freads above did not succeed in reading the correct number of - // objects, result will be nonzero. - // - if (result) - { - return true; - } + m_file.read ((char *)&header.m_tsSec, sizeof(header.m_tsSec)); + m_file.read ((char *)&header.m_tsUsec, sizeof(header.m_tsUsec)); + m_file.read ((char *)&header.m_inclLen, sizeof(header.m_inclLen)); + m_file.read ((char *)&header.m_origLen, sizeof(header.m_origLen)); if (m_swapMode) { @@ -521,11 +435,7 @@ // for example, to figure out what is going on. // readLen = maxBytes < header.m_inclLen ? maxBytes : header.m_inclLen; - result = fread (data, 1, readLen, m_filePtr) != readLen; - if (result) - { - return result; - } + m_file.read ((char *)data, readLen); // // To keep the file pointer pointed in the right place, however, we always @@ -533,15 +443,8 @@ // if (readLen < header.m_inclLen) { - uint64_t pos = ftell (m_filePtr); - int result = fseek (m_filePtr, pos + header.m_inclLen - readLen, SEEK_SET); - if (result) - { - return true; - } + m_file.seekg (header.m_inclLen - readLen, std::ios::cur); } - - return false; } bool @@ -549,59 +452,58 @@ uint32_t & sec, uint32_t & usec, uint32_t snapLen) { - PcapFile pcap[2]; - for (int i = 0; i < 2; ++i) + PcapFile pcap1, pcap2; + pcap1.Open (f1, std::ios::in); + pcap2.Open (f2, std::ios::in); + bool bad = pcap1.Fail () || pcap2.Fail (); + if (bad) { - std::string const & file = (i == 0) ? f1 : f2; - bool err = pcap[i].Open (file, "r"); - if (err) - { - // Can't open file - return true; - } + return true; } - uint8_t data[2][snapLen]; - uint32_t tsSec[2], tsUsec[2], inclLen[2], origLen[2], readLen[2]; - bool err[2]; - bool diff(false); + uint8_t *data1 = new uint8_t [snapLen] (); + uint8_t *data2 = new uint8_t [snapLen] (); + uint32_t tsSec1, tsSec2; + uint32_t tsUsec1, tsUsec2; + uint32_t inclLen1, inclLen2; + uint32_t origLen1, origLen2; + uint32_t readLen1, readLen2; + bool diff = false; - while (1) + while (!pcap1.Eof () && !pcap2.Eof () + && !pcap1.Fail () && !pcap2.Fail ()) { - for (int i = 0; i < 2; ++i) - err[i] = pcap[i].Read (data[i], snapLen, tsSec[i], tsUsec[i], inclLen[i], origLen[i], readLen[i]); - - sec = tsSec[0]; - usec = tsUsec[0]; - - if (err[0] != err[1]) - { - diff = true; // Read status doesn't match - break; - } - - if (err[0]) break; // nothing left - - if (tsSec[0] != tsSec[1] || tsUsec[0] != tsUsec[1]) + pcap1.Read (data1, snapLen, tsSec1, tsUsec1, inclLen1, origLen1, readLen1); + pcap2.Read (data2, snapLen, tsSec2, tsUsec2, inclLen2, origLen2, readLen2); + + if (tsSec1 != tsSec2 || tsUsec1 != tsUsec2) { diff = true; // Next packet timestamps do not match break; } - if (readLen[0] != readLen[1]) + if (readLen1 != readLen2) { diff = true; // Packet lengths do not match break; } - if (std::memcmp(data[0], data[1], readLen[0]) != 0) + if (std::memcmp(data1, data2, readLen1) != 0) { diff = true; // Packet data do not match break; } } - pcap[0].Close (); - pcap[1].Close (); + sec = tsSec1; + usec = tsUsec1; + + bad = pcap1.Fail () || pcap2.Fail (); + bool eof = pcap1.Eof () && pcap2.Eof (); + if (bad && !eof) + { + diff = true; + } + return diff; } diff -r cd0d8ba00e6c src/common/pcap-file.h --- a/src/common/pcap-file.h Thu Apr 08 13:39:07 2010 +0200 +++ b/src/common/pcap-file.h Wed Apr 14 08:47:33 2010 +0200 @@ -22,10 +22,15 @@ #define PCAP_FILE_H #include +#include #include +#include "ns3/ptr.h" namespace ns3 { +class Packet; +class Header; + /* * A class representing a pcap file. This allows easy creation, writing and * reading of files composed of stored packets; which may be viewed using @@ -43,67 +48,35 @@ ~PcapFile (); /** + * \return true if the 'fail' bit is set in the underlying iostream, false otherwise. + */ + bool Fail (void) const; + /** + * \return true if the 'eof' bit is set in the underlying iostream, false otherwise. + */ + bool Eof (void) const; + /** + * Clear all state bits of the underlying iostream. + */ + void Clear (void); + + /** * Create a new pcap file or open an existing pcap file. Semantics are - * similar to the C standard library function \c fopen, but differ in that + * similar to the stdc++ io stream classes, but differ in that * positions in the file are based on packets not characters. For example * if the file is opened for reading, the file position indicator (seek * position) points to the beginning of the first packet in the file, not * zero (which would point to the start of the pcap header). * - * Possible modes are: - * - * \verbatim - * "r": Open a file for reading. The file must exist. The pcap header - * is assumed to exist in the file and will be read and checked. - * The file seek position indicator is set to point to the first - * packet on exit. - * - * "w": Create an empty file for writing. If a file with the same name - * already exists its content is erased and the file is treated as a - * new empty pcap file. The file is assumed not to have a pcap - * header and the caller is responsible for calling Init before saving - * any packet data. The file seek position indicator is set to point - * to the beginning of the file on exit since there will be no pcap - * header. - * - * "a": Append to an existing file. This mode allows for adding packet data - * to the end of an existing pcap file. The file must exist and have a - * valid pcap header written (N.B. this is different from standard fopen - * semantics). The file seek position indicator is set to point - * to the end of the file on exit. - * - * "r+": Open a file for update -- both reading and writing. The file must - * exist. The pcap header is assumed to have been written to the - * file and will be read and checked. The file seek position indicator - * is set to point to the first packet on exit. - * - * "w+": Create an empty file for both reading and writing. If a file with - * the same name already exists, its content is erased and the file is - * treated as a new empty pcap file. Since this new file will not have - * a pcap header, the caller is responsible for calling Init before - * saving any packet data. On exit, the file seek position indicator is - * set to point to the beginning of the file. - * - * "a+" Open a file for reading and appending. The file must exist and have a - * valid pcap header written (N.B. this is different from standard fopen - * semantics). The file seek position indicator is set to point - * to the end of the file on exit. Existing content is preserved. - * \endverbatim - * * Since a pcap file is always a binary file, the file type is automatically - * selected as a binary file. For example, providing a mode string "a+" - * results in the underlying OS file being opened in "a+b" mode. + * selected as a binary file (fstream::binary is automatically ored with the mode + * field). * * \param filename String containing the name of the file. * - * \param mode String containing the access mode for the file. - * - * \returns Error indication that should be interpreted as, "did an error - * happen"? That is, the method returns false if the open succeeds, true - * otherwise. The errno variable will be set by the OS to to provide a - * more descriptive failure indication. + * \param mode the access mode for the file. */ - bool Open (std::string const &filename, std::string const &mode); + void Open (std::string const &filename, std::ios::openmode mode); /** * Close the underlying file. @@ -138,7 +111,7 @@ * \warning Calling this method on an existing file will result in the loss * any existing data. */ - bool Init (uint32_t dataLinkType, + void Init (uint32_t dataLinkType, uint32_t snapLen = SNAPLEN_DEFAULT, int32_t timeZoneCorrection = ZONE_DEFAULT, bool swapMode = false); @@ -151,9 +124,29 @@ * \param data Data buffer * \param totalLen Total packet length * - * \return true on error, false otherwise */ - bool Write (uint32_t tsSec, uint32_t tsUsec, uint8_t const * const data, uint32_t totalLen); + void Write (uint32_t tsSec, uint32_t tsUsec, uint8_t const * const data, uint32_t totalLen); + + /** + * \brief Write next packet to file + * + * \param tsSec Packet timestamp, seconds + * \param tsUsec Packet timestamp, microseconds + * \param p Packet to write + * + */ + void Write (uint32_t tsSec, uint32_t tsUsec, Ptr p); + /** + * \brief Write next packet to file + * + * \param tsSec Packet timestamp, seconds + * \param tsUsec Packet timestamp, microseconds + * \param header Header to write, in front of packet + * \param p Packet to write + * + */ + void Write (uint32_t tsSec, uint32_t tsUsec, Header &header, Ptr p); + /** * \brief Read next packet from file @@ -166,9 +159,8 @@ * \param origLen [out] Original length * \param readLen [out] Number of bytes read * - * \return true if read failed, false otherwise */ - bool Read (uint8_t * const data, + void Read (uint8_t * const data, uint32_t maxBytes, uint32_t &tsSec, uint32_t &tsUsec, @@ -290,13 +282,13 @@ void Swap (PcapFileHeader *from, PcapFileHeader *to); void Swap (PcapRecordHeader *from, PcapRecordHeader *to); - bool WriteFileHeader (void); - bool ReadAndVerifyFileHeader (void); + void WriteFileHeader (void); + uint32_t WritePacketHeader (uint32_t tsSec, uint32_t tsUsec, uint32_t totalLen); + void ReadAndVerifyFileHeader (void); std::string m_filename; - FILE *m_filePtr; + std::fstream m_file; PcapFileHeader m_fileHeader; - bool m_haveFileHeader; bool m_swapMode; }; diff -r cd0d8ba00e6c src/helper/csma-helper.cc --- a/src/helper/csma-helper.cc Thu Apr 08 13:39:07 2010 +0200 +++ b/src/helper/csma-helper.cc Wed Apr 14 08:47:33 2010 +0200 @@ -98,7 +98,8 @@ filename = pcapHelper.GetFilenameFromDevice (prefix, device); } - Ptr file = pcapHelper.CreateFile (filename, "w", PcapHelper::DLT_EN10MB); + Ptr file = pcapHelper.CreateFile (filename, std::ios::out, + PcapHelper::DLT_EN10MB); if (promiscuous) { pcapHelper.HookDefaultSink (device, "PromiscSniffer", file); @@ -159,7 +160,7 @@ filename = asciiTraceHelper.GetFilenameFromDevice (prefix, device); } - Ptr theStream = asciiTraceHelper.CreateFileStream (filename, "w"); + Ptr theStream = asciiTraceHelper.CreateFileStream (filename); // // The MacRx trace source provides our "r" event. diff -r cd0d8ba00e6c src/helper/emu-helper.cc --- a/src/helper/emu-helper.cc Thu Apr 08 13:39:07 2010 +0200 +++ b/src/helper/emu-helper.cc Wed Apr 14 08:47:33 2010 +0200 @@ -91,7 +91,7 @@ filename = pcapHelper.GetFilenameFromDevice (prefix, device); } - Ptr file = pcapHelper.CreateFile (filename, "w", PcapHelper::DLT_EN10MB); + Ptr file = pcapHelper.CreateFile (filename, std::ios::out, PcapHelper::DLT_EN10MB); if (promiscuous) { pcapHelper.HookDefaultSink (device, "PromiscSniffer", file); @@ -152,7 +152,7 @@ filename = asciiTraceHelper.GetFilenameFromDevice (prefix, device); } - Ptr theStream = asciiTraceHelper.CreateFileStream (filename, "w"); + Ptr theStream = asciiTraceHelper.CreateFileStream (filename); // // The MacRx trace source provides our "r" event. diff -r cd0d8ba00e6c src/helper/internet-stack-helper.cc --- a/src/helper/internet-stack-helper.cc Thu Apr 08 13:39:07 2010 +0200 +++ b/src/helper/internet-stack-helper.cc Wed Apr 14 08:47:33 2010 +0200 @@ -470,7 +470,7 @@ filename = pcapHelper.GetFilenameFromInterfacePair (prefix, ipv4, interface); } - Ptr file = pcapHelper.CreateFile (filename, "w", PcapHelper::DLT_RAW); + Ptr file = pcapHelper.CreateFile (filename, std::ios::out, PcapHelper::DLT_RAW); // // However, we only hook the trace source once to avoid multiple trace sink @@ -562,7 +562,7 @@ filename = pcapHelper.GetFilenameFromInterfacePair (prefix, ipv6, interface); } - Ptr file = pcapHelper.CreateFile (filename, "w", PcapHelper::DLT_RAW); + Ptr file = pcapHelper.CreateFile (filename, std::ios::out, PcapHelper::DLT_RAW); // // However, we only hook the trace source once to avoid multiple trace sink @@ -714,7 +714,7 @@ filename = asciiTraceHelper.GetFilenameFromInterfacePair (prefix, ipv4, interface); } - Ptr theStream = asciiTraceHelper.CreateFileStream (filename, "w"); + Ptr theStream = asciiTraceHelper.CreateFileStream (filename); // // However, we only hook the trace sources once to avoid multiple trace sink @@ -909,7 +909,7 @@ filename = asciiTraceHelper.GetFilenameFromInterfacePair (prefix, ipv6, interface); } - Ptr theStream = asciiTraceHelper.CreateFileStream (filename, "w"); + Ptr theStream = asciiTraceHelper.CreateFileStream (filename); // // However, we only hook the trace sources once to avoid multiple trace sink diff -r cd0d8ba00e6c src/helper/point-to-point-helper.cc --- a/src/helper/point-to-point-helper.cc Thu Apr 08 13:39:07 2010 +0200 +++ b/src/helper/point-to-point-helper.cc Wed Apr 14 08:47:33 2010 +0200 @@ -99,7 +99,8 @@ filename = pcapHelper.GetFilenameFromDevice (prefix, device); } - Ptr file = pcapHelper.CreateFile (filename, "w", PcapHelper::DLT_PPP); + Ptr file = pcapHelper.CreateFile (filename, std::ios::out, + PcapHelper::DLT_PPP); pcapHelper.HookDefaultSink (device, "PromiscSniffer", file); } @@ -154,7 +155,7 @@ filename = asciiTraceHelper.GetFilenameFromDevice (prefix, device); } - Ptr theStream = asciiTraceHelper.CreateFileStream (filename, "w"); + Ptr theStream = asciiTraceHelper.CreateFileStream (filename); // // The MacRx trace source provides our "r" event. diff -r cd0d8ba00e6c src/helper/trace-helper.cc --- a/src/helper/trace-helper.cc Thu Apr 08 13:39:07 2010 +0200 +++ b/src/helper/trace-helper.cc Wed Apr 14 08:47:33 2010 +0200 @@ -48,7 +48,7 @@ Ptr PcapHelper::CreateFile ( std::string filename, - std::string filemode, + std::ios::openmode filemode, uint32_t dataLinkType, uint32_t snapLen, int32_t tzCorrection) @@ -56,11 +56,11 @@ NS_LOG_FUNCTION (filename << filemode << dataLinkType << snapLen << tzCorrection); Ptr file = CreateObject (); - bool err = file->Open (filename, filemode); - NS_ABORT_MSG_IF (err, "Unable to Open " << filename << " for mode " << filemode); + file->Open (filename, filemode); + NS_ABORT_MSG_IF (file->Fail (), "Unable to Open " << filename << " for mode " << filemode); - err = file->Init (dataLinkType, snapLen, tzCorrection); - NS_ABORT_MSG_IF (err, "Unable to Init " << filename); + file->Init (dataLinkType, snapLen, tzCorrection); + NS_ABORT_MSG_IF (file->Fail (), "Unable to Init " << filename); // // Note that the pcap helper promptly forgets all about the pcap file. We @@ -181,27 +181,13 @@ } Ptr -AsciiTraceHelper::CreateFileStream (std::string filename, std::string filemode) +AsciiTraceHelper::CreateFileStream (std::string filename, std::ios::openmode filemode) { NS_LOG_FUNCTION (filename << filemode); std::ofstream *ofstream = new std::ofstream; - std::ios_base::openmode mode = std::ios_base::out | std::ios_base::trunc; - if (filemode == "a") - { - mode = std::ios_base::out | std::ios_base::app; - } - else if (filemode == "w") - { - mode = std::ios_base::out | std::ios_base::trunc; - } - else - { - NS_ABORT_MSG ("AsciiTraceHelper::CreateFileStream(): Unexpected file mode"); - } - - ofstream->open (filename.c_str (), mode); + ofstream->open (filename.c_str (), filemode); NS_ABORT_MSG_UNLESS (ofstream->is_open (), "AsciiTraceHelper::CreateFileStream(): Unable to Open " << filename << " for mode " << filemode); diff -r cd0d8ba00e6c src/helper/trace-helper.h --- a/src/helper/trace-helper.h Thu Apr 08 13:39:07 2010 +0200 +++ b/src/helper/trace-helper.h Wed Apr 14 08:47:33 2010 +0200 @@ -84,7 +84,7 @@ /** * @brief Create and initialize a pcap file. */ - Ptr CreateFile (std::string filename, std::string filemode, + Ptr CreateFile (std::string filename, std::ios::openmode filemode, uint32_t dataLinkType, uint32_t snapLen = 65535, int32_t tzCorrection = 0); /** * @brief Hook a trace source to the default trace sink @@ -156,7 +156,8 @@ * that can solve the problem so we use one of those to carry the stream * around and deal with the lifetime issues. */ - Ptr CreateFileStream (std::string filename, std::string filemode = "w"); + Ptr CreateFileStream (std::string filename, + std::ios::openmode filemode = std::ios::out); /** * @brief Hook a trace source to the default enqueue operation trace sink that diff -r cd0d8ba00e6c src/helper/wimax-helper.cc --- a/src/helper/wimax-helper.cc Thu Apr 08 13:39:07 2010 +0200 +++ b/src/helper/wimax-helper.cc Wed Apr 14 08:47:33 2010 +0200 @@ -480,7 +480,7 @@ { filename = asciiTraceHelper.GetFilenameFromDevice (prefix, device); } - Ptr theStream = asciiTraceHelper.CreateFileStream (filename, "w"); + Ptr theStream = asciiTraceHelper.CreateFileStream (filename); uint32_t nodeid = nd->GetNode ()->GetId (); uint32_t deviceid = nd->GetIfIndex (); @@ -586,7 +586,7 @@ filename = pcapHelper.GetFilenameFromDevice (prefix, device); } - Ptr file = pcapHelper.CreateFile (filename, "w", PcapHelper::DLT_EN10MB); + Ptr file = pcapHelper.CreateFile (filename, std::ios::out, PcapHelper::DLT_EN10MB); phy->TraceConnectWithoutContext ("Tx", MakeBoundCallback (&PcapSniffTxEvent, file)); phy->TraceConnectWithoutContext ("Rx", MakeBoundCallback (&PcapSniffRxEvent, file)); diff -r cd0d8ba00e6c src/helper/yans-wifi-helper.cc --- a/src/helper/yans-wifi-helper.cc Thu Apr 08 13:39:07 2010 +0200 +++ b/src/helper/yans-wifi-helper.cc Wed Apr 14 08:47:33 2010 +0200 @@ -409,7 +409,7 @@ filename = pcapHelper.GetFilenameFromDevice (prefix, device); } - Ptr file = pcapHelper.CreateFile (filename, "w", m_pcapDlt); + Ptr file = pcapHelper.CreateFile (filename, std::ios::out, m_pcapDlt); phy->TraceConnectWithoutContext ("PromiscSnifferTx", MakeBoundCallback (&PcapSniffTxEvent, file)); phy->TraceConnectWithoutContext ("PromiscSnifferRx", MakeBoundCallback (&PcapSniffRxEvent, file));