Merge in Craig's tracing changes as of Thursday; rename net-device-serial files to serial-net-device
authorTom Henderson <tomh@tomh.org>
Sat, 17 Feb 2007 16:40:03 -0800
changeset 292 cc17705d3344
parent 291 f5a98bae86c1
child 296 9b8fc589860b
Merge in Craig's tracing changes as of Thursday; rename net-device-serial files to serial-net-device
SConstruct
samples/main-serial-net-device-if.cc
src/common/trace-writer.cc
src/node/arp-ipv4-interface.cc
src/node/arp.cc
src/node/drop-tail.cc
src/node/net-device-serial.cc
src/node/net-device-serial.h
src/node/queue.cc
src/node/serial-channel.cc
src/node/serial-channel.h
src/node/serial-net-device.cc
src/node/serial-net-device.h
--- a/SConstruct	Thu Feb 15 23:55:15 2007 -0800
+++ b/SConstruct	Sat Feb 17 16:40:03 2007 -0800
@@ -122,6 +122,7 @@
     'packet.cc',
     'tags.cc',
     'pcap-writer.cc',
+    'trace-writer.cc',
     'trace-container.cc',
     'variable-tracer-test.cc',
     'stream-tracer-test.cc',
@@ -137,6 +138,7 @@
     'f-variable-tracer.h',
     'callback-tracer.h',
     'stream-tracer.h',
+    'trace-writer.h',
     'trace-container.h',
     'pcap-writer.h',
     ])
@@ -155,7 +157,7 @@
     'ipv4-address.cc',
     'internet-node.cc',
     'net-device.cc',
-    'net-device-serial.cc',
+    'serial-net-device.cc',
     'mac-address.cc',
     'ipv4-header.cc',
     'udp-header.cc',
@@ -199,14 +201,13 @@
     'l3-protocol.h',
     'ipv4-l4-demux.h',
     'net-device-list.h',
-    'net-device-serial.h',
+    'serial-net-device.h',
     'llc-snap-header.h',
     'header-utils.h',
     'protocol.h',
     'demux.h',
     'serial-channel.h',
     'queue.h',
-    'drop-tail.h'
     ])
 node.add_inst_headers ([
     'node.h',
@@ -223,7 +224,8 @@
     'ipv4-route.h',
     'serial-channel.h',
     'queue.h',
-    'net-device-serial.h'
+    'drop-tail.h',
+    'serial-net-device.h'
     ])
 
 
@@ -290,6 +292,13 @@
 sample_test.add_dep('core')
 sample_test.add_source('main-test.cc')
 
+sample_serial_net_device_if = build.Ns3Module ('sample-serial-net-device-if', 'samples')
+sample_serial_net_device_if.set_executable ()
+ns3.add (sample_serial_net_device_if)
+sample_serial_net_device_if.add_dep ('common')
+sample_serial_net_device_if.add_dep ('node')
+sample_serial_net_device_if.add_source ('main-serial-net-device-if.cc')
+
 sample_simple = build.Ns3Module('sample-simple', 'samples')
 sample_simple.set_executable()
 ns3.add(sample_simple)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/main-serial-net-device-if.cc	Sat Feb 17 16:40:03 2007 -0800
