1.1 --- a/src/common/pcap-file-test-suite.cc Tue Oct 27 18:43:45 2009 +0300
1.2 +++ b/src/common/pcap-file-test-suite.cc Wed Oct 28 11:43:57 2009 +0300
1.3 @@ -12,6 +12,8 @@
1.4 * You should have received a copy of the GNU General Public License
1.5 * along with this program; if not, write to the Free Software
1.6 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1.7 + *
1.8 + * Author: Craig Dowell (craigdo@ee.washington.edu)
1.9 */
1.10
1.11 #include <iostream>
1.12 @@ -948,6 +950,62 @@
1.13 return false;
1.14 }
1.15
1.16 +// ===========================================================================
1.17 +// Test case to make sure that the Pcap::Diff method works as expected
1.18 +// ===========================================================================
1.19 +class DiffTestCase : public TestCase
1.20 +{
1.21 +public:
1.22 + DiffTestCase ();
1.23 +
1.24 +private:
1.25 + virtual bool DoRun (void);
1.26 +};
1.27 +
1.28 +DiffTestCase::DiffTestCase ()
1.29 + : TestCase ("Check that PcapFile::Diff works as expected")
1.30 +{
1.31 +}
1.32 +
1.33 +bool
1.34 +DiffTestCase::DoRun (void)
1.35 +{
1.36 + //
1.37 + // Check that PcapDiff(file, file) is false
1.38 + //
1.39 + std::string filename = NS_TEST_SOURCEDIR + "known.pcap";
1.40 + uint32_t sec(0), usec(0);
1.41 + bool diff = PcapFile::Diff (filename, filename, sec, usec);
1.42 + NS_TEST_EXPECT_MSG_EQ (diff, false, "PcapDiff(file, file) must always be false");
1.43 +
1.44 + //
1.45 + // Create different PCAP file (with the same timestamps, but different packets) and check that it is indeed different
1.46 + //
1.47 + std::string filename2 = "different.pcap";
1.48 + PcapFile f;
1.49 +
1.50 + bool err = f.Open (filename2, "w");
1.51 + NS_TEST_ASSERT_MSG_EQ (err, false, "Open (" << filename2 << ", \"w\") returns error");
1.52 + err = f.Init (1, N_PACKET_BYTES);
1.53 + NS_TEST_ASSERT_MSG_EQ (err, false, "Init (1, " << N_PACKET_BYTES << ") returns error");
1.54 +
1.55 + for (uint32_t i = 0; i < N_KNOWN_PACKETS; ++i)
1.56 + {
1.57 + PacketEntry const & p = knownPackets[i];
1.58 +
1.59 + err = f.Write (p.tsSec, p.tsUsec, (uint8_t const *)p.data, p.origLen);
1.60 + NS_TEST_EXPECT_MSG_EQ (err, false, "Write must not fail");
1.61 + }
1.62 + f.Close ();
1.63 +
1.64 + diff = PcapFile::Diff (filename, filename2, sec, usec);
1.65 + NS_TEST_EXPECT_MSG_EQ (diff, true, "PcapDiff(file, file2) must be true");
1.66 + NS_TEST_EXPECT_MSG_EQ (sec, 2, "Files are different from 2.3696 seconds");
1.67 + NS_TEST_EXPECT_MSG_EQ (usec, 3696, "Files are different from 2.3696 seconds");
1.68 +
1.69 + return GetErrorStatus();
1.70 +}
1.71 +
1.72 class PcapFileTestSuite : public TestSuite
1.73 {
1.74 public:
1.75 @@ -963,6 +1021,7 @@
1.76 AddTestCase (new FileHeaderTestCase);
1.77 AddTestCase (new RecordHeaderTestCase);
1.78 AddTestCase (new ReadFileTestCase);
1.79 + AddTestCase (new DiffTestCase);
1.80 }
1.81
1.82 PcapFileTestSuite pcapFileTestSuite;
2.1 --- a/src/common/pcap-file.cc Tue Oct 27 18:43:45 2009 +0300
2.2 +++ b/src/common/pcap-file.cc Wed Oct 28 11:43:57 2009 +0300
2.3 @@ -14,14 +14,16 @@
2.4 * You should have received a copy of the GNU General Public License
2.5 * along with this program; if not, write to the Free Software
2.6 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2.7 + *
2.8 + * Author: Craig Dowell (craigdo@ee.washington.edu)
2.9 */
2.10
2.11 #include <iostream>
2.12 #include <stdio.h>
2.13 #include <stdlib.h>
2.14 +#include <cstring>
2.15
2.16 #include "pcap-file.h"
2.17 -
2.18 //
2.19 // This file is used as part of the ns-3 test framework, so please refrain from
2.20 // adding any ns-3 specific constructs such as Packet to this file.
2.21 @@ -516,4 +518,65 @@
2.22 return false;
2.23 }
2.24
2.25 +bool
2.26 +PcapFile::Diff (std::string const & f1, std::string const & f2,
2.27 + uint32_t & sec, uint32_t & usec,
2.28 + uint32_t snapLen)
2.29 +{
2.30 + PcapFile pcap[2];
2.31 + for (int i = 0; i < 2; ++i)
2.32 + {
2.33 + std::string const & file = (i == 0) ? f1 : f2;
2.34 + bool err = pcap[i].Open (file, "r");
2.35 + if (err)
2.36 + {
2.37 + // Can't open file
2.38 + return true;
2.39 + }
2.40 + }
2.41 +
2.42 + uint8_t data[2][snapLen];
2.43 + uint32_t tsSec[2], tsUsec[2], inclLen[2], origLen[2], readLen[2];
2.44 + bool err[2];
2.45 + bool diff(false);
2.46 +
2.47 + while (1)
2.48 + {
2.49 + for (int i = 0; i < 2; ++i)
2.50 + err[i] = pcap[i].Read (data[i], snapLen, tsSec[i], tsUsec[i], inclLen[i], origLen[i], readLen[i]);
2.51 +
2.52 + sec = tsSec[0];
2.53 + usec = tsUsec[0];
2.54 +
2.55 + if (err[0] != err[1])
2.56 + {
2.57 + diff = true; // Read status doesn't match
2.58 + break;
2.59 + }
2.60 +
2.61 + if (err[0]) break; // nothing left
2.62 +
2.63 + if (tsSec[0] != tsSec[1] || tsUsec[0] != tsUsec[1])
2.64 + {
2.65 + diff = true; // Next packet timestamps do not match
2.66 + break;
2.67 + }
2.68 +
2.69 + if (readLen[0] != readLen[1])
2.70 + {
2.71 + diff = true; // Packet lengths do not match
2.72 + break;
2.73 + }
2.74 +
2.75 + if (std::memcmp(data[0], data[1], readLen[0]) != 0)
2.76 + {
2.77 + diff = true; // Packet data do not match
2.78 + break;
2.79 + }
2.80 + }
2.81 + pcap[0].Close ();
2.82 + pcap[1].Close ();
2.83 + return diff;
2.84 +}
2.85 +
2.86 } //namespace ns3
3.1 --- a/src/common/pcap-file.h Tue Oct 27 18:43:45 2009 +0300
3.2 +++ b/src/common/pcap-file.h Wed Oct 28 11:43:57 2009 +0300
3.3 @@ -14,6 +14,8 @@
3.4 * You should have received a copy of the GNU General Public License
3.5 * along with this program; if not, write to the Free Software
3.6 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3.7 + *
3.8 + * Author: Craig Dowell (craigdo@ee.washington.edu)
3.9 */
3.10
3.11 #ifndef PCAP_FILE_H
3.12 @@ -125,7 +127,7 @@
3.13 * time zone from UTC/GMT. For example, Pacific Standard Time in the US is
3.14 * GMT-8, so one would enter -8 for that correction. Defaults to 0 (UTC).
3.15 *
3.16 - * \returns false if the open succeeds, true otherwise.
3.17 + * \return false if the open succeeds, true otherwise.
3.18 *
3.19 * \warning Calling this method on an existing file will result in the loss
3.20 * any existing data.
3.21 @@ -135,8 +137,31 @@
3.22 int32_t timeZoneCorrection = ZONE_DEFAULT,
3.23 bool swapMode = false);
3.24
3.25 + /**
3.26 + * \brief Write next packet to file
3.27 + *
3.28 + * \param tsSec Packet timestamp, seconds
3.29 + * \param tsUsec Packet timestamp, microseconds
3.30 + * \param data Data buffer
3.31 + * \param totalLen Total packet length
3.32 + *
3.33 + * \return true on error, false otherwise
3.34 + */
3.35 bool Write (uint32_t tsSec, uint32_t tsUsec, uint8_t const * const data, uint32_t totalLen);
3.36
3.37 + /**
3.38 + * \brief Read next packet from file
3.39 + *
3.40 + * \param data [out] Data buffer
3.41 + * \param maxBytes Allocated data buffer size
3.42 + * \param tsSec [out] Packet timestamp, seconds
3.43 + * \param tsUsec [out] Packet timestamp, microseconds
3.44 + * \param inclLen [out] Included length
3.45 + * \param origLen [out] Original length
3.46 + * \param readLen [out] Number of bytes read
3.47 + *
3.48 + * \return true if read failed, false otherwise
3.49 + */
3.50 bool Read (uint8_t * const data,
3.51 uint32_t maxBytes,
3.52 uint32_t &tsSec,
3.53 @@ -154,6 +179,21 @@
3.54 uint32_t GetSigFigs (void);
3.55 uint32_t GetSnapLen (void);
3.56 uint32_t GetDataLinkType (void);
3.57 +
3.58 + /**
3.59 + * \brief Compare two PCAP files packet-by-packet
3.60 + *
3.61 + * \return true if files are different, false otherwise
3.62 + *
3.63 + * \param f1 First PCAP file name
3.64 + * \param f2 Second PCAP file name
3.65 + * \param sec [out] Time stamp of first different packet, seconds. Undefined if files doesn't differ.
3.66 + * \param uses [out] Time stamp of first different packet, microseconds. Undefined if files doesn't differ.
3.67 + * \param snapLen Snap length (if used)
3.68 + */
3.69 + static bool Diff (std::string const & f1, std::string const & f2,
3.70 + uint32_t & sec, uint32_t & usec,
3.71 + uint32_t snapLen = SNAPLEN_DEFAULT);
3.72
3.73 private:
3.74 typedef struct {