Add IPv6 packet support to data collection
authorTommaso Pecorella <tommaso.pecorella@unifi.it>
Sun, 11 Aug 2013 12:34:17 +0200
changeset 10125 49db55240008
parent 10124 8c67f59ab691
child 10126 9af31e6577bb
Add IPv6 packet support to data collection
examples/tutorial/seventh.cc
src/internet/model/ipv4-packet-probe.cc
src/internet/model/ipv6-packet-probe.cc
src/internet/model/ipv6-packet-probe.h
src/internet/wscript
src/stats/helper/file-helper.cc
src/stats/helper/gnuplot-helper.cc
--- a/examples/tutorial/seventh.cc	Sat Aug 10 16:55:31 2013 -0700
+++ b/examples/tutorial/seventh.cc	Sun Aug 11 12:34:17 2013 +0200
@@ -117,7 +117,14 @@
 {
   m_running = true;
   m_packetsSent = 0;
-  m_socket->Bind ();
+  if (InetSocketAddress::IsMatchingType (m_peer))
+    {
+      m_socket->Bind ();
+    }
+  else
+    {
+      m_socket->Bind6 ();
+    }
   m_socket->Connect (m_peer);
   SendPacket ();
 }
@@ -177,6 +184,12 @@
 int
 main (int argc, char *argv[])
 {
+  bool useV6 = false;
+
+  CommandLine cmd;
+  cmd.AddValue ("useIpv6", "Use Ipv6", useV6);
+  cmd.Parse (argc, argv);
+
   NodeContainer nodes;
   nodes.Create (2);
 
@@ -194,13 +207,33 @@
   InternetStackHelper stack;
   stack.Install (nodes);
 
-  Ipv4AddressHelper address;
-  address.SetBase ("10.1.1.0", "255.255.255.252");
-  Ipv4InterfaceContainer interfaces = address.Assign (devices);
+  uint16_t sinkPort = 8080;
+  Address sinkAddress;
+  Address anyAddress;
+  std::string probeName;
+  std::string probeTrace;
+  if (useV6 == false)
+    {
+      Ipv4AddressHelper address;
+      address.SetBase ("10.1.1.0", "255.255.255.0");
+      Ipv4InterfaceContainer interfaces = address.Assign (devices);
+      sinkAddress = InetSocketAddress (interfaces.GetAddress (1), sinkPort);
+      anyAddress = InetSocketAddress (Ipv4Address::GetAny (), sinkPort);
+      probeName = "ns3::Ipv4PacketProbe";
+      probeTrace = "/NodeList/*/$ns3::Ipv4L3Protocol/Tx";
+    }
+  else
+    {
+      Ipv6AddressHelper address;
+      address.SetBase ("2001:0000:f00d:cafe::", Ipv6Prefix (64));
+      Ipv6InterfaceContainer interfaces = address.Assign (devices);
+      sinkAddress = Inet6SocketAddress (interfaces.GetAddress (1,1), sinkPort);
+      anyAddress = Inet6SocketAddress (Ipv6Address::GetAny (), sinkPort);
+      probeName = "ns3::Ipv6PacketProbe";
+      probeTrace = "/NodeList/*/$ns3::Ipv6L3Protocol/Tx";
+    }
 
-  uint16_t sinkPort = 8080;
-  Address sinkAddress (InetSocketAddress (interfaces.GetAddress (1), sinkPort));
-  PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), sinkPort));
+  PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", anyAddress);
   ApplicationContainer sinkApps = packetSinkHelper.Install (nodes.Get (1));
   sinkApps.Start (Seconds (0.));
   sinkApps.Stop (Seconds (20.));
@@ -236,8 +269,8 @@
   // probe output trace source ("OutputBytes") to plot.  The fourth argument
   // specifies the name of the data series label on the plot.  The last
   // argument formats the plot by specifying where the key should be placed.
