merge
authorTom Henderson <tomh@tomh.org>
Fri, 27 Jul 2007 10:49:29 -0700
changeset 980 469fb688f446
parent 979 cb805f7a2e8d (current diff)
parent 978 081711898aea (diff)
child 981 eda90b17fc05
merge
src/devices/p2p/p2p-channel.cc
src/devices/p2p/p2p-channel.h
src/devices/p2p/p2p-net-device.cc
src/devices/p2p/p2p-net-device.h
src/devices/p2p/p2p-topology.cc
src/devices/p2p/p2p-topology.h
src/devices/p2p/wscript
src/internet-node/header-utils.cc
src/internet-node/header-utils.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/simple-csma-cd.cc	Fri Jul 27 10:49:29 2007 -0700
@@ -0,0 +1,168 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * 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
+ */
+
+// Port of ns-2/tcl/ex/simple.tcl to ns-3
+//
+// Network topology
+//
+//       n0
+//       |
+//       |
+//  n2---+----n3
+//       |
+//       |
+//       n1
+//
+// - CBR/UDP flows from n0 to n1, and from n3 to n0
+// - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec.
+//   (i.e., DataRate of 448,000 bps)
+// - DropTail queues 
+// - Tracing of queues and packet receptions to file "simple-csma-cd.tr"
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <cassert>
+
+#include "ns3/command-line.h"
+#include "ns3/default-value.h"
+#include "ns3/ptr.h"
+#include "ns3/random-variable.h"
+#include "ns3/debug.h"
+
+#include "ns3/simulator.h"
+#include "ns3/nstime.h"
+#include "ns3/data-rate.h"
+
+#include "ns3/ascii-trace.h"
+#include "ns3/pcap-trace.h"
+#include "ns3/internet-node.h"
+#include "ns3/csma-cd-channel.h"
+#include "ns3/csma-cd-net-device.h"
+#include "ns3/csma-cd-topology.h"
+#include "ns3/csma-cd-ipv4-topology.h"
+#include "ns3/mac-address.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/ipv4.h"
+#include "ns3/socket.h"
+#include "ns3/ipv4-route.h"
+#include "ns3/onoff-application.h"
+
+#include "ns3/ascii-trace.h"
+
+#include "ns3/trace-context.h"
+#include "ns3/trace-root.h"
+
+
+using namespace ns3;
+
+
+int main (int argc, char *argv[])
+{
+
+  // Users may find it convenient to turn on explicit debugging
+  // for selected modules; the below lines suggest how to do this
+#if 0 
+  DebugComponentEnable("Channel");
+  DebugComponentEnable("CsmaCdChannel");
+  DebugComponentEnable("CsmaCdNetDevice");
+  DebugComponentEnable("NetDevice");
+  DebugComponentEnable("PacketSocket");
+#endif
+
+  // Set up some default values for the simulation.  Use the Bind()
+  // technique to tell the system what subclass of Queue to use,
+  // and what the queue limit is
+
+  // The below Bind command tells the queue factory which class to
+  // instantiate, when the queue factory is invoked in the topology code
+  Bind ("Queue", "DropTailQueue");
+
+  // Allow the user to override any of the defaults and the above
+  // Bind()s at run-time, via command-line arguments
+  CommandLine::Parse (argc, argv);
+
+  // Here, we will explicitly create four nodes.  In more sophisticated
+  // topologies, we could configure a node factory.
+  Ptr<Node> n0 = Create<InternetNode> ();
+  Ptr<Node> n1 = Create<InternetNode> (); 
+  Ptr<Node> n2 = Create<InternetNode> (); 
+  Ptr<Node> n3 = Create<InternetNode> ();
+
+  // We create the channels first without any IP addressing information
+  Ptr<CsmaCdChannel> channel0 = 
+    CsmaCdTopology::CreateCsmaCdChannel(
+      DataRate(5000000), MilliSeconds(2));
+
+  CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n0, channel0, 
+                                         MacAddress("10:54:23:54:23:50"));
+  CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n1, channel0,
+                                         MacAddress("10:54:23:54:23:51"));
+  CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n2, channel0,
+                                         MacAddress("10:54:23:54:23:52"));
+  CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n3, channel0,
+                                         MacAddress("10:54:23:54:23:53"));
+
+  // Later, we add IP addresses.  
+  CsmaCdIpv4Topology::AddIpv4Address (
+      n0, 1, Ipv4Address("10.1.1.1"), Ipv4Mask("255.255.255.0"));
+
+  CsmaCdIpv4Topology::AddIpv4Address (
+      n1, 1, Ipv4Address("10.1.1.2"), Ipv4Mask("255.255.255.0"));
+
+  CsmaCdIpv4Topology::AddIpv4Address (
+      n2, 1, Ipv4Address("10.1.1.3"), Ipv4Mask("255.255.255.0"));
+  
+  CsmaCdIpv4Topology::AddIpv4Address (
+      n3, 1, Ipv4Address("10.1.1.4"), Ipv4Mask("255.255.255.0"));
+
+
+  // Create the OnOff application to send UDP datagrams of size
+  // 210 bytes at a rate of 448 Kb/s
+  // from n0 to n1
+  Ptr<OnOffApplication> ooff = Create<OnOffApplication> (
+    n0, 
+    Ipv4Address("10.1.1.2"), 
+    80, 
+    "Udp",
+    ConstantVariable(1), 
+    ConstantVariable(0));
+  // Start the application
+  ooff->Start(Seconds(1.0));
+  ooff->Stop (Seconds(10.0));
+
+  // Create a similar flow from n3 to n0, starting at time 1.1 seconds
+  ooff = Create<OnOffApplication> (
+    n3, 
+    Ipv4Address("10.1.1.1"), 
+    80, 
+    "Udp",
+    ConstantVariable(1), 
+    ConstantVariable(0));
+  // Start the application
+  ooff->Start(Seconds(1.1));
+  ooff->Stop (Seconds(10.0));
+ 
+  // Configure tracing of all enqueue, dequeue, and NetDevice receive events
+  // Trace output will be sent to the simple-p2p.tr file
+  AsciiTrace asciitrace ("simple-csma-cd.tr");
+  asciitrace.TraceAllNetDeviceRx ();
+  //  asciitrace.TraceAllQueues ();
+
+  Simulator::Run ();
+    
+  Simulator::Destroy ();
+}
--- a/examples/simple-p2p.cc	Fri Jul 27 10:48:10 2007 -0700
+++ b/examples/simple-p2p.cc	Fri Jul 27 10:49:29 2007 -0700
@@ -54,14 +54,14 @@
 #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"
+#include "ns3/point-to-point-channel.h"
+#include "ns3/point-to-point-net-device.h"
 #include "ns3/mac-address.h"
 #include "ns3/ipv4-address.h"
 #include "ns3/ipv4.h"
 #include "ns3/socket.h"
 #include "ns3/ipv4-route.h"
-#include "ns3/p2p-topology.h"
+#include "ns3/point-to-point-topology.h"
 #include "ns3/onoff-application.h"
 
 using namespace ns3;
--- a/examples/wscript	Fri Jul 27 10:48:10 2007 -0700
+++ b/examples/wscript	Fri Jul 27 10:49:29 2007 -0700
@@ -9,5 +9,6 @@
         obj.source = source
         return obj
         
-    obj = create_ns_prog('simple-p2p', 'simple-p2p.cc', deps=['p2p', 'internet-node'])
+    obj = create_ns_prog('simple-p2p', 'simple-p2p.cc', deps=['point-to-point', 'internet-node'])
+    obj = create_ns_prog('simple-csma-cd', 'simple-csma-cd.cc', deps=['csma-cd', 'internet-node'])
 
--- a/samples/wscript	Fri Jul 27 10:48:10 2007 -0700
+++ b/samples/wscript	Fri Jul 27 10:49:29 2007 -0700
@@ -18,9 +18,9 @@
     obj = create_ns_prog('main-test', 'main-test.cc')
     obj = create_ns_prog('main-simple', 'main-simple.cc',
                          deps=['node', 'internet-node', 'applications'])
