add in the helpers
authorCraig Dowell <craigdo@ee.washington.edu>
Mon, 27 Oct 2008 23:05:57 -0700
changeset 3828 337b244e6d8f
parent 3827 4b603cd4ee42
child 3829 97ae21d8caca
add in the helpers
src/helper/emu-helper.cc
src/helper/emu-helper.h
src/helper/tap-helper.cc
src/helper/tap-helper.h
src/helper/wscript
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/emu-helper.cc	Mon Oct 27 23:05:57 2008 -0700
@@ -0,0 +1,273 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 University of Washington
+ *
+ * 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
+ */
+
+#include <string>
+
+#include "ns3/log.h"
+#include "ns3/simulator.h"
+#include "ns3/object-factory.h"
+#include "ns3/queue.h"
+#include "ns3/emulated-net-device.h"
+#include "ns3/pcap-writer.h"
+#include "ns3/config.h"
+#include "ns3/packet.h"
+
+#include "emu-helper.h"
+
+NS_LOG_COMPONENT_DEFINE ("EmuHelper");
+
+namespace ns3 {
+
+EmuHelper::EmuHelper ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_queueFactory.SetTypeId ("ns3::DropTailQueue");
+  m_deviceFactory.SetTypeId ("ns3::EmulatedNetDevice");
+}
+
+  void 
+EmuHelper::SetQueue (
+  std::string type,
+  std::string n1, const AttributeValue &v1,
+  std::string n2, const AttributeValue &v2,
+  std::string n3, const AttributeValue &v3,
+  std::string n4, const AttributeValue &v4)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_queueFactory.SetTypeId (type);
+  m_queueFactory.Set (n1, v1);
+  m_queueFactory.Set (n2, v2);
+  m_queueFactory.Set (n3, v3);
+  m_queueFactory.Set (n4, v4);
+}
+
+  void 
+EmuHelper::SetAttribute (std::string n1, const AttributeValue &v1)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_deviceFactory.Set (n1, v1);
+}
+
+  void 
+EmuHelper::EnablePcap (
+  std::string filename, 
+  uint32_t nodeid, 
+  uint32_t deviceid)
+{
+  NS_LOG_FUNCTION (filename << nodeid << deviceid);
+  std::ostringstream oss;
+  oss << filename << "-" << nodeid << "-" << deviceid << ".pcap";
+  Ptr<PcapWriter> pcap = Create<PcapWriter> ();
+  pcap->Open (oss.str ());
+  pcap->WriteEthernetHeader ();
+
+  oss.str ("");
+  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << 
+    "/$ns3::EmulatedNetDevice/Rx";
+  Config::ConnectWithoutContext (oss.str (), 
+    MakeBoundCallback (&EmuHelper::RxEvent, pcap));
+
+  oss.str ("");
+  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << 
+    "/$ns3::EmulatedNetDevice/TxQueue/Enqueue";
+  Config::ConnectWithoutContext (oss.str (), 
+    MakeBoundCallback (&EmuHelper::EnqueueEvent, pcap));
+}
+
+  void 
+EmuHelper::EnablePcap (std::string filename, NetDeviceContainer d)
+{
+  NS_LOG_FUNCTION (filename << &d);
+  for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i)
+    {
+      Ptr<NetDevice> dev = *i;
+      EnablePcap (filename, dev->GetNode ()->GetId (), dev->GetIfIndex ());
+    }
+}
+
+  void
+EmuHelper::EnablePcap (std::string filename, NodeContainer n)
+{
+  NS_LOG_FUNCTION (filename << &n);
+  NetDeviceContainer devs;
+  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
+    {
+      Ptr<Node> node = *i;
+      for (uint32_t j = 0; j < node->GetNDevices (); ++j)
+	{
+	  devs.Add (node->GetDevice (j));
+	}
+    }
+  EnablePcap (filename, devs);
+}
+
+  void
+EmuHelper::EnablePcapAll (std::string filename)
+{
+  NS_LOG_FUNCTION (filename);
+  EnablePcap (filename, NodeContainer::GetGlobal ());
+}
+
+  void 
+EmuHelper::EnableAscii (std::ostream &os, uint32_t nodeid, uint32_t deviceid)
+{
+  NS_LOG_FUNCTION (&os << nodeid << deviceid);
+  Packet::EnablePrinting ();
+  std::ostringstream oss;
+
+  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << 
+    "/$ns3::EmulatedNetDevice/Rx";
+  Config::Connect (oss.str (), 
+    MakeBoundCallback (&EmuHelper::AsciiRxEvent, &os));
+
+  oss.str ("");
+  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << 
+    "/$ns3::EmulatedNetDevice/TxQueue/Enqueue";
+  Config::Connect (oss.str (), 
+    MakeBoundCallback (&EmuHelper::AsciiEnqueueEvent, &os));
+
+  oss.str ("");
+  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << 
+    "/$ns3::EmulatedNetDevice/TxQueue/Dequeue";
+  Config::Connect (oss.str (), 
+    MakeBoundCallback (&EmuHelper::AsciiDequeueEvent, &os));
+
+  oss.str ("");
+  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << 
+    "/$ns3::EmulatedNetDevice/TxQueue/Drop";
+  Config::Connect (oss.str (), 
+    MakeBoundCallback (&EmuHelper::AsciiDropEvent, &os));
+}
+
+  void 
+EmuHelper::EnableAscii (std::ostream &os, NetDeviceContainer d)
+{
+  NS_LOG_FUNCTION (&os << &d);
+  for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i)
+    {
+      Ptr<NetDevice> dev = *i;
+      EnableAscii (os, dev->GetNode ()->GetId (), dev->GetIfIndex ());
+    }
+}
+
+void
+EmuHelper::EnableAscii (std::ostream &os, NodeContainer n)
+{
+  NS_LOG_FUNCTION (&os << &n);
+  NetDeviceContainer devs;
+  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
+    {
+      Ptr<Node> node = *i;
+      for (uint32_t j = 0; j < node->GetNDevices (); ++j)
+	{
+	  devs.Add (node->GetDevice (j));
+	}
+    }
+  EnableAscii (os, devs);
+}
+
+  void
+EmuHelper::EnableAsciiAll (std::ostream &os)
+{
+  NS_LOG_FUNCTION (&os);
+  EnableAscii (os, NodeContainer::GetGlobal ());
+}
+
+  NetDeviceContainer 
+EmuHelper::Install (const NodeContainer &c)
+{
+  NS_LOG_FUNCTION (&c);
+  NetDeviceContainer container;
+  for (NodeContainer::Iterator i = c.Begin (); i != c.End (); i++)
+    {
+      Ptr<Node> node = *i;
+
+      Ptr<EmulatedNetDevice> device = m_deviceFactory.Create<EmulatedNetDevice> ();
+      //
+      // This is a mac address used for ns-3 internal things.  It cannot override the real MAC address on the NIC in
+      // question.
+      //
+      device->SetAddress (Mac48Address::Allocate ());
+      node->AddDevice (device);
+
+      Ptr<Queue> queue = m_queueFactory.Create<Queue> ();
+      device->SetQueue (queue);
+      container.Add (device);
+    }
+  return container;
+}
+
+  void 
+EmuHelper::EnqueueEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet)
+{
+  NS_LOG_FUNCTION (writer << packet);
+  writer->WritePacket (packet);
+}
+
+  void 
+EmuHelper::RxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet)
+{
+  NS_LOG_FUNCTION (writer << packet);
+  writer->WritePacket (packet);
+}
+
+  void 
+EmuHelper::AsciiEnqueueEvent (
+  std::ostream *os, 
+  std::string path, 
+  Ptr<const Packet> packet)
+{
+  NS_LOG_FUNCTION (&os << path << packet);
+  *os << "+ " << Simulator::Now ().GetSeconds () << " ";
+  *os << path << " " << *packet << std::endl;
+}
+
+  void 
+EmuHelper::AsciiDequeueEvent (
+  std::ostream *os, 
+  std::string path, 
+  Ptr<const Packet> packet)
+{
+  NS_LOG_FUNCTION (&os << path << packet);
+  *os << "- " << Simulator::Now ().GetSeconds () << " ";
+  *os << path << " " << *packet << std::endl;
+}
+
+  void 
+EmuHelper::AsciiDropEvent (
+  std::ostream *os, 
+  std::string path, 
+  Ptr<const Packet> packet)
+{
+  NS_LOG_FUNCTION (&os << path << packet);
+  *os << "d " << Simulator::Now ().GetSeconds () << " ";
+  *os << path << " " << *packet << std::endl;
+}
+
+  void 
+EmuHelper::AsciiRxEvent (
+  std::ostream *os, 
+  std::string path, 
+  Ptr<const Packet> packet)
+{
+  NS_LOG_FUNCTION (&os << path << packet);
+  *os << "r " << Simulator::Now ().GetSeconds () << " ";
+  *os << path << " " << *packet << std::endl;
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/emu-helper.h	Mon Oct 27 23:05:57 2008 -0700
@@ -0,0 +1,181 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 University of Washington
+ *
+ * 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
+ */
+
+#ifndef EMU_HELPER_H
+#define EMU_HELPER_H
+
+#include <string>
+#include <ostream>
+#include "ns3/attribute.h"
+#include "ns3/object-factory.h"
+#include "ns3/net-device-container.h"
+#include "ns3/node-container.h"
+#include "ns3/emulated-net-device.h"
+
+namespace ns3 {
+
+class Packet;
+class PcapWriter;
+
+/**
+ * \brief build a set of EmuNetDevice objects
+ */
+class EmuHelper
+{
+public:
+  EmuHelper ();
+
+  /**
+   * \param type the type of queue
+   * \param n1 the name of the attribute to set on the queue
+   * \param v1 the value of the attribute to set on the queue
+   * \param n2 the name of the attribute to set on the queue
+   * \param v2 the value of the attribute to set on the queue
+   * \param n3 the name of the attribute to set on the queue
+   * \param v3 the value of the attribute to set on the queue
+   * \param n4 the name of the attribute to set on the queue
+   * \param v4 the value of the attribute to set on the queue
+   *
+   * Set the type of queue to create and associated to each
+   * EmuNetDevice created through EmuHelper::Install.
+   */
+  void SetQueue (std::string type,
+    std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
+    std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
+    std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
+    std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue ());
+
+  /**
+   * \param n1 the name of the attribute to set
+   * \param v1 the value of the attribute to set
+   *
+   * Set these attributes on each ns3::EmuNetDevice created
+   * by EmuHelper::Install
+   */
+  void SetAttribute (std::string n1, const AttributeValue &v1);
+
+  /**
+   * \param filename filename prefix to use for pcap files.
+   * \param nodeid the id of the node to generate pcap output for.
+   * \param deviceid the id of the device to generate pcap output for.
+   *
+   * Generate a pcap file which contains the link-level data observed
+   * by the specified deviceid within the specified nodeid. The pcap
+   * data is stored in the file prefix-nodeid-deviceid.pcap.
+   *
+   * This method should be invoked after the network topology has 
+   * been fully constructed.
+   */
+  static void EnablePcap (std::string filename, uint32_t nodeid, 
+    uint32_t deviceid);
+
+  /**
+   * \param filename filename prefix to use for pcap files.
+   * \param d container of devices of type ns3::EmuNetDevice
+   *
+   * Enable pcap output on each input device which is of the
+   * ns3::EmuNetDevice type.
+   */
+  static void EnablePcap (std::string filename, NetDeviceContainer d);
+
+  /**
+   * \param filename filename prefix to use for pcap files.
+   * \param n container of nodes.
+   *
+   * Enable pcap output on each device which is of the
+   * ns3::EmuNetDevice type and which is located in one of the 
+   * input nodes.
+   */
+  static void EnablePcap (std::string filename, NodeContainer n);
+
+  /**
+   * \param filename filename prefix to use for pcap files.
+   *
+   * Enable pcap output on each device which is of the
+   * ns3::EmuNetDevice type
+   */
+  static void EnablePcapAll (std::string filename);
+
+  /**
+   * \param os output stream
+   * \param nodeid the id of the node to generate ascii output for.
+   * \param deviceid the id of the device to generate ascii output for.
+   *
+   * Enable ascii output on the specified deviceid within the
+   * specified nodeid if it is of type ns3::EmuNetDevice and dump 
+   * that to the specified stdc++ output stream.
+   */
+  static void EnableAscii (std::ostream &os, uint32_t nodeid, 
+    uint32_t deviceid);
+
+  /**
+   * \param os output stream
+   * \param d device container
+   *
+   * Enable ascii output on each device which is of the
+   * ns3::EmuNetDevice type and which is located in the input
+   * device container and dump that to the specified
+   * stdc++ output stream.
+   */
+  static void EnableAscii (std::ostream &os, NetDeviceContainer d);
+
+  /**
+   * \param os output stream
+   * \param n node container
+   *
+   * Enable ascii output on each device which is of the
+   * ns3::EmuNetDevice type and which is located in one
+   * of the input node and dump that to the specified
+   * stdc++ output stream.
+   */
+  static void EnableAscii (std::ostream &os, NodeContainer n);
+
+  /**
+   * \param os output stream
+   *
+   * Enable ascii output on each device which is of the
+   * ns3::EmuNetDevice type and dump that to the specified
+   * stdc++ output stream.
+   */
+  static void EnableAsciiAll (std::ostream &os);
+
+  /**
+   * \param c a set of nodes
+   */
+  NetDeviceContainer Install (const NodeContainer &c);
+
+private:
+  static void RxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet);
+  static void EnqueueEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet);
+  static void AsciiEnqueueEvent (std::ostream *os, std::string path, 
+    Ptr<const Packet> packet);
+  static void AsciiDequeueEvent (std::ostream *os, std::string path, 
+    Ptr<const Packet> packet);
+  static void AsciiDropEvent (std::ostream *os, std::string path, 
+    Ptr<const Packet> packet);
+  static void AsciiRxEvent (std::ostream *os, std::string path, 
+    Ptr<const Packet> packet);
+
+  ObjectFactory m_queueFactory;
+  ObjectFactory m_deviceFactory;
+};
+
+
+} // namespace ns3
+
+#endif /* EMU_HELPER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/tap-helper.cc	Mon Oct 27 23:05:57 2008 -0700
@@ -0,0 +1,109 @@
+#include "tap-helper.h"
+#include "ns3/tap-net-device.h"
+#include "ns3/host-tap-net-device.h"
+#include "ns3/tap-channel.h"
+#include "ns3/pcap-writer.h"
+#include "ns3/config.h"
+#include "ns3/packet.h"
+#include "ns3/callback.h"
+#include "ns3/log.h"
+
+namespace ns3 {
+
+NS_LOG_COMPONENT_DEFINE ("TapHelper");
+
+NetDeviceContainer
+TapHelper::Install (NodeContainer hosts, NodeContainer taps)
+{
+  NS_ASSERT (hosts.GetN () == 1 && taps.GetN () == 1);
+  NetDeviceContainer devices;
+
+  Ptr<TapChannel> channel = CreateObject<TapChannel> ();
+
+  // the host.
+  Ptr<Node> host = hosts.Get (0);
+  Ptr<HostTapNetDevice> hostDev = CreateObject<HostTapNetDevice> ();
+  hostDev->SetChannel (channel);
+  hostDev->SetAddress (Mac48Address::Allocate ());
+  host->AddDevice (hostDev);
+  devices.Add (hostDev);
+
+  // the tap
+  Ptr<Node> tap = taps.Get (0);
+  Ptr<TapNetDevice> tapDev = CreateObject<TapNetDevice> ();
+  tapDev->SetChannel (channel);
+  tapDev->SetAddress (Mac48Address::Allocate ());
+  tap->AddDevice (tapDev);
+  devices.Add (tapDev);
+
+  return devices;
+}
+
+void 
+TapHelper::SetupHost (NetDeviceContainer dev, Ipv4Address ad, Ipv4Mask mask, Ipv4Address gateway)
+{
+  NS_ASSERT (dev.GetN () == 2);
+  Ptr<TapNetDevice> tap = dev.Get (1)->GetObject<TapNetDevice> ();
+  tap->SetupHost (ad, mask, gateway);
+}
+
+static void TxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet, Mac48Address from, Mac48Address to)
+{
+  NS_LOG_FUNCTION (writer << packet << from << to);
+  writer->WritePacket (packet);
+}
+static void RxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet, Mac48Address from, Mac48Address to)
+{
+  NS_LOG_FUNCTION (writer << packet << from << to);
+  writer->WritePacket (packet);
+}
+
+
+void 
+TapHelper::EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid)
+{
+  std::ostringstream oss;
+  oss << filename << "-" << nodeid << "-" << deviceid << ".pcap";
+  Ptr<PcapWriter> pcap = Create<PcapWriter> ();
+  pcap->Open (oss.str ());
+  pcap->WriteEthernetHeader ();
+  oss.str ("");
+  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::TapNetDevice/Rx";
+  Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&RxEvent, pcap));
+  oss.str ("");
+  oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::TapNetDevice/Tx";
+  Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&TxEvent, pcap));
+}
+
+void 
+TapHelper::EnablePcap (std::string filename, NetDeviceContainer d)
+{
+  for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i)
+    {
+      Ptr<NetDevice> dev = *i;
+      EnablePcap (filename, dev->GetNode ()->GetId (), dev->GetIfIndex ());
+    }
+}
+void
+TapHelper::EnablePcap (std::string filename, NodeContainer n)
+{
+  NetDeviceContainer devs;
+  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
+    {
+      Ptr<Node> node = *i;
+      for (uint32_t j = 0; j < node->GetNDevices (); ++j)
+	{
+	  devs.Add (node->GetDevice (j));
+	}
+    }
+  EnablePcap (filename, devs);
+}
+
+void
+TapHelper::EnablePcapAll (std::string filename)
+{
+  EnablePcap (filename, NodeContainer::GetGlobal ());
+}
+
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/tap-helper.h	Mon Oct 27 23:05:57 2008 -0700
@@ -0,0 +1,32 @@
+#ifndef TAP_HELPER_H
+#define TAP_HELPER_H
+
+#include "ns3/ipv4-address.h"
+#include "node-container.h"
+#include "net-device-container.h"
+
+namespace ns3 {
+
+class PcapWriter;
+class Packet;
+
+class TapHelper 
+{
+public:
+  /**
+   * \param host a node which represents the host which our tap is connected to
+   * \param tap the simulation node which should get a tap connected to the host.
+   */
+  NetDeviceContainer Install (NodeContainer host, NodeContainer tap);
+  void SetupHost (NetDeviceContainer dev, Ipv4Address ad, Ipv4Mask mask, Ipv4Address gateway);
+
+  static void EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid);
+  static void EnablePcap (std::string filename, NetDeviceContainer d);
+  static void EnablePcap (std::string filename, NodeContainer n);
+  static void EnablePcapAll (std::string filename);
+};
+
+
+} // namespace ns3
+
+#endif /* TAP_HELPER_H */
--- a/src/helper/wscript	Mon Oct 27 22:01:24 2008 -0700
+++ b/src/helper/wscript	Mon Oct 27 23:05:57 2008 -0700
@@ -10,6 +10,8 @@
         'static-multicast-route-helper.cc',
         'point-to-point-helper.cc',
         'csma-helper.cc',
+        'emu-helper.cc',
+        'tap-helper.cc',
         'mobility-helper.cc',
         'ns2-mobility-helper.cc',
         'ipv4-address-helper.cc',
@@ -33,6 +35,8 @@
         'static-multicast-route-helper.h',
         'point-to-point-helper.h',
         'csma-helper.h',
+        'emu-helper.h',
+        'tap-helper.h',
         'mobility-helper.h',
         'ns2-mobility-helper.h',
         'ipv4-address-helper.h',