00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "ns3/assert.h"
00022 #include "ns3/log.h"
00023 #include "ns3/object.h"
00024 #include "ns3/ipv4.h"
00025 #include "internet-stack-helper.h"
00026 #include "ns3/internet-stack.h"
00027 #include "ns3/packet-socket-factory.h"
00028 #include "ns3/config.h"
00029 #include "ns3/simulator.h"
00030 #include <limits>
00031
00032 namespace ns3 {
00033
00034 std::vector<InternetStackHelper::Trace> InternetStackHelper::m_traces;
00035 std::string InternetStackHelper::m_pcapBaseFilename;
00036
00037 InternetStackHelper::InternetStackHelper() : m_nscLibrary("")
00038 {
00039 }
00040
00041 void
00042 InternetStackHelper::Cleanup (void)
00043 {
00044 uint32_t illegal = std::numeric_limits<uint32_t>::max();
00045
00046 for (std::vector<Trace>::iterator i = m_traces.begin ();
00047 i != m_traces.end (); i++)
00048 {
00049 i->nodeId = illegal;
00050 i->interfaceId = illegal;
00051 i->writer = 0;
00052 }
00053 m_traces.clear ();
00054 }
00055
00056 void
00057 InternetStackHelper::SetNscStack(const std::string soname)
00058 {
00059 m_nscLibrary = soname;
00060 }
00061
00062 void
00063 InternetStackHelper::Install (NodeContainer c) const
00064 {
00065 for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
00066 {
00067 Install (*i);
00068 }
00069 }
00070
00071 void
00072 InternetStackHelper::Install (Ptr<Node> node) const
00073 {
00074 if (node->GetObject<Ipv4> () != 0)
00075 {
00076 NS_FATAL_ERROR ("InternetStackHelper::Install(): Aggregating "
00077 "an InternetStack to a node with an existing Ipv4 object");
00078 return;
00079 }
00080
00081 if (m_nscLibrary != "")
00082 {
00083 AddNscInternetStack (node, m_nscLibrary);
00084 }
00085 else
00086 {
00087 AddInternetStack (node);
00088 }
00089
00090 Ptr<PacketSocketFactory> factory = CreateObject<PacketSocketFactory> ();
00091 node->AggregateObject (factory);
00092 }
00093
00094 void
00095 InternetStackHelper::EnableAscii (std::ostream &os, NodeContainer n)
00096 {
00097 Packet::EnablePrinting ();
00098 std::ostringstream oss;
00099 for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
00100 {
00101 Ptr<Node> node = *i;
00102 oss << "/NodeList/" << node->GetId () << "/$ns3::Ipv4L3Protocol/Drop";
00103 Config::Connect (oss.str (), MakeBoundCallback (&InternetStackHelper::AsciiDropEvent, &os));
00104 oss.str ("");
00105 oss << "/NodeList/" << node->GetId () << "/$ns3::ArpL3Protocol/Drop";
00106 Config::Connect (oss.str (), MakeBoundCallback (&InternetStackHelper::AsciiDropEvent, &os));
00107 oss.str ("");
00108 }
00109 }
00110
00111 void
00112 InternetStackHelper::EnableAsciiAll (std::ostream &os)
00113 {
00114 EnableAscii (os, NodeContainer::GetGlobal ());
00115 }
00116
00117 void
00118 InternetStackHelper::EnablePcapAll (std::string filename)
00119 {
00120 Simulator::ScheduleDestroy (&InternetStackHelper::Cleanup);
00121
00122 InternetStackHelper::m_pcapBaseFilename = filename;
00123 Config::Connect ("/NodeList/*/$ns3::Ipv4L3Protocol/Tx",
00124 MakeCallback (&InternetStackHelper::LogTxIp));
00125 Config::Connect ("/NodeList/*/$ns3::Ipv4L3Protocol/Rx",
00126 MakeCallback (&InternetStackHelper::LogRxIp));
00127 }
00128
00129 uint32_t
00130 InternetStackHelper::GetNodeIndex (std::string context)
00131 {
00132 std::string::size_type pos;
00133 pos = context.find ("/NodeList/");
00134 NS_ASSERT (pos == 0);
00135 std::string::size_type afterNodeIndex = context.find ("/", 11);
00136 NS_ASSERT (afterNodeIndex != std::string::npos);
00137 std::string index = context.substr (10, afterNodeIndex - 10);
00138 std::istringstream iss;
00139 iss.str (index);
00140 uint32_t nodeIndex;
00141 iss >> nodeIndex;
00142 return nodeIndex;
00143 }
00144
00145 void
00146 InternetStackHelper::LogTxIp (std::string context, Ptr<const Packet> packet, uint32_t interfaceIndex)
00147 {
00148 Ptr<PcapWriter> writer = InternetStackHelper::GetStream (GetNodeIndex (context), interfaceIndex);
00149 writer->WritePacket (packet);
00150 }
00151
00152 void
00153 InternetStackHelper::LogRxIp (std::string context, Ptr<const Packet> packet, uint32_t interfaceIndex)
00154 {
00155 Ptr<PcapWriter> writer = InternetStackHelper::GetStream (GetNodeIndex (context), interfaceIndex);
00156 writer->WritePacket (packet);
00157 }
00158
00159 Ptr<PcapWriter>
00160 InternetStackHelper::GetStream (uint32_t nodeId, uint32_t interfaceId)
00161 {
00162 for (std::vector<Trace>::iterator i = m_traces.begin ();
00163 i != m_traces.end (); i++)
00164 {
00165 if (i->nodeId == nodeId &&
00166 i->interfaceId == interfaceId)
00167 {
00168 return i->writer;
00169 }
00170 }
00171 InternetStackHelper::Trace trace;
00172 trace.nodeId = nodeId;
00173 trace.interfaceId = interfaceId;
00174 trace.writer = Create<PcapWriter> ();
00175 std::ostringstream oss;
00176 oss << m_pcapBaseFilename << "-" << nodeId << "-" << interfaceId << ".pcap";
00177 trace.writer->Open (oss.str ());
00178 trace.writer->WriteIpHeader ();
00179 m_traces.push_back (trace);
00180 return trace.writer;
00181 }
00182
00183 void
00184 InternetStackHelper::AsciiDropEvent (std::ostream *os, std::string path, Ptr<const Packet> packet)
00185 {
00186 *os << "d " << Simulator::Now ().GetSeconds () << " ";
00187 *os << path << " " << *packet << std::endl;
00188 }
00189
00190 }