-  plotHelper.PlotProbe ("ns3::Ipv4PacketProbe",
-                        "/NodeList/*/$ns3::Ipv4L3Protocol/Tx",
+  plotHelper.PlotProbe (probeName,
+                        probeTrace,
                         "OutputBytes",
                         "Packet Byte Count",
                         GnuplotAggregator::KEY_BELOW);
@@ -254,8 +287,8 @@
 
   // Specify the probe type, probe path (in configuration namespace), and
   // probe output trace source ("OutputBytes") to write.
-  fileHelper.WriteProbe ("ns3::Ipv4PacketProbe",
-                         "/NodeList/*/$ns3::Ipv4L3Protocol/Tx",
+  fileHelper.WriteProbe (probeName,
+                         probeTrace,
                          "OutputBytes");
 
   Simulator::Stop (Seconds (20));
--- a/src/internet/model/ipv4-packet-probe.cc	Sat Aug 10 16:55:31 2013 -0700
+++ b/src/internet/model/ipv4-packet-probe.cc	Sun Aug 11 12:34:17 2013 +0200
@@ -54,6 +54,7 @@
 {
   NS_LOG_FUNCTION (this);
   m_packet    = 0;
+  m_packetSizeOld = 0;
   m_ipv4      = 0;
   m_interface = 0;
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet/model/ipv6-packet-probe.cc	Sun Aug 11 12:34:17 2013 +0200
@@ -0,0 +1,125 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2011 Bucknell University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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
+ *
+ * Authors: L. Felipe Perrone (perrone@bucknell.edu)
+ *          Tiago G. Rodrigues (tgr002@bucknell.edu)
+ *
+ * Modified by: Mitch Watrous (watrous@u.washington.edu)
+ * Adapted to Ipv6 by: Tommaso Pecorella (tommaso.pecorella@unifi.it)
+ */
+
+#include "ns3/ipv6-packet-probe.h"
+#include "ns3/object.h"
+#include "ns3/log.h"
+#include "ns3/names.h"
+#include "ns3/config.h"
+#include "ns3/trace-source-accessor.h"
+
+NS_LOG_COMPONENT_DEFINE ("Ipv6PacketProbe");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6PacketProbe);
+
+TypeId
+Ipv6PacketProbe::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::Ipv6PacketProbe")
+    .SetParent<Probe> ()
+    .AddConstructor<Ipv6PacketProbe> ()
+    .AddTraceSource ( "Output",
+                      "The packet plus its IPv6 object and interface that serve as the output for this probe",
+                      MakeTraceSourceAccessor (&Ipv6PacketProbe::m_output))
+    .AddTraceSource ( "OutputBytes",
+                      "The number of bytes in the packet",
+                      MakeTraceSourceAccessor (&Ipv6PacketProbe::m_outputBytes))
+  ;
+  return tid;
+}
+
+Ipv6PacketProbe::Ipv6PacketProbe ()
+{
+  NS_LOG_FUNCTION (this);
+  m_packet    = 0;
+  m_packetSizeOld = 0;
+  m_ipv6      = 0;
+  m_interface = 0;
+}
+
+Ipv6PacketProbe::~Ipv6PacketProbe ()
+{
+  NS_LOG_FUNCTION (this);
+}
+
+void
+Ipv6PacketProbe::SetValue (Ptr<const Packet> packet, Ptr<Ipv6> ipv6, uint32_t interface)
+{
+  NS_LOG_FUNCTION (this << packet << ipv6 << interface);
+  m_packet    = packet;
+  m_ipv6      = ipv6;
+  m_interface = interface;
+  m_output (packet, ipv6, interface);
+
+  uint32_t packetSizeNew = packet->GetSize ();
+  m_outputBytes (m_packetSizeOld, packetSizeNew);
+  m_packetSizeOld = packetSizeNew;
+}
+
+void
+Ipv6PacketProbe::SetValueByPath (std::string path, Ptr<const Packet> packet, Ptr<Ipv6> ipv6, uint32_t interface)
+{
+  NS_LOG_FUNCTION (path << packet << ipv6 << interface);
+  Ptr<Ipv6PacketProbe> probe = Names::Find<Ipv6PacketProbe> (path);
+  NS_ASSERT_MSG (probe, "Error:  Can't find probe for path " << path);
+  probe->SetValue (packet, ipv6, interface);
+}
+
+bool
+Ipv6PacketProbe::ConnectByObject (std::string traceSource, Ptr<Object> obj)
+{
+  NS_LOG_FUNCTION (this << traceSource << obj);
+  NS_LOG_DEBUG ("Name of probe (if any) in names database: " << Names::FindPath (obj));
+  bool connected = obj->TraceConnectWithoutContext (traceSource, MakeCallback (&ns3::Ipv6PacketProbe::TraceSink, this));
+  return connected;
+}
+
+void
+Ipv6PacketProbe::ConnectByPath (std::string path)
+{
+  NS_LOG_FUNCTION (this << path);
+  NS_LOG_DEBUG ("Name of probe to search for in config database: " << path);
+  Config::ConnectWithoutContext (path, MakeCallback (&ns3::Ipv6PacketProbe::TraceSink, this));
+}
+
+void
+Ipv6PacketProbe::TraceSink (Ptr<const Packet> packet, Ptr<Ipv6> ipv6, uint32_t interface)
+{
+  NS_LOG_FUNCTION (this << packet << ipv6 << interface);
+  if (IsEnabled ())
+    {
+      m_packet    = packet;
+      m_ipv6      = ipv6;
+      m_interface = interface;
+      m_output (packet, ipv6, interface);
+
+      uint32_t packetSizeNew = packet->GetSize ();
+      m_outputBytes (m_packetSizeOld, packetSizeNew);
+      m_packetSizeOld = packetSizeNew;
+    }
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet/model/ipv6-packet-probe.h	Sun Aug 11 12:34:17 2013 +0200
@@ -0,0 +1,125 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2011 Bucknell University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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
+ *
+ * Authors: L. Felipe Perrone (perrone@bucknell.edu)
+ *          Tiago G. Rodrigues (tgr002@bucknell.edu)
+ *
+ * Modified by: Mitch Watrous (watrous@u.washington.edu)
+ * Adapted to Ipv6 by: Tommaso Pecorella (tommaso.pecorella@unifi.it)
+ */
+
+#ifndef IPV6_PACKET_PROBE_H
+#define IPV6_PACKET_PROBE_H
+
+#include "ns3/object.h"
+#include "ns3/callback.h"
+#include "ns3/boolean.h"
+#include "ns3/nstime.h"
+#include "ns3/packet.h"
+#include "ns3/ipv6.h"
+#include "ns3/traced-value.h"
+#include "ns3/simulator.h"
+#include "ns3/probe.h"
+
+namespace ns3 {
+
+/**
+ * This class is designed to probe an underlying ns3 TraceSource
+ * exporting a packet, an IPv6 object, and an interface.  This probe
+ * exports a trace source "Output" with arguments of type Ptr<const Packet>,
+ * Ptr<Ipv6>, and uint32_t.  The Output trace source emits a value
+ * when either the trace source emits a new value, or when SetValue ()
+ * is called.
+ */
+class Ipv6PacketProbe : public Probe
+{
+public:
+  static TypeId GetTypeId ();
+  Ipv6PacketProbe ();
+  virtual ~Ipv6PacketProbe ();
+
+  /**
+   * \brief Set a probe value
+   *
+   * \param packet set the traced packet equal to this
+   * \param ipv6 set the IPv6 object for the traced packet equal to this
+   * \param interface set the IPv6 interface for the traced packet equal to this
+   */
+  void SetValue (Ptr<const Packet> packet, Ptr<Ipv6> ipv6, uint32_t interface);
+
+  /**
+   * \brief Set a probe value by its name in the Config system
+   *
+   * \param path config path to access the probe
+   * \param packet set the traced packet equal to this
+   * \param ipv6 set the IPv6 object for the traced packet equal to this
+   * \param interface set the IPv6 interface for the traced packet equal to this
+   */
+  static void SetValueByPath (std::string path, Ptr<const Packet> packet, Ptr<Ipv6> ipv6, uint32_t interface);
+
+  /**
+   * \brief connect to a trace source attribute provided by a given object
+   *
+   * \param traceSource the name of the attribute TraceSource to connect to
+   * \param obj ns3::Object to connect to
+   * \return true if the trace source was successfully connected
+   */
+  virtual bool ConnectByObject (std::string traceSource, Ptr<Object> obj);
+
+  /**
+   * \brief connect to a trace source provided by a config path
+   *
+   * \param path Config path to bind to
+   *
+   * Note, if an invalid path is provided, the probe will not be connected
+   * to anything.
+   */
+  virtual void ConnectByPath (std::string path);
+
+private:
+  /**
+   * \brief Method to connect to an underlying ns3::TraceSource with
+   * arguments of type Ptr<const Packet>, Ptr<Ipv6>, and uint32_t
+   *
+   * \param packet the traced packet
+   * \param ipv6 the IPv6 object for the traced packet
+   * \param interface the IPv6 interface for the traced packet
+   *
+   * \internal
+   */
+  void TraceSink (Ptr<const Packet> packet, Ptr<Ipv6> ipv6, uint32_t interface);
+
+  TracedCallback<Ptr<const Packet>, Ptr<Ipv6>, uint32_t> m_output;
+  TracedCallback<uint32_t, uint32_t> m_outputBytes;
+
+  /// The traced packet.
+  Ptr<const Packet> m_packet;
+
+  /// The IPv6 object for the traced packet.
+  Ptr<Ipv6> m_ipv6;
+
+  /// The IPv6 interface for the traced packet.
+  uint32_t m_interface;
+
+  /// The size of the traced packet.
+  uint32_t m_packetSizeOld;
+};
+
+
+} // namespace ns3
+
+#endif // IPV6_PACKET_PROBE_H
--- a/src/internet/wscript	Sat Aug 10 16:55:31 2013 -0700
+++ b/src/internet/wscript	Sun Aug 11 12:34:17 2013 +0200
@@ -190,6 +190,7 @@
         'helper/ipv6-routing-helper.cc',
         'model/ipv6-address-generator.cc',
         'model/ipv4-packet-probe.cc',
+        'model/ipv6-packet-probe.cc',
         ]
 
     internet_test = bld.create_ns3_module_test_library('internet')
@@ -302,6 +303,7 @@
         'model/tcp-rx-buffer.h',
         'model/rtt-estimator.h',
         'model/ipv4-packet-probe.h',
+        'model/ipv6-packet-probe.h',
        ]
 
     if bld.env['NSC_ENABLED']:
