10#include "ns3/assert.h" 
   13#include "ns3/net-device.h" 
   15#include "ns3/pcap-file-wrapper.h" 
   39                       std::ios::openmode filemode,
 
   44    NS_LOG_FUNCTION(filename << filemode << dataLinkType << snapLen << tzCorrection);
 
   47    file->Open(filename, filemode);
 
   48    NS_ABORT_MSG_IF(file->Fail(), 
"Unable to Open " << filename << 
" for mode " << filemode);
 
   50    file->Init(dataLinkType, snapLen, tzCorrection);
 
 
   73    std::ostringstream oss;
 
   77    std::string devicename;
 
   87    if (!nodename.empty())
 
   98    if (!devicename.empty())
 
  104        oss << device->GetIfIndex();
 
 
  121    std::ostringstream oss;
 
  122    oss << prefix << 
"-";
 
  125    std::string nodename;
 
  135    if (!objname.empty())
 
  139    else if (!nodename.empty())
 
  145        oss << 
"n" << node->GetId();
 
  148    oss << 
"-i" << 
interface << ".pcap
"; 
 
  154// The basic default trace sink.  This one just writes the packet to the pcap 
  155// file which is good enough for most kinds of captures. 
  158PcapHelper::DefaultSink(Ptr<PcapFileWrapper> file, Ptr<const Packet> p) 
  160    NS_LOG_FUNCTION(file << p); 
  161    file->Write(Simulator::Now(), p); 
 
  165PcapHelper::SinkWithHeader(Ptr<PcapFileWrapper> file, const Header& header, Ptr<const Packet> p) 
  167    NS_LOG_FUNCTION(file << p); 
  168    file->Write(Simulator::Now(), header, p); 
 
  171AsciiTraceHelper::AsciiTraceHelper() 
  173    NS_LOG_FUNCTION_NOARGS(); 
 
  176AsciiTraceHelper::~AsciiTraceHelper() 
  178    NS_LOG_FUNCTION_NOARGS(); 
 
  181Ptr<OutputStreamWrapper> 
  182AsciiTraceHelper::CreateFileStream(std::string filename, std::ios::openmode filemode) 
  184    NS_LOG_FUNCTION(filename << filemode); 
  186    Ptr<OutputStreamWrapper> StreamWrapper = Create<OutputStreamWrapper>(filename, filemode); 
  189    // Note that the ascii trace helper promptly forgets all about the trace file. 
  190    // We rely on the reference count of the file object which will soon be owned 
  191    // by the caller to keep the object alive.  If the caller uses the stream 
  192    // object to hook a trace source, ownership of the stream object will be 
  193    // implicitly transferred to the callback which keeps the object alive. 
  194    // When the callback is destroyed (when either the trace is disconnected or 
  195    // the object with the trace source is deleted) the callback will be destroyed 
  196    // and the stream object will be destroyed, releasing the pointer and closing 
  197    // the underlying file. 
  199    return StreamWrapper; 
 
  203AsciiTraceHelper::GetFilenameFromDevice(std::string prefix, 
  204                                        Ptr<NetDevice> device, 
  207    NS_LOG_FUNCTION(prefix << device << useObjectNames); 
  208    NS_ABORT_MSG_UNLESS(!prefix.empty(), "Empty prefix string
"); 
  210    std::ostringstream oss; 
  211    oss << prefix << "-
"; 
  213    std::string nodename; 
  214    std::string devicename; 
  216    Ptr<Node> node = device->GetNode(); 
  220        nodename = Names::FindName(node); 
  221        devicename = Names::FindName(device); 
  224    if (!nodename.empty()) 
  230        oss << node->GetId(); 
  235    if (!devicename.empty()) 
  241        oss << device->GetIfIndex(); 
 
  250AsciiTraceHelper::GetFilenameFromInterfacePair(std::string prefix, 
  255    NS_LOG_FUNCTION(prefix << object << interface << useObjectNames); 
  256    NS_ABORT_MSG_UNLESS(!prefix.empty(), "Empty prefix string
"); 
  258    std::ostringstream oss; 
  259    oss << prefix << "-
"; 
  262    std::string nodename; 
  264    Ptr<Node> node = object->GetObject<Node>(); 
  268        objname = Names::FindName(object); 
  269        nodename = Names::FindName(node); 
  272    if (!objname.empty()) 
  276    else if (!nodename.empty()) 
  282        oss << "n
" << node->GetId(); 
  285    oss << "-i
" << interface << ".tr
"; 
 
  291// One of the basic default trace sink sets.  Enqueue: 
  293//   When a packet has been sent to a device for transmission, the device is 
  294//   expected to place the packet onto a transmit queue even if it does not 
  295//   have to delay the packet at all, if only to trigger this event.  This 
  296//   event will eventually translate into a '+' operation in the trace file. 
  298//   This is typically implemented by hooking the "TxQueue/Enqueue
" trace hook 
  299//   in the device (actually the Queue in the device). 
  302AsciiTraceHelper::DefaultEnqueueSinkWithoutContext(Ptr<OutputStreamWrapper> stream, 
  305    NS_LOG_FUNCTION(stream << p); 
  306    *stream->GetStream() << "+ 
" << Simulator::Now().GetSeconds() << " " << *p << std::endl; 
 
  310AsciiTraceHelper::DefaultEnqueueSinkWithContext(Ptr<OutputStreamWrapper> stream, 
  314    NS_LOG_FUNCTION(stream << p); 
  315    *stream->GetStream() << "+ 
" << Simulator::Now().GetSeconds() << " " << context << " " << *p 
 
  320// One of the basic default trace sink sets.  Drop: 
  322//   When a packet has been sent to a device for transmission, the device is 
  323//   expected to place the packet onto a transmit queue.  If this queue is 
  324//   full the packet will be dropped.  The device is expected to trigger an 
  325//   event to indicate that an outbound packet is being dropped.  This event 
  326//   will eventually translate into a 'd' operation in the trace file. 
  328//   This is typically implemented by hooking the "TxQueue/Drop
" trace hook 
  329//   in the device (actually the Queue in the device). 
  332AsciiTraceHelper::DefaultDropSinkWithoutContext(Ptr<OutputStreamWrapper> stream, 
  335    NS_LOG_FUNCTION(stream << p); 
  336    *stream->GetStream() << "d 
" << Simulator::Now().GetSeconds() << " " << *p << std::endl; 
 
  340AsciiTraceHelper::DefaultDropSinkWithContext(Ptr<OutputStreamWrapper> stream, 
  344    NS_LOG_FUNCTION(stream << p); 
  345    *stream->GetStream() << "d 
" << Simulator::Now().GetSeconds() << " " << context << " " << *p 
 
  350// One of the basic default trace sink sets.  Dequeue: 
  352//   When a packet has been sent to a device for transmission, the device is 
  353//   expected to place the packet onto a transmit queue even if it does not 
  354//   have to delay the packet at all.  The device removes the packet from the 
  355//   transmit queue when the packet is ready to send, and this dequeue will 
  356//   fire a corresponding event.  This event will eventually translate into a 
  357//   '-' operation in the trace file. 
  359//   This is typically implemented by hooking the "TxQueue/Dequeue
" trace hook 
  360//   in the device (actually the Queue in the device). 
  363AsciiTraceHelper::DefaultDequeueSinkWithoutContext(Ptr<OutputStreamWrapper> stream, 
  366    NS_LOG_FUNCTION(stream << p); 
  367    *stream->GetStream() << "- 
" << Simulator::Now().GetSeconds() << " " << *p << std::endl; 
 
  371AsciiTraceHelper::DefaultDequeueSinkWithContext(Ptr<OutputStreamWrapper> stream, 
  375    NS_LOG_FUNCTION(stream << p); 
  376    *stream->GetStream() << "- 
" << Simulator::Now().GetSeconds() << " " << context << " " << *p 
 
  381// One of the basic default trace sink sets.  Receive: 
  383//   When a packet is received by a device for transmission, the device is 
  384//   expected to trigger this event to indicate the reception has occurred. 
  385//   This event will eventually translate into an 'r' operation in the trace 
  388//   This is typically implemented by hooking the "MacRx
" trace hook in the 
  391AsciiTraceHelper::DefaultReceiveSinkWithoutContext(Ptr<OutputStreamWrapper> stream, 
  394    NS_LOG_FUNCTION(stream << p); 
  395    *stream->GetStream() << "r 
" << Simulator::Now().GetSeconds() << " " << *p << std::endl; 
 
  399AsciiTraceHelper::DefaultReceiveSinkWithContext(Ptr<OutputStreamWrapper> stream, 
  403    NS_LOG_FUNCTION(stream << p); 
  404    *stream->GetStream() << "r 
" << Simulator::Now().GetSeconds() << " " << context << " " << *p 
 
  409PcapHelperForDevice::EnablePcap(std::string prefix, 
  412                                bool explicitFilename) 
  414    EnablePcapInternal(prefix, nd, promiscuous, explicitFilename); 
 
  418PcapHelperForDevice::EnablePcap(std::string prefix, 
  421                                bool explicitFilename) 
  423    Ptr<NetDevice> nd = Names::Find<NetDevice>(ndName); 
  424    EnablePcap(prefix, nd, promiscuous, explicitFilename); 
 
  428PcapHelperForDevice::EnablePcap(std::string prefix, NetDeviceContainer d, bool promiscuous) 
  430    for (auto i = d.Begin(); i != d.End(); ++i) 
  432        Ptr<NetDevice> dev = *i; 
  433        EnablePcap(prefix, dev, promiscuous); 
 
  438PcapHelperForDevice::EnablePcap(std::string prefix, NodeContainer n, bool promiscuous) 
  440    NetDeviceContainer devs; 
  441    for (auto i = n.Begin(); i != n.End(); ++i) 
  444        for (uint32_t j = 0; j < node->GetNDevices(); ++j) 
  446            devs.Add(node->GetDevice(j)); 
  449    EnablePcap(prefix, devs, promiscuous); 
 
  453PcapHelperForDevice::EnablePcapAll(std::string prefix, bool promiscuous) 
  455    EnablePcap(prefix, NodeContainer::GetGlobal(), promiscuous); 
 
  459PcapHelperForDevice::EnablePcap(std::string prefix, 
  464    NodeContainer n = NodeContainer::GetGlobal(); 
  466    for (auto i = n.Begin(); i != n.End(); ++i) 
  469        if (node->GetId() != nodeid) 
  474        NS_ABORT_MSG_IF(deviceid >= node->GetNDevices(), 
  476        Ptr<NetDevice> nd = node->GetDevice(deviceid);
 
  477        EnablePcap(prefix, nd, promiscuous);
 
 
  497    EnableAsciiInternal(stream, std::string(), nd, 
false);
 
 
  506                                       bool explicitFilename)
 
 
  517    EnableAsciiImpl(stream, std::string(), ndName, 
false);
 
 
  527                                           bool explicitFilename)
 
  530    EnableAsciiInternal(stream, prefix, nd, explicitFilename);
 
 
  548    EnableAsciiImpl(stream, std::string(), d);
 
 
  559    for (
auto i = d.
Begin(); i != d.
End(); ++i)
 
  562        EnableAsciiInternal(stream, prefix, dev, 
false);
 
 
  581    EnableAsciiImpl(stream, std::string(), n);
 
 
  593    for (
auto i = n.
Begin(); i != n.
End(); ++i)
 
  596        for (
uint32_t j = 0; j < node->GetNDevices(); ++j)
 
  598            devs.
Add(node->GetDevice(j));
 
  601    EnableAsciiImpl(stream, prefix, devs);
 
 
  630    EnableAsciiImpl(stream, std::string(), nodeid, deviceid, 
false);
 
 
  640                                       bool explicitFilename)
 
 
  653                                           bool explicitFilename)
 
  657    for (
auto i = n.
Begin(); i != n.
End(); ++i)
 
  660        if (node->GetId() != nodeid)
 
  666            deviceid >= node->GetNDevices(),
 
  667            "AsciiTraceHelperForDevice::EnableAscii(): Unknown deviceid = " << deviceid);
 
  671        EnableAsciiInternal(stream, prefix, nd, explicitFilename);
 
 
void EnableAsciiImpl(Ptr< OutputStreamWrapper > stream, std::string prefix, uint32_t nodeid, uint32_t deviceid, bool explicitFilename)
Enable ascii trace output on the device specified by a global node-id (of a previously created node) ...
void EnableAscii(std::string prefix, Ptr< NetDevice > nd, bool explicitFilename=false)
Enable ascii trace output on the indicated net device.
void EnableAsciiAll(std::string prefix)
Enable ascii trace output on each device (which is of the appropriate type) in the set of all nodes c...
Empty class, used as a default parent class for SimpleRefCount.
static Ptr< T > Find(std::string path)
Given a name path string, look to see if there's an object in the system with that associated to it.
static std::string FindName(Ptr< Object > object)
Given a pointer to an object, look to see if that object has a name associated with it and,...
holds a vector of ns3::NetDevice pointers
Iterator Begin() const
Get an iterator which refers to the first NetDevice in the container.
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
Iterator End() const
Get an iterator which indicates past-the-last NetDevice in the container.
keep track of a set of node pointers.
Iterator End() const
Get an iterator which indicates past-the-last Node in the container.
static NodeContainer GetGlobal()
Create a NodeContainer that contains a list of all nodes created through NodeContainer::Create() and ...
Iterator Begin() const
Get an iterator which refers to the first Node in the container.
Base class providing common user-level pcap operations for helpers representing net devices.
std::string GetFilenameFromDevice(std::string prefix, Ptr< NetDevice > device, bool useObjectNames=true)
Let the pcap helper figure out a reasonable filename to use for a pcap file associated with a device.
Ptr< PcapFileWrapper > CreateFile(std::string filename, std::ios::openmode filemode, DataLinkType dataLinkType, uint32_t snapLen=std::numeric_limits< uint32_t >::max(), int32_t tzCorrection=0)
Create and initialize a pcap file.
DataLinkType
This enumeration holds the data link types that will be written to the pcap file.
std::string GetFilenameFromInterfacePair(std::string prefix, Ptr< Object > object, uint32_t interface, bool useObjectNames=true)
Let the pcap helper figure out a reasonable filename to use for the pcap file associated with a node.
~PcapHelper()
Destroy a pcap helper.
PcapHelper()
Create a pcap helper.
Smart pointer class similar to boost::intrusive_ptr.
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if a condition is false, with a message.
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Every class exported by the ns3 library is enclosed in the ns3 namespace.