diff --git a/SConstruct b/SConstruct index 5aed0cab7..89ce1c537 100644 --- a/SConstruct +++ b/SConstruct @@ -32,15 +32,12 @@ if env['PLATFORM'] == 'posix' or env['PLATFORM'] == 'darwin' or env['PLATFORM'] core.add_external_dep('pthread') core.add_sources([ 'unix-system-wall-clock-ms.cc', - 'unix-system-file.cc' ]) elif env['PLATFORM'] == 'win32': core.add_sources([ 'win32-system-wall-clock-ms.cc', - 'win32-system-file.cc' ]) core.add_inst_headers([ - 'system-file.h', 'system-wall-clock-ms.h', 'reference-list.h', 'callback.h', @@ -219,6 +216,7 @@ node.add_sources ([ 'ascii-trace.cc', 'socket.cc', 'udp-socket.cc', + 'pcap-trace.cc', ]) node.add_headers ([ 'ipv4-header.h', @@ -268,6 +266,7 @@ node.add_inst_headers ([ 'udp-end-point.h', 'ipv4-end-point-demux.h', 'ipv4-end-point.h', + 'pcap-trace.h', ]) p2p = build.Ns3Module ('p2p', 'src/devices/p2p') diff --git a/doc/main.txt b/doc/main.txt index 0e85d3f3a..e267038ca 100644 --- a/doc/main.txt +++ b/doc/main.txt @@ -15,7 +15,6 @@ * * The "core" module contains: * - a Functor class: ns3::Callback - * - an os-independent interface to get write-only access to a file: ns3::SystemFile * - an os-independent interface to get access to the elapsed wall clock time: ns3::SystemWallClockMs * - a class to register regression tests with the test manager: ns3::Test and ns3::TestManager * - debugging facilities: \ref debugging, \ref assert, \ref error diff --git a/examples/simple-p2p.cc b/examples/simple-p2p.cc index 70858b94e..c8694cb67 100644 --- a/examples/simple-p2p.cc +++ b/examples/simple-p2p.cc @@ -49,6 +49,7 @@ #include "ns3/data-rate.h" #include "ns3/ascii-trace.h" +#include "ns3/pcap-trace.h" #include "ns3/internet-node.h" #include "ns3/p2p-channel.h" #include "ns3/p2p-net-device.h" @@ -154,9 +155,14 @@ int main (int argc, char *argv[]) // Configure tracing of all enqueue, dequeue, and NetDevice receive events // Trace output will be sent to the simple-p2p.tr file +#if 0 AsciiTrace trace ("simple-p2p.tr"); trace.TraceAllQueues (); trace.TraceAllNetDeviceRx (); +#else + PcapTrace trace ("simple-p2p.tr"); + trace.TraceAllIp (); +#endif Simulator::StopAt (Seconds(10.0)); diff --git a/src/common/pcap-writer.cc b/src/common/pcap-writer.cc index cbca7bf3b..cb5c06ad3 100644 --- a/src/common/pcap-writer.cc +++ b/src/common/pcap-writer.cc @@ -24,8 +24,9 @@ * http://wiki.ethereal.com/Development/LibpcapFileFormat */ +#include + #include "ns3/simulator.h" -#include "ns3/system-file.h" #include "pcap-writer.h" #include "packet.h" @@ -33,7 +34,9 @@ namespace ns3 { enum { - PCAP_ETHERNET = 1 + PCAP_ETHERNET = 1, + PCAP_RAW_IP = 101, + PCAP_80211 = 105, }; PcapWriter::PcapWriter () @@ -46,14 +49,32 @@ PcapWriter::~PcapWriter () } void -PcapWriter::Open (char const *name) +PcapWriter::Open (std::string const &name) { - m_writer = new SystemFile (); - m_writer->Open (name); + m_writer = new std::ofstream (); + m_writer->open (name.c_str ()); } void -PcapWriter::WriteHeaderEthernet (void) +PcapWriter::WriteEthernetHeader (void) +{ + WriteHeader (PCAP_ETHERNET); +} + +void +PcapWriter::WriteIpHeader (void) +{ + WriteHeader (PCAP_RAW_IP); +} + +void +PcapWriter::WriteWifiHeader (void) +{ + WriteHeader (PCAP_80211); +} + +void +PcapWriter::WriteHeader (uint32_t network) { Write32 (0xa1b2c3d4); Write16 (2); @@ -61,9 +82,12 @@ PcapWriter::WriteHeaderEthernet (void) Write32 (0); Write32 (0); Write32 (0xffff); - Write32 (PCAP_ETHERNET); + Write32 (network); } + + + void PcapWriter::WritePacket (Packet const packet) { @@ -76,24 +100,24 @@ PcapWriter::WritePacket (Packet const packet) Write32 (us & 0xffffffff); Write32 (packet.GetSize ()); Write32 (packet.GetSize ()); - m_writer->Write (packet.PeekData (), packet.GetSize ()); + WriteData (packet.PeekData (), packet.GetSize ()); } } void -PcapWriter::WriteData (uint8_t *buffer, uint32_t size) +PcapWriter::WriteData (uint8_t const*buffer, uint32_t size) { - m_writer->Write (buffer, size); + m_writer->write ((char const *)buffer, size); } void PcapWriter::Write32 (uint32_t data) { - m_writer->Write ((uint8_t*)&data, 4); + WriteData ((uint8_t*)&data, 4); } void PcapWriter::Write16 (uint16_t data) { - m_writer->Write ((uint8_t*)&data, 2); + WriteData((uint8_t*)&data, 2); } }; // namespace ns3 diff --git a/src/common/pcap-writer.h b/src/common/pcap-writer.h index c50981b44..29646a529 100644 --- a/src/common/pcap-writer.h +++ b/src/common/pcap-writer.h @@ -28,8 +28,6 @@ namespace ns3 { -class SystemFile; - /** * \brief Pcap output for Packet logger * @@ -46,7 +44,7 @@ public: * This method creates the file if it does not exist. If it * exists, the file is emptied. */ - void Open (char const *name); + void Open (std::string const &name); /** * Write a pcap header in the output file which specifies @@ -55,7 +53,11 @@ public: * be invoked before ns3::PcapWriter::writePacket and after * ns3::PcapWriter::open. */ - void WriteHeaderEthernet (void); + void WriteEthernetHeader (void); + + void WriteIpHeader (void); + + void WriteWifiHeader (void); /** * \param packet packet to write to output file @@ -63,10 +65,11 @@ public: void WritePacket (Packet const packet); private: - void WriteData (uint8_t *buffer, uint32_t size); + void WriteData (uint8_t const*buffer, uint32_t size); void Write32 (uint32_t data); void Write16 (uint16_t data); - SystemFile *m_writer; + void WriteHeader (uint32_t network); + std::ofstream *m_writer; Callback m_writeCallback; }; diff --git a/src/core/system-file.h b/src/core/system-file.h deleted file mode 100644 index a1dba2b13..000000000 --- a/src/core/system-file.h +++ /dev/null @@ -1,77 +0,0 @@ -/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ -/* - * Copyright (c) 2005 INRIA - * All rights reserved. - * - * 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 - * - * Author: Mathieu Lacage - */ - -#ifndef SYSTEM_FILE_H -#define SYSTEM_FILE_H - -#include - -namespace ns3 { - -class SystemFilePrivate; - -/** - * \brief os-independent file creation and writing - * - * Create a file and write data to this file. - */ -class SystemFile { -public: - /** - * This method does not create or open any - * file on disk. - */ - SystemFile (); - /** - * If a file has been opened, it is closed by - * this destructor. - */ - ~SystemFile (); - - /** - * \param filename name of file to open - * - * Open a file for writing. If the file does not - * exist, it is created. If it exists, it is - * emptied first. - */ - void Open (char const *filename); - /** - * \param buffer data to write - * \param size size of data to write - * - * Write data in file on disk. This method cannot fail: - * it will write _all_ the data to disk. This method does not - * perform any data caching and forwards the data - * to the OS through a direct syscall. However, - * it is not possible to rely on the data being - * effectively written to disk after this method returns. - * To make sure the data is written to disk, destroy - * this object. - */ - void Write (uint8_t const*buffer, uint32_t size); -private: - SystemFilePrivate *m_priv; -}; - -}; //namespace ns3 - -#endif /* SYSTEM_FILE_H */ diff --git a/src/core/unix-system-file.cc b/src/core/unix-system-file.cc deleted file mode 100644 index 6fa7916a7..000000000 --- a/src/core/unix-system-file.cc +++ /dev/null @@ -1,122 +0,0 @@ -/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ -/* - * Copyright (c) 2005 INRIA - * All rights reserved. - * - * 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 - * - * Author: Mathieu Lacage - */ -#include "system-file.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "assert.h" - -#define noTRACE_SYS_FILE 1 - -#ifdef TRACE_SYS_FILE -#include -# define TRACE(x) \ -std::cout << "SYS FILE TRACE " << this << " " << x << std::endl; -#else /* TRACE_SYS_FILE */ -# define TRACE(format,...) -#endif /* TRACE_SYS_FILE */ - -#define BUFFER_SIZE (4096) - - -namespace ns3 { - -class SystemFilePrivate { -public: - SystemFilePrivate (); - ~SystemFilePrivate (); - - void Open (char const *filename); - void Write (uint8_t const*buffer, uint32_t size); -private: - uint8_t m_data[BUFFER_SIZE]; - uint32_t m_current; - int m_fd; -}; - -SystemFilePrivate::SystemFilePrivate () - : m_current (0) -{} -SystemFilePrivate::~SystemFilePrivate () -{ - ::write (m_fd, m_data, m_current); - ::close (m_fd); -} - - -void -SystemFilePrivate::Open (char const *filename) -{ - m_fd = ::open (filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); - NS_ASSERT (m_fd != -1); -} - -#ifndef min -#define min(a,b) ((a)<(b)?(a):(b)) -#endif /* min */ - -void -SystemFilePrivate::Write (uint8_t const*buffer, uint32_t size) -{ - while (size > 0) - { - uint32_t toCopy = min (BUFFER_SIZE - m_current, size); - memcpy (m_data + m_current, buffer, toCopy); - size -= toCopy; - m_current += toCopy; - buffer += toCopy; - if (m_current == BUFFER_SIZE) - { - ssize_t written = 0; - written = ::write (m_fd, m_data, BUFFER_SIZE); - NS_ASSERT (written == BUFFER_SIZE); - m_current = 0; - } - } -} - -SystemFile::SystemFile () - : m_priv (new SystemFilePrivate ()) -{} -SystemFile::~SystemFile () -{ - delete m_priv; - m_priv = 0; -} - -void -SystemFile::Open (char const *filename) -{ - m_priv->Open (filename); -} -void -SystemFile::Write (uint8_t const*buffer, uint32_t size) -{ - m_priv->Write (buffer, size); -} - -}; // namespace diff --git a/src/core/win32-system-file.cc b/src/core/win32-system-file.cc deleted file mode 100644 index 4812633d7..000000000 --- a/src/core/win32-system-file.cc +++ /dev/null @@ -1,86 +0,0 @@ -/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ -/* - * Copyright (c) 2005 INRIA - * All rights reserved. - * - * 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 - * - * Author: Mathieu Lacage - */ -#include "system-file.h" - - -#define noTRACE_SYS_FILE 1 - -#ifdef TRACE_SYS_FILE -#include -# define TRACE(x) \ -std::cout << "SYS FILE TRACE " << this << " " << x << std::endl; -#else /* TRACE_SYS_FILE */ -# define TRACE(format,...) -#endif /* TRACE_SYS_FILE */ - -#define BUFFER_SIZE (4096) - - -namespace ns3 { - -class SystemFilePrivate { -public: - SystemFilePrivate (); - ~SystemFilePrivate (); - - void open (char const *filename); - void write (uint8_t const*buffer, uint32_t size); -private: -}; - -SystemFilePrivate::SystemFilePrivate () -{} -SystemFilePrivate::~SystemFilePrivate () -{ -} - - -void -SystemFilePrivate::Open (char const *filename) -{ -} - -void -SystemFilePrivate::Write (uint8_t const*buffer, uint32_t size) -{ -} - -SystemFile::SystemFile () - : m_priv (new SystemFilePrivate ()) -{} -SystemFile::~SystemFile () -{ - delete m_priv; - m_priv = 0; -} - -void -SystemFile::Open (char const *filename) -{ - m_priv->Open (filename); -} -void -SystemFile::Write (uint8_t const*buffer, uint32_t size) -{ - m_priv->Write (buffer, size); -} - -}; // namespace diff --git a/src/node/ipv4.cc b/src/node/ipv4.cc index d2eb66d40..da112396b 100644 --- a/src/node/ipv4.cc +++ b/src/node/ipv4.cc @@ -356,7 +356,16 @@ Ipv4::Copy(Node *node) const void Ipv4::Receive(Packet& packet, NetDevice &device) { - m_rxTrace (packet); + uint32_t index = 0; + for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++) + { + if ((*i)->GetDevice () == &device) + { + m_rxTrace (packet, index); + break; + } + index++; + } Ipv4Header ipHeader; packet.Peek (ipHeader); packet.Remove (ipHeader); @@ -376,9 +385,9 @@ Ipv4::Receive(Packet& packet, NetDevice &device) void Ipv4::Send (Packet const &packet, - Ipv4Address source, - Ipv4Address destination, - uint8_t protocol) + Ipv4Address source, + Ipv4Address destination, + uint8_t protocol) { Ipv4Header ipHeader; @@ -418,7 +427,7 @@ Ipv4::SendRealOut (Packet const &p, Ipv4Header const &ip, Ipv4Route const &route packet.Add (ip); Ipv4Interface *outInterface = GetInterface (route.GetInterface ()); NS_ASSERT (packet.GetSize () <= outInterface->GetMtu ()); - m_txTrace (packet); + m_txTrace (packet, route.GetInterface ()); if (route.IsGateway ()) { outInterface->Send (packet, route.GetGateway ()); diff --git a/src/node/ipv4.h b/src/node/ipv4.h index 63a3272a6..d0c52d694 100644 --- a/src/node/ipv4.h +++ b/src/node/ipv4.h @@ -241,8 +241,8 @@ public: NetworkRoutes m_networkRoutes; Ipv4Route *m_defaultRoute; Node *m_node; - CallbackTraceSource m_txTrace; - CallbackTraceSource m_rxTrace; + CallbackTraceSource m_txTrace; + CallbackTraceSource m_rxTrace; CallbackTraceSource m_dropTrace; }; diff --git a/src/node/pcap-trace.cc b/src/node/pcap-trace.cc new file mode 100644 index 000000000..acc478bcf --- /dev/null +++ b/src/node/pcap-trace.cc @@ -0,0 +1,93 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2007 INRIA + * All rights reserved. + * + * 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 + * + * Author: Mathieu Lacage + */ +#include "pcap-trace.h" + +#include + +#include "ns3/trace-root.h" +#include "ns3/trace-context.h" +#include "ns3/callback.h" +#include "ns3/pcap-writer.h" + +#include "ipv4.h" +#include "node-list.h" +#include "node.h" + + +namespace ns3 { + + +PcapTrace::PcapTrace (std::string filename) + : m_filename (filename) +{} +PcapTrace::~PcapTrace () +{ + for (std::vector::iterator i = m_traces.begin (); + i != m_traces.end (); i++) + { + delete i->writer; + } +} + +void +PcapTrace::TraceAllIp (void) +{ + TraceRoot::Connect ("/nodes/*/ipv4/(tx|rx)", + MakeCallback (&PcapTrace::LogIp, this)); +} + +PcapWriter * +PcapTrace::GetStream (uint32_t nodeId, uint32_t interfaceId) +{ + for (std::vector::iterator i = m_traces.begin (); + i != m_traces.end (); i++) + { + if (i->nodeId == nodeId && + i->interfaceId == interfaceId) + { + return i->writer; + } + } + PcapTrace::Trace trace; + trace.nodeId = nodeId; + trace.interfaceId = interfaceId; + trace.writer = new PcapWriter (); + std::ostringstream oss; + oss << m_filename << "-" << nodeId << "-" << interfaceId; + std::string filename = oss.str (); + trace.writer->Open (filename); + trace.writer->WriteIpHeader (); + m_traces.push_back (trace); + return trace.writer; +} + +void +PcapTrace::LogIp (TraceContext const &context, Packet const &p, uint32_t interfaceIndex) +{ + NodeList::NodeIndex nodeIndex; + context.Get (nodeIndex); + uint32_t nodeId = NodeList::GetNode (nodeIndex)->GetId (); + PcapWriter *writer = GetStream (nodeId, interfaceIndex); + writer->WritePacket (p); +} + + +}//namespace ns3 diff --git a/src/node/pcap-trace.h b/src/node/pcap-trace.h new file mode 100644 index 000000000..3d0f6547a --- /dev/null +++ b/src/node/pcap-trace.h @@ -0,0 +1,54 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2007 INRIA + * All rights reserved. + * + * 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 + * + * Author: Mathieu Lacage + */ +#ifndef PCAP_TRACE_H +#define PCAP_TRACE_H + +#include +#include + +namespace ns3 { + +class Packet; +class TraceContext; +class PcapWriter; + +class PcapTrace +{ +public: + PcapTrace (std::string filename); + ~PcapTrace (); + + void TraceAllIp (void); +private: + PcapWriter *GetStream (uint32_t nodeId, uint32_t interfaceId); + void LogIp (TraceContext const &context, Packet const &p, uint32_t interfaceIndex); + std::string m_filename; + struct Trace { + uint32_t nodeId; + uint32_t interfaceId; + PcapWriter *writer; + }; + std::vector m_traces; +}; + +}//namespace ns3 + +#endif /* PCAP_TRACE_H */