--- a/src/stats/helper/file-helper.cc	Sat Aug 10 16:55:31 2013 -0700
+++ b/src/stats/helper/file-helper.cc	Sun Aug 11 12:34:17 2013 +0200
@@ -515,6 +515,13 @@
         MakeCallback (&TimeSeriesAdaptor::TraceSinkUinteger32,
                       m_timeSeriesAdaptorMap[probeContext]));
     }
+  else if (m_probeMap[probeName].second == "ns3::Ipv6PacketProbe")
+    {
+      m_probeMap[probeName].first->TraceConnectWithoutContext
+        (probeTraceSource,
+        MakeCallback (&TimeSeriesAdaptor::TraceSinkUinteger32,
+                      m_timeSeriesAdaptorMap[probeContext]));
+    }
   else if (m_probeMap[probeName].second == "ns3::Uinteger8Probe")
     {
       m_probeMap[probeName].first->TraceConnectWithoutContext
--- a/src/stats/helper/gnuplot-helper.cc	Sat Aug 10 16:55:31 2013 -0700
+++ b/src/stats/helper/gnuplot-helper.cc	Sun Aug 11 12:34:17 2013 +0200
@@ -372,6 +372,13 @@
         MakeCallback (&TimeSeriesAdaptor::TraceSinkUinteger32,
                       m_timeSeriesAdaptorMap[probeContext]));
     }
+  else if (m_probeMap[probeName].second == "ns3::Ipv6PacketProbe")
+    {
+      m_probeMap[probeName].first->TraceConnectWithoutContext
+        (probeTraceSource,
+        MakeCallback (&TimeSeriesAdaptor::TraceSinkUinteger32,
+                      m_timeSeriesAdaptorMap[probeContext]));
+    }
   else if (m_probeMap[probeName].second == "ns3::Uinteger8Probe")
     {
       m_probeMap[probeName].first->TraceConnectWithoutContext