-    #obj = create_ns_prog('main-simple-p2p', 'main-simple-p2p.cc', deps=['node', 'p2p'])
+    #obj = create_ns_prog('main-simple-p2p', 'main-simple-p2p.cc', deps=['node', 'point-to-point'])
     obj = create_ns_prog('main-default-value', 'main-default-value.cc',
-                         deps=['core', 'simulator', 'node', 'p2p'])
+                         deps=['core', 'simulator', 'node', 'point-to-point'])
     obj = create_ns_prog('main-grid-topology', 'main-grid-topology.cc',
                          deps=['core', 'simulator', 'mobility', 'internet-node'])
     obj = create_ns_prog('main-random-topology', 'main-random-topology.cc',
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma-cd/backoff.cc	Fri Jul 27 10:49:29 2007 -0700
@@ -0,0 +1,83 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007, Emmanuelle Laprise
+ * 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
+ */
+
+#include "backoff.h"
+
+namespace ns3 {
+
+Backoff::Backoff() 
+{
+  m_slotTime = MicroSeconds(1);
+  m_minSlots = 1;
+  m_maxSlots = 1000;
+  m_ceiling = 10;
+  m_maxRetries = 1000;
+
+  ResetBackoffTime();
+}
+
+Backoff::Backoff(Time slotTime, uint32_t minSlots, uint32_t maxSlots,
+                 uint32_t ceiling, uint32_t maxRetries)
+{
+  m_slotTime = slotTime;
+  m_minSlots = minSlots;
+  m_maxSlots = maxSlots;
+  m_ceiling = ceiling;
+  m_maxRetries = maxRetries;
+}  
+
+Time
+Backoff::GetBackoffTime (void)
+{
+  Time backoff;
+  uint32_t ceiling;
+
+  if ((m_ceiling > 0) &&(m_numBackoffRetries > m_ceiling))
+    ceiling = m_ceiling;
+  else
+    ceiling = m_numBackoffRetries;
+
+  uint32_t minSlot = m_minSlots;
+  uint32_t maxSlot = (uint32_t)pow(2, ceiling) - 1;
+  if (maxSlot > m_maxSlots)
+    maxSlot = m_maxSlots;
+
+  uint32_t backoffSlots = 
+    (uint32_t)UniformVariable::GetSingleValue(minSlot, maxSlot);
+
+  backoff = Scalar(backoffSlots) * m_slotTime;
+  return (backoff);
+}
+
+void Backoff::ResetBackoffTime (void)
+{
+  m_numBackoffRetries = 0;
+}
+
+bool Backoff::MaxRetriesReached(void) {
+  return (m_numBackoffRetries >= m_maxRetries);
+}
+
+void Backoff::IncrNumRetries(void) {
+  m_numBackoffRetries++;
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma-cd/backoff.h	Fri Jul 27 10:49:29 2007 -0700
@@ -0,0 +1,87 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 Emmanuelle Laprise
+ *
+ * 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca
+ * Derived from the p2p net device file
+Transmi */
+
+#ifndef BACKOFF_H
+#define BACKOFF_H
+
+#include <stdint.h>
+#include "ns3/nstime.h"
+#include "ns3/random-variable.h"
+
+namespace ns3 {
+
+  /**
+   * \brief The backoff class is used for calculating backoff times
+   * when many net devices can write to the same channel
+   *
+   */
+
+class Backoff {
+public:
+  uint32_t m_minSlots; // Minimum number of backoff slots (when
+                       // multiplied by m_slotTime, determines minimum
+                       // backoff time)
+  uint32_t m_maxSlots; // Maximim number of backoff slots (when
+                       // multiplied by m_slotTime, determines
+                       // maximum backoff time)
+  uint32_t m_ceiling;  // Caps the exponential function when the
+                       // number of retries reaches m_ceiling
+  uint32_t m_maxRetries; // Maximum number of transmission retries
+                         // before the packet is dropped.
+  Time     m_slotTime; // Length of one slot. A slot time, it usually
+                       // the packet transmission time, if the packet
+                       // size is fixed.
+
+  Backoff();
+  Backoff(Time slotTime, uint32_t minSlots, uint32_t maxSlots, 
+          uint32_t ceiling, uint32_t maxRetries);
+
+  /**
+   * \return The amount of time that the net device should wait before
+   * trying to retransmit the packet
+   */
+  Time GetBackoffTime();
+  /**
+   * Indicates to the backoff object that the last packet was
+   * successfully transmitted and that the number of retries should be
+   * reset to 0.
+   */
+  void ResetBackoffTime();
+  /**
+   * \return True if the maximum number of retries has been reached
+   */
+  bool MaxRetriesReached();
+  /**
+   * Increments the number of retries by 1.
+   */
+  void IncrNumRetries();
+
+private:
+  uint32_t m_numBackoffRetries; // Number of times that the
+                                // transmitter has tried to
+                                // unsuccessfully transmit the current
+                                // packet
+};
+
+}; // namespace ns3
+
+#endif // BACKOFF_H
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma-cd/csma-cd-channel.cc	Fri Jul 27 10:49:29 2007 -0700
@@ -0,0 +1,359 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 Emmanuelle Laprise
+ * 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
+ */
+
+#include "csma-cd-channel.h"
+#include "csma-cd-net-device.h"
+#include "ns3/packet.h"
+#include "ns3/simulator.h"
+#include "ns3/debug.h"
+
+NS_DEBUG_COMPONENT_DEFINE ("CsmaCdChannel");
+
+namespace ns3 {
+
+CsmaCdDeviceRec::CsmaCdDeviceRec()
+{
+  active = false;
+}
+
+CsmaCdDeviceRec::CsmaCdDeviceRec(Ptr<CsmaCdNetDevice> device)
+{
+  devicePtr = device; 
+  active = true;
+}
+
+bool
+CsmaCdDeviceRec::IsActive() {
+  return active;
+}
+
+
+//
+// By default, you get a channel with the name "CsmaCd Channel" that 
+// has an "infitely" fast transmission speed and zero delay.
+CsmaCdChannel::CsmaCdChannel()
+: 
+  Channel ("CsmaCd Channel"), 
+  m_bps (DataRate(0xffffffff)),
+  m_delay (Seconds(0))
+{
+  NS_DEBUG("CsmaCdChannel::CsmaCdChannel ()");
+  Init();
+}
+
+CsmaCdChannel::CsmaCdChannel(
+  const DataRate& bps, 
+  const Time& delay)
+: 
+  Channel ("CsmaCd Channel"), 
+  m_bps (bps),
+  m_delay (delay)
+{
+  NS_DEBUG("CsmaCdChannel::CsmaCdChannel (" << Channel::GetName() 
+    << ", " << bps.GetBitRate() << ", " << delay << ")");
+  Init();
+}
+
+CsmaCdChannel::CsmaCdChannel(
+  const std::string& name,
+  const DataRate& bps, 
+  const Time& delay)
+: 
+  Channel (name),
+  m_bps (bps), 
+  m_delay (delay)
+{
+  NS_DEBUG("CsmaCdChannel::CsmaCdChannel (" << name << ", " << 
+           bps.GetBitRate() << ", " << delay << ")");
+  Init();
+}
+
+void CsmaCdChannel::Init() {
+  m_state = IDLE;
+  m_deviceList.clear();
+}
+
+int32_t
+CsmaCdChannel::Attach(Ptr<CsmaCdNetDevice> device)
+{
+  NS_DEBUG("CsmaCdChannel::Attach (" << device << ")");
+  NS_ASSERT(device != 0);
+
+  CsmaCdDeviceRec rec(device);
+  
+  m_deviceList.push_back(rec);
+  return (m_deviceList.size() - 1);
+}
+
+bool
+CsmaCdChannel::Reattach(Ptr<CsmaCdNetDevice> device)
+{
+  NS_DEBUG("CsmaCdChannel::Reattach (" << device << ")");
+  NS_ASSERT(device != 0);
+
+  std::vector<CsmaCdDeviceRec>::iterator it;
+  for (it = m_deviceList.begin(); it < m_deviceList.end(); it++) 
+    {
+      if (it->devicePtr == device) 
+        {
+          if (!it->active) {
+            it->active = true;
+            return true;
+          } else {
+            return false;
+          }
+        }
+    }
+  return false;
+}
+
+bool
+CsmaCdChannel::Reattach(uint32_t deviceId)
+{
+  NS_DEBUG("CsmaCdChannel::Reattach (" << deviceId << ")");
+  if (deviceId < m_deviceList.size())
+    {
+      return false;
+    }
+
+  if (m_deviceList[deviceId].active)
+    {
+      return false;
+    } else {
+      m_deviceList[deviceId].active = true;
+      return true;
+    }
+}
+
+bool
+CsmaCdChannel::Detach(uint32_t deviceId)
+{
+  NS_DEBUG("CsmaCdChannel::Detach (" << deviceId << ")");
+
+  if (deviceId < m_deviceList.size())
+    {
+      if (!m_deviceList[deviceId].active)
+        {
+          NS_DEBUG("CsmaCdChannel::Detach Device is already detached (" 
+                   << deviceId << ")");
+          return false;
+        }
+
+      m_deviceList[deviceId].active = false;
+      if ((m_state == TRANSMITTING) && (m_currentSrc == deviceId))
+        {
+          NS_DEBUG("CsmaCdChannel::Detach Device is currently"
+                   << "transmitting (" << deviceId << ")");
+          // Here we will need to place a warning in the packet
+        }
+
+      return true;
+    } else {
+      return false;
+    }
+}
+
+bool
+CsmaCdChannel::Detach(Ptr<CsmaCdNetDevice> device)
+{
+  NS_DEBUG("CsmaCdChannel::Detach (" << device << ")");
+  NS_ASSERT(device != 0);
+
+  std::vector<CsmaCdDeviceRec>::iterator it;
+  for (it = m_deviceList.begin(); it < m_deviceList.end(); it++) 
+    {
+      if ((it->devicePtr == device) && (it->active)) 
+        {
+          it->active = false;
+          return true;
+        }
+    }
+  return false;
+}
+
+bool
+CsmaCdChannel::TransmitStart(Packet& p, uint32_t srcId)
+{
+  NS_DEBUG ("CsmaCdChannel::TransmitStart (" << &p << ", " << srcId 
+            << ")");
+  NS_DEBUG ("CsmaCdChannel::TransmitStart (): UID is " << 
+            p.GetUid () << ")");
+
+  if (m_state != IDLE)
+    {
+      NS_DEBUG("CsmaCdChannel::TransmitStart (): state is not IDLE");
+      return false;
+    }
+
+  if (!IsActive(srcId))
+    {
+      NS_DEBUG("CsmaCdChannel::TransmitStart (): ERROR: Seclected "
+               << "source is not currently attached to network");
+      return false;
+    }
+
+  NS_DEBUG("CsmaCdChannel::TransmitStart (): switch to TRANSMITTING");
+  m_currentPkt = p;
+  m_currentSrc = srcId;
+  m_state = TRANSMITTING;
+  return true;
+}
+
+bool
+CsmaCdChannel::IsActive(uint32_t deviceId) {
+    return (m_deviceList[deviceId].active);
+}
+
+bool
+CsmaCdChannel::TransmitEnd()
+{
+  NS_DEBUG("CsmaCdChannel::TransmitEnd (" << &m_currentPkt << ", " 
+           << m_currentSrc << ")");
+  NS_DEBUG("CsmaCdChannel::TransmitEnd (): UID is " << 
+            m_currentPkt.GetUid () << ")");
+
+  NS_ASSERT(m_state == TRANSMITTING);
+  m_state = PROPAGATING;
+
+  bool retVal = true;
+
+  if (!IsActive(m_currentSrc)) {
+    NS_DEBUG("CsmaCdChannel::TransmitEnd (): ERROR: Seclected source "
+             << "was detached before the end of the transmission");
+    retVal = false;
+  }
+
+  NS_DEBUG ("CsmaCdChannel::TransmitEnd (): Schedule event in " << 
+            m_delay.GetSeconds () << "sec");
+
+  Simulator::Schedule (m_delay,
+                       &CsmaCdChannel::PropagationCompleteEvent,
+                       this);
+  return retVal;
+}
+
+void
+CsmaCdChannel::PropagationCompleteEvent()
+{
+  NS_DEBUG("CsmaCdChannel::PropagationCompleteEvent (" 
+           << &m_currentPkt << ")");
+  NS_DEBUG ("CsmaCdChannel::PropagationCompleteEvent (): UID is " << 
+            m_currentPkt.GetUid () << ")");
+
+  NS_ASSERT(m_state == PROPAGATING);
+  m_state = IDLE;
+
+  NS_DEBUG ("CsmaCdChannel::PropagationCompleteEvent (): Receive");
+  
+  std::vector<CsmaCdDeviceRec>::iterator it;
+  for (it = m_deviceList.begin(); it < m_deviceList.end(); it++) 
+    {
+      if (it->IsActive())
+      {
+        it->devicePtr->Receive (m_currentPkt);
+      }
+    }
+}
+
+
+uint32_t 
+CsmaCdChannel::GetNumActDevices (void)
+{
+  int numActDevices = 0;
+  std::vector<CsmaCdDeviceRec>::iterator it;
+  for (it = m_deviceList.begin(); it < m_deviceList.end(); it++) 
+    {
+      if (it->active)
+        {
+          numActDevices++;
+        }
+    }
+  return numActDevices;
+}
+
+// This is not the number of active devices. This is the total number
+// of devices even if some were detached after.
+uint32_t 
+CsmaCdChannel::GetNDevices (void) const
+{
+  return (m_deviceList.size());
+}
+
+Ptr<NetDevice>
+CsmaCdChannel::GetDevice (uint32_t i) const
+{
+  Ptr< CsmaCdNetDevice > netDevice;
+
+  netDevice = m_deviceList[i].devicePtr;
+  return netDevice;
+}
+
+int32_t
+CsmaCdChannel::GetDeviceNum (Ptr<CsmaCdNetDevice> device)
+{
+  std::vector<CsmaCdDeviceRec>::iterator it;
+  int i = 0;
+  for (it = m_deviceList.begin(); it < m_deviceList.end(); it++) 
+    {
+      if (it->devicePtr == device)
+        {
+          if (it->active) 
+            {
+              return i;
+            } else {
+              return -2;
+            }
+        }
+      i++;
+    }
+  return -1;
+}
+
+bool 
+CsmaCdChannel::IsBusy (void)
+{
+  if (m_state == IDLE) 
+    {
+      return false;
+    } else {
+      return true;
+    }
+}
+
+DataRate
+CsmaCdChannel::GetDataRate (void)
+{
+  return m_bps;
+}
+
+Time
+CsmaCdChannel::GetDelay (void)
+{
+  return m_delay;
+}
+
+WireState
+CsmaCdChannel::GetState(void)
+{
+  return m_state;
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma-cd/csma-cd-channel.h	Fri Jul 27 10:49:29 2007 -0700
@@ -0,0 +1,307 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 Emmanuelle Laprise
+ *
+ * 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: Emmanuelle Laprise<emmanuelle.laprise@bluekazoo.ca>
+ */
+
+#ifndef CSMA_CD_CHANNEL_H
+#define CSMA_CD_CHANNEL_H
+
+#include "ns3/channel.h"
+#include "ns3/ptr.h"
+#include "ns3/packet.h"
+#include "ns3/nstime.h"
+#include "ns3/data-rate.h"
+
+namespace ns3 {
+
+class CsmaCdNetDevice;
+
+  /**
+   * \brief CsmaCdNetDevice Record 
+   *
+   * Stores the information related to each net device that is
+   * connected to the channel. 
+   */
+  class CsmaCdDeviceRec {
+  public:
+    Ptr< CsmaCdNetDevice > devicePtr; /// Pointer to the net device
+    bool                       active;    /// Is net device enabled to TX/RX
+
+    CsmaCdDeviceRec();
+    CsmaCdDeviceRec(Ptr< CsmaCdNetDevice > device);
+    /*
+     * \return If the net device pointed to by the devicePtr is active
+     * and ready to RX/TX.
+     */
+    bool IsActive();                   
+  };
+
+  /**
+   * Current state of the channel
+   */ 
+  enum WireState
+    {
+      IDLE,          /**< Channel is IDLE, no packet is being
+                        transmitted */
+      TRANSMITTING,  /**< Channel is BUSY, a packet is being written
+                        by a net device */
+      PROPAGATING    /**< Channel is BUSY, packet is propagating to
+                        all attached net devices */
+    };
+
+/**
+ * \brief CsmaCd Channel.
+ *
+ * This class represents a simple Csma/Cd channel that can be used
+ * when many nodes are connected to one wire. It uses a single busy
+ * flag to indicate if the channel is currently in use. It does not
+ * take into account the distances between stations or the speed of
+ * light to determine collisions.
+ *
+ * Each net device must query the state of the channel and make sure
+ * that it is IDLE before writing a packet to the channel.
+ *
+ * When the channel is instaniated, the constructor takes parameters
+ * for a single speed, in bits per second, and a speed-of-light delay
+ * time as a Time object.  When a net device is attached to a channel,
+ * it is assigned a device ID, this is in order to facilitate the
+ * check that makes sure that a net device that is trying to send a
+ * packet to the channel is really connected to this channel
+ *
+ */
+class CsmaCdChannel : public Channel {
+public:
+  /**
+   * \brief Create a CsmaCdChannel
+   *
+   * By default, you get a channel with the name "CsmaCd Channel" that
+   * has an "infitely" fast transmission speed and zero delay.
+   */
+  CsmaCdChannel ();
+  
+  /**
+   * \brief Create a CsmaCdChannel
+   *
+   * \param bps The bitrate of the channel
+   * \param delay Transmission delay through the channel
+   */  
+  CsmaCdChannel (const DataRate& bps, const Time& delay);
+  
+  /**
+   * \brief Create a CsmaCdChannel
+   *
+   * \param name the name of the channel for identification purposes
+   * \param bps The bitrate of the channel
+   * \param delay Transmission delay through the channel
+   */
+  CsmaCdChannel (const std::string& name,
+                     const DataRate& bps, const Time& delay);
+
+  /**
+   * \brief Attach a given netdevice to this channel
+   *
+   * \param device Device pointer to the netdevice to attach to the channel
+   * \return The assigned device number
+   */
+  int32_t Attach (Ptr<CsmaCdNetDevice> device);
+  /**
+   * \brief Detach a given netdevice from this channel
+   *
+   * The net device is marked as inactive and it is not allowed to
+   * receive or transmit packets
+   *
+   * \param device Device pointer to the netdevice to detach from the channel
+   * \return True if the device is found and attached to the channel,
+   * false if the device is not currently connected to the channel or
+   * can't be found.
+   */
+  bool Detach (Ptr<CsmaCdNetDevice> device);
+  /**
+   * \brief Detach a given netdevice from this channel
+   *
+   * The net device is marked as inactive and it is not allowed to
+   * receive or transmit packets
+   *
+   * \param deviceId The deviceID assigned to the net device when it
+   * was connected to the channel
+   * \return True if the device is found and attached to the channel,
+   * false if the device is not currently connected to the channel or
+   * can't be found.
+   */
+  bool Detach (uint32_t deviceId);
+  /**
+   * \brief Reattach a previously detached net device to the channel
+   *
+   * The net device is marked as active. It is now allowed to receive
+   * or transmit packets. The net device must have been previously
+   * attached to the channel using the attach function.
+   *
+   * \param deviceId The device ID assigned to the net device when it
+   * was connected to the channel
+   * \return True if the device is found and is not attached to the
+   * channel, false if the device is currently connected to the
+   * channel or can't be found.
+   */
+  bool Reattach(uint32_t deviceId);
+  /**
+   * \brief Reattach a previously detached net device to the channel
+   *
+   * The net device is marked as active. It is now allowed to receive
+   * or transmit packets. The net device must have been previously
+   * attached to the channel using the attach function.
+   *
+   * \param device Device pointer to the netdevice to detach from the channel
+   * \return True if the device is found and is not attached to the
+   * channel, false if the device is currently connected to the
+   * channel or can't be found.
+   */
+  bool Reattach(Ptr<CsmaCdNetDevice> device);
+  /**
+   * \brief Start transmitting a packet over the channel
+   *
+   * If the srcId belongs to a net device that is connected to the
+   * channel, packet transmission begins, and the channel becomes busy
+   * until the packet has completely reached all destinations.
+   *
+   * \param p A reference to the packet that will be transmitted over
+   * the channel
+   * \param srcId The device Id of the net device that wants to
+   * transmit on the channel.
+   * \return True if the channel is not busy and the transmitting net
+   * device is currently active.
+   */
+  bool TransmitStart (Packet& p, uint32_t srcId);
+  /**
+   * \brief Indicates that the net device has finished transmitting
+   * the packet over the channel
+   *
+   * The channel will stay busy until the packet has completely
+   * propagated to all net devices attached to the channel. The
+   * TransmitEnd function schedules the PropagationCompleteEvent which
+   * will free the channel for further transmissions. Stores the
+   * packet p as the m_currentPkt, the packet being currently
+   * transmitting.
+   *
+   * \return Returns true unless the source was detached before it
+   * completed its transmission.
+   */
+  bool TransmitEnd ();
+  /**
+   * \brief Indicates that the channel has finished propagating the
+   * current packet. The channel is released and becomes free.
+   *
+   * Calls the receive function of every active net device that is
+   * attached to the channel.
+   */
+  void PropagationCompleteEvent();
+  /**
+   * \return Returns the device number assigned to a net device by the
+   * channel
+   *
+   * \param device Device pointer to the netdevice for which the device
+   * number is needed
+   */
+  int32_t GetDeviceNum (Ptr<CsmaCdNetDevice> device);
+  /**
+   * \return Returns the state of the channel (IDLE -- free,
+   * TRANSMITTING -- busy, PROPAGATING - busy )
+   */
+  WireState GetState();
+
+  /**
+   * \brief Indicates if the channel is busy. The channel will only
+   * accept new packets for transmission if it is not busy.
+   *
+   * \return Returns true if the channel is busy and false if it is
+   * free.
+   */
+  bool IsBusy();
+  
+  /**
+   * \brief Indicates if a net device is currently attached or
+   * detached from the channel.
+   *
+   * \param deviceId The ID that was assigned to the net device when
+   * it was attached to the channel.
+   * \return Returns true if the net device is attached to the
+   * channel, false otherwise.
+   */
+  bool IsActive(uint32_t deviceId);
+  /**
+   * \return Returns the number of net devices that are currently
+   * attached to the channel.
+   */
+  uint32_t GetNumActDevices (void);
+  /**
+   * \return Returns the total number of devices including devices
+   * that have been detached from the channel.
+   */
+  virtual uint32_t GetNDevices (void) const;
+  /**
+   * \param i The deviceId of the net device for which we want the
+   * pointer.
+   * \return Returns the pointer to the net device that is associated
+   * with deviceId i.
+   */
+  virtual Ptr<NetDevice> GetDevice (uint32_t i) const;
+
+  virtual DataRate GetDataRate (void);
+  virtual Time GetDelay (void);
+
+private:
+  DataRate      m_bps;    /// Data rate of the channel
+  Time          m_delay;  /// Delay of the channel.
+
+  /**
+   * List of the net devices that have been or are currently connected
+   * to the channel.
+   *
+   * Devices are nor removed from this list, they are marked as
+   * inactive. Otherwise the assigned device IDs will not refer to the
+   * correct NetDevice. The DeviceIds are used so that it is possible
+   * to have a number to refer to an entry in the list so that the
+   * whole list does not have to be searched when making sure that a
+   * source is attached to a channel when it is transmitting data.
+   */
+  std::vector< CsmaCdDeviceRec >            m_deviceList;
+  /**
+   * Packet that is currently being transmitted on the channel (or last
+   * packet to have been transmitted on the channel if the channel is
+   * free.)
+   */
+  Packet                              m_currentPkt;
+  /**
+   * Device Id of the source that is currently transmitting on the
+   * channel. Or last source to have transmitted a packet on the
+   * channel, if the channel is currently not busy.
+   */
+  uint32_t                            m_currentSrc;
+  /**
+   * Current state of the channel
+   */
+  WireState          m_state;
+  /**
+   * Initializes the channel when it is constructed. Resets the
+   * deviceList and sets the channel state to IDLE.
+   */
+  void Init (void);
+};
+
+} // namespace ns3
+
+#endif /* CSMA_CD_CHANNEL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma-cd/csma-cd-ipv4-topology.cc	Fri Jul 27 10:49:29 2007 -0700
@@ -0,0 +1,162 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+//
+// Copyright (c) 2007 Emmanuelle Laprise
+//
+// 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
+//
+
+#include <algorithm>
+#include "ns3/assert.h"
+#include "ns3/debug.h"
+#include "ns3/fatal-error.h"
+#include "ns3/nstime.h"
+#include "ns3/internet-node.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/ipv4.h"
+#include "ns3/queue.h"
+
+#include "csma-cd-channel.h"
+#include "csma-cd-net-device.h"
+#include "csma-cd-ipv4-topology.h"
+
+namespace ns3 {
+
+
+void
+CsmaCdIpv4Topology::AddIpv4CsmaCdNode(Ptr<Node> n1,
+                                      Ptr<CsmaCdChannel> ch,
+                                      MacAddress addr)
+{
+  Ptr<Queue> q = Queue::CreateDefault ();
+
+  // Use the first net device in the node to transmit
+  Ptr<CsmaCdNetDevice> nd0 = Create<CsmaCdNetDevice> (n1, addr, 
+                                                      ns3::CsmaCdNetDevice::IP_ARP,
+                                                      true, false);
+  nd0->AddQueue(q);
+  nd0->Attach (ch);
+
+  // Use the second net device in the node to transmit
+  Ptr<CsmaCdNetDevice> nd1 = Create<CsmaCdNetDevice> (n1, addr, 
+                                                      ns3::CsmaCdNetDevice::IP_ARP,
+                                                      false, true);
+  nd1->AddQueue(q);
+  nd1->Attach (ch);
+}
+
+
+void
+CsmaCdIpv4Topology::AddIpv4LlcCsmaCdNode(Ptr<Node> n1,
+                                         Ptr<CsmaCdChannel> ch,
+                                         MacAddress addr)
+{
+  Ptr<Queue> q = Queue::CreateDefault ();
+
+  Ptr<CsmaCdNetDevice> nd0 = Create<CsmaCdNetDevice> (n1, addr,
+                                                      ns3::CsmaCdNetDevice::LLC,
+                                                      true, false);
+  nd0->AddQueue(q);
+  nd0->Attach (ch);
+
+  Ptr<CsmaCdNetDevice> nd1 = Create<CsmaCdNetDevice> (n1, addr,
+                                                      ns3::CsmaCdNetDevice::LLC,
+                                                      false, true);
+  nd1->AddQueue(q);
+  nd1->Attach (ch);
+}
+
+void
+CsmaCdIpv4Topology::AddIpv4RawCsmaCdNode(Ptr<Node> n1,
+                                         Ptr<CsmaCdChannel> ch,
+                                         MacAddress addr)
+{
+  Ptr<Queue> q = Queue::CreateDefault ();
+
+  Ptr<CsmaCdNetDevice> nd0 = Create<CsmaCdNetDevice> (n1, addr,
+                                                      ns3::CsmaCdNetDevice::RAW,
+                                                      true, false);
+  nd0->AddQueue(q);
+  nd0->Attach (ch);
+
+  Ptr<CsmaCdNetDevice> nd1 = Create<CsmaCdNetDevice> (n1, addr,
+                                                      ns3::CsmaCdNetDevice::RAW,
+                                                      false, true);
+  nd1->AddQueue(q);
+  nd1->Attach (ch);
+}
+
+void
+CsmaCdIpv4Topology::AddIpv4Address(Ptr<Node> n1,
+                                       int ndNum,
+                                       const Ipv4Address& addr1,
+                                       const Ipv4Mask& netmask1)
+{
+
+  // Duplex link is assumed to be subnetted as a /30
+  // May run this unnumbered in the future?
+  Ipv4Mask netmask(netmask1);
+
+  Ptr<NetDevice> nd1 = n1->GetDevice(ndNum);
+
+  Ptr<Ipv4> ip1 = n1->QueryInterface<Ipv4> (Ipv4::iid);
+  uint32_t index1 = ip1->AddInterface (nd1);
+
+  ip1->SetAddress (index1, addr1);
+  ip1->SetNetworkMask (index1, netmask);
+  ip1->SetUp (index1);
+
+}
+
+void
+CsmaCdIpv4Topology::AddIpv4Routes (
+  Ptr<NetDevice> nd1, Ptr<NetDevice> nd2)
+{ 
+  // Assert that both are Ipv4 nodes
+  Ptr<Ipv4> ip1 = nd1->GetNode ()->QueryInterface<Ipv4> (Ipv4::iid);
+  Ptr<Ipv4> ip2 = nd2->GetNode ()->QueryInterface<Ipv4> (Ipv4::iid);
+  NS_ASSERT(ip1 != 0 && ip2 != 0);
+
+  // Get interface indexes for both nodes corresponding to the right channel
+  uint32_t index1 = 0;
+  bool found = false;
+  for (uint32_t i = 0; i < ip1->GetNInterfaces (); i++)
+    {
+      if (ip1 ->GetNetDevice (i) == nd1)
+        {
+          index1 = i;
+          found = true;
+        }
+    }
+  NS_ASSERT(found);
+
+  uint32_t index2 = 0;
+  found = false;
+  for (uint32_t i = 0; i < ip2->GetNInterfaces (); i++)
+    {
+      if (ip2 ->GetNetDevice (i) == nd2)
+        {
+          index2 = i;
+          found = true;
+        }
+    }
+  NS_ASSERT(found);
+
+  ip1->AddHostRouteTo (ip2-> GetAddress (index2), index1);
+  ip2->AddHostRouteTo (ip1-> GetAddress (index1), index2); 
+}
+
+} // namespace ns3
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma-cd/csma-cd-ipv4-topology.h	Fri Jul 27 10:49:29 2007 -0700
@@ -0,0 +1,120 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+//
+// Copyright (c) 2007 Emmanuelle Laprise
+//
+// 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
+//
+
+#ifndef __CSMA_CD_IPV4_TOPOLOGY_H__
+#define __CSMA_CD_IPV4_TOPOLOGY_H__
+
+#include "ns3/ptr.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/ipv4.h"
+#include "ns3/ipv4-route.h"
+#include "ns3/internet-node.h"
+#include "ns3/csma-cd-net-device.h"
+
+// The topology class consists of only static methods thar are used to
+// create the topology and data flows for an ns3 simulation
+
+namespace ns3 {
+
+class CsmaCdIpv4Channel;
+class Node;
+class IPAddr;
+class DataRate;
+class Queue;
+
+/**
+ * \brief A helper class to create Topologies based on the
+ * InternetNodes and CsmaCdChannels. Either the
+ * SimpleCsmaCdNetDevice or the LLCCsmaCdNetDevice can be used
+ * when constructing these topologies.
+ */
+class CsmaCdIpv4Topology {
+public:
+
+  /**
+   * \param n1 Node to be attached to the Csma/Cd channel
+   * \param ch CsmaCdChannel to which node n1 should be attached
+   * \param addr Mac address of the node
+   *
+   * Add a Csma/Cd node to a Csma/Cd channel. This function adds
+   * a EthernetCsmaCdNetDevice to the nodes so that they can
+   * connect to a CsmaCdChannel. This means that Ethernet headers
+   * and trailers will be added to the packet before sending out on
+   * the net device.
+   */
+  static void AddIpv4CsmaCdNode( Ptr<Node> n1,
+                                 Ptr<CsmaCdChannel> ch,
+                                 MacAddress addr);
+
+  /**
+   * \param n1 Node to be attached to the Csma/Cd channel
+   * \param ch CsmaCdChannel to which node n1 should be attached
+   * \param addr Mac address of the node
+   *
+   * Add a Csma/Cd node to a Csma/Cd channel. This function adds
+   * a RawCsmaCdNetDevice to the nodes so that they can connect
+   * to a CsmaCdChannel.
+   */
+  static void AddIpv4RawCsmaCdNode( Ptr<Node> n1,
+                                    Ptr<CsmaCdChannel> ch,
+                                    MacAddress addr);
+
+  /**
+   * \param n1 Node to be attached to the Csma/Cd channel
+   * \param ch CsmaCdChannel to which node n1 should be attached
+   * \param addr Mac address of the node
+   *
+   * Add a Csma/Cd node to a Csma/Cd channel. This function adds
+   * a LlcCsmaCdNetDevice to the nodes so that they can connect
+   * to a CsmaCdChannel.
+   */
+  static void AddIpv4LlcCsmaCdNode( Ptr<Node> n1,
+                                    Ptr<CsmaCdChannel> ch,
+                                    MacAddress addr);
+
+
+
+  /** 
+   * \param n1 Node
+   * \param ndNum NetDevice number with which to associate address
+   * \param addr1 Ipv4 Address for ndNum of n1
+   * \param network network mask for ndNum of node n1
+   * 
+   * Add an Ipv4Address to the Ipv4 interface associated with the
+   * ndNum CsmaCdIpv4NetDevices on the provided
+   * CsmaCdIpv4Channel
+   */
+  static void AddIpv4Address(Ptr<Node> n1, int ndNum, 
+                             const Ipv4Address& addr1,
+                             const Ipv4Mask& netmask1);
+
+  /**
+   * \param nd1 Node
+   * \param nd2 Node
+   * 
+   * Add an IPV4 host route between the two specified net devices
+   */
+  static void AddIpv4Routes (Ptr<NetDevice> nd1, Ptr<NetDevice> nd2);
+};
+
+} // namespace ns3
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma-cd/csma-cd-net-device.cc	Fri Jul 27 10:49:29 2007 -0700
@@ -0,0 +1,504 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 Emmanuelle Laprise
+ * 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
+ */
+
+#include <iostream>
+#include <cassert>
+#include "ns3/debug.h"
+#include "ns3/queue.h"
+#include "ns3/simulator.h"
+#include "ns3/composite-trace-resolver.h"
+#include "csma-cd-net-device.h"
+#include "csma-cd-channel.h"
+#include "ns3/ethernet-header.h"
+#include "ns3/ethernet-trailer.h"
+#include "ns3/llc-snap-header.h"
+
+NS_DEBUG_COMPONENT_DEFINE ("CsmaCdNetDevice");
+
+namespace ns3 {
+
+CsmaCdNetDevice::CsmaCdNetDevice (Ptr<Node> node, MacAddress addr, 
+                                  CsmaCdEncapsulationMode pktType) 
+  : NetDevice(node, addr), m_bps (DataRate (0xffffffff))
+{
+  NS_DEBUG ("CsmaCdNetDevice::CsmaCdNetDevice (" << node << ")");
+  m_pktType = pktType;
+
+  Init(true, true);
+}
+
+CsmaCdNetDevice::CsmaCdNetDevice (Ptr<Node> node, MacAddress addr, 
+                                  CsmaCdEncapsulationMode pktType,
+                                  bool sendEnable, bool receiveEnable) 
+  : NetDevice(node, addr), m_bps (DataRate (0xffffffff))
+{
+  NS_DEBUG ("CsmaCdNetDevice::CsmaCdNetDevice (" << node << ")");
+  m_pktType = pktType;
+
+  Init(sendEnable, receiveEnable);
+}
+
+CsmaCdNetDevice::~CsmaCdNetDevice()
+{
+  NS_DEBUG ("CsmaCdNetDevice::~CsmaCdNetDevice ()");
+  m_queue = 0;
+}
+
+//
+// Copy constructor for CsmaCdNetDevice.
+//
+// We use the underlying NetDevice copy constructor to get the base class
+// copied.  These just remain as is (e.g. you get the same name, the same
+// MAC address).  If you need to fix them up, YOU, the copier need to do 
+// that.
+// 
+// The things we need to be careful of are the channel, the queue and the
+// trace callback.  If the channel pointer is non-zero, we copy the pointer 
+// and add a reference.  If the queue is non-zero, we copy it using the queue
+// assignment operator.  We don't mess with the trace -- we just reset it.
+// We're assuming that the tracing will be set up after the topology creation
+// phase and this won't actually matter.
+//
+
+CsmaCdNetDevice::CsmaCdNetDevice (const CsmaCdNetDevice& nd)
+  : NetDevice(nd), m_bps (nd.m_bps)
+{
+  NS_DEBUG ("CsmaCdNetDevice::CsmaCdNetDevice (" << &nd << ")");
+
+  m_txMachineState = READY;
+  m_tInterframeGap = nd.m_tInterframeGap;
+  m_backoff = nd.m_backoff;
+  m_channel = nd.m_channel; 
+  m_queue = 0;
+  m_pktType = nd.m_pktType;
+  m_sendEnable = nd.m_sendEnable;
+  m_receiveEnable = nd.m_receiveEnable;
+    
+  if (nd.m_queue)
+    {
+      m_queue = nd.m_queue;
+    }
+    
+}
+
+void 
+CsmaCdNetDevice::DoDispose ()
+{
+  m_channel = 0;
+  NetDevice::DoDispose ();
+}
+
+//
+// Assignment operator for CsmaCdNetDevice.
+//
+// This uses the non-obvious trick of taking the source net device passed by
+// value instead of by reference.  This causes the copy constructor to be
+// invoked (where the real work is done -- see above).  All we have to do
+// here is to return the newly constructed net device.
+//
+/*
+CsmaCdNetDevice&
+CsmaCdNetDevice::operator= (const CsmaCdNetDevice nd)
+{
+  NS_DEBUG ("CsmaCdNetDevice::operator= (" << &nd << ")");
+  return *this;
+}
+*/
+
+void 
+CsmaCdNetDevice::Init(bool sendEnable, bool receiveEnable)
+{
+  m_txMachineState = READY;
+  m_tInterframeGap = Seconds(0);
+  m_channel = 0; 
+  m_queue = 0;
+
+  EnableBroadcast (MacAddress ("ff:ff:ff:ff:ff:ff"));
+  EnableMulticast();
+  EnablePointToPoint();
+
+  SetSendEnable (sendEnable);
+  SetReceiveEnable (receiveEnable);
+}
+
+void
+CsmaCdNetDevice::SetSendEnable (bool sendEnable)
+{
+  m_sendEnable = sendEnable;
+}
+
+void
+CsmaCdNetDevice::SetReceiveEnable (bool receiveEnable)
+{
+  m_receiveEnable = receiveEnable;
+}
+bool
+CsmaCdNetDevice::IsSendEnabled (void)
+{
+  return (m_sendEnable);
+}
+
+bool
+CsmaCdNetDevice::IsReceiveEnabled (void)
+{
+  return (m_receiveEnable);
+}
+
+void 
+CsmaCdNetDevice::SetDataRate (DataRate bps)
+{
+  m_bps = bps;
+}
+
+void 
+CsmaCdNetDevice::SetInterframeGap (Time t)
+{
+  m_tInterframeGap = t;
+}
+
+void 
+CsmaCdNetDevice::SetBackoffParams (Time slotTime, uint32_t minSlots, 
+                                      uint32_t maxSlots, uint32_t ceiling, 
+                                      uint32_t maxRetries)
+{
+  m_backoff.m_slotTime = slotTime;
+  m_backoff.m_minSlots = minSlots;
+  m_backoff.m_maxSlots = maxSlots;
+  m_backoff.m_ceiling = ceiling;
+  m_backoff.m_maxRetries = maxRetries;
+}
+void 
+CsmaCdNetDevice::AddHeader (Packet& p, const MacAddress& dest,
+                                  uint16_t protocolNumber)
+{
+  if ((m_pktType == ETHERNET_V1) || (m_pktType == IP_ARP))
+    {
+      EthernetHeader  header;
+      EthernetTrailer trailer;
+      
+      header.SetSource(this->GetAddress());
+      header.SetDestination(dest);
+      switch (m_pktType)
+        {
+        case IP_ARP:
+          header.SetLengthType(protocolNumber);
+          break;
+        default:
+          header.SetLengthType(p.GetSize() + header.GetSize() + trailer.GetSize());
+          break;
+        }
+      p.AddHeader(header);
+      trailer.CalcFcs(p);
+      p.AddTrailer(trailer);
+    } 
+  else if (m_pktType == LLC) 
+    {
+      LlcSnapHeader llc;
+      llc.SetType (protocolNumber);
+      p.AddHeader (llc);
+    }
+}
+bool 
+CsmaCdNetDevice::ProcessHeader(Packet& p, int& param)
+{
+  bool retVal = true;
+
+  if ((m_pktType == ETHERNET_V1) || (m_pktType == IP_ARP))
+    {
+      EthernetHeader  header;
+      EthernetTrailer trailer;
+      
+      p.RemoveTrailer(trailer);
+      trailer.CheckFcs(p);
+      p.RemoveHeader(header);
+      
+      param = header.GetLengthType();
+      if ((header.GetDestination() != this->GetBroadcast()) &&
+          (header.GetDestination() != this->GetAddress()))
+        {
+          retVal = false;
+        }
+    }
+  else if (m_pktType == LLC)
+    {
+      LlcSnapHeader llc;
+      p.RemoveHeader (llc);
+
+      param = llc.GetType ();
+    }
+
+  return retVal;
+}
+
+bool
+CsmaCdNetDevice::DoNeedsArp (void) const
+{
+  if ((m_pktType == IP_ARP) || (m_pktType == LLC))
+    {
+      return true;
+    } else {
+      return false;
+    }
+}
+
+bool
+CsmaCdNetDevice::SendTo (Packet& p, const MacAddress& dest, uint16_t protocolNumber)
+{
+  NS_DEBUG ("CsmaCdNetDevice::SendTo (" << &p << ")");
+  NS_DEBUG ("CsmaCdNetDevice::SendTo (): UID is " << p.GetUid () << ")");
+
+  NS_ASSERT (IsLinkUp ());
+
+  // Only transmit if send side of net device is enabled
+  if (!IsSendEnabled())
+    return false;
+
+  AddHeader(p, dest, protocolNumber);
+
+  // Place the packet to be sent on the send queue
+    if (m_queue->Enqueue(p) == false )
+      {
+        return false;
+      }
+    // If the device is idle, we need to start a transmission. Otherwise,
+    // the transmission will be started when the current packet finished
+    // transmission (see TransmitCompleteEvent)
+    if (m_txMachineState == READY) 
+      {
+        // Store the next packet to be transmitted
+        if (m_queue->Dequeue (m_currentPkt))
+          {
+            TransmitStart();
+          }
+      }
+    return true;
+}
+
+void
+CsmaCdNetDevice::TransmitStart ()
+{
+  NS_DEBUG ("CsmaCdNetDevice::TransmitStart (" << &m_currentPkt << ")");
+  NS_DEBUG ("CsmaCdNetDevice::TransmitStart (): UID is " 
+            << m_currentPkt.GetUid () << ")");
+//
+// This function is called to start the process of transmitting a packet.
+// We need to tell the channel that we've started wiggling the wire and
+// schedule an event that will be executed when it's time to tell the 
+// channel that we're done wiggling the wire.
+//
+  NS_ASSERT_MSG((m_txMachineState == READY) || (m_txMachineState == BACKOFF), 
+                "Must be READY to transmit. Tx state is: " 
+                << m_txMachineState);
+
+  // Only transmit if send side of net device is enabled
+  if (!IsSendEnabled())
+    return;
+
+  if (m_channel->GetState() != IDLE)
+    { // Channel busy, backoff and rechedule TransmitStart()
+      m_txMachineState = BACKOFF;
+      if (m_backoff.MaxRetriesReached())
+        { // Too many retries reached, abort transmission of packet
+          TransmitAbort();
+        } else {
+          m_backoff.IncrNumRetries();
+          Time backoffTime = m_backoff.GetBackoffTime();
+
+          NS_DEBUG ("CsmaCdNetDevice::TransmitStart (): " 
+                    << "Channel busy, backing off for " 
+                    << backoffTime.GetSeconds () << "sec");
+
+          Simulator::Schedule (backoffTime, 
+                               &CsmaCdNetDevice::TransmitStart, 
+                               this);
+        }
+    } else {
+      // Channel is free, transmit packet
+      m_txMachineState = BUSY;
+      Time tEvent = Seconds (m_bps.CalculateTxTime(m_currentPkt.GetSize()));
+      
+      NS_DEBUG ("CsmaCdNetDevice::TransmitStart (): " <<
+                "Schedule TransmitCompleteEvent in " << 
+                tEvent.GetSeconds () << "sec");
+      
+      Simulator::Schedule (tEvent, 
+                           &CsmaCdNetDevice::TransmitCompleteEvent, 
+                           this);
+      if (!m_channel->TransmitStart (m_currentPkt, m_deviceId))
+        {
+          NS_DEBUG ("CsmaCdNetDevice::TransmitStart (): " <<
+                    "Channel transmit start did not work at " << 
+                    tEvent.GetSeconds () << "sec");
+          m_txMachineState = READY;
+        } else {
+          // Transmission success, reset backoff time parameters.
+          m_backoff.ResetBackoffTime();
+        }
+    }
+}
+
+
+void
+CsmaCdNetDevice::TransmitAbort (void)
+{
+  NS_DEBUG ("CsmaCdNetDevice::TransmitAbort ()");
+
+  NS_DEBUG ("CsmaCdNetDevice::TransmitAbort (): Pkt UID is " <<
+            m_currentPkt.GetUid () << ")");
+
+  // Try to transmit a new packet
+  bool found;
+  found = m_queue->Dequeue (m_currentPkt);
+  NS_ASSERT_MSG(found, "IsEmpty false but no Packet on queue?");
+  m_backoff.ResetBackoffTime();
+  m_txMachineState = READY;
+  TransmitStart ();
+}
+
+void
+CsmaCdNetDevice::TransmitCompleteEvent (void)
+{
+  NS_DEBUG ("CsmaCdNetDevice::TransmitCompleteEvent ()");
+//
+// This function is called to finish the  process of transmitting a packet.
+// We need to tell the channel that we've stopped wiggling the wire and
+// schedule an event that will be executed when it's time to re-enable
+// the transmitter after the interframe gap.
+//
+  NS_ASSERT_MSG(m_txMachineState == BUSY, "Must be BUSY if transmitting");
+  // Channel should be transmitting
+  NS_ASSERT(m_channel->GetState() == TRANSMITTING);
+  m_txMachineState = GAP;
+
+  NS_DEBUG ("CsmaCdNetDevice::TransmitCompleteEvent (): Pkt UID is " << 
+            m_currentPkt.GetUid () << ")");
+  m_channel->TransmitEnd (); 
+
+  NS_DEBUG (
+    "CsmaCdNetDevice::TransmitCompleteEvent (): " <<
+    "Schedule TransmitReadyEvent in "
+    << m_tInterframeGap.GetSeconds () << "sec");
+
+  Simulator::Schedule (m_tInterframeGap, 
+                       &CsmaCdNetDevice::TransmitReadyEvent, 
+                       this);
+}
+
+void
+CsmaCdNetDevice::TransmitReadyEvent (void)
+{
+  NS_DEBUG ("CsmaCdNetDevice::TransmitReadyEvent ()");
+//
+// This function is called to enable the transmitter after the interframe
+// gap has passed.  If there are pending transmissions, we use this opportunity
+// to start the next transmit.
+//
+  NS_ASSERT_MSG(m_txMachineState == GAP, "Must be in interframe gap");
+  m_txMachineState = READY;
+
+  // Get the next packet from the queue for transmitting
+  if (m_queue->IsEmpty())
+    {
+      return;
+    }
+  else
+    {
+      bool found;
+      found = m_queue->Dequeue (m_currentPkt);
+      NS_ASSERT_MSG(found, "IsEmpty false but no Packet on queue?");
+      TransmitStart ();
+    }
+}
+
+TraceResolver *
+CsmaCdNetDevice::DoCreateTraceResolver (TraceContext const &context)
+{
+  CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
+  resolver->Add ("queue", 
+                 MakeCallback (&Queue::CreateTraceResolver, 
+                               PeekPointer (m_queue)),
+                 CsmaCdNetDevice::QUEUE);
+  resolver->Add ("rx",
+                 m_rxTrace,
+                 CsmaCdNetDevice::RX);
+  return resolver;
+}
+
+bool
+CsmaCdNetDevice::Attach (Ptr<CsmaCdChannel> ch)
+{
+  NS_DEBUG ("CsmaCdNetDevice::Attach (" << &ch << ")");
+
+  m_channel = ch;
+
+  m_deviceId = m_channel->Attach(this);
+  m_bps = m_channel->GetDataRate ();
+  m_tInterframeGap = m_channel->GetDelay ();
+
+  /* 
+   * For now, this device is up whenever a channel is attached to it.
+   */
+  NotifyLinkUp ();
+  return true;
+}
+
+void
+CsmaCdNetDevice::AddQueue (Ptr<Queue> q)
+{
+  NS_DEBUG ("CsmaCdNetDevice::AddQueue (" << q << ")");
+
+  m_queue = q;
+}
+
+void
+CsmaCdNetDevice::Receive (Packet& p)
+{
+  NS_DEBUG ("CsmaCdNetDevice::Receive UID is (" << p.GetUid() << ")");
+
+  // Only receive if send side of net device is enabled
+  if (!IsReceiveEnabled())
+    return;
+
+  int param = 0;
+  Packet packet = p;
+
+  if (ProcessHeader(packet, param))
+    {
+      m_rxTrace (packet);
+      ForwardUp (packet, param);
+    } else {
+      m_dropTrace (packet);
+    }
+}
+
+Ptr<Queue>
+CsmaCdNetDevice::GetQueue(void) const 
+{ 
+    return m_queue;
+}
+
+Ptr<Channel>
+CsmaCdNetDevice::DoGetChannel(void) const 
+{ 
+    return m_channel;
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma-cd/csma-cd-net-device.h	Fri Jul 27 10:49:29 2007 -0700
@@ -0,0 +1,424 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 Emmanuelle Laprise
+ *
+ * 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca
+ * Derived from the p2p net device file
+ */
+
+#ifndef CSMA_CD_NET_DEVICE_H
+#define CSMA_CD_NET_DEVICE_H
+
+#include <string.h>
+#include "ns3/node.h"
+#include "ns3/backoff.h"
+#include "ns3/mac-address.h"
+#include "ns3/net-device.h"
+#include "ns3/callback.h"
+#include "ns3/packet.h"
+#include "ns3/callback-trace-source.h"
+#include "ns3/nstime.h"
+#include "ns3/data-rate.h"
+#include "ns3/ptr.h"
+#include "ns3/random-variable.h"
+
+namespace ns3 {
+
+class Queue;
+class CsmaCdChannel;
+
+/**
+ * \class CsmaCdNetDevice
+ * \brief A Device for a CsmaCd Network Link.
+ *
+ * The Csma/Cd net device class is analogous to layer 1 and 2 of the
+ * TCP stack. The NetDevice takes a raw packet of bytes and creates a
+ * protocol specific packet from them. The Csma/Cd net device class
+ * takes this packet and adds and processes the headers/trailers that
+ * are associated with EthernetV1, EthernetV2, RAW or LLC
+ * protocols. The EthernetV1 packet type adds and removes Ethernet
+ * destination and source addresses. The LLC packet type adds and
+ * removes LLC snap headers. The raw packet type does not add or
+ * remove any headers.  Each Csma/Cd net device will receive all
+ * packets written to the Csma/Cd link. The ProcessHeader function can
+ * be used to filter out the packets such that higher level layers
+ * only receive packets that are addressed to their associated net
+ * devices
+ *
+ */
+class CsmaCdNetDevice : public NetDevice {
+public:
+  /**
+   * Enumeration of the types of traces supported in the class.
+   *
+   */
+  enum TraceType {
+    QUEUE, /**< Trace queue events on the attached queue */
+    RX,    /**< Trace packet reception events (from the channel) */
+    DROP    /**< Trace packet drop events (from the channel) */
+  };
+
+  /**
+   * Enumeration of the types of packets supported in the class.
+   *
+   */
+enum CsmaCdEncapsulationMode {
+  ETHERNET_V1, /**< Version one ethernet packet, length field */
+  IP_ARP,      /**< Ethernet packet encapsulates IP/ARP packet */
+  RAW,         /**< Packet that contains no headers */
+  LLC,         /**< LLC packet encapsulation */  
+};
+
+  /**
+   * Construct a CsmaCdNetDevice
+   *
+   * This is the constructor for the CsmaCdNetDevice.  It takes as a
+   * parameter the Node to which this device is connected.  Ownership of the
+   * Node pointer is not implied and the node must not be deleted.
+   *
+   * \param node the Node to which this device is connected.
+   * \param addr The source MAC address of the net device.
+   */
+  CsmaCdNetDevice (Ptr<Node> node, MacAddress addr, CsmaCdEncapsulationMode pktType);
+  CsmaCdNetDevice (Ptr<Node> node, MacAddress addr,
+                   CsmaCdEncapsulationMode pktType,
+                   bool sendEnable, bool receiveEnable);
+  /**
+   * Copy Construct a CsmaCdNetDevice
+   *
+   * This is the copy constructor for the CsmaCdNetDevice.  This is
+   * primarily used in topology creation.
+   *
+   * \param nd the object to be copied
+   */
+  CsmaCdNetDevice (const CsmaCdNetDevice& nd);
+  /**
+   * Destroy a CsmaCdNetDevice
+   *
+   * This is the destructor for the CsmaCdNetDevice.
+   */
+  virtual ~CsmaCdNetDevice();
+  /**
+   * Assignment Operator for a CsmaCdNetDevice
+   *
+   * This is the assignment operator for the CsmaCdNetDevice.  This is
+   * to allow
+   *
+   * \param nd the object to be copied
+   */
+  // CsmaCdNetDevice& operator= (CsmaCdNetDevice nd);
+  /**
+   * Set the Data Rate used for transmission of packets.  The data rate is
+   * set in the Attach () method from the corresponding field in the channel
+   * to which the device is attached.  It can be overridden using this method.
+   *
+   * @see Attach ()
+   * \param bps the data rate at which this object operates
+   */
+  void SetDataRate (DataRate bps);
+  /**
+   * Set the inteframe gap used to separate packets.  The interframe gap
+   * defines the minimum space required between packets sent by this device.
+   * It is usually set in the Attach () method based on the speed of light
+   * delay of the channel to which the device is attached.  It can be 
+   * overridden using this method if desired.
+   *
+   * @see Attach ()
+   * \param t the interframe gap time
+   */
+  void SetInterframeGap (Time t);
+  /**
+   * Set the backoff parameters used to determine the wait to retry
+   * transmitting a packet when the channel is busy.
+   *
+   * @see Attach ()
+   * \param slotTime Length of a packet slot (or average packet time)
+   * \param minSlots Minimum number of slots to wait
+   * \param maxSlots Maximum number of slots to wait
+   * \param maxRetries Maximum number of retries before packet is discard
+   * \param ceiling Cap on the exponential function when calculating max slots
+   */
+  void SetBackoffParams (Time slotTime, uint32_t minSlots, uint32_t maxSlots, 
+                        uint32_t maxRetries, uint32_t ceiling);
+  /**
+   * Attach the device to a channel.
+   *
+   * The function Attach is used to add a CsmaCdNetDevice to a
+   * CsmaCdChannel.
+   *
+   * @see SetDataRate ()
+   * @see SetInterframeGap ()
+   * \param ch a pointer to the channel to which this object is being attached.
+   */
+  bool Attach (Ptr<CsmaCdChannel> ch);
+  /**
+   * Attach a queue to the CsmaCdNetDevice.
+   *
+   * The CsmaCdNetDevice "owns" a queue.  This queue is created by the
+   * CsmaCdTopology object and implements a queueing method such as
+   * DropTail or RED.  The CsmaCdNetDevice assumes ownership of this
+   * queue and must delete it when the device is destroyed.
+   *
+   * @see CsmaCdTopology::AddCsmaCdLink ()
+   * @see Queue
+   * @see DropTailQueue
+   * \param queue a pointer to the queue for which object is assuming
+   *        ownership.
+   */
+  void AddQueue (Ptr<Queue> queue);
+  /**
+   * Receive a packet from a connected CsmaCdChannel.
+   *
+   * The CsmaCdNetDevice receives packets from its connected channel
+   * and forwards them up the protocol stack.  This is the public method
+   * used by the channel to indicate that the last bit of a packet has 
+   * arrived at the device.
+   *
+   * @see CsmaCdChannel
+   * \param p a reference to the received packet
+   */
+  void Receive (Packet& p);
+
+  bool IsSendEnabled (void);
+  bool IsReceiveEnabled (void);
+
+  void SetSendEnable (bool);
+  void SetReceiveEnable (bool);
+
+protected:
+  virtual bool DoNeedsArp (void) const;
+  virtual void DoDispose (void);
+  /**
+   * Get a copy of the attached Queue.
+   *
+   * This method is provided for any derived class that may need to get
+   * direct access to the underlying queue.
+   *
+   * \return a pointer to the queue.
+   */
+  Ptr<Queue> GetQueue (void) const; 
+  /**
+   * Get a copy of the attached Channel
+   *
+   * This method is provided for any derived class that may need to get
+   * direct access to the connected channel
+   *
+   * \return a pointer to the channel
+   */
+  virtual Ptr<Channel> DoGetChannel (void) const;
+  /**
+   * Adds the necessary headers and trailers to a packet of data in order to
+   * respect the packet type
+   *
+   * \param p Packet to which header should be added
+   * \param dest MAC destination address to which packet should be sent
+   * \param protocolNumber In some protocols, identifies the type of
+   * payload contained in this packet.
+   */
+  void AddHeader (Packet& p, const MacAddress& dest, 
+                  uint16_t protocolNumber);
+  /**
+   * Removes, from a packet of data, all headers and trailers that
+   * relate to the packet type
+   *
+   * \param p Packet whose headers need to be processed
+   * \param param An integer parameter that can be set by the function
+   * to return information gathered in the header
+   * \return Returns true if the packet should be forwarded up the
+   * protocol stack.
+   */
+  bool ProcessHeader (Packet& p, int& param);
+
+private:
+  /**
+   * Initializes variablea when construction object.
+   */
+  void Init (bool sendEnable, bool receiveEnable);
+  /**
+   * Send a Packet on the Csma/Cd network
+   *
+   * This method does not use a destination address since all packets
+   * are broadcast to all NetDevices attached to the channel. Packet
+   * should contain all needed headers at this time.
+   *
+   * If the device is ready to transmit, the next packet is read off
+   * of the queue and stored locally until it has been transmitted.
+   *
+   * \param p a reference to the packet to send
+   * \param dest destination address
+   * \param protocolNumber -- this parameter is not used here
+   * \return true if success, false on failure
+   */
+  virtual bool SendTo (Packet& p, const MacAddress& dest, uint16_t protocolNumber);
+
+  /**
+   * Start Sending a Packet Down the Wire.
+   *
+   * The TransmitStart method is the method that is used internally in
+   * the CsmaCdNetDevice to begin the process of sending a packet
+   * out on the channel.  The corresponding method is called on the
+   * channel to let it know that the physical device this class
+   * represents has virually started sending signals, this causes the
+   * channel to become busy.  An event is scheduled for the time at
+   * which the bits have been completely transmitted. If the channel
+   * is busy, the method reschedules itself for a later time (within
+   * the backoff period)
+   *
+   * @see CsmaCdChannel::TransmitStart ()
+   * @see TransmitCompleteEvent ()
+   */
+  void TransmitStart ();
+  /**
+   * Stop Sending a Packet Down the Wire and Begin the Interframe Gap.
+   *
+   * The TransmitCompleteEvent method is used internally to finish the process
+   * of sending a packet out on the channel.  During execution of this method
+   * the TransmitEnd method is called on the channel to let it know that the
+   * physical device this class represents has virually finished sending 
+   * signals.  The channel uses this event to begin its speed of light delay
+   * timer after which it notifies the Net Device at the other end of the 
+   * link that the bits have arrived.  During this method, the net device 
+   * also schedules the TransmitReadyEvent at which time the transmitter 
+   * becomes ready to send the next packet.
+   *
+   * @see CsmaCdChannel::TransmitEnd ()
+   * @see TransmitReadyEvent ()
+   */
+  void TransmitCompleteEvent (void);
+  /**
+   * Cause the Transmitter to Become Ready to Send Another Packet.
+   *
+   * The TransmitReadyEvent method is used internally to re-enable the 
+   * transmit machine of the net device.  It is scheduled after a suitable
+   * interframe gap after the completion of the previous transmission.
+   * The queue is checked at this time, and if there is a packet waiting on
+   * the queue, the transmission process is begun.
+   *
+   * If a packet is in the queue, it is extracted for the queue as the
+   * next packet to be transmitted by the net device.
+   *
+   * @see TransmitStart ()
+   */
+  void TransmitReadyEvent (void);
+  /**
+   * Create a Trace Resolver for events in the net device.
+   * (NOT TESTED)
+   * @see class TraceResolver
+   */
+  virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
+
+  /**
+   * Aborts the transmission of the current packet
+   *
+   * If the net device has tried to transmit a packet for more times
+   * than the maximum allowed number of retries (channel always busy)
+   * then the packet is dropped.
+   *
+   */
+  void TransmitAbort (void);
+
+  /** 
+   * Device ID returned by the attached functions. It is used by the
+   * mp-channel to identify each net device to make sure that only
+   * active net devices are writing to the channel
+   */
+  uint32_t m_deviceId; 
+
+  /**
+   * Enable net device to send packets. True by default
+   */
+  bool m_sendEnable;
+  /**
+   * Enable net device to receive packets. True by default
+   */
+  bool m_receiveEnable;
+  /**
+   * Enumeration of the states of the transmit machine of the net device.
+   */
+  enum TxMachineState
+    {
+      READY, /**< The transmitter is ready to begin transmission of a packet */
+      BUSY,  /**< The transmitter is busy transmitting a packet */
+      GAP,    /**< The transmitter is in the interframe gap time */
+      BACKOFF    /**< The transmitter is waiting for the channel to be free */
+    };
+  /**
+   * The state of the Net Device transmit state machine.
+   * @see TxMachineState
+   */
+  TxMachineState m_txMachineState;
+  
+  /**
+   * The type of packet that should be created by the AddHeader
+   * function and that should be processed by the ProcessHeader
+   * function.
+   */
+  CsmaCdEncapsulationMode m_pktType;
+  /**
+   * The data rate that the Net Device uses to simulate packet transmission
+   * timing.
+   * @see class DataRate
+   */
+  DataRate m_bps;
+  /**
+   * The interframe gap that the Net Device uses to throttle packet
+   * transmission
+   * @see class Time
+   */
+  Time m_tInterframeGap;
+  /**
+   * Holds the backoff parameters and is used to calculate the next
+   * backoff time to use when the channel is busy and the net device
+   * is ready to transmit
+   */
+  Backoff m_backoff;
+  /**
+   * Next packet that will be transmitted (if transmitter is not
+   * currently transmitting) or packet that is currently being
+   * transmitted.
+   */
+  Packet m_currentPkt;
+  /**
+   * The CsmaCdChannel to which this CsmaCdNetDevice has been
+   * attached.
+   * @see class CsmaCdChannel
+   */
+  Ptr<CsmaCdChannel> m_channel;
+  /**
+   * The Queue which this CsmaCdNetDevice uses as a packet source.
+   * Management of this Queue has been delegated to the CsmaCdNetDevice
+   * and it has the responsibility for deletion.
+   * @see class Queue
+   * @see class DropTailQueue
+   */
+  Ptr<Queue> m_queue;
+  /**
+   * NOT TESTED
+   * The trace source for the packet reception events that the device can
+   * fire.
+   *
+   * @see class CallBackTraceSource
+   * @see class TraceResolver
+   */
+  CallbackTraceSource<Packet &> m_rxTrace;
+  CallbackTraceSource<Packet &> m_dropTrace;
+
+};
+
+}; // namespace ns3
+
+#endif // CSMA_CD_NET_DEVICE_H
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma-cd/csma-cd-topology.cc	Fri Jul 27 10:49:29 2007 -0700
@@ -0,0 +1,103 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+//
+// Copyright (c) 2007 Emmanuelle Laprise
+//
+// 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
+//
+
+//
+// Topology helper for CsmaCd channels in ns3.
+
+#include "ns3/assert.h"
+#include "ns3/debug.h"
+#include "ns3/queue.h"
+
+#include "csma-cd-channel.h"
+#include "csma-cd-net-device.h"
+#include "csma-cd-topology.h"
+#include "ns3/socket-factory.h"
+
+namespace ns3 {
+
+Ptr<CsmaCdChannel>
+CsmaCdTopology::CreateCsmaCdChannel(
+  const DataRate& bps,
+  const Time& delay)
+{
+  Ptr<CsmaCdChannel> channel = Create<CsmaCdChannel> (bps, delay);
+
+  return channel;
+}
+
+#if 0
+Ptr<CsmaCdNetDevice>
+CsmaCdTopology::AddCsmaCdEthernetNode(
+  Ptr<Node> n1,
+  Ptr<CsmaCdChannel> ch,
+  MacAddress addr)
+{
+  Ptr<CsmaCdNetDevice> nd1 = Create<CsmaCdNetDevice> (n1, addr, 
+                                                      ns3::CsmaCdNetDevice::ETHERNET_V1);
+
+  Ptr<Queue> q = Queue::CreateDefault ();
+  nd1->AddQueue(q);
+  nd1->Attach (ch);
+  
+  return nd1;
+}
+
+Ptr<PacketSocket>
+CsmaCdTopology::ConnectPacketSocket(Ptr<PacketSocketApp> app, 
+                                        Ptr<CsmaCdNetDevice> ndSrc,
+                                        Ptr<CsmaCdNetDevice> ndDest)
+{
+  Ptr<PacketSocket> socket = Create<PacketSocket> ();
+  socket->Bind(ndSrc);
+  socket->Connect(ndDest->GetAddress());
+  app->Connect(socket);
+
+  return socket;
+}
+
+Ptr<PacketSocket>
+CsmaCdTopology::ConnectPacketSocket(Ptr<PacketSocketApp> app,
+                                        Ptr<CsmaCdNetDevice> ndSrc,
+                                        MacAddress macAddr)
+{
+  Ptr<PacketSocket> socket = Create<PacketSocket> ();
+  socket->Bind(ndSrc);
+  socket->Connect(macAddr);
+  app->Connect(socket);
+
+  return socket;
+}
+
+Ptr<Socket>
+CsmaCdTopology::CreatePacketSocket(Ptr<Node> n1, std::string iid_name)
+{
+  InterfaceId iid = InterfaceId::LookupByName (iid_name);
+
+  Ptr<SocketFactory> socketFactory =
+    n1->QueryInterface<SocketFactory> (iid);
+
+  Ptr<Socket> socket = socketFactory->CreateSocket ();
+
+  return socket;
+}
+#endif
+
+} // namespace ns3
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma-cd/csma-cd-topology.h	Fri Jul 27 10:49:29 2007 -0700
@@ -0,0 +1,128 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+//
+// Copyright (c) 2007 Emmanuelle Laprise
+//
+// 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
+//
+// Topology helper for multipoint channels in ns3.
+// 
+#ifndef CSMA_CD_TOPOLOGY_H
+#define CSMA_CD_TOPOLOGY_H
+
+#include "ns3/ptr.h"
+#include "ns3/csma-cd-net-device.h"
+#if 0
+#include "ns3/packet-socket.h"
+#include "ns3/packet-socket-app.h"
+#endif
+#include "ns3/node.h"
+#include "ns3/mac-address.h"
+
+// The topology class consists of only static methods thar are used to
+// create the topology and data flows for an ns3 simulation
+
+namespace ns3 {
+
+class CsmaCdChannel;
+class Node;
+class DataRate;
+class Queue;
+
+/**
+ * \brief A helper class to create CsmaCd Topologies 
+ *
+ * CsmaCd topologies are created based on the
+ * ns3::CsmaCdNetDevice subclasses and ns3::CsmaCdChannel
+ * objects.  This class uses the EthernetNetDevice and
+ * PacketSocket classes in order to create logical connections between
+ * net devices. The PacketSocket class generates the data and the
+ * EthernetNetDevice class creates ethernet packets from the
+ * data, filling in source and destination addresses. The
+ * EthernetNetDevice class filters received data packets
+ * according to its destination Mac addresses.
+ */
+class CsmaCdTopology {
+public:
+  /** 
+   * \param dataRate Maximum transmission link rate 
+   * \param delay propagation delay between any two nodes 
+   * \return Pointer to the created CsmaCdChannel
+   * 
+   * Create a CsmaCdChannel. All nodes connected to a multipoint
+   * channels will receive all packets written to that channel
+   */
+  static Ptr<CsmaCdChannel> CreateCsmaCdChannel(
+    const DataRate& dataRate, const Time& delay);
+
+#if 0
+  /**
+   * \param n1 Node to be attached to the multipoint channel
+   * \param ch CsmaCdChannel to which node n1 should be attached 
+   * \param addr MacAddress that should be assigned to the
+   * EthernetNetDevice that will be added to the node.
+   *
+   * Add a multipoint node to a multipoint channel
+   */
+  static Ptr<CsmaCdNetDevice> AddCsmaCdEthernetNode(Ptr<Node> n1, 
+                                                    Ptr<CsmaCdChannel> ch,
+                                                    MacAddress addr);
+
+  /**
+   * \param app Application that will be sending data to the agent
+   * \param ndSrc Net Device that will be sending the packets onto the
+   * network
+   * \param ndDest Net Device to which ndSrc will be sending the packets
+   * \return A pointer to the PacketSocket
+   *
+   * Creates an PacketSocket and configure it to send packets between
+   * two net devices
+   */
+static Ptr<PacketSocket> ConnectPacketSocket(Ptr<PacketSocketApp> app,
+                                      Ptr<CsmaCdNetDevice> ndSrc,
+                                      Ptr<CsmaCdNetDevice> ndDest);
+
+  /**
+   * \param app Application that will be sending data to the agent
+   * \param ndSrc Net Device that will be sending the packets onto the
+   * network 
+   * \param macAddr Mac destination address for the packets send by
+   * the ndSrc net device \return a Pointer to the created
+   * PacketSocket
+   *
+   * Creates an PacketSocket and configure it to send packets from a
+   * net device to a destination MacAddress
+   */
+static Ptr<PacketSocket> ConnectPacketSocket(Ptr<PacketSocketApp> app,
+                                      Ptr<CsmaCdNetDevice> ndSrc,
+                                      MacAddress macAddr);
+
+  /**
+   * \param n1 Node from which socketfactory should be tested.
+   * \param iid_name Interface identifier ("Packet", in this case)
+   *
+   * This is a test function to make sure that a socket can be created
+   * by using the socketfactory interface provided in the
+   * netdevicenode.
+   */
+static  Ptr<Socket> CreatePacketSocket(Ptr<Node> n1, 
+                                       std::string iid_name);
+#endif
+
+};
+} // namespace ns3
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma-cd/wscript	Fri Jul 27 10:49:29 2007 -0700
@@ -0,0 +1,24 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+
+def build(bld):
+    obj = bld.create_obj('cpp', 'shlib')
+    obj.name = 'ns3-csma-cd'
+    obj.target = obj.name
+    obj.uselib_local = ['ns3-node']
+    obj.source = [
+        'backoff.cc',
+        'csma-cd-net-device.cc',
+        'csma-cd-channel.cc',
+        'csma-cd-topology.cc',
+        'csma-cd-ipv4-topology.cc',
+        ]
+    headers = bld.create_obj('ns3header')
+    headers.source = [
+        'backoff.h',
+        'csma-cd-net-device.h',
+        'csma-cd-channel.h',
+        'csma-cd-topology.h',
+        'csma-cd-ipv4-topology.h',
+        ]
+
--- a/src/devices/p2p/p2p-channel.cc	Fri Jul 27 10:48:10 2007 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,142 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 University of Washington
- * 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: Craig Dowell <craigdo@ee.washington.edu>
- */
-
-#include "p2p-channel.h"
-#include "p2p-net-device.h"
-#include "ns3/packet.h"
-#include "ns3/simulator.h"
-#include "ns3/debug.h"
-
-NS_DEBUG_COMPONENT_DEFINE ("PointToPointChannel");
-
-namespace ns3 {
-
-//
-// By default, you get a channel with the name "PointToPoint Channel" that 
-// has an "infitely" fast transmission speed and zero delay.
-PointToPointChannel::PointToPointChannel()
-: 
-  Channel ("PointToPoint Channel"), 
-  m_bps (DataRate(0xffffffff)),
-  m_delay (Seconds(0)),
-  m_nDevices(0)
-{
-  NS_DEBUG("PointToPointChannel::PointToPointChannel ()");
-}
-
-PointToPointChannel::PointToPointChannel(
-  const DataRate& bps, 
-  const Time& delay)
-: 
-  Channel ("PointToPoint Channel"), 
-  m_bps (bps),
-  m_delay (delay),
-  m_nDevices(0)
-{
-  NS_DEBUG("PointToPointChannel::PointToPointChannel (" << Channel::GetName() 
-    << ", " << bps.GetBitRate() << ", " << delay << ")");
-}
-
-PointToPointChannel::PointToPointChannel(
-  const std::string& name,
-  const DataRate& bps, 
-  const Time& delay)
-: 
-  Channel (name),
-  m_bps (bps), 
-  m_delay (delay),
-  m_nDevices(0)
-{
-  NS_DEBUG("PointToPointChannel::PointToPointChannel (" << name << ", " << 
-    bps.GetBitRate() << ", " << delay << ")");
-}
-
-  void
-PointToPointChannel::Attach(Ptr<PointToPointNetDevice> device)
-{
-  NS_DEBUG("PointToPointChannel::Attach (" << device << ")");
-  NS_ASSERT(m_nDevices < N_DEVICES && "Only two devices permitted");
-  NS_ASSERT(device != 0);
-
-  m_link[m_nDevices++].m_src = device;
-//
-// If we have both devices connected to the channel, then finish introducing
-// the two halves and set the links to IDLE.
-//
-  if (m_nDevices == N_DEVICES)
-    {
-      m_link[0].m_dst = m_link[1].m_src;
-      m_link[1].m_dst = m_link[0].m_src;
-      m_link[0].m_state = IDLE;
-      m_link[1].m_state = IDLE;
-    }
-}
-
-bool PointToPointChannel::TransmitStart(Packet& p,
-                                        Ptr<PointToPointNetDevice> src,
-                                        const Time& txTime)
-{
-  NS_DEBUG ("PointToPointChannel::TransmitStart (" << &p << ", " << src << 
-            ")");
-  NS_DEBUG ("PointToPointChannel::TransmitStart (): UID is " << 
-            p.GetUid () << ")");
-
-  NS_ASSERT(m_link[0].m_state != INITIALIZING);
-  NS_ASSERT(m_link[1].m_state != INITIALIZING);
-
-  uint32_t wire = src == m_link[0].m_src ? 0 : 1;
-
-  // Here we schedule the packet receive event at the receiver,
-  // which simplifies this model quite a bit.  The channel just
-  // adds the propagation delay time
-  Simulator::Schedule (txTime + m_delay,
-                       &PointToPointNetDevice::Receive,
-                       m_link[wire].m_dst, p);
-  return true;
-}
-
-uint32_t 
-PointToPointChannel::GetNDevices (void) const
-{
-  return m_nDevices;
-}
-
-Ptr<NetDevice>
-PointToPointChannel::GetDevice (uint32_t i) const
-{
-  NS_ASSERT(i < 2);
-  return m_link[i].m_src;
-}
-
-const DataRate&
-PointToPointChannel::GetDataRate (void)
-{
-  return m_bps;
-}
-
-const Time&
-PointToPointChannel::GetDelay (void)
-{
-  return m_delay;
-}
-
-
-} // namespace ns3
--- a/src/devices/p2p/p2p-channel.h	Fri Jul 27 10:48:10 2007 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,127 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 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 POINT_TO_POINT_CHANNEL_H
-#define POINT_TO_POINT_CHANNEL_H
-
-#include <list>
-#include "ns3/channel.h"
-#include "ns3/ptr.h"
-#include "ns3/packet.h"
-#include "ns3/nstime.h"
-#include "ns3/data-rate.h"
-
-namespace ns3 {
-
-class PointToPointNetDevice;
-
-/**
- * \brief Simple Point To Point Channel.
- *
- * This class represents a very simple point to point channel.  Think full
- * duplex RS-232 or RS-422 with null modem and no handshaking.  There is no
- * multi-drop capability on this channel -- there can be a maximum of two 
- * point-to-point net devices connected.  Once we start talking about multi-
- * drop, or CSMA, or some other sharing mechanism, things begin getting 
- * complicated quickly.  Rather than invent some ad-hoc mechanism, we just
- * Keep It Simple everywhere.
- *
- * When the channel is instaniated, the constructor takes parameters for
- * a single speed, in bits per second, and a speed-of-light delay time as a
- * Time object.  Both directions use the same speed and delay time.
- *
- * There are two "wires" in the channel.  The first device connected gets the
- * [0] wire to transmit on.  The second device gets the [1] wire.  There is a
- * state (IDLE, TRANSMITTING) associated with each wire.
- */
-class PointToPointChannel : public Channel {
-public:
-// Each point to point link has exactly two net devices
-  static const int N_DEVICES = 2;
-  /**
-   * \brief Create a PointToPointChannel
-   *
-   * By default, you get a channel with the name "PointToPoint Channel" that
-   * has an "infitely" fast transmission speed and zero delay.
-   */
-  PointToPointChannel ();
-  
-  /**
-   * \brief Create a PointToPointChannel
-   *
-   * \param bps The maximum bitrate of the channel
-   * \param delay Transmission delay through the channel
-   */  
-  PointToPointChannel (const DataRate& bps, const Time& delay);
-  
-  /**
-   * \brief Create a PointToPointChannel
-   *
-   * \param name the name of the channel for identification purposes
-   * \param bps The maximum bitrate of the channel
-   * \param delay Transmission delay through the channel
-   */
-  PointToPointChannel (const std::string& name,
-                 const DataRate& bps, const Time& delay);
-
-  /**
-   * \brief Attach a given netdevice to this channel
-   * \param device pointer to the netdevice to attach to the channel
-   */
-  void Attach (Ptr<PointToPointNetDevice> device);
-  bool TransmitStart (Packet& p, Ptr<PointToPointNetDevice> src,
-                      const Time& txTime);
-  // Below two not needed
-  //bool TransmitEnd (Packet &p, Ptr<PointToPointNetDevice> src);
-  //void PropagationCompleteEvent(Packet p, Ptr<PointToPointNetDevice> src);
-
-
-  virtual uint32_t GetNDevices (void) const;
-  virtual Ptr<NetDevice> GetDevice (uint32_t i) const;
-
-  virtual const DataRate& GetDataRate (void);
-  virtual const Time&     GetDelay (void);
-
-private:
-  DataRate      m_bps;
-  Time          m_delay;
-  int32_t       m_nDevices;
-
-  enum WireState
-    {
-      INITIALIZING,
-      IDLE,
-      TRANSMITTING,
-      PROPAGATING
-    };
-
-  class Link
-  {
-  public:
-    Link() : m_state (INITIALIZING), m_src (0), m_dst (0) {}
-    WireState              m_state;
-    Ptr<PointToPointNetDevice> m_src;
-    Ptr<PointToPointNetDevice> m_dst;
-  };
-    
-  Link    m_link[N_DEVICES];
-};
-
-} // namespace ns3
-
-#endif /* POINT_TO_POINT_CHANNEL_H */
--- a/src/devices/p2p/p2p-net-device.cc	Fri Jul 27 10:48:10 2007 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,221 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005,2006 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:  Craig Dowell <craigdo@ee.washington.edu>
- * Revised: George Riley <riley@ece.gatech.edu>
- */
-
-#include <iostream>
-#include <cassert>
-#include "ns3/debug.h"
-#include "ns3/queue.h"
-#include "ns3/simulator.h"
-#include "ns3/composite-trace-resolver.h"
-#include "p2p-net-device.h"
-#include "p2p-channel.h"
-
-NS_DEBUG_COMPONENT_DEFINE ("PointToPointNetDevice");
-
-namespace ns3 {
-
-DataRateDefaultValue PointToPointNetDevice::g_defaultRate(
-           "PointToPointLinkDataRate", 
-           "The default data rate for point to point links",
-           DataRate ("10Mb/s"));
-
-  PointToPointNetDevice::PointToPointNetDevice (Ptr<Node> node,
-                                                const DataRate& rate) 
-: 
-  NetDevice(node, MacAddress (6)), 
-  m_txMachineState (READY),
-  m_bps (rate),
-  m_tInterframeGap (Seconds(0)),
-  m_channel (0), 
-  m_queue (0),
-  m_rxTrace ()
-{
-  NS_DEBUG ("PointToPointNetDevice::PointToPointNetDevice (" << node << ")");
-
-  // BUGBUG FIXME
-  //
-  // You _must_ support broadcast to get any sort of packet from the ARP layer.
-  EnableBroadcast (MacAddress ("ff:ff:ff:ff:ff:ff"));
-  EnableMulticast();
-  EnablePointToPoint();
-}
-
-PointToPointNetDevice::~PointToPointNetDevice()
-{
-  NS_DEBUG ("PointToPointNetDevice::~PointToPointNetDevice ()");
-  m_queue = 0;
-}
-
-void PointToPointNetDevice::DoDispose()
-{
-  m_channel = 0;
-  NetDevice::DoDispose ();
-}
-
-
-void PointToPointNetDevice::SetDataRate(const DataRate& bps)
-{
-  m_bps = bps;
-}
-
-void PointToPointNetDevice::SetInterframeGap(const Time& t)
-{
-  m_tInterframeGap = t;
-}
-
-bool PointToPointNetDevice::SendTo (Packet& p, const MacAddress& dest)
-{
-  NS_DEBUG ("PointToPointNetDevice::SendTo (" << &p << ", " << &dest << ")");
-  NS_DEBUG ("PointToPointNetDevice::SendTo (): UID is " << p.GetUid () << ")");
-
-  // GFR Comment. Why is this an assertion? Can't a link legitimately
-  // "go down" during the simulation?  Shouldn't we just wait for it
-  // to come back up?
-  NS_ASSERT (IsLinkUp ());
-
-//
-// This class simulates a point to point device.  In the case of a serial
-// link, this means that we're simulating something like a UART.
-//
-//
-// If there's a transmission in progress, we enque the packet for later
-// trnsmission; otherwise we send it now.
-    if (m_txMachineState == READY) 
-      {
-        return TransmitStart (p);
-      }
-    else
-      {
-        return m_queue->Enqueue(p);
-      }
-}
-
-  bool
-PointToPointNetDevice::TransmitStart (Packet &p)
-{
-  NS_DEBUG ("PointToPointNetDevice::TransmitStart (" << &p << ")");
-  NS_DEBUG (
-    "PointToPointNetDevice::TransmitStart (): UID is " << p.GetUid () << ")");
-//
-// This function is called to start the process of transmitting a packet.
-// We need to tell the channel that we've started wiggling the wire and
-// schedule an event that will be executed when the transmission is complete.
-//
-  NS_ASSERT_MSG(m_txMachineState == READY, "Must be READY to transmit");
-  m_txMachineState = BUSY;
-  Time txTime = Seconds (m_bps.CalculateTxTime(p.GetSize()));
-  Time txCompleteTime = txTime + m_tInterframeGap;
-
-  NS_DEBUG ("PointToPointNetDevice::TransmitStart (): " <<
-    "Schedule TransmitCompleteEvent in " << 
-    txCompleteTime.GetSeconds () << "sec");
-  // Schedule the tx complete event
-  Simulator::Schedule (txCompleteTime, 
-                       &PointToPointNetDevice::TransmitComplete, 
-                       this);
-  return m_channel->TransmitStart(p, this, txTime); 
-}
-
-void PointToPointNetDevice::TransmitComplete (void)
-{
-  NS_DEBUG ("PointToPointNetDevice::TransmitCompleteEvent ()");
-//
-// This function is called to finish the  process of transmitting a packet.
-// We need to tell the channel that we've stopped wiggling the wire and
-// get the next packet from the queue.  If the queue is empty, we are
-// done, otherwise transmit the next packet.
-//
-  NS_ASSERT_MSG(m_txMachineState == BUSY, "Must be BUSY if transmitting");
-  m_txMachineState = READY;
-  Packet p;
-  if (!m_queue->Dequeue(p)) return; // Nothing to do at this point
-  TransmitStart(p);
-}
-
-TraceResolver* PointToPointNetDevice::DoCreateTraceResolver (
-                                      TraceContext const &context)
-{
-  CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
-  resolver->Add ("queue", 
-                 MakeCallback (&Queue::CreateTraceResolver, PeekPointer (m_queue)),
-                 PointToPointNetDevice::QUEUE);
-  resolver->Add ("rx",
-                 m_rxTrace,
-                 PointToPointNetDevice::RX);
-  return resolver;
-}
-
-bool PointToPointNetDevice::Attach (Ptr<PointToPointChannel> ch)
-{
-  NS_DEBUG ("PointToPointNetDevice::Attach (" << &ch << ")");
-
-  m_channel = ch;
-
-  m_channel->Attach(this);
-  m_bps = m_channel->GetDataRate ();
-  // GFR Comment.  Below is definitely wrong.  Interframe gap
-  // is unrelated to channel delay.
-  //m_tInterframeGap = m_channel->GetDelay ();
-
-  /* 
-   * For now, this device is up whenever a channel is attached to it.
-   * In fact, it should become up only when the second device
-   * is attached to the channel. So, there should be a way for
-   * a PointToPointChannel to notify both of its attached devices
-   * that the channel is 'complete', hence that the devices are
-   * up, hence that they can call NotifyLinkUp. 
-   */
-  NotifyLinkUp ();
-  return true;
-}
-
-void PointToPointNetDevice::AddQueue (Ptr<Queue> q)
-{
-  NS_DEBUG ("PointToPointNetDevice::AddQueue (" << q << ")");
-
-  m_queue = q;
-}
-
-void PointToPointNetDevice::Receive (Packet& p)
-{
-  NS_DEBUG ("PointToPointNetDevice::Receive (" << &p << ")");
-
-  m_rxTrace (p);
-  ForwardUp (p);
-}
-
-Ptr<Queue> PointToPointNetDevice::GetQueue(void) const 
-{ 
-    return m_queue;
-}
-
-Ptr<Channel> PointToPointNetDevice::DoGetChannel(void) const 
-{ 
-    return m_channel;
-}
-
-bool PointToPointNetDevice::DoNeedsArp (void) const
-{
-  return false;
-}
-
-} // namespace ns3
--- a/src/devices/p2p/p2p-net-device.h	Fri Jul 27 10:48:10 2007 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,296 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 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
- *
- * Author: Craig Dowell <craigdo@ee.washington.edu>
- */
-
-#ifndef POINT_TO_POINT_NET_DEVICE_H
-#define POINT_TO_POINT_NET_DEVICE_H
-
-#include <string.h>
-#include "ns3/mac-address.h"
-#include "ns3/node.h"
-#include "ns3/net-device.h"
-#include "ns3/callback.h"
-#include "ns3/packet.h"
-#include "ns3/callback-trace-source.h"
-#include "ns3/nstime.h"
-#include "ns3/data-rate.h"
-#include "ns3/default-value.h"
-#include "ns3/ptr.h"
-
-namespace ns3 {
-
-class Queue;
-class PointToPointChannel;
-
-/**
- * \class PointToPointNetDevice
- * \brief A Device for a Point to Point Network Link.
- *
- * Ns-3 takes a four-layer view of a protocol stack.  This is the same model
- * that TCP uses.  In this view, layers 5-7 of the OSI reference model are
- * grouped together into an application layer; layer four (transport / TCP) is
- * broken out; layer three (network / IP) is broken out; and layers 1-2 are
- * grouped together.  We call this grouping of layers one and two a NetDevice
- * and represent it as a class in the system.
- *
- * The NetDevice class is specialized according to the needs of the specific
- * kind of network link.  In this case, the link is a PointToPoint link.  The
- * PointToPoint link is a family of classes that includes this class, the
- * PointToPointNetDevice, a PointToPointChannel class that represents the 
- * actual medium across which bits are sent, a PointToPointIpv4Interface class
- * that provides the hook to tie a general purpose node to this specific
- * link, and finally, a PointToPointTopology object that is responsible for
- * putting all of the pieces together.
- *
- * This is the PointToPointNetDevice class that represents, essentially, the
- * PC card that is used to connect to the PointToPoint network.
- */
-class PointToPointNetDevice : public NetDevice {
-public:
-  /**
-   * Enumeration of the types of traces supported in the class.
-   *
-   */
-  enum TraceType {
-    QUEUE, /**< Trace queue events on the attached queue */
-    RX,    /**< Trace packet reception events (from the channel) */
-  };
-  /**
-   * Construct a PointToPointNetDevice
-   *
-   * This is the constructor for the PointToPointNetDevice.  It takes as a
-   * parameter the Node to which this device is connected.  Ownership of the
-   * Node pointer is not implied and the node must not be deleded.
-   *
-   * @see PointToPointTopology::AddPointToPointLink ()
-   * @param node the Node to which this device is connected.
-   */
-  PointToPointNetDevice (Ptr<Node> node,
-                         const DataRate& = g_defaultRate.GetValue());
-  /**
-   * Destroy a PointToPointNetDevice
-   *
-   * This is the destructor for the PointToPointNetDevice.
-   */
-  virtual ~PointToPointNetDevice();
-  /**
-   * Set the Data Rate used for transmission of packets.  The data rate is
-   * set in the Attach () method from the corresponding field in the channel
-   * to which the device is attached.  It can be overridden using this method.
-   *
-   * @see Attach ()
-   * @param bps the data rate at which this object operates
-   */
-  void SetDataRate(const DataRate& bps);
-  /**
-   * Set the inteframe gap used to separate packets.  The interframe gap
-   * defines the minimum space required between packets sent by this device.
-   * It is usually set in the Attach () method based on the speed of light
-   * delay of the channel to which the device is attached.  It can be 
-   * overridden using this method if desired.
-   *
-   * @see Attach ()
-   * @param t the interframe gap time
-   */
-  void SetInterframeGap(const Time& t);
-  /**
-   * Attach the device to a channel.
-   *
-   * The PointToPointTopology object creates a PointToPointChannel and two
-   * PointtoPointNetDevices.  In order to introduce these components to each
-   * other, the topology object calls Attach () on each PointToPointNetDevice.
-   * Inside this method, the Net Device calls out to the PointToPointChannel
-   * to introduce itself.
-   *
-   * @see PointToPointTopology::AddPointToPointLink ()
-   * @see SetDataRate ()
-   * @see SetInterframeGap ()
-   * @param ch a pointer to the channel to which this object is being attached.
-   */
-  bool Attach(Ptr<PointToPointChannel> ch);
-  /**
-   * Attach a queue to the PointToPointNetDevice.
-   *
-   * The PointToPointNetDevice "owns" a queue.  This queue is created by the
-   * PointToPointTopology object and implements a queueing method such as
-   * DropTail or RED.  The PointToPointNetDevice assumes ownership of this
-   * queue and must delete it when the device is destroyed.
-   *
-   * @see PointToPointTopology::AddPointToPointLink ()
-   * @see Queue
-   * @see DropTailQueue
-   * @param queue a pointer to the queue for which object is assuming
-   *        ownership.
-   */
-  void AddQueue(Ptr<Queue> queue);
-  /**
-   * Receive a packet from a connected PointToPointChannel.
-   *
-   * The PointToPointNetDevice receives packets from its connected channel
-   * and forwards them up the protocol stack.  This is the public method
-   * used by the channel to indicate that the last bit of a packet has 
-   * arrived at the device.
-   *
-   * @see PointToPointChannel
-   * @param p a reference to the received packet
-   */
-  void Receive (Packet& p);
-protected:
-  virtual void DoDispose (void);
-  /**
-   * Get a copy of the attached Queue.
-   *
-   * This method is provided for any derived class that may need to get
-   * direct access to the underlying queue.
-   *
-   * @see PointToPointTopology
-   * @returns a pointer to the queue.
-   */
-  Ptr<Queue> GetQueue(void) const; 
-  /**
-   * Get a copy of the attached Channel
-   *
-   * This method is provided for any derived class that may need to get
-   * direct access to the connected channel
-   *
-   * @see PointToPointChannel
-   * @returns a pointer to the channel
-   */
-  virtual Ptr<Channel> DoGetChannel(void) const;
-  /**
-   * Set a new default data rate
-   * @param Data rate to set for new default
-   */
-  static void SetDefaultRate(const DataRate&);
-
-  /** 
-   * Get the current default rate.
-   * @returns a const reference to current default
-   */
-
-  static const DataRate& GetDefaultRate();
-
-private:
-  // unimplemented methods to make it impossible
-  // to copy these objects.
-  PointToPointNetDevice (const PointToPointNetDevice& nd);
-  PointToPointNetDevice& operator = (const PointToPointNetDevice&o);
-  
-  /**
-   * Send a Packet Down the Wire.
-   *
-   * The SendTo method is defined as the standard way that the level three
-   * protocol uses to tell a NetDevice to send a packet.  SendTo is declared
-   * as abstract in the NetDevice class and we declare it here.
-   *
-   * @see NetDevice
-   * @param p a reference to the packet to send
-   * @param dest a reference to the MacAddress of the destination device
-   * @returns true if success, false on failure
-   */
-  virtual bool SendTo (Packet& p, const MacAddress& dest);
-  /**
-   * Start Sending a Packet Down the Wire.
-   *
-   * The TransmitStart method is the method that is used internally in the
-   * PointToPointNetDevice to begin the process of sending a packet out on
-   * the channel.  The corresponding method is called on the channel to let
-   * it know that the physical device this class represents has virually
-   * started sending signals.  An event is scheduled for the time at which
-   * the bits have been completely transmitted.
-   *
-   * @see PointToPointChannel::TransmitStart ()
-   * @see TransmitCompleteEvent ()
-   * @param p a reference to the packet to send
-   * @returns true if success, false on failure
-   */
-  bool TransmitStart (Packet &p);
-  /**
-   * Stop Sending a Packet Down the Wire and Begin the Interframe Gap.
-   *
-   * The TransmitComplete method is used internally to finish the process
-   * of sending a packet out on the channel.
-   *
-   */
-  void TransmitComplete(void);
-  /**
-   * Create a Trace Resolver for events in the net device.
-   *
-   * @see class TraceResolver
-   */
-  virtual TraceResolver* DoCreateTraceResolver (TraceContext const &context);
-  virtual bool DoNeedsArp (void) const;
-  /**
-   * Enumeration of the states of the transmit machine of the net device.
-   */
-  enum TxMachineState
-    {
-      READY, /**< The transmitter is ready to begin transmission of a packet */
-      BUSY   /**< The transmitter is busy transmitting a packet */
-    };
-  /**
-   * The state of the Net Device transmit state machine.
-   * @see TxMachineState
-   */
-  TxMachineState m_txMachineState;
-  /**
-   * The data rate that the Net Device uses to simulate packet transmission
-   * timing.
-   * @see class DataRate
-   */
-  DataRate       m_bps;
-  /**
-   * The interframe gap that the Net Device uses to throttle packet
-   * transmission
-   * @see class Time
-   */
-  Time           m_tInterframeGap;
-  /**
-   * The PointToPointChannel to which this PointToPointNetDevice has been
-   * attached.
-   * @see class PointToPointChannel
-   */
-  Ptr<PointToPointChannel> m_channel;
-  /**
-   * The Queue which this PointToPointNetDevice uses as a packet source.
-   * Management of this Queue has been delegated to the PointToPointNetDevice
-   * and it has the responsibility for deletion.
-   * @see class Queue
-   * @see class DropTailQueue
-   */
-  Ptr<Queue> m_queue;
-  /**
-   * The trace source for the packet reception events that the device can
-   * fire.
-   *
-   * @see class CallBackTraceSource
-   * @see class TraceResolver
-   */
-  CallbackTraceSource<Packet &> m_rxTrace;
-  /** 
-   * Default data rate.  Used for all newly created p2p net devices
-   */
-   static DataRateDefaultValue g_defaultRate;
-
-};
-
-}; // namespace ns3
-
-#endif // POINT_TO_POINT_NET_DEVICE_H
-
--- a/src/devices/p2p/p2p-topology.cc	Fri Jul 27 10:48:10 2007 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,172 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-//
-// 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: George F. Riley<riley@ece.gatech.edu>
-//
-
-//
-// Topology helper for ns3.
-// George F. Riley, Georgia Tech, Spring 2007
-
-#include <algorithm>
-#include "ns3/assert.h"
-#include "ns3/debug.h"
-#include "ns3/fatal-error.h"
-#include "ns3/nstime.h"
-#include "ns3/internet-node.h"
-#include "ns3/ipv4-address.h"
-#include "ns3/ipv4.h"
-#include "ns3/queue.h"
-
-#include "p2p-channel.h"
-#include "p2p-net-device.h"
-#include "p2p-topology.h"
-
-namespace ns3 {
-
-Ptr<PointToPointChannel>
-PointToPointTopology::AddPointToPointLink(
-  Ptr<Node> n1,
-  Ptr<Node> n2,
-  const DataRate& bps,
-  const Time& delay)
-{
-  Ptr<PointToPointChannel> channel = Create<PointToPointChannel> (bps, delay);
-
-  Ptr<PointToPointNetDevice> net1 = Create<PointToPointNetDevice> (n1);
-
-  Ptr<Queue> q = Queue::CreateDefault ();
-  net1->AddQueue(q);
-  net1->Attach (channel);
-  
-  Ptr<PointToPointNetDevice> net2 = Create<PointToPointNetDevice> (n2);
-
-  q = Queue::CreateDefault ();
-  net2->AddQueue(q);
-  net2->Attach (channel);
-
-  return channel;
-}
-
-void
-PointToPointTopology::AddIpv4Addresses(
-  Ptr<const PointToPointChannel> chan,
-  Ptr<Node> n1, const Ipv4Address& addr1,
-  Ptr<Node> n2, const Ipv4Address& addr2)
-{
-
-  // Duplex link is assumed to be subnetted as a /30
-  // May run this unnumbered in the future?
-  Ipv4Mask netmask("255.255.255.252");
-  NS_ASSERT (netmask.IsMatch(addr1,addr2));
-
-  // The PointToPoint channel is used to find the relevant NetDevices
-  NS_ASSERT (chan->GetNDevices () == 2);
-  Ptr<NetDevice> nd1 = chan->GetDevice (0);
-  Ptr<NetDevice> nd2 = chan->GetDevice (1);
-  // Make sure that nd1 belongs to n1 and nd2 to n2
-  if ( (nd1->GetNode ()->GetId () == n2->GetId () ) && 
-       (nd2->GetNode ()->GetId () == n1->GetId () ) )
-    {
-      std::swap(nd1, nd2);
-    }
-  NS_ASSERT (nd1->GetNode ()->GetId () == n1->GetId ());
-  NS_ASSERT (nd2->GetNode ()->GetId () == n2->GetId ());
-  
-  Ptr<Ipv4> ip1 = n1->QueryInterface<Ipv4> (Ipv4::iid);
-  uint32_t index1 = ip1->AddInterface (nd1);
-
-  ip1->SetAddress (index1, addr1);
-  ip1->SetNetworkMask (index1, netmask);
-  ip1->SetUp (index1);
-
-  Ptr<Ipv4> ip2 = n2->QueryInterface<Ipv4> (Ipv4::iid);
-  uint32_t index2 = ip2->AddInterface (nd2);
-
-  ip2->SetAddress (index2, addr2);
-  ip2->SetNetworkMask (index2, netmask);
-  ip2->SetUp (index2);
-  
-}
-
-void
-PointToPointTopology::AddIpv4Routes (
-  Ptr<Node> n1, Ptr<Node> n2, Ptr<const PointToPointChannel> chan)
-{ 
-  // The PointToPoint channel is used to find the relevant NetDevices
-  NS_ASSERT (chan->GetNDevices () == 2);
-  Ptr<NetDevice> nd1 = chan->GetDevice (0);
-  Ptr<NetDevice> nd2 = chan->GetDevice (1);
-
-  // Assert that n1 is the Node owning one of the two NetDevices
-  // and make sure that nd1 corresponds to it
-  if (nd1->GetNode ()->GetId () == n1->GetId ())
-    {
-      ; // Do nothing
-    }
-  else if (nd2->GetNode ()->GetId () == n1->GetId ())
-    {
-      std::swap(nd1, nd2);
-    }
-  else
-    {
-      NS_FATAL_ERROR("P2PTopo: Node does not contain an interface on Channel");
-    }
-
-   // Assert that n2 is the Node owning one of the two NetDevices
-   // and make sure that nd2 corresponds to it
-  if (nd2->GetNode ()->GetId () != n2->GetId ())
-    {
-      NS_FATAL_ERROR("P2PTopo: Node does not contain an interface on Channel");
-    }
-
-  // Assert that both are Ipv4 nodes
-  Ptr<Ipv4> ip1 = nd1->GetNode ()->QueryInterface<Ipv4> (Ipv4::iid);
-  Ptr<Ipv4> ip2 = nd2->GetNode ()->QueryInterface<Ipv4> (Ipv4::iid);
-  NS_ASSERT(ip1 != 0 && ip2 != 0);
-
-  // Get interface indexes for both nodes corresponding to the right channel
-  uint32_t index1 = 0;
-  bool found = false;
-  for (uint32_t i = 0; i < ip1->GetNInterfaces (); i++)
-    {
-      if (ip1 ->GetNetDevice (i) == nd1)
-        {
-          index1 = i;
-          found = true;
-        }
-    }
-  NS_ASSERT(found);
-
-  uint32_t index2 = 0;
-  found = false;
-  for (uint32_t i = 0; i < ip2->GetNInterfaces (); i++)
-    {
-      if (ip2 ->GetNetDevice (i) == nd2)
-        {
-          index2 = i;
-          found = true;
-        }
-    }
-  NS_ASSERT(found);
-
-  ip1->AddHostRouteTo (ip2-> GetAddress (index2), index1);
-  ip2->AddHostRouteTo (ip1-> GetAddress (index1), index2); 
-}
-
-} // namespace ns3
- 
--- a/src/devices/p2p/p2p-topology.h	Fri Jul 27 10:48:10 2007 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-//
-// 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: George F. Riley<riley@ece.gatech.edu>
-//
-// Topology helper for ns3.
-// George F. Riley, Georgia Tech, Spring 2007
-#ifndef __POINT_TO_POINT_TOPOLOGY_H__
-#define __POINT_TO_POINT_TOPOLOGY_H__
-
-#include "ns3/ptr.h"
-
-// The topology class consists of only static methods thar are used to
-// create the topology and data flows for an ns3 simulation
-
-namespace ns3 {
-
-class PointToPointChannel;
-class Node;
-class IPAddr;
-class DataRate;
-class Queue;
-
-/**
- * \brief A helper class to create Topologies based on the 
- * ns3::PointToPointNetDevice and  ns3::PointToPointChannel objects.
- */
-class PointToPointTopology {
-public:
-  /** 
-   * \param n1 Node
-   * \param n2 Node
-   * \param dataRate Maximum transmission link rate 
-   * \param delay one-way propagation delay 
-   * \return Pointer to the underlying PointToPointChannel
-   * 
-   * Add a full-duplex point-to-point link between two nodes
-   * and attach PointToPointNetDevices to the resulting
-   * PointToPointChannel.  
-   */
-  static Ptr<PointToPointChannel> AddPointToPointLink(
-    Ptr<Node> n1, Ptr<Node> n2, const DataRate& dataRate, const Time& delay);
-
-  /** 
-   * \param chan PointToPointChannel to use
-   * \param n1 Node
-   * \param addr1 Ipv4 Address for n1
-   * \param n2 Node
-   * \param addr2 Ipv4 Address for n2
-   * 
-   * Add Ipv4Addresses to the Ipv4 interfaces associated with the 
-   * two PointToPointNetDevices on the provided PointToPointChannel
-   */
-  static void AddIpv4Addresses(
-    Ptr<const PointToPointChannel> chan,
-    Ptr<Node> n1, const Ipv4Address& addr1,
-    Ptr<Node> n2, const Ipv4Address& addr2);
-
-  /**
-   * \param channel PointToPointChannel to use
-   * \param n1 Node
-   * \param n2 Node
-   * 
-   * For the given PointToPointChannel, for each Node, add an 
-   * IPv4 host route to the IPv4 address of the peer node.  
-   */
-  static void AddIpv4Routes (Ptr<Node> n1, Ptr<Node> n2, Ptr<const PointToPointChannel> channel);
-};
-
-} // namespace ns3
-
-#endif
-
--- a/src/devices/p2p/wscript	Fri Jul 27 10:48:10 2007 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
-
-
-def build(bld):
-    p2p = bld.create_obj('cpp', 'shlib')
-    p2p.name = 'ns3-p2p'
-    p2p.target = p2p.name
-    p2p.uselib_local = ['ns3-node']
-    p2p.source = [
-        'p2p-net-device.cc',
-        'p2p-channel.cc',
-        'p2p-topology.cc',
-        ]
-    p2p.includes = '.'
-
-    headers = bld.create_obj('ns3header')
-    headers.source = [
-        'p2p-net-device.h',
-        'p2p-channel.h',
-        'p2p-topology.h',
-        ]
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/point-to-point/point-to-point-channel.cc	Fri Jul 27 10:49:29 2007 -0700
@@ -0,0 +1,142 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 University of Washington
+ * 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: Craig Dowell <craigdo@ee.washington.edu>
+ */
+
+#include "point-to-point-channel.h"
+#include "point-to-point-net-device.h"
+#include "ns3/packet.h"
+#include "ns3/simulator.h"
+#include "ns3/debug.h"
+
+NS_DEBUG_COMPONENT_DEFINE ("PointToPointChannel");
+
+namespace ns3 {
+
+//
+// By default, you get a channel with the name "PointToPoint Channel" that 
+// has an "infitely" fast transmission speed and zero delay.
+PointToPointChannel::PointToPointChannel()
+: 
+  Channel ("PointToPoint Channel"), 
+  m_bps (DataRate(0xffffffff)),
+  m_delay (Seconds(0)),
+  m_nDevices(0)
+{
+  NS_DEBUG("PointToPointChannel::PointToPointChannel ()");
+}
+
+PointToPointChannel::PointToPointChannel(
+  const DataRate& bps, 
+  const Time& delay)
+: 
+  Channel ("PointToPoint Channel"), 
+  m_bps (bps),
+  m_delay (delay),
+  m_nDevices(0)
+{
+  NS_DEBUG("PointToPointChannel::PointToPointChannel (" << Channel::GetName() 
+    << ", " << bps.GetBitRate() << ", " << delay << ")");
+}
+
+PointToPointChannel::PointToPointChannel(
+  const std::string& name,
+  const DataRate& bps, 
+  const Time& delay)
+: 
+  Channel (name),
+  m_bps (bps), 
+  m_delay (delay),
+  m_nDevices(0)
+{
+  NS_DEBUG("PointToPointChannel::PointToPointChannel (" << name << ", " << 
+    bps.GetBitRate() << ", " << delay << ")");
+}
+
+  void
+PointToPointChannel::Attach(Ptr<PointToPointNetDevice> device)
+{
+  NS_DEBUG("PointToPointChannel::Attach (" << device << ")");
+  NS_ASSERT(m_nDevices < N_DEVICES && "Only two devices permitted");
+  NS_ASSERT(device != 0);
+
+  m_link[m_nDevices++].m_src = device;
+//
+// If we have both devices connected to the channel, then finish introducing
+// the two halves and set the links to IDLE.
+//
+  if (m_nDevices == N_DEVICES)
+    {
+      m_link[0].m_dst = m_link[1].m_src;
+      m_link[1].m_dst = m_link[0].m_src;
+      m_link[0].m_state = IDLE;
+      m_link[1].m_state = IDLE;
+    }
+}
+
+bool PointToPointChannel::TransmitStart(Packet& p,
+                                        Ptr<PointToPointNetDevice> src,
+                                        const Time& txTime)
+{
+  NS_DEBUG ("PointToPointChannel::TransmitStart (" << &p << ", " << src << 
+            ")");
+  NS_DEBUG ("PointToPointChannel::TransmitStart (): UID is " << 
+            p.GetUid () << ")");
+
+  NS_ASSERT(m_link[0].m_state != INITIALIZING);
+  NS_ASSERT(m_link[1].m_state != INITIALIZING);
+
+  uint32_t wire = src == m_link[0].m_src ? 0 : 1;
+
+  // Here we schedule the packet receive event at the receiver,
+  // which simplifies this model quite a bit.  The channel just
+  // adds the propagation delay time
+  Simulator::Schedule (txTime + m_delay,
+                       &PointToPointNetDevice::Receive,
+                       m_link[wire].m_dst, p);
+  return true;
+}
+
+uint32_t 
+PointToPointChannel::GetNDevices (void) const
+{
+  return m_nDevices;
+}
+
+Ptr<NetDevice>
+PointToPointChannel::GetDevice (uint32_t i) const
+{
+  NS_ASSERT(i < 2);
+  return m_link[i].m_src;
+}
+
+const DataRate&
+PointToPointChannel::GetDataRate (void)
+{
+  return m_bps;
+}
+
+const Time&
+PointToPointChannel::GetDelay (void)
+{
+  return m_delay;
+}
+
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/point-to-point/point-to-point-channel.h	Fri Jul 27 10:49:29 2007 -0700
@@ -0,0 +1,127 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 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 POINT_TO_POINT_CHANNEL_H
+#define POINT_TO_POINT_CHANNEL_H
+
+#include <list>
+#include "ns3/channel.h"
+#include "ns3/ptr.h"
+#include "ns3/packet.h"
+#include "ns3/nstime.h"
+#include "ns3/data-rate.h"
+
+namespace ns3 {
+
+class PointToPointNetDevice;
+
+/**
+ * \brief Simple Point To Point Channel.
+ *
+ * This class represents a very simple point to point channel.  Think full
+ * duplex RS-232 or RS-422 with null modem and no handshaking.  There is no
+ * multi-drop capability on this channel -- there can be a maximum of two 
+ * point-to-point net devices connected.  Once we start talking about multi-
+ * drop, or CSMA, or some other sharing mechanism, things begin getting 
+ * complicated quickly.  Rather than invent some ad-hoc mechanism, we just
+ * Keep It Simple everywhere.
+ *
+ * When the channel is instaniated, the constructor takes parameters for
+ * a single speed, in bits per second, and a speed-of-light delay time as a
+ * Time object.  Both directions use the same speed and delay time.
+ *
+ * There are two "wires" in the channel.  The first device connected gets the
+ * [0] wire to transmit on.  The second device gets the [1] wire.  There is a
+ * state (IDLE, TRANSMITTING) associated with each wire.
+ */
+class PointToPointChannel : public Channel {
+public:
+// Each point to point link has exactly two net devices
+  static const int N_DEVICES = 2;
+  /**
+   * \brief Create a PointToPointChannel
+   *
+   * By default, you get a channel with the name "PointToPoint Channel" that
+   * has an "infitely" fast transmission speed and zero delay.
+   */
+  PointToPointChannel ();
+  
+  /**
+   * \brief Create a PointToPointChannel
+   *
+   * \param bps The maximum bitrate of the channel
+   * \param delay Transmission delay through the channel
+   */  
+  PointToPointChannel (const DataRate& bps, const Time& delay);
+  
+  /**
+   * \brief Create a PointToPointChannel
+   *
+   * \param name the name of the channel for identification purposes
+   * \param bps The maximum bitrate of the channel
+   * \param delay Transmission delay through the channel
+   */
+  PointToPointChannel (const std::string& name,
+                 const DataRate& bps, const Time& delay);
+
+  /**
+   * \brief Attach a given netdevice to this channel
+   * \param device pointer to the netdevice to attach to the channel
+   */
+  void Attach (Ptr<PointToPointNetDevice> device);
+  bool TransmitStart (Packet& p, Ptr<PointToPointNetDevice> src,
+                      const Time& txTime);
+  // Below two not needed
+  //bool TransmitEnd (Packet &p, Ptr<PointToPointNetDevice> src);
+  //void PropagationCompleteEvent(Packet p, Ptr<PointToPointNetDevice> src);
+
+
+  virtual uint32_t GetNDevices (void) const;
+  virtual Ptr<NetDevice> GetDevice (uint32_t i) const;
+
+  virtual const DataRate& GetDataRate (void);
+  virtual const Time&     GetDelay (void);
+
+private:
+  DataRate      m_bps;
+  Time          m_delay;
+  int32_t       m_nDevices;
+
+  enum WireState
+    {
+      INITIALIZING,
+      IDLE,
+      TRANSMITTING,
+      PROPAGATING
+    };
+
+  class Link
+  {
+  public:
+    Link() : m_state (INITIALIZING), m_src (0), m_dst (0) {}
+    WireState              m_state;
+    Ptr<PointToPointNetDevice> m_src;
+    Ptr<PointToPointNetDevice> m_dst;
+  };
+    
+  Link    m_link[N_DEVICES];
+};
+
+} // namespace ns3
+
+#endif /* POINT_TO_POINT_CHANNEL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/point-to-point/point-to-point-net-device.cc	Fri Jul 27 10:49:29 2007 -0700
@@ -0,0 +1,244 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005,2006 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:  Craig Dowell <craigdo@ee.washington.edu>
+ * Revised: George Riley <riley@ece.gatech.edu>
+ */
+
+#include <iostream>
+#include <cassert>
+#include "ns3/debug.h"
+#include "ns3/queue.h"
+#include "ns3/simulator.h"
+#include "ns3/composite-trace-resolver.h"
+#include "point-to-point-net-device.h"
+#include "point-to-point-channel.h"
+#include "ns3/llc-snap-header.h"
+
+NS_DEBUG_COMPONENT_DEFINE ("PointToPointNetDevice");
+
+namespace ns3 {
+
+DataRateDefaultValue PointToPointNetDevice::g_defaultRate(
+           "PointToPointLinkDataRate", 
+           "The default data rate for point to point links",
+           DataRate ("10Mb/s"));
+
+  PointToPointNetDevice::PointToPointNetDevice (Ptr<Node> node,
+                                                const DataRate& rate) 
+: 
+  NetDevice(node, MacAddress (6)), 
+  m_txMachineState (READY),
+  m_bps (rate),
+  m_tInterframeGap (Seconds(0)),
+  m_channel (0), 
+  m_queue (0),
+  m_rxTrace ()
+{
+  NS_DEBUG ("PointToPointNetDevice::PointToPointNetDevice (" << node << ")");
+
+  // BUGBUG FIXME
+  //
+  // You _must_ support broadcast to get any sort of packet from the ARP layer.
+  EnableBroadcast (MacAddress ("ff:ff:ff:ff:ff:ff"));
+  EnableMulticast();
+  EnablePointToPoint();
+}
+
+PointToPointNetDevice::~PointToPointNetDevice()
+{
+  NS_DEBUG ("PointToPointNetDevice::~PointToPointNetDevice ()");
+  m_queue = 0;
+}
+
+void PointToPointNetDevice::AddHeader(Packet& p, const MacAddress& dest,
+                                      uint16_t protocolNumber)
+{
+  LlcSnapHeader llc;
+  llc.SetType (protocolNumber);
+  p.AddHeader (llc);
+}
+
+bool PointToPointNetDevice::ProcessHeader(Packet& p, int& param)
+{
+  LlcSnapHeader llc;
+  p.RemoveHeader (llc);
+
+  param = llc.GetType ();
+
+  return true;
+}
+
+void PointToPointNetDevice::DoDispose()
+{
+  m_channel = 0;
+  NetDevice::DoDispose ();
+}
+
+void PointToPointNetDevice::SetDataRate(const DataRate& bps)
+{
+  m_bps = bps;
+}
+
+void PointToPointNetDevice::SetInterframeGap(const Time& t)
+{
+  m_tInterframeGap = t;
+}
+
+bool PointToPointNetDevice::SendTo (Packet& p, const MacAddress& dest, 
+                                    uint16_t protocolNumber)
+{
+  NS_DEBUG ("PointToPointNetDevice::SendTo (" << &p << ", " << &dest << ")");
+  NS_DEBUG ("PointToPointNetDevice::SendTo (): UID is " << p.GetUid () << ")");
+
+  // GFR Comment. Why is this an assertion? Can't a link legitimately
+  // "go down" during the simulation?  Shouldn't we just wait for it
+  // to come back up?
+  NS_ASSERT (IsLinkUp ());
+  AddHeader(p, dest, protocolNumber);
+
+//
+// This class simulates a point to point device.  In the case of a serial
+// link, this means that we're simulating something like a UART.
+//
+//
+// If there's a transmission in progress, we enque the packet for later
+// trnsmission; otherwise we send it now.
+    if (m_txMachineState == READY) 
+      {
+        return TransmitStart (p);
+      }
+    else
+      {
+        return m_queue->Enqueue(p);
+      }
+}
+
+  bool
+PointToPointNetDevice::TransmitStart (Packet &p)
+{
+  NS_DEBUG ("PointToPointNetDevice::TransmitStart (" << &p << ")");
+  NS_DEBUG (
+    "PointToPointNetDevice::TransmitStart (): UID is " << p.GetUid () << ")");
+//
+// This function is called to start the process of transmitting a packet.
+// We need to tell the channel that we've started wiggling the wire and
+// schedule an event that will be executed when the transmission is complete.
+//
+  NS_ASSERT_MSG(m_txMachineState == READY, "Must be READY to transmit");
+  m_txMachineState = BUSY;
+  Time txTime = Seconds (m_bps.CalculateTxTime(p.GetSize()));
+  Time txCompleteTime = txTime + m_tInterframeGap;
+
+  NS_DEBUG ("PointToPointNetDevice::TransmitStart (): " <<
+    "Schedule TransmitCompleteEvent in " << 
+    txCompleteTime.GetSeconds () << "sec");
+  // Schedule the tx complete event
+  Simulator::Schedule (txCompleteTime, 
+                       &PointToPointNetDevice::TransmitComplete, 
+                       this);
+  return m_channel->TransmitStart(p, this, txTime); 
+}
+
+void PointToPointNetDevice::TransmitComplete (void)
+{
+  NS_DEBUG ("PointToPointNetDevice::TransmitCompleteEvent ()");
+//
+// This function is called to finish the  process of transmitting a packet.
+// We need to tell the channel that we've stopped wiggling the wire and
+// get the next packet from the queue.  If the queue is empty, we are
+// done, otherwise transmit the next packet.
+//
+  NS_ASSERT_MSG(m_txMachineState == BUSY, "Must be BUSY if transmitting");
+  m_txMachineState = READY;
+  Packet p;
+  if (!m_queue->Dequeue(p)) return; // Nothing to do at this point
+  TransmitStart(p);
+}
+
+TraceResolver* PointToPointNetDevice::DoCreateTraceResolver (
+                                      TraceContext const &context)
+{
+  CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
+  resolver->Add ("queue", 
+                 MakeCallback (&Queue::CreateTraceResolver, PeekPointer (m_queue)),
+                 PointToPointNetDevice::QUEUE);
+  resolver->Add ("rx",
+                 m_rxTrace,
+                 PointToPointNetDevice::RX);
+  return resolver;
+}
+
+bool PointToPointNetDevice::Attach (Ptr<PointToPointChannel> ch)
+{
+  NS_DEBUG ("PointToPointNetDevice::Attach (" << &ch << ")");
+
+  m_channel = ch;
+
+  m_channel->Attach(this);
+  m_bps = m_channel->GetDataRate ();
+  // GFR Comment.  Below is definitely wrong.  Interframe gap
+  // is unrelated to channel delay.
+  //m_tInterframeGap = m_channel->GetDelay ();
+
+  /* 
+   * For now, this device is up whenever a channel is attached to it.
+   * In fact, it should become up only when the second device
+   * is attached to the channel. So, there should be a way for
+   * a PointToPointChannel to notify both of its attached devices
+   * that the channel is 'complete', hence that the devices are
+   * up, hence that they can call NotifyLinkUp. 
+   */
+  NotifyLinkUp ();
+  return true;
+}
+
+void PointToPointNetDevice::AddQueue (Ptr<Queue> q)
+{
+  NS_DEBUG ("PointToPointNetDevice::AddQueue (" << q << ")");
+
+  m_queue = q;
+}
+
+void PointToPointNetDevice::Receive (Packet& p)
+{
+  NS_DEBUG ("PointToPointNetDevice::Receive (" << &p << ")");
+  int param = 0;
+  Packet packet = p;
+
+  ProcessHeader(packet, param);
+  m_rxTrace (packet);
+  ForwardUp (packet, param);
+}
+
+Ptr<Queue> PointToPointNetDevice::GetQueue(void) const 
+{ 
+    return m_queue;
+}
+
+Ptr<Channel> PointToPointNetDevice::DoGetChannel(void) const 
+{ 
+    return m_channel;
+}
+
+bool PointToPointNetDevice::DoNeedsArp (void) const
+{
+  return false;
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/point-to-point/point-to-point-net-device.h	Fri Jul 27 10:49:29 2007 -0700
@@ -0,0 +1,305 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 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
+ *
+ * Author: Craig Dowell <craigdo@ee.washington.edu>
+ */
+
+#ifndef POINT_TO_POINT_NET_DEVICE_H
+#define POINT_TO_POINT_NET_DEVICE_H
+
+#include <string.h>
+#include "ns3/mac-address.h"
+#include "ns3/node.h"
+#include "ns3/net-device.h"
+#include "ns3/callback.h"
+#include "ns3/packet.h"
+#include "ns3/callback-trace-source.h"
+#include "ns3/nstime.h"
+#include "ns3/data-rate.h"
+#include "ns3/default-value.h"
+#include "ns3/ptr.h"
+
+namespace ns3 {
+
+class Queue;
+class PointToPointChannel;
+
+/**
+ * \class PointToPointNetDevice
+ * \brief A Device for a Point to Point Network Link.
+ *
+ * Ns-3 takes a four-layer view of a protocol stack.  This is the same model
+ * that TCP uses.  In this view, layers 5-7 of the OSI reference model are
+ * grouped together into an application layer; layer four (transport / TCP) is
+ * broken out; layer three (network / IP) is broken out; and layers 1-2 are
+ * grouped together.  We call this grouping of layers one and two a NetDevice
+ * and represent it as a class in the system.
+ *
+ * The NetDevice class is specialized according to the needs of the specific
+ * kind of network link.  In this case, the link is a PointToPoint link.  The
+ * PointToPoint link is a family of classes that includes this class, the
+ * PointToPointNetDevice, a PointToPointChannel class that represents the 
+ * actual medium across which bits are sent, a PointToPointIpv4Interface class
+ * that provides the hook to tie a general purpose node to this specific
+ * link, and finally, a PointToPointTopology object that is responsible for
+ * putting all of the pieces together.
+ *
+ * This is the PointToPointNetDevice class that represents, essentially, the
+ * PC card that is used to connect to the PointToPoint network.
+ */
+class PointToPointNetDevice : public NetDevice {
+public:
+  /**
+   * Enumeration of the types of traces supported in the class.
+   *
+   */
+  enum TraceType {
+    QUEUE, /**< Trace queue events on the attached queue */
+    RX,    /**< Trace packet reception events (from the channel) */
+  };
+  /**
+   * Construct a PointToPointNetDevice
+   *
+   * This is the constructor for the PointToPointNetDevice.  It takes as a
+   * parameter the Node to which this device is connected.  Ownership of the
+   * Node pointer is not implied and the node must not be deleded.
+   *
+   * @see PointToPointTopology::AddPointToPointLink ()
+   * @param node the Node to which this device is connected.
+   */
+  PointToPointNetDevice (Ptr<Node> node,
+                         const DataRate& = g_defaultRate.GetValue());
+  /**
+   * Destroy a PointToPointNetDevice
+   *
+   * This is the destructor for the PointToPointNetDevice.
+   */
+  virtual ~PointToPointNetDevice();
+  /**
+   * Set the Data Rate used for transmission of packets.  The data rate is
+   * set in the Attach () method from the corresponding field in the channel
+   * to which the device is attached.  It can be overridden using this method.
+   *
+   * @see Attach ()
+   * @param bps the data rate at which this object operates
+   */
+  void SetDataRate(const DataRate& bps);
+  /**
+   * Set the inteframe gap used to separate packets.  The interframe gap
+   * defines the minimum space required between packets sent by this device.
+   * It is usually set in the Attach () method based on the speed of light
+   * delay of the channel to which the device is attached.  It can be 
+   * overridden using this method if desired.
+   *
+   * @see Attach ()
+   * @param t the interframe gap time
+   */
+  void SetInterframeGap(const Time& t);
+  /**
+   * Attach the device to a channel.
+   *
+   * The PointToPointTopology object creates a PointToPointChannel and two
+   * PointtoPointNetDevices.  In order to introduce these components to each
+   * other, the topology object calls Attach () on each PointToPointNetDevice.
+   * Inside this method, the Net Device calls out to the PointToPointChannel
+   * to introduce itself.
+   *
+   * @see PointToPointTopology::AddPointToPointLink ()
+   * @see SetDataRate ()
+   * @see SetInterframeGap ()
+   * @param ch a pointer to the channel to which this object is being attached.
+   */
+  bool Attach(Ptr<PointToPointChannel> ch);
+  /**
+   * Attach a queue to the PointToPointNetDevice.
+   *
+   * The PointToPointNetDevice "owns" a queue.  This queue is created by the
+   * PointToPointTopology object and implements a queueing method such as
+   * DropTail or RED.  The PointToPointNetDevice assumes ownership of this
+   * queue and must delete it when the device is destroyed.
+   *
+   * @see PointToPointTopology::AddPointToPointLink ()
+   * @see Queue
+   * @see DropTailQueue
+   * @param queue a pointer to the queue for which object is assuming
+   *        ownership.
+   */
+  void AddQueue(Ptr<Queue> queue);
+  /**
+   * Receive a packet from a connected PointToPointChannel.
+   *
+   * The PointToPointNetDevice receives packets from its connected channel
+   * and forwards them up the protocol stack.  This is the public method
+   * used by the channel to indicate that the last bit of a packet has 
+   * arrived at the device.
+   *
+   * @see PointToPointChannel
+   * @param p a reference to the received packet
+   */
+  void Receive (Packet& p);
+protected:
+  virtual void DoDispose (void);
+  /**
+   * Get a copy of the attached Queue.
+   *
+   * This method is provided for any derived class that may need to get
+   * direct access to the underlying queue.
+   *
+   * @see PointToPointTopology
+   * @returns a pointer to the queue.
+   */
+  Ptr<Queue> GetQueue(void) const; 
+  /**
+   * Get a copy of the attached Channel
+   *
+   * This method is provided for any derived class that may need to get
+   * direct access to the connected channel
+   *
+   * @see PointToPointChannel
+   * @returns a pointer to the channel
+   */
+  virtual Ptr<Channel> DoGetChannel(void) const;
+  /**
+   * Set a new default data rate
+   * @param Data rate to set for new default
+   */
+  static void SetDefaultRate(const DataRate&);
+
+  /** 
+   * Get the current default rate.
+   * @returns a const reference to current default
+   */
+
+  static const DataRate& GetDefaultRate();
+
+private:
+  /**
+   * Adds the necessary headers and trailers to a packet of data in order to
+   * respect the protocol implemented by the agent.
+   */
+  void AddHeader(Packet& p, const MacAddress& dest, uint16_t protocolNumber);
+  /**
+   * Removes, from a packet of data, all headers and trailers that
+   * relate to the protocol implemented by the agent
+   * \return Returns true if the packet should be forwarded up the
+   * protocol stack.
+   */
+  bool ProcessHeader(Packet& p, int& param);
+  /**
+   * Send a Packet Down the Wire.
+   *
+   * The SendTo method is defined as the standard way that the level three
+   * protocol uses to tell a NetDevice to send a packet.  SendTo is declared
+   * as abstract in the NetDevice class and we declare it here.
+   *
+   * @see NetDevice
+   * @param p a reference to the packet to send
+   * @param dest a reference to the MacAddress of the destination device
+   * @param protocolNumber Protocol Number used to find protocol touse
+   * @returns true if success, false on failure
+   */
+  virtual bool SendTo (Packet& p, const MacAddress& dest, 
+                       uint16_t protocolNumber);
+  /**
+   * Start Sending a Packet Down the Wire.
+   *
+   * The TransmitStart method is the method that is used internally in the
+   * PointToPointNetDevice to begin the process of sending a packet out on
+   * the channel.  The corresponding method is called on the channel to let
+   * it know that the physical device this class represents has virually
+   * started sending signals.  An event is scheduled for the time at which
+   * the bits have been completely transmitted.
+   *
+   * @see PointToPointChannel::TransmitStart ()
+   * @see TransmitCompleteEvent ()
+   * @param p a reference to the packet to send
+   * @returns true if success, false on failure
+   */
+  bool TransmitStart (Packet &p);
+  /**
+   * Stop Sending a Packet Down the Wire and Begin the Interframe Gap.
+   *
+   * The TransmitComplete method is used internally to finish the process
+   * of sending a packet out on the channel.
+   *
+   */
+  void TransmitComplete(void);
+  /**
+   * Create a Trace Resolver for events in the net device.
+   *
+   * @see class TraceResolver
+   */
+  virtual TraceResolver* DoCreateTraceResolver (TraceContext const &context);
+  virtual bool DoNeedsArp (void) const;
+  /**
+   * Enumeration of the states of the transmit machine of the net device.
+   */
+  enum TxMachineState
+    {
+      READY, /**< The transmitter is ready to begin transmission of a packet */
+      BUSY   /**< The transmitter is busy transmitting a packet */
+    };
+  /**
+   * The state of the Net Device transmit state machine.
+   * @see TxMachineState
+   */
+  TxMachineState m_txMachineState;
+  /**
+   * The data rate that the Net Device uses to simulate packet transmission
+   * timing.
+   * @see class DataRate
+   */
+  DataRate       m_bps;
+  /**
+   * The interframe gap that the Net Device uses to throttle packet
+   * transmission
+   * @see class Time
+   */
+  Time           m_tInterframeGap;
+  /**
+   * The PointToPointChannel to which this PointToPointNetDevice has been
+   * attached.
+   * @see class PointToPointChannel
+   */
+  Ptr<PointToPointChannel> m_channel;
+  /**
+   * The Queue which this PointToPointNetDevice uses as a packet source.
+   * Management of this Queue has been delegated to the PointToPointNetDevice
+   * and it has the responsibility for deletion.
+   * @see class Queue
+   * @see class DropTailQueue
+   */
+  Ptr<Queue> m_queue;
+  /**
+   * The trace source for the packet reception events that the device can
+   * fire.
+   *
+   * @see class CallBackTraceSource
+   * @see class TraceResolver
+   */
+  CallbackTraceSource<Packet &> m_rxTrace;
+  /** 
+   * Default data rate.  Used for all newly created p2p net devices
+   */
+   static DataRateDefaultValue g_defaultRate;
+
+};
+
+}; // namespace ns3
+
+#endif // POINT_TO_POINT_NET_DEVICE_H
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/point-to-point/point-to-point-topology.cc	Fri Jul 27 10:49:29 2007 -0700
@@ -0,0 +1,172 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+//
+// 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: George F. Riley<riley@ece.gatech.edu>
+//
+
+//
+// Topology helper for ns3.
+// George F. Riley, Georgia Tech, Spring 2007
+
+#include <algorithm>
+#include "ns3/assert.h"
+#include "ns3/debug.h"
+#include "ns3/fatal-error.h"
+#include "ns3/nstime.h"
+#include "ns3/internet-node.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/ipv4.h"
+#include "ns3/queue.h"
+
+#include "point-to-point-channel.h"
+#include "point-to-point-net-device.h"
+#include "point-to-point-topology.h"
+
+namespace ns3 {
+
+Ptr<PointToPointChannel>
+PointToPointTopology::AddPointToPointLink(
+  Ptr<Node> n1,
+  Ptr<Node> n2,
+  const DataRate& bps,
+  const Time& delay)
+{
+  Ptr<PointToPointChannel> channel = Create<PointToPointChannel> (bps, delay);
+
+  Ptr<PointToPointNetDevice> net1 = Create<PointToPointNetDevice> (n1);
+
+  Ptr<Queue> q = Queue::CreateDefault ();
+  net1->AddQueue(q);
+  net1->Attach (channel);
+  
+  Ptr<PointToPointNetDevice> net2 = Create<PointToPointNetDevice> (n2);
+
+  q = Queue::CreateDefault ();
+  net2->AddQueue(q);
+  net2->Attach (channel);
+
+  return channel;
+}
+
+void
+PointToPointTopology::AddIpv4Addresses(
+  Ptr<const PointToPointChannel> chan,
+  Ptr<Node> n1, const Ipv4Address& addr1,
+  Ptr<Node> n2, const Ipv4Address& addr2)
+{
+
+  // Duplex link is assumed to be subnetted as a /30
+  // May run this unnumbered in the future?
+  Ipv4Mask netmask("255.255.255.252");
+  NS_ASSERT (netmask.IsMatch(addr1,addr2));
+
+  // The PointToPoint channel is used to find the relevant NetDevices
+  NS_ASSERT (chan->GetNDevices () == 2);
+  Ptr<NetDevice> nd1 = chan->GetDevice (0);
+  Ptr<NetDevice> nd2 = chan->GetDevice (1);
+  // Make sure that nd1 belongs to n1 and nd2 to n2
+  if ( (nd1->GetNode ()->GetId () == n2->GetId () ) && 
+       (nd2->GetNode ()->GetId () == n1->GetId () ) )
+    {
+      std::swap(nd1, nd2);
+    }
+  NS_ASSERT (nd1->GetNode ()->GetId () == n1->GetId ());
+  NS_ASSERT (nd2->GetNode ()->GetId () == n2->GetId ());
+  
+  Ptr<Ipv4> ip1 = n1->QueryInterface<Ipv4> (Ipv4::iid);
+  uint32_t index1 = ip1->AddInterface (nd1);
+
+  ip1->SetAddress (index1, addr1);
+  ip1->SetNetworkMask (index1, netmask);
+  ip1->SetUp (index1);
+
+  Ptr<Ipv4> ip2 = n2->QueryInterface<Ipv4> (Ipv4::iid);
+  uint32_t index2 = ip2->AddInterface (nd2);
+
+  ip2->SetAddress (index2, addr2);
+  ip2->SetNetworkMask (index2, netmask);
+  ip2->SetUp (index2);
+  
+}
+
+void
+PointToPointTopology::AddIpv4Routes (
+  Ptr<Node> n1, Ptr<Node> n2, Ptr<const PointToPointChannel> chan)
+{ 
+  // The PointToPoint channel is used to find the relevant NetDevices
+  NS_ASSERT (chan->GetNDevices () == 2);
+  Ptr<NetDevice> nd1 = chan->GetDevice (0);
+  Ptr<NetDevice> nd2 = chan->GetDevice (1);
+
+  // Assert that n1 is the Node owning one of the two NetDevices
+  // and make sure that nd1 corresponds to it
+  if (nd1->GetNode ()->GetId () == n1->GetId ())
+    {
+      ; // Do nothing
+    }
+  else if (nd2->GetNode ()->GetId () == n1->GetId ())
+    {
+      std::swap(nd1, nd2);
+    }
+  else
+    {
+      NS_FATAL_ERROR("P2PTopo: Node does not contain an interface on Channel");
+    }
+
+   // Assert that n2 is the Node owning one of the two NetDevices
+   // and make sure that nd2 corresponds to it
+  if (nd2->GetNode ()->GetId () != n2->GetId ())
+    {
+      NS_FATAL_ERROR("P2PTopo: Node does not contain an interface on Channel");
+    }
+
+  // Assert that both are Ipv4 nodes
+  Ptr<Ipv4> ip1 = nd1->GetNode ()->QueryInterface<Ipv4> (Ipv4::iid);
+  Ptr<Ipv4> ip2 = nd2->GetNode ()->QueryInterface<Ipv4> (Ipv4::iid);
+  NS_ASSERT(ip1 != 0 && ip2 != 0);
+
+  // Get interface indexes for both nodes corresponding to the right channel
+  uint32_t index1 = 0;
+  bool found = false;
+  for (uint32_t i = 0; i < ip1->GetNInterfaces (); i++)
+    {
+      if (ip1 ->GetNetDevice (i) == nd1)
+        {
+          index1 = i;
+          found = true;
+        }
+    }
+  NS_ASSERT(found);
+
+  uint32_t index2 = 0;
+  found = false;
+  for (uint32_t i = 0; i < ip2->GetNInterfaces (); i++)
+    {
+      if (ip2 ->GetNetDevice (i) == nd2)
+        {
+          index2 = i;
+          found = true;
+        }
+    }
+  NS_ASSERT(found);
+
+  ip1->AddHostRouteTo (ip2-> GetAddress (index2), index1);
+  ip2->AddHostRouteTo (ip1-> GetAddress (index1), index2); 
+}
+
+} // namespace ns3
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/point-to-point/point-to-point-topology.h	Fri Jul 27 10:49:29 2007 -0700
@@ -0,0 +1,87 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+//
+// 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: George F. Riley<riley@ece.gatech.edu>
+//
+// Topology helper for ns3.
+// George F. Riley, Georgia Tech, Spring 2007
+#ifndef __POINT_TO_POINT_TOPOLOGY_H__
+#define __POINT_TO_POINT_TOPOLOGY_H__
+
+#include "ns3/ptr.h"
+
+// The topology class consists of only static methods thar are used to
+// create the topology and data flows for an ns3 simulation
+
+namespace ns3 {
+
+class PointToPointChannel;
+class Node;
+class IPAddr;
+class DataRate;
+class Queue;
+
+/**
+ * \brief A helper class to create Topologies based on the 
+ * ns3::PointToPointNetDevice and  ns3::PointToPointChannel objects.
+ */
+class PointToPointTopology {
+public:
+  /** 
+   * \param n1 Node
+   * \param n2 Node
+   * \param dataRate Maximum transmission link rate 
+   * \param delay one-way propagation delay 
+   * \return Pointer to the underlying PointToPointChannel
+   * 
+   * Add a full-duplex point-to-point link between two nodes
+   * and attach PointToPointNetDevices to the resulting
+   * PointToPointChannel.  
+   */
+  static Ptr<PointToPointChannel> AddPointToPointLink(
+    Ptr<Node> n1, Ptr<Node> n2, const DataRate& dataRate, const Time& delay);
+
+  /** 
+   * \param chan PointToPointChannel to use
+   * \param n1 Node
+   * \param addr1 Ipv4 Address for n1
+   * \param n2 Node
+   * \param addr2 Ipv4 Address for n2
+   * 
+   * Add Ipv4Addresses to the Ipv4 interfaces associated with the 
+   * two PointToPointNetDevices on the provided PointToPointChannel
+   */
+  static void AddIpv4Addresses(
+    Ptr<const PointToPointChannel> chan,
+    Ptr<Node> n1, const Ipv4Address& addr1,
+    Ptr<Node> n2, const Ipv4Address& addr2);
+
+  /**
+   * \param channel PointToPointChannel to use
+   * \param n1 Node
+   * \param n2 Node
+   * 
+   * For the given PointToPointChannel, for each Node, add an 
+   * IPv4 host route to the IPv4 address of the peer node.  
+   */
+  static void AddIpv4Routes (Ptr<Node> n1, Ptr<Node> n2, Ptr<const PointToPointChannel> channel);
+};
+
+} // namespace ns3
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/point-to-point/wscript	Fri Jul 27 10:49:29 2007 -0700
@@ -0,0 +1,21 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+
+def build(bld):
+    module = bld.create_obj('cpp', 'shlib')
+    module.name = 'ns3-point-to-point'
+    module.target = module.name
+    module.uselib_local = ['ns3-node']
+    module.source = [
+        'point-to-point-net-device.cc',
+        'point-to-point-channel.cc',
+        'point-to-point-topology.cc',
+        ]
+    headers = bld.create_obj('ns3header')
+    headers.source = [
+        'point-to-point-net-device.h',
+        'point-to-point-channel.h',
+        'point-to-point-topology.h',
+        ]
+    module.includes = '.'
+
--- a/src/internet-node/arp-header.cc	Fri Jul 27 10:48:10 2007 -0700
+++ b/src/internet-node/arp-header.cc	Fri Jul 27 10:49:29 2007 -0700
@@ -20,8 +20,8 @@
  */
 
 #include "ns3/assert.h"
+#include "ns3/address-utils.h"
 #include "arp-header.h"
-#include "header-utils.h"
 
 namespace ns3 {
 
--- a/src/internet-node/header-utils.cc	Fri Jul 27 10:48:10 2007 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006 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 "header-utils.h"
-
-namespace ns3 {
-
-void WriteTo (Buffer::Iterator &i, Ipv4Address ad)
-{
-  i.WriteHtonU32 (ad.GetHostOrder ());
-}
-void WriteTo (Buffer::Iterator &i, MacAddress ad)
-{
-  uint8_t mac[MacAddress::MAX_LEN];
-  ad.Peek (mac);
-  i.Write (mac, ad.GetLength ());
-}
-
-void ReadFrom (Buffer::Iterator &i, Ipv4Address &ad)
-{
-  ad.SetHostOrder (i.ReadNtohU32 ());
-}
-void ReadFrom (Buffer::Iterator &i, MacAddress &ad, uint32_t len)
-{
-  uint8_t mac[MacAddress::MAX_LEN];
-  i.Read (mac, len);
-  ad.Set (mac, len);
-}
-
-
-
-}; // namespace ns3
--- a/src/internet-node/header-utils.h	Fri Jul 27 10:48:10 2007 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006 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 HEADER_UTILS_H
-#define HEADER_UTILS_H
-
-#include "ns3/buffer.h"
-#include "ns3/ipv4-address.h"
-#include "ns3/mac-address.h"
-
-namespace ns3 {
-
-void WriteTo (Buffer::Iterator &i, Ipv4Address ad);
-void WriteTo (Buffer::Iterator &i, MacAddress ad);
-
-void ReadFrom (Buffer::Iterator &i, Ipv4Address &ad);
-void ReadFrom (Buffer::Iterator &i, MacAddress &ad, uint32_t len);
-
-};
-
-#endif /* HEADER_UTILS_H */
--- a/src/internet-node/wscript	Fri Jul 27 10:48:10 2007 -0700
+++ b/src/internet-node/wscript	Fri Jul 27 10:49:29 2007 -0700
@@ -24,7 +24,6 @@
         'arp-ipv4-interface.cc',
         'arp-l3-protocol.cc',
         'ipv4-loopback-interface.cc',
-        'header-utils.cc',
         'udp-socket.cc',
         'ipv4-end-point-demux.cc',
         'arp-private.cc',
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/address-utils.cc	Fri Jul 27 10:49:29 2007 -0700
@@ -0,0 +1,49 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 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 "address-utils.h"
+
+namespace ns3 {
+
+void WriteTo (Buffer::Iterator &i, Ipv4Address ad)
+{
+  i.WriteHtonU32 (ad.GetHostOrder ());
+}
+void WriteTo (Buffer::Iterator &i, MacAddress ad)
+{
+  uint8_t mac[MacAddress::MAX_LEN];
+  ad.Peek (mac);
+  i.Write (mac, ad.GetLength ());
+}
+
+void ReadFrom (Buffer::Iterator &i, Ipv4Address &ad)
+{
+  ad.SetHostOrder (i.ReadNtohU32 ());
+}
+void ReadFrom (Buffer::Iterator &i, MacAddress &ad, uint32_t len)
+{
+  uint8_t mac[MacAddress::MAX_LEN];
+  i.Read (mac, len);
+  ad.Set (mac, len);
+}
+
+
+
+}; // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/address-utils.h	Fri Jul 27 10:49:29 2007 -0700
@@ -0,0 +1,38 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 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 ADDRESS_UTILS_H
+#define ADDRESS_UTILS_H
+
+#include "ns3/buffer.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/mac-address.h"
+
+namespace ns3 {
+
+void WriteTo (Buffer::Iterator &i, Ipv4Address ad);
+void WriteTo (Buffer::Iterator &i, MacAddress ad);
+
+void ReadFrom (Buffer::Iterator &i, Ipv4Address &ad);
+void ReadFrom (Buffer::Iterator &i, MacAddress &ad, uint32_t len);
+
+};
+
+#endif /* ADDRESS_UTILS_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ethernet-header.cc	Fri Jul 27 10:49:29 2007 -0700
@@ -0,0 +1,173 @@
+/* -*-  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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
+ */
+
+#include "ns3/assert.h"
+#include "ns3/debug.h"
+#include "ns3/header.h"
+#include "ethernet-header.h"
+#include "address-utils.h"
+
+NS_DEBUG_COMPONENT_DEFINE ("EthernetHeader");
+
+namespace ns3 {
+
+bool EthernetHeader::m_enPreambleSfd = false;
+
+EthernetHeader::EthernetHeader ()
+{
+  Init();
+}
+
+EthernetHeader::~EthernetHeader ()
+{}
+
+void 
+EthernetHeader::Init()
+{
+  m_preambleSfd = 0;
+  m_lengthType = 0x0;
+}
+
+void 
+EthernetHeader::EnablePreambleSfd (bool enable)
+{
+  m_enPreambleSfd = enable;
+}
+
+void 
+EthernetHeader::SetLengthType (uint16_t lengthType)
+{
+  m_lengthType = lengthType;
+}
+uint16_t 
+EthernetHeader::GetLengthType (void) const
+{
+  return m_lengthType;
+}
+
+void 
+EthernetHeader::SetPreambleSfd (uint64_t preambleSfd)
+{
+  m_preambleSfd = preambleSfd;
+}
+uint64_t 
+EthernetHeader::GetPreambleSfd (void) const
+{
+  return m_preambleSfd;
+}
+
+void 
+EthernetHeader::SetSource (MacAddress source)
+{
+  m_source = source;
+}
+MacAddress
+EthernetHeader::GetSource (void) const
+{
+  return m_source;
+}
+
+void 
+EthernetHeader::SetDestination (MacAddress dst)
+{
+  m_destination = dst;
+}
+MacAddress
+EthernetHeader::GetDestination (void) const
+{
+  return m_destination;
+}
+
+ethernet_header_t 
+EthernetHeader::GetPacketType (void) const
+{
+  return LENGTH;
+}
+
+uint32_t 
+EthernetHeader::GetHeaderSize (void) const
+{
+  return GetSerializedSize();
+}
+
+std::string
+EthernetHeader::DoGetName (void) const
+{
+  return "ETHERNET";
+}
+
+void 
+EthernetHeader::PrintTo (std::ostream &os) const
+{
+  // ethernet, right ?
+  os << "(ethernet)";
+  if (m_enPreambleSfd)
+    {
+      os << " preamble/sfd=" << m_preambleSfd << ",";
+    }
+  os << " length/type=" << m_lengthType
+     << ", source=" << m_source
+     << ", destination=" << m_destination;
+}
+uint32_t 
+EthernetHeader::GetSerializedSize (void) const
+{
+  if (m_enPreambleSfd)
+    {
+      return PREAMBLE_SIZE + LENGTH_SIZE + 2*MAC_ADDR_SIZE;
+    } else {
+      return LENGTH_SIZE + 2*MAC_ADDR_SIZE;
+    }
+}
+
+void
+EthernetHeader::SerializeTo (Buffer::Iterator start) const
+{
+  Buffer::Iterator i = start;
+  
+  if (m_enPreambleSfd)
+    {
+      i.WriteU64(m_preambleSfd);
+    }
+  NS_ASSERT (m_destination.GetLength () == MAC_ADDR_SIZE);
+  NS_ASSERT (m_source.GetLength () == MAC_ADDR_SIZE);
+  WriteTo (i, m_destination);
+  WriteTo (i, m_source);
+  i.WriteU16 (m_lengthType);
+}
+uint32_t
+EthernetHeader::DeserializeFrom (Buffer::Iterator start)
+{
+  Buffer::Iterator i = start;
+
+  if (m_enPreambleSfd)
+    {
+      m_enPreambleSfd = i.ReadU64 ();
+    }
+
+  ReadFrom (i, m_destination, MAC_ADDR_SIZE);
+  ReadFrom (i, m_source, MAC_ADDR_SIZE);
+  m_lengthType = i.ReadU16 ();
+
+  return GetSerializedSize ();
+}
+
+}; // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ethernet-header.h	Fri Jul 27 10:49:29 2007 -0700
@@ -0,0 +1,128 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 Emmanuelle Laprise
+ * 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
+ */
+
+#ifndef ETHERNET_HEADER_H
+#define ETHERNET_HEADER_H
+
+#include "ns3/header.h"
+#include "ns3/mac-address.h"
+
+namespace ns3 {
+
+  /**
+   * Types of ethernet packets. Indicates the type of the current
+   * header.
+   */
+  enum ethernet_header_t {
+    LENGTH,   /**< Basic ethernet packet, no tags, type/length field
+                 indicates packet length or IP/ARP packet */
+    VLAN,     /**< Single tagged packet. Header includes VLAN tag */
+    QINQ      /**< Double tagged packet. Header includes two VLAN tags */
+  };
+/**
+ * \brief Packet header for Ethernet
+ *
+ * This class can be used to add a header to an ethernet packet that
+ * will specify the source and destination addresses and the length of
+ * the packet. Eventually the class will be improved to also support
+ * VLAN tags in packet headers.
+ */
+class EthernetHeader : public Header {
+public:
+  static const int PREAMBLE_SIZE = 8; /// size of the preamble_sfd header field
+  static const int LENGTH_SIZE = 2;   /// size of the length_type header field
+  static const int MAC_ADDR_SIZE = 6; /// size of src/dest addr header fields
+
+  /**
+   * \brief Construct a null ethernet header
+   */
+  EthernetHeader ();
+  virtual ~EthernetHeader ();
+  /**
+   * \brief Enable or disabled the serialisation of the preamble and
+   * Sfd header fields
+   */
+  static void EnablePreambleSfd (bool enable);
+  /**
+   * \param size The size of the payload in bytes
+   */
+  void SetLengthType (uint16_t size);
+  /**
+   * \param source The source address of this packet
+   */
+  void SetSource (MacAddress source);
+  /**
+   * \param destination The destination address of this packet.
+   */
+  void SetDestination (MacAddress destination);
+  /**
+   * \param preambleSfd The value that the preambleSfd field should take
+   */
+  void SetPreambleSfd (uint64_t preambleSfd);
+  /**
+   * \return The size of the payload in bytes
+   */
+  uint16_t GetLengthType (void) const;
+  /**
+   * \return The type of packet (only basic Ethernet is currently supported)
+   */
+  ethernet_header_t GetPacketType (void) const;
+  /**
+   * \return The source address of this packet
+   */
+  MacAddress GetSource (void) const;
+  /**
+   * \return The destination address of this packet
+   */
+  MacAddress GetDestination (void) const;  
+  /**
+   * \return The value of the PreambleSfd field
+   */
+  uint64_t GetPreambleSfd () const;
+  /**
+   * \return The size of the header
+   */
+  uint32_t GetHeaderSize() const;
+
+private:
+  virtual std::string DoGetName (void) const;
+  virtual void PrintTo (std::ostream &os) const;
+  virtual uint32_t GetSerializedSize (void) const;
+  virtual void SerializeTo (Buffer::Iterator start) const;
+  virtual uint32_t DeserializeFrom (Buffer::Iterator start);
+
+  void Init (void);
+
+  /**
+   * If false, the preamble/sfd are not serialised/deserialised.
+   */
+  static bool m_enPreambleSfd;
+
+  uint64_t m_preambleSfd;     /// Value of the Preamble/SFD fields
+  uint16_t m_lengthType : 16; /// Length or type of the packet
+  MacAddress m_source;        /// Source address
+  MacAddress m_destination;   /// Destination address
+};
+
+}; // namespace ns3
+
+
+#endif /* ETHERNET_HEADER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ethernet-trailer.cc	Fri Jul 27 10:49:29 2007 -0700
@@ -0,0 +1,124 @@
+/* -*-  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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
+ */
+
+#include "ns3/assert.h"
+#include "ns3/debug.h"
+#include "ns3/trailer.h"
+#include "ethernet-trailer.h"
+
+NS_DEBUG_COMPONENT_DEFINE ("EthernetTrailer");
+
+namespace ns3 {
+
+bool EthernetTrailer::m_calcFcs = false;
+
+EthernetTrailer::EthernetTrailer ()
+{
+  Init();
+}
+
+EthernetTrailer::~EthernetTrailer ()
+{}
+
+void EthernetTrailer::Init()
+{
+  m_fcs = 0;
+}
+
+void 
+EthernetTrailer::EnableFcs (bool enable)
+{
+  m_calcFcs = enable;
+}
+
+bool
+EthernetTrailer::CheckFcs (const Packet& p) const
+{
+  if (!m_calcFcs)
+    {
+      return true;
+    } else {
+      NS_DEBUG("FCS calculation is not yet enabled" << std::endl);
+      return false;
+    }
+}
+
+void
+EthernetTrailer::CalcFcs (const Packet& p)
+{
+  NS_DEBUG("FCS calculation is not yet enabled" << std::endl);
+}
+
+void
+EthernetTrailer::SetFcs (uint32_t fcs)
+{
+  m_fcs = fcs;
+}
+
+uint32_t
+EthernetTrailer::GetFcs (void)
+{
+  return m_fcs;
+}
+
+uint32_t
+EthernetTrailer::GetTrailerSize (void) const
+{
+  return GetSerializedSize();
+}
+std::string
+EthernetTrailer::DoGetName (void) const
+{
+  return "ETHERNET";
+}
+
+void 
+EthernetTrailer::PrintTo (std::ostream &os) const
+{
+  os << " fcs=" << m_fcs;
+}
+uint32_t 
+EthernetTrailer::GetSerializedSize (void) const
+{
+  return 4;
+}
+
+void
+EthernetTrailer::SerializeTo (Buffer::Iterator end) const
+{
+  Buffer::Iterator i = end;
+  i.Prev(GetSerializedSize());
+  
+  i.WriteU32 (m_fcs);
+}
+uint32_t
+EthernetTrailer::DeserializeFrom (Buffer::Iterator end)
+{
+  Buffer::Iterator i = end;
+  uint32_t size = GetSerializedSize();
+  i.Prev(size);
+
+  m_fcs = i.ReadU32 ();
+
+  return size;
+}
+
+}; // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ethernet-trailer.h	Fri Jul 27 10:49:29 2007 -0700
@@ -0,0 +1,104 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 Emmanuelle Laprise
+ * 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
+ */
+
+#ifndef ETHERNET_TRAILER_H
+#define ETHERNET_TRAILER_H
+
+#include "ns3/trailer.h"
+#include "ns3/packet.h"
+
+namespace ns3 {
+/**
+ * \brief Packet trailer for Ethernet
+ *
+ * This class can be used to add and verify the FCS at the end of an
+ * ethernet packet. The actual FCS functionality is not yet coded and
+ * so this acts more as a placeholder.
+ */
+class EthernetTrailer : public Trailer {
+public:
+  /**
+   * \brief Construct a null ethernet trailer
+   */
+  EthernetTrailer ();
+  virtual ~EthernetTrailer ();
+  /**
+   * \brief Enable or disabled FCS checking and calculations
+   * \param enable If true, enables FCS calculations.
+   */
+  static void EnableFcs (bool enable);
+  /**
+   * \brief Updates the Fcs Field to the correct FCS
+   * \param p Reference to a packet on which the FCS should be
+   * calculated. The packet should not currently contain an FCS
+   * trailer.
+   */
+  void CalcFcs (const Packet& p);
+  /**
+   * \brief Sets the FCS to a new value
+   * \param fcs New FCS value
+   */
+  void SetFcs (uint32_t fcs);
+  /**
+   * \return the FCS contained in this trailer
+   */
+  uint32_t GetFcs ();
+
+  /**
+   * \param p Reference to the packet on which the FCS should be
+   * calculated. The packet should not contain an FCS trailer.
+   * \return Returns true if the packet fcs is correct, false otherwise.
+   *
+   * If FCS checking is disabled, this method will always
+   * return true.
+   */
+  bool CheckFcs (const Packet& p) const;
+
+  /**
+   *\return Returns the size of the trailer
+   */ 
+  uint32_t GetTrailerSize() const;
+
+private:
+  virtual std::string DoGetName (void) const;
+  virtual void PrintTo (std::ostream &os) const;
+  virtual uint32_t GetSerializedSize (void) const;
+  virtual void SerializeTo (Buffer::Iterator end) const;
+  virtual uint32_t DeserializeFrom (Buffer::Iterator end);
+
+  /**
+   * Initializes the trailer parameters during construction.
+   */
+  void Init (void);
+
+  /**
+   * Enabled FCS calculations. If false, fcs is set to 0 and checkFCS
+   * returns true.
+   */
+  static bool m_calcFcs;
+  uint32_t m_fcs; /// Value of the fcs contained in the trailer
+
+};
+
+}; // namespace ns3
+
+
+#endif /* ETHERNET_TRAILER_H */
--- a/src/node/net-device.cc	Fri Jul 27 10:48:10 2007 -0700
+++ b/src/node/net-device.cc	Fri Jul 27 10:49:29 2007 -0700
@@ -22,12 +22,15 @@
 #include <iostream>
 #include "ns3/assert.h"
 #include "ns3/object.h"
+#include "ns3/debug.h"
+
 
 #include "channel.h"
 #include "net-device.h"
-#include "llc-snap-header.h"
 #include "node.h"
 
+NS_DEBUG_COMPONENT_DEFINE ("NetDevice");
+
 namespace ns3 {
 
 const InterfaceId NetDevice::iid = MakeInterfaceId ("NetDevice", Object::iid);
@@ -172,10 +175,7 @@
 {
   if (m_isUp)
     {
-      LlcSnapHeader llc;
-      llc.SetType (protocolNumber);
-      p.AddHeader (llc);
-      return SendTo(p, dest);
+      return SendTo(p, dest, protocolNumber);
     }
   else
     {
@@ -195,18 +195,24 @@
   return DoGetChannel ();
 }
 
-// Receive packet from below
+// Receive packets from below
 bool
-NetDevice::ForwardUp (Packet& packet)
+NetDevice::ForwardUp(Packet& p, uint32_t param)
 {
   bool retval = false;
-  LlcSnapHeader llc;
-  packet.RemoveHeader (llc);
+  Packet packet = p;
+
+  NS_DEBUG ("NetDevice::ForwardUp: UID is " << packet.GetUid()
+            << " device is: " << GetName());
+  
   if (!m_receiveCallback.IsNull ())
     {
-      retval = m_receiveCallback (this, packet, llc.GetType ());
+      retval = m_receiveCallback (this, packet, param);
+    } else {
+      NS_DEBUG ("NetDevice::Receive call back is NULL");
     }
-  return retval;
+
+    return retval;
 }
 
 void 
--- a/src/node/net-device.h	Fri Jul 27 10:48:10 2007 -0700
+++ b/src/node/net-device.h	Fri Jul 27 10:49:29 2007 -0700
@@ -17,6 +17,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Modified by Emmanuelle Laprise to remove dependance on LLC headers
  */
 #ifndef NET_DEVICE_H
 #define NET_DEVICE_H
@@ -227,6 +228,8 @@
 
   /**
    * \param p packet sent from below up to Network Device
+   * \param param Extra parameter extracted from header and needed by
+   * some protocols
    * \returns true if the packet was forwarded successfully,
    *          false otherwise.
    *
@@ -234,7 +237,8 @@
    * forwards it to the higher layers by calling this method
    * which is responsible for passing it up to the Rx callback.
    */
-  bool ForwardUp (Packet& p);
+  bool ForwardUp (Packet& p, uint32_t param);
+
 
   /**
    * The dispose method for this NetDevice class.
@@ -244,10 +248,13 @@
    */
   virtual void DoDispose (void);
 
+  Callback<bool,Ptr<NetDevice>,const Packet &,uint16_t> m_receiveCallback;
+
  private:
   /**
    * \param p packet to send
    * \param dest address of destination to which packet must be sent
+   * \param protocolNumber Number of the protocol (used with some protocols)
    * \returns true if the packet could be sent successfully, false
    *          otherwise.
    *
@@ -255,7 +262,7 @@
    * method.  When the link is Up, this method is invoked to ask 
    * subclasses to forward packets. Subclasses MUST override this method.
    */
-  virtual bool SendTo (Packet& p, const MacAddress& dest) = 0;
+  virtual bool SendTo (Packet& p, const MacAddress &dest, uint16_t protocolNumber) = 0;
   /**
    * \returns true if this NetDevice needs the higher-layers
    *          to perform ARP over it, false otherwise.
@@ -279,7 +286,7 @@
    */
   virtual Ptr<Channel> DoGetChannel (void) const = 0;
 
-  Ptr<Node>         m_node;
+  Ptr<Node>     m_node;
   std::string   m_name;
   uint16_t      m_ifIndex;
   MacAddress    m_address;
@@ -290,7 +297,6 @@
   bool          m_isMulticast;
   bool          m_isPointToPoint;
   Callback<void> m_linkChangeCallback;
-  Callback<bool,Ptr<NetDevice>,const Packet &,uint16_t> m_receiveCallback;
 };
 
 }; // namespace ns3
--- a/src/node/wscript	Fri Jul 27 10:48:10 2007 -0700
+++ b/src/node/wscript	Fri Jul 27 10:49:29 2007 -0700
@@ -10,7 +10,10 @@
         'ipv4-address.cc',
         'net-device.cc',
         'mac-address.cc',
+        'address-utils.cc',
         'llc-snap-header.cc',
+        'ethernet-header.cc',
+        'ethernet-trailer.cc',
         'ipv4-route.cc',
         'queue.cc',
         'drop-tail-queue.cc',
@@ -30,10 +33,13 @@
         'ipv4-address.h',
         'net-device.h',
         'mac-address.h',
+        'address-utils.h',
         'ipv4-route.h',
         'queue.h',
         'drop-tail-queue.h',
         'llc-snap-header.h',
+        'ethernet-header.h',
+        'ethernet-trailer.h',
         'channel.h',
         'node-list.h',
         'socket.h',
--- a/src/wscript	Fri Jul 27 10:48:10 2007 -0700
+++ b/src/wscript	Fri Jul 27 10:49:29 2007 -0700
@@ -15,7 +15,8 @@
     'simulator',
     'node',
     'internet-node',
-    'devices/p2p',
+    'devices/point-to-point',
+    'devices/csma-cd',
     'applications',
     'mobility',
     )