@@ -0,0 +1,189 @@
+/* -*- 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
+ */
+
+#if 0
+#include <list>
+#include <cassert>
+#endif
+
+#include "ns3/debug.h"
+#include "ns3/internet-node.h"
+#include "ns3/mac-address.h"
+#include "ns3/packet.h"
+#include "ns3/arp-ipv4-interface.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/serial-channel.h"
+#include "ns3/serial-net-device.h"
+#include "ns3/trace-writer.h"
+#include "ns3/trace-container.h"
+#include "ns3/drop-tail.h"
+#include "ns3/arp-ipv4-interface.h"
+#include "ns3/ipv4.h"
+
+#include "ns3/pcap-writer.h"
+
+using namespace ns3;
+
+class Logger : public TraceWriter{
+public:
+  Logger ()
+  {
+    NS3_TRACEALL("**** Logger()")
+  };
+
+  Logger (std::string const &filename) 
+  {
+    NS3_TRACEALL("**** Logger(string const &)")
+    Open(filename);
+  };
+
+  Logger (char const *filename) : m_tracer(filename)
+  {
+    NS3_TRACEALL("**** Logger(char const *)")
+    Open(filename);
+  };
+
+  ~Logger () {};
+
+  void Log (const char *s, const Packet &p)
+  {
+    NS3_TRACEALL("**** LogEnque ("<< s << &p << ")")
+    m_filestr << s << &p << std::endl;
+  }
+
+protected:
+  TraceWriter m_tracer;
+};
+
+int main (int argc, char *argv[])
+{
+  NS3_TRACEALL("Serial Net Device Test")
+
+  TraceContainer traceContainerA;
+  TraceContainer traceContainerB;
+  
+  // create two nodes and a simple SerialChannel
+  InternetNode a;
+  InternetNode b;
+  SerialChannel ch;
+
+  // create two NetDevices and assign one to each node
+  // Note:  this would normally be done also in conjunction with
+  //        creating a Channel
+  //        Here, we do not care about the Device Address (point-to-point)
+  //        but more generally, we would use a subclass such as MacAddress
+  //        as follows:    MacAddress addra("00:00:00:00:00:01");
+  //        so we'll pretend and give them simple MacAddresses here
+   
+  MacAddress addra("00:00:00:00:00:01");
+  SerialNetDevice neta(&a, addra);
+
+  DropTailQueue dtqa (traceContainerA);
+
+  neta.AddQueue(&dtqa);
+  neta.SetName("a.eth0"); 
+
+  MacAddress addrb("00:00:00:00:00:02");
+  SerialNetDevice netb(&b, addrb);
+
+  DropTailQueue dtqb (traceContainerB);
+
+  netb.AddQueue(&dtqb);
+  netb.SetName("b.eth0"); 
+
+  // bind the two NetDevices together by using a simple Channel
+  // this method changed to do a bidirectional binding
+  ch.Attach(&neta);
+  ch.Attach(&netb);
+
+  // Some simple prints to see whether it is working
+  NS3_TRACEALL("neta.GetMtu() <= " << neta.GetMtu())
+  NS3_TRACEALL("netb.GetMtu() <= " << netb.GetMtu())
+  NS3_DEBUG (MacAddress addr = neta.GetAddress();)
+  NS3_TRACEALL("neta.GetAddress() <= " << addr)
+  NS3_DEBUG (addr = netb.GetAddress();)
+  NS3_TRACEALL("netb.GetAddress() <= " << addr)
+
+  // Note:  InternetNode constructor instantiates multiple Layer-3
+  // protocols and registers them with the L3Demux object.
+  // This takes care of Layer-2 -> Layer-3 bindings.
+  //  XXX TODO:  will need to create a dummy IPv4 object for insertion
+  //             into the Demux
+
+  // We now need to bind the InternetNode to the various interfaces.
+  // to get the Layer-3 -> Layer-2 bindings.
+
+  // We do this by calling an "AddArpIpv4Interface(neta)" function on node a.
+  // This should:  
+  // i) create an Ipv4ArpInterface object (subclass of pure virtual
+  //    Ipv4Interface object)
+  // ii) add the Ipv4ArpInterface object to the InternetNode's internal
+  //     vector of Ipv4Interfaces (keyed off of ifIndex)
+
+  NS3_TRACEALL("Adding ARP Interface to InternetNode a")
+  ArpIpv4Interface* arpipv4interfacep = new ArpIpv4Interface(&a, &neta);
+  uint32_t indexA = (&a)->GetIpv4 ()->AddInterface (arpipv4interfacep);
+  NS3_TRACEALL("Adding Interface " << indexA);
+
+
+  // iii) give the interface an IP address
+
+  NS3_TRACEALL("Giving IP address to ARP Interface")
+  arpipv4interfacep->SetAddress(Ipv4Address("10.1.1.1"));
+  arpipv4interfacep->SetNetworkMask(Ipv4Mask("255.255.255.0"));
+
+  // iv) set the interface's state to "UP"
+
+  NS3_TRACEALL("Setting ARP interface to UP")
+  arpipv4interfacep->SetUp();
+
+  NS3_TRACEALL("Adding ARP Interface to InternetNode b")
+  ArpIpv4Interface* arpipv4interfacepb = new ArpIpv4Interface(&b, &netb);
+  uint32_t indexB = (&b)->GetIpv4 ()->AddInterface (arpipv4interfacepb);
+  NS3_TRACEALL("Adding Interface " << indexB);
+
+
+  // iii) give the interface an IP address
+
+  NS3_TRACEALL("Giving IP address to ARP Interface")
+  arpipv4interfacepb->SetAddress(Ipv4Address("10.1.1.2"));
+  arpipv4interfacepb->SetNetworkMask(Ipv4Mask("255.255.255.0"));
+
+  // iv) set the interface's state to "UP"
+
+  NS3_TRACEALL("Setting ARP interface to UP")
+  arpipv4interfacepb->SetUp();
+
+  Logger logger("serial-net-test.log");
+
+  traceContainerA.SetCallback ("Queue::Enque", 
+    MakeCallback (&Logger::Log, &logger));
+
+  // create a packet on one node and send it through, reading it
+  // on the other node
+  Packet p;
+
+  NS3_TRACEALL("Sending Packet " << &p)
+  arpipv4interfacep->Send(p, Ipv4Address("10.1.1.2"));
+
+  //neta.Send(p, MacAddress());  // Test that all-zero's MacAddress used
+  //netb.Send(p, "00:01:02:03:04:05");  // Dummy function call
+
+  return 0;
+}
--- a/src/common/trace-writer.cc	Thu Feb 15 23:55:15 2007 -0800
+++ b/src/common/trace-writer.cc	Sat Feb 17 16:40:03 2007 -0800
@@ -18,7 +18,7 @@
  *
  * Author: Craig Dowell <craigdo@ee.washingon.edu>
  *
