--- /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',