From 7531f592585a7e5c916de6933bb80c7d49f33d85 Mon Sep 17 00:00:00 2001 From: Kirill Andreev Date: Tue, 27 Oct 2009 18:43:45 +0300 Subject: [PATCH 1/2] Mesh: fixed FLAME PATH_UPDATE procedure, fixed mesh.cc, valgrind errors in FLAME --- examples/mesh/mesh.cc | 11 ++++++- src/devices/mesh/flame/flame-protocol-mac.cc | 2 ++ src/devices/mesh/flame/flame-protocol.cc | 33 +++++++++++++------- 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/examples/mesh/mesh.cc b/examples/mesh/mesh.cc index fa42ae62b..866b28a33 100644 --- a/examples/mesh/mesh.cc +++ b/examples/mesh/mesh.cc @@ -158,7 +158,16 @@ MeshTest::CreateNodes () * mesh point device */ mesh = MeshHelper::Default (); - mesh.SetStackInstaller (m_stack, "Root", Mac48AddressValue (Mac48Address (m_root.c_str ()))); + if (!Mac48Address (m_root.c_str ()).IsBroadcast ()) + { + mesh.SetStackInstaller (m_stack, "Root", Mac48AddressValue (Mac48Address (m_root.c_str ()))); + } + else + { + //If root is not set, we do not use "Root" attribute, because it + //is specified only for 11s + mesh.SetStackInstaller (m_stack); + } if (m_chan) { mesh.SetSpreadInterfaceChannels (MeshHelper::SPREAD_CHANNELS); diff --git a/src/devices/mesh/flame/flame-protocol-mac.cc b/src/devices/mesh/flame/flame-protocol-mac.cc index f9b6650c5..d1a047a4a 100644 --- a/src/devices/mesh/flame/flame-protocol-mac.cc +++ b/src/devices/mesh/flame/flame-protocol-mac.cc @@ -31,6 +31,8 @@ FlameProtocolMac::FlameProtocolMac (uint32_t ifIndex, Ptr protoco } FlameProtocolMac::~FlameProtocolMac () { + m_protocol = 0; + m_parent = 0; } void FlameProtocolMac::SetParent (Ptr parent) diff --git a/src/devices/mesh/flame/flame-protocol.cc b/src/devices/mesh/flame/flame-protocol.cc index d0bd251f0..8a0ebbdf2 100644 --- a/src/devices/mesh/flame/flame-protocol.cc +++ b/src/devices/mesh/flame/flame-protocol.cc @@ -127,7 +127,7 @@ FlameProtocol::GetTypeId () return tid; } FlameProtocol::FlameProtocol () : - m_address (Mac48Address ()), m_broadcastInterval (Seconds (5)), m_lastBroadcast (Simulator::Now ()), + m_address (Mac48Address ()), m_broadcastInterval (Seconds (5)), m_lastBroadcast (Seconds (0)), m_maxCost (32), m_myLastSeqno (1), m_rtable (CreateObject ()) { } @@ -137,6 +137,9 @@ FlameProtocol::~FlameProtocol () void FlameProtocol::DoDispose () { + m_interfaces.clear (); + m_rtable = 0; + m_mp = 0; } bool FlameProtocol::RequestRoute (uint32_t sourceIface, const Mac48Address source, const Mac48Address destination, @@ -224,8 +227,12 @@ FlameProtocol::RequestRoute (uint32_t sourceIface, const Mac48Address source, co m_stats.totalDropped++; return false; } + tag.receiver = result.retransmitter; + } + else + { + tag.receiver = Mac48Address::GetBroadcast (); } - tag.receiver = result.retransmitter; if (result.retransmitter == Mac48Address::GetBroadcast ()) { m_stats.txBroadcast++; @@ -262,19 +269,21 @@ FlameProtocol::RemoveRoutingStuff (uint32_t fromIface, const Mac48Address source } FlameHeader flameHdr; packet->RemoveHeader (flameHdr); - if ((destination == GetAddress ()) && (m_lastBroadcast + m_broadcastInterval < Simulator::Now ())) - { - Ptr packet = Create (); - m_mp->Send(packet, Mac48Address::GetBroadcast (), 0); - m_lastBroadcast = Simulator::Now (); - } - NS_ASSERT (protocolType == FLAME_PROTOCOL); - protocolType = flameHdr.GetProtocol (); - if ((HandleDataFrame (flameHdr.GetSeqno (), source, flameHdr, tag.transmitter, fromIface)) - || packet->GetSize () == 0) + if (HandleDataFrame (flameHdr.GetSeqno (), source, flameHdr, tag.transmitter, fromIface)) { return false; } + // Start PATH_UPDATE procedure if destination is our own address and last broadcast was sent more + // than broadcast interval ago or was not sent at all + if ((destination == GetAddress ()) && ((m_lastBroadcast + m_broadcastInterval < Simulator::Now ()) + || (m_lastBroadcast == Seconds (0)))) + { + Ptr packet = Create (); + m_mp->Send (packet, Mac48Address::GetBroadcast (), 0); + m_lastBroadcast = Simulator::Now (); + } + NS_ASSERT (protocolType == FLAME_PROTOCOL); + protocolType = flameHdr.GetProtocol (); return true; } bool From 663d74325791b5db0becd75a175606f4184ff8bd Mon Sep 17 00:00:00 2001 From: Pavel Boyko Date: Wed, 28 Oct 2009 11:43:57 +0300 Subject: [PATCH 2/2] Pcap::Diff() method added to compare PCAP traces packet-by-packet --- src/common/pcap-file-test-suite.cc | 59 +++++++++++++++++++++++++++ src/common/pcap-file.cc | 65 +++++++++++++++++++++++++++++- src/common/pcap-file.h | 42 ++++++++++++++++++- 3 files changed, 164 insertions(+), 2 deletions(-) diff --git a/src/common/pcap-file-test-suite.cc b/src/common/pcap-file-test-suite.cc index 6a9e3903f..d71c19b31 100644 --- a/src/common/pcap-file-test-suite.cc +++ b/src/common/pcap-file-test-suite.cc @@ -12,6 +12,8 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Craig Dowell (craigdo@ee.washington.edu) */ #include @@ -948,6 +950,62 @@ ReadFileTestCase::DoRun (void) return false; } +// =========================================================================== +// Test case to make sure that the Pcap::Diff method works as expected +// =========================================================================== +class DiffTestCase : public TestCase +{ +public: + DiffTestCase (); + +private: + virtual bool DoRun (void); +}; + +DiffTestCase::DiffTestCase () + : TestCase ("Check that PcapFile::Diff works as expected") +{ +} + +bool +DiffTestCase::DoRun (void) +{ + // + // Check that PcapDiff(file, file) is false + // + std::string filename = NS_TEST_SOURCEDIR + "known.pcap"; + uint32_t sec(0), usec(0); + bool diff = PcapFile::Diff (filename, filename, sec, usec); + NS_TEST_EXPECT_MSG_EQ (diff, false, "PcapDiff(file, file) must always be false"); + + // + // Create different PCAP file (with the same timestamps, but different packets) and check that it is indeed different + // + 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"); + + 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.Close (); + + diff = PcapFile::Diff (filename, filename2, sec, usec); + NS_TEST_EXPECT_MSG_EQ (diff, true, "PcapDiff(file, file2) must be true"); + NS_TEST_EXPECT_MSG_EQ (sec, 2, "Files are different from 2.3696 seconds"); + NS_TEST_EXPECT_MSG_EQ (usec, 3696, "Files are different from 2.3696 seconds"); + + return GetErrorStatus(); +} + class PcapFileTestSuite : public TestSuite { public: @@ -963,6 +1021,7 @@ PcapFileTestSuite::PcapFileTestSuite () AddTestCase (new FileHeaderTestCase); AddTestCase (new RecordHeaderTestCase); AddTestCase (new ReadFileTestCase); + AddTestCase (new DiffTestCase); } PcapFileTestSuite pcapFileTestSuite; diff --git a/src/common/pcap-file.cc b/src/common/pcap-file.cc index c652d9808..e55e9da10 100644 --- a/src/common/pcap-file.cc +++ b/src/common/pcap-file.cc @@ -14,14 +14,16 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Craig Dowell (craigdo@ee.washington.edu) */ #include #include #include +#include #include "pcap-file.h" - // // This file is used as part of the ns-3 test framework, so please refrain from // adding any ns-3 specific constructs such as Packet to this file. @@ -516,4 +518,65 @@ PcapFile::Read ( return false; } +bool +PcapFile::Diff (std::string const & f1, std::string const & f2, + uint32_t & sec, uint32_t & usec, + uint32_t snapLen) +{ + PcapFile pcap[2]; + for (int i = 0; i < 2; ++i) + { + std::string const & file = (i == 0) ? f1 : f2; + bool err = pcap[i].Open (file, "r"); + if (err) + { + // Can't open file + 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); + + while (1) + { + 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]) + { + diff = true; // Next packet timestamps do not match + break; + } + + if (readLen[0] != readLen[1]) + { + diff = true; // Packet lengths do not match + break; + } + + if (std::memcmp(data[0], data[1], readLen[0]) != 0) + { + diff = true; // Packet data do not match + break; + } + } + pcap[0].Close (); + pcap[1].Close (); + return diff; +} + } //namespace ns3 diff --git a/src/common/pcap-file.h b/src/common/pcap-file.h index 2e9fe03e7..648766965 100644 --- a/src/common/pcap-file.h +++ b/src/common/pcap-file.h @@ -14,6 +14,8 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Craig Dowell (craigdo@ee.washington.edu) */ #ifndef PCAP_FILE_H @@ -125,7 +127,7 @@ public: * 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). * - * \returns false if the open succeeds, true otherwise. + * \return false if the open succeeds, true otherwise. * * \warning Calling this method on an existing file will result in the loss * any existing data. @@ -135,8 +137,31 @@ public: int32_t timeZoneCorrection = ZONE_DEFAULT, bool swapMode = false); + /** + * \brief Write next packet to file + * + * \param tsSec Packet timestamp, seconds + * \param tsUsec Packet timestamp, microseconds + * \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); + /** + * \brief Read next packet from file + * + * \param data [out] Data buffer + * \param maxBytes Allocated data buffer size + * \param tsSec [out] Packet timestamp, seconds + * \param tsUsec [out] Packet timestamp, microseconds + * \param inclLen [out] Included length + * \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, uint32_t maxBytes, uint32_t &tsSec, @@ -154,6 +179,21 @@ public: uint32_t GetSigFigs (void); uint32_t GetSnapLen (void); uint32_t GetDataLinkType (void); + + /** + * \brief Compare two PCAP files packet-by-packet + * + * \return true if files are different, false otherwise + * + * \param f1 First PCAP file name + * \param f2 Second PCAP file name + * \param sec [out] Time stamp of first different packet, seconds. Undefined if files doesn't differ. + * \param uses [out] Time stamp of first different packet, microseconds. Undefined if files doesn't differ. + * \param snapLen Snap length (if used) + */ + static bool Diff (std::string const & f1, std::string const & f2, + uint32_t & sec, uint32_t & usec, + uint32_t snapLen = SNAPLEN_DEFAULT); private: typedef struct {