- *      Thu Feb  8 10:42:52 PST 2007 craigdo:  Created
+ *      Thu Feb  8 10:42:52 PST 2007 craigdo:  Created from pcap-writer.c
  */
 
 #include "ns3/debug.h"
@@ -27,21 +27,7 @@
 namespace ns3 {
 
 namespace {
-  int twDebug = 0;
-}
-
-  void
-TraceWriter::Init (const char *filename)
-{
-  NS3_TRACE(twDebug, "TraceWriter()::Init(" << filename << ")")
-
-  std::streambuf *sb = m_filestr.rdbuf();
-  rdbuf(sb);
-
-  if (filename) 
-    {
-      m_filestr.open (filename, std::ios::out | std::ios::app);
-    }
+  int twDebug = 1;
 }
 
 TraceWriter::TraceWriter () :
@@ -49,15 +35,27 @@
 {
   NS3_TRACE(twDebug, "TraceWriter()::TraceWriter()")
 
-  Init (0);
+  std::streambuf *sb = m_filestr.rdbuf();
+
+  NS3_TRACE(twDebug, "TraceWriter()::TraceWriter():  rdbuf ()")
+  rdbuf(sb);
+
+  NS3_TRACE(twDebug, "TraceWriter()::TraceWriter():  done")
 }
 
-TraceWriter::TraceWriter (std::string const &filename) :
+  TraceWriter::TraceWriter (std::string const &filename) :
   m_filestr()
 {
   NS3_TRACE(twDebug, "TraceWriter()::TraceWriter (\"" << filename << "\")")
 
-  Init (filename.c_str());
+  m_filestr.open (filename.c_str(), std::ios::out | std::ios::app);
+
+  std::streambuf *sb = m_filestr.rdbuf();
+
+  NS3_TRACE(twDebug, "TraceWriter()::TraceWriter():  rdbuf ()")
+  rdbuf(sb);
+
+  NS3_TRACE(twDebug, "TraceWriter()::TraceWriter():  done")
 }
 
 TraceWriter::TraceWriter (char const *filename) :
@@ -65,7 +63,14 @@
 {
   NS3_TRACE(twDebug, "TraceWriter()::TraceWriter (\"" << filename << "\")")
 
-  Init (filename);
+  m_filestr.open (filename, std::ios::out | std::ios::app);
+
+  std::streambuf *sb = m_filestr.rdbuf();
+
+  NS3_TRACE(twDebug, "TraceWriter()::TraceWriter():  rdbuf ()")
+  rdbuf(sb);
+
+  NS3_TRACE(twDebug, "TraceWriter()::TraceWriter():  done")
 }
 
 
@@ -79,7 +84,7 @@
 {
   NS3_TRACE(twDebug, "TraceWriter()::Open (\"" << filename << "\")")
 
-  Init(filename.c_str());
+  m_filestr.open (filename.c_str(), std::ios::out | std::ios::app);
 }
 
   void
@@ -87,7 +92,7 @@
 {
   NS3_TRACE(twDebug, "TraceWriter()::Open (\"" << filename << "\")")
 
-  Init(filename);
+  m_filestr.open (filename, std::ios::out | std::ios::app);
 }
 
   void
--- a/src/node/arp-ipv4-interface.cc	Thu Feb 15 23:55:15 2007 -0800
+++ b/src/node/arp-ipv4-interface.cc	Sat Feb 17 16:40:03 2007 -0800
@@ -40,6 +40,7 @@
 ArpIpv4Interface::SendTo (Packet p, Ipv4Address dest)
 {
   Arp * arp = m_node->GetArp ();
+  printf("Arp %p\n", arp);
   MacAddress hardwareDestination;
   bool found = arp->Lookup (p, dest, GetDevice (), &hardwareDestination);
   if (found)
--- a/src/node/arp.cc	Thu Feb 15 23:55:15 2007 -0800
+++ b/src/node/arp.cc	Sat Feb 17 16:40:03 2007 -0800
@@ -180,6 +180,7 @@
 Arp::SendArpRequest (ArpCache const *cache, Ipv4Address to)
 {
   ArpHeader arp;
+  printf("%p %p %p %p\n", cache->GetDevice(), cache->GetInterface(), cache->GetDevice(), &to);
   arp.SetRequest (cache->GetDevice ()->GetAddress (),
 		  cache->GetInterface ()->GetAddress (), 
                   cache->GetDevice ()->GetBroadcast (),
--- a/src/node/drop-tail.cc	Thu Feb 15 23:55:15 2007 -0800
+++ b/src/node/drop-tail.cc	Sat Feb 17 16:40:03 2007 -0800
@@ -23,7 +23,7 @@
 namespace ns3 {
 
 namespace {
-  int dtqDebug = 0;
+  int dtqDebug = 1;
 }
 
 DropTailQueue::DropTailQueue () :
--- a/src/node/net-device-serial.cc	Thu Feb 15 23:55:15 2007 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,141 +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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#include <iostream>
-#include <cassert>
-#include "ns3/debug.h"
-#include "protocol.h"
-#include "demux.h"
-#include "queue.h"
-#include "net-device-serial.h"
-#include "serial-channel.h"
-
-namespace ns3 {
-
-const int IPv4ProtocolNumber = 4;
-
-namespace {
-  int sndDebug = 0;
-}
-
-SerialNetDevice::SerialNetDevice(Node* node, const MacAddress& addr) : 
-  NetDevice(node, addr)
-{
-  NS3_TRACE(sndDebug, 
-    "SerialNetDevice::SerialNetDevice (" << node << ", " << &addr << ")")
-
-  // 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();
-  SetMtu(512); // bytes
-}
-
-SerialNetDevice::~SerialNetDevice()
-{
-  NS3_TRACE(sndDebug, 
-    "SerialNetDevice::~SerialNetDevice ()")
-}
-
-
-  bool
-SerialNetDevice::SendTo (Packet& p, const MacAddress& dest)
-{
-  NS3_TRACE(sndDebug, 
-    "SerialNetDevice::SendTo (" << &p << ", " << &dest << ")")
-
-  assert (IsLinkUp ());
-
-#ifdef NOTYET
-    struct NetDevicePacketDestAddress tag;
-    tag.address = address;
-    p.AddTag (tag);
-#endif
-    if (m_queue->Enque(p) )
-      {
-        NotifyDataAvailable ();
-        return true;
-      }
-    return false;
-}
-
-  bool
-SerialNetDevice::Attach (SerialChannel* ch)
-{
-  NS3_TRACE(sndDebug, 
-    "SerialNetDevice::Attach (" << &ch << ")")
-
-  m_channel = ch;
-  /* 
-   * 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 SerialChannel 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
-SerialNetDevice::AddQueue (Queue* q)
-{
-  NS3_TRACE(sndDebug, 
-    "SerialNetDevice::AddQueue (" << q << ")")
-
-  m_queue = q;
-}
-
-void
-SerialNetDevice::Receive (Packet& p)
-{
-  // ignore return value for now.
-  NS3_TRACE(sndDebug, 
-    "SerialNetDevice::Receive (" << &p << ")")
-
-  ForwardUp (p);
-}
-
-void
-SerialNetDevice::NotifyDataAvailable(void)
-{
-  NS3_TRACE(sndDebug, 
-    "SerialNetDevice::NotifyDataAvailable ()")
-
-  Packet p;
-  bool found = GetQueue ()->Deque (p);
-  if (found)
-    {
-#ifdef NOTYET
-      struct NetDevicePacketDestAddress tag;
-      p.PeekTag (tag);
-      // send packet to address tag.address
-#endif
-      NS3_TRACE(sndDebug, 
-        "SerialNetDevice::NotifyDataAvailable (): Dequeued")
-      m_channel->Send(p, this);
-    }
-}
-
-} // namespace ns3
--- a/src/node/net-device-serial.h	Thu Feb 15 23:55:15 2007 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +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>
- */
-
-#ifndef SERIAL_NET_DEVICE_H
-#define SERIAL_NET_DEVICE_H
-
-#include <string.h>
-#include "mac-address.h"
-#include "internet-node.h"
-#include "net-device.h"
-#include "ns3/callback.h"
-#include "ns3/packet.h"
-
-namespace ns3 {
-
-class SerialChannel;
-class Queue;
-
-class SerialNetDevice : public NetDevice {
-public:
-  SerialNetDevice(Node* node, const MacAddress& addr);
-  virtual ~SerialNetDevice();
-
-private:
-  // Don't let the compiler slip in copy and assignment construction
-  SerialNetDevice(const SerialNetDevice&);
-  SerialNetDevice&operator=(const SerialNetDevice&);
-
-public:
-  bool Attach(SerialChannel* ch);
-  void AddQueue(Queue *);
-  // called by ChannelSerial
-  void Receive (Packet& p);
-
-protected:
-  Queue* GetQueue(void) const { return m_queue;};
-
-private:
-  virtual void NotifyDataAvailable (void);
-  virtual bool SendTo (Packet& p, const MacAddress& dest);
-
-  SerialChannel* m_channel;
-  Queue* m_queue;
-};
-
-}; // namespace ns3
-
-#endif // SERIAL_NET_DEVICE_H
-
--- a/src/node/queue.cc	Thu Feb 15 23:55:15 2007 -0800
+++ b/src/node/queue.cc	Sat Feb 17 16:40:03 2007 -0800
@@ -23,7 +23,7 @@
 namespace ns3 {
 
 namespace {
-  int qDebug = 0;
+  int qDebug = 1;
 }
 
 Queue::Queue() : 
--- a/src/node/serial-channel.cc	Thu Feb 15 23:55:15 2007 -0800
+++ b/src/node/serial-channel.cc	Sat Feb 17 16:40:03 2007 -0800
@@ -18,7 +18,7 @@
  */
 
 #include "serial-channel.h"
-#include "net-device-serial.h"
+#include "serial-net-device.h"
 #include "ns3/packet.h"
 
 namespace ns3 {
--- a/src/node/serial-channel.h	Thu Feb 15 23:55:15 2007 -0800
+++ b/src/node/serial-channel.h	Sat Feb 17 16:40:03 2007 -0800
@@ -26,7 +26,7 @@
 #define CHANNEL_SERIAL_H
 
 #include <list>
-#include "net-device-serial.h"
+#include "serial-net-device.h"
 #include "ns3/packet.h"
 
 namespace ns3 {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/serial-net-device.cc	Sat Feb 17 16:40:03 2007 -0800
@@ -0,0 +1,141 @@
+/* -*- 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#include <iostream>
+#include <cassert>
+#include "ns3/debug.h"
+#include "protocol.h"
+#include "demux.h"
+#include "queue.h"
+#include "serial-net-device.h"
+#include "serial-channel.h"
+
+namespace ns3 {
+
+const int IPv4ProtocolNumber = 4;
+
+namespace {
+  int sndDebug = 0;
+}
+
+SerialNetDevice::SerialNetDevice(Node* node, const MacAddress& addr) : 
+  NetDevice(node, addr)
+{
+  NS3_TRACE(sndDebug, 
+    "SerialNetDevice::SerialNetDevice (" << node << ", " << &addr << ")")
+
+  // 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();
+  SetMtu(512); // bytes
+}
+
+SerialNetDevice::~SerialNetDevice()
+{
+  NS3_TRACE(sndDebug, 
+    "SerialNetDevice::~SerialNetDevice ()")
+}
+
+
+  bool
+SerialNetDevice::SendTo (Packet& p, const MacAddress& dest)
+{
+  NS3_TRACE(sndDebug, 
+    "SerialNetDevice::SendTo (" << &p << ", " << &dest << ")")
+
+  assert (IsLinkUp ());
+
+#ifdef NOTYET
+    struct NetDevicePacketDestAddress tag;
+    tag.address = address;
+    p.AddTag (tag);
+#endif
+    if (m_queue->Enque(p) )
+      {
+        NotifyDataAvailable ();
+        return true;
+      }
+    return false;
+}
+
+  bool
+SerialNetDevice::Attach (SerialChannel* ch)
+{
+  NS3_TRACE(sndDebug, 
+    "SerialNetDevice::Attach (" << &ch << ")")
+
+  m_channel = ch;
+  /* 
+   * 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 SerialChannel 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
+SerialNetDevice::AddQueue (Queue* q)
+{
+  NS3_TRACE(sndDebug, 
+    "SerialNetDevice::AddQueue (" << q << ")")
+
+  m_queue = q;
+}
+
+void
+SerialNetDevice::Receive (Packet& p)
+{
+  // ignore return value for now.
+  NS3_TRACE(sndDebug, 
+    "SerialNetDevice::Receive (" << &p << ")")
+
+  ForwardUp (p);
+}
+
+void
+SerialNetDevice::NotifyDataAvailable(void)
+{
+  NS3_TRACE(sndDebug, 
+    "SerialNetDevice::NotifyDataAvailable ()")
+
+  Packet p;
+  bool found = GetQueue ()->Deque (p);
+  if (found)
+    {
+#ifdef NOTYET
+      struct NetDevicePacketDestAddress tag;
+      p.PeekTag (tag);
+      // send packet to address tag.address
+#endif
+      NS3_TRACE(sndDebug, 
+        "SerialNetDevice::NotifyDataAvailable (): Dequeued")
+      m_channel->Send(p, this);
+    }
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/serial-net-device.h	Sat Feb 17 16:40:03 2007 -0800
@@ -0,0 +1,67 @@
+/* -*- 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>
+ */
+
+#ifndef SERIAL_NET_DEVICE_H
+#define SERIAL_NET_DEVICE_H
+
+#include <string.h>
+#include "mac-address.h"
+#include "internet-node.h"
+#include "net-device.h"
+#include "ns3/callback.h"
+#include "ns3/packet.h"
+
+namespace ns3 {
+
+class SerialChannel;
+class Queue;
+
+class SerialNetDevice : public NetDevice {
+public:
+  SerialNetDevice(Node* node, const MacAddress& addr);
+  virtual ~SerialNetDevice();
+
+private:
+  // Don't let the compiler slip in copy and assignment construction
+  SerialNetDevice(const SerialNetDevice&);
+  SerialNetDevice&operator=(const SerialNetDevice&);
+
+public:
+  bool Attach(SerialChannel* ch);
+  void AddQueue(Queue *);
+  // called by ChannelSerial
+  void Receive (Packet& p);
+
+protected:
+  Queue* GetQueue(void) const { return m_queue;};
+
+private:
+  virtual void NotifyDataAvailable (void);
+  virtual bool SendTo (Packet& p, const MacAddress& dest);
+
+  SerialChannel* m_channel;
+  Queue* m_queue;
+};
+
+}; // namespace ns3
+
+#endif // SERIAL_NET_DEVICE_H
+