merge with pcap branch
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Tue, 01 May 2007 11:35:27 +0200
changeset 461 3cde302c4300
parent 453 ddbb935800d8 (current diff)
parent 460 9b4ba94e2357 (diff)
child 462 9f39ce362810
merge with pcap branch
SConstruct
doc/main.txt
examples/simple-p2p.cc
src/core/system-file.h
src/core/unix-system-file.cc
src/core/win32-system-file.cc
src/node/ipv4.cc
src/node/ipv4.h
--- a/SConstruct	Mon Apr 30 16:23:10 2007 +0200
+++ b/SConstruct	Tue May 01 11:35:27 2007 +0200
@@ -32,15 +32,12 @@
     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 @@
     'ascii-trace.cc',
     'socket.cc',
     'udp-socket.cc',
+    'pcap-trace.cc',
     ])
 node.add_headers ([
     'ipv4-header.h',
@@ -268,6 +266,7 @@
     'udp-end-point.h',
     'ipv4-end-point-demux.h',
     'ipv4-end-point.h',
+    'pcap-trace.h',
     ])
 
 p2p = build.Ns3Module ('p2p', 'src/devices/p2p')
--- a/doc/main.txt	Mon Apr 30 16:23:10 2007 +0200
+++ b/doc/main.txt	Tue May 01 11:35:27 2007 +0200
@@ -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
--- a/examples/simple-p2p.cc	Mon Apr 30 16:23:10 2007 +0200
+++ b/examples/simple-p2p.cc	Tue May 01 11:35:27 2007 +0200
@@ -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 @@
 
   // 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));
 
--- a/src/common/pcap-writer.cc	Mon Apr 30 16:23:10 2007 +0200
+++ b/src/common/pcap-writer.cc	Tue May 01 11:35:27 2007 +0200
@@ -24,8 +24,9 @@
  * http://wiki.ethereal.com/Development/LibpcapFileFormat
  */
 
+#include <fstream>
+
 #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 @@
 }
 
 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::WriteEthernetHeader (void)
+{
+  WriteHeader (PCAP_ETHERNET);
 }
 
 void 
-PcapWriter::WriteHeaderEthernet (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 @@
   Write32 (0);
   Write32 (0);
   Write32 (0xffff);
-  Write32 (PCAP_ETHERNET);
+  Write32 (network);
 }
 
+
+
+
 void 
 PcapWriter::WritePacket (Packet const packet)
 {
@@ -76,24 +100,24 @@
       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
--- a/src/common/pcap-writer.h	Mon Apr 30 16:23:10 2007 +0200
+++ b/src/common/pcap-writer.h	Tue May 01 11:35:27 2007 +0200
@@ -28,8 +28,6 @@
 
 namespace ns3 {
 
-class SystemFile;
-
 /**
  * \brief Pcap output for Packet logger
  *
@@ -46,7 +44,7 @@
    * 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 @@
    * 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 @@
   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<void,uint8_t *,uint32_t> m_writeCallback;
 };
 
--- a/src/core/system-file.h	Mon Apr 30 16:23:10 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -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 <mathieu.lacage@sophia.inria.fr>
- */
-
-#ifndef SYSTEM_FILE_H
-#define SYSTEM_FILE_H
-
-#include <stdint.h>
-
-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 */
--- a/src/core/unix-system-file.cc	Mon Apr 30 16:23:10 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -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 <mathieu.lacage@sophia.inria.fr>
- */
-#include "system-file.h"
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/poll.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
-#include <list>
-
-#include "assert.h"
-
-#define noTRACE_SYS_FILE 1
-
-#ifdef TRACE_SYS_FILE
-#include <iostream>
-# 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
--- a/src/core/win32-system-file.cc	Mon Apr 30 16:23:10 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -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 <mathieu.lacage@sophia.inria.fr>
- */
-#include "system-file.h"
-
-
-#define noTRACE_SYS_FILE 1
-
-#ifdef TRACE_SYS_FILE
-#include <iostream>
-# 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
--- a/src/node/ipv4.cc	Mon Apr 30 16:23:10 2007 +0200
+++ b/src/node/ipv4.cc	Tue May 01 11:35:27 2007 +0200
@@ -356,7 +356,16 @@
 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 @@
 
 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 @@
   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 ());
--- a/src/node/ipv4.h	Mon Apr 30 16:23:10 2007 +0200
+++ b/src/node/ipv4.h	Tue May 01 11:35:27 2007 +0200
@@ -241,8 +241,8 @@
   NetworkRoutes m_networkRoutes;
   Ipv4Route *m_defaultRoute;
   Node *m_node;
-  CallbackTraceSource<Packet const &> m_txTrace;
-  CallbackTraceSource<Packet const &> m_rxTrace;
+  CallbackTraceSource<Packet const &, uint32_t> m_txTrace;
+  CallbackTraceSource<Packet const &, uint32_t> m_rxTrace;
   CallbackTraceSource<Packet const &> m_dropTrace;
 };
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/pcap-trace.cc	Tue May 01 11:35:27 2007 +0200
@@ -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 <mathieu.lacage@sophia.inria.fr>
+ */
+#include "pcap-trace.h"
+
+#include <sstream>
+
+#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<Trace>::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<Trace>::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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/pcap-trace.h	Tue May 01 11:35:27 2007 +0200
@@ -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 <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef PCAP_TRACE_H
+#define PCAP_TRACE_H
+
+#include <string>
+#include <vector>
+
+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<Trace> m_traces;
+};
+
+}//namespace ns3
+
+#endif /* PCAP_TRACE_H */