merge
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Tue, 12 Jun 2007 22:54:10 +0200
changeset 886 8fd09dc635cf
parent 885 4f385160b3d5 (current diff)
parent 762 b64b1d4eadc0 (diff)
child 889 2dcd6fff540a
merge
SConstruct
src/core/callback.h
src/core/interface.cc
src/core/interface.h
src/core/object.cc
src/core/object.h
src/internet-node/arp.cc
src/internet-node/arp.h
src/internet-node/i-arp-private.cc
src/internet-node/i-arp-private.h
src/internet-node/i-ipv4-impl.cc
src/internet-node/i-ipv4-impl.h
src/internet-node/i-ipv4-private.cc
src/internet-node/i-ipv4-private.h
src/internet-node/i-node-impl.cc
src/internet-node/i-node-impl.h
src/internet-node/i-udp-impl.cc
src/internet-node/i-udp-impl.h
src/internet-node/internet-node.cc
src/internet-node/internet-node.h
src/internet-node/ipv4.cc
src/internet-node/ipv4.h
src/internet-node/udp.cc
src/internet-node/udp.h
src/node/drop-tail.cc
src/node/drop-tail.h
src/node/i-ipv4.cc
src/node/i-ipv4.h
src/node/i-node.cc
src/node/i-node.h
src/node/i-socket-factory.cc
src/node/i-socket-factory.h
src/node/i-udp.cc
src/node/i-udp.h
--- a/AUTHORS	Thu Jun 07 13:19:25 2007 +0200
+++ b/AUTHORS	Tue Jun 12 22:54:10 2007 +0200
@@ -1,5 +1,5 @@
 Raj Bhattarcharjea (raj.b@gatech.edu)
-Gustavo Carneiro (gjcarneiro@gmail.com)
+Gustavo Carneiro (gjc@inescporto.pt, gjcarneiro@gmail.com)
 Craig Dowell (craigdo@ee.washington.edu)
 Tom Henderson (tomhend@u.washington.edu)
 Mathieu Lacage (mathieu.lacage@sophia.inria.fr)
--- a/RELEASE_NOTES	Thu Jun 07 13:19:25 2007 +0200
+++ b/RELEASE_NOTES	Tue Jun 12 22:54:10 2007 +0200
@@ -3,6 +3,19 @@
 
 This file contains ns-3 release notes (most recent releases first).
 
+Release 3.0.3 (2007/06/15)
+========================
+
+  - Enable Waf for release tarballs: users can now build ns-3
+    with the "waf" tool. See doc/build-waf.txt.
+  - Add support for variable time precision: it is now possible
+    to run a simulation with an accuracy which is higher or lower
+    than a nanosecond: seconds, milliseconds, microseconds, 
+    femtoseconds and picoseconds are supported.
+  - Optimize and rework the COM framework, solidify the component 
+    manager
+  - Many small API cleanups
+
 Release 3.0.2 (2007/05/18)
 ========================
 
--- a/SConstruct	Thu Jun 07 13:19:25 2007 +0200
+++ b/SConstruct	Tue Jun 12 22:54:10 2007 +0200
@@ -60,7 +60,6 @@
     'test.cc',
     'random-variable.cc',
     'rng-stream.cc',
-    'interface.cc',
     'uid-manager.cc',
     'default-value.cc',
     'command-line.cc',
@@ -83,6 +82,7 @@
 ])
 core.add_inst_headers([
     'system-wall-clock-ms.h',
+    'empty.h',
     'callback.h',
     'ptr.h',
     'object.h',
@@ -92,7 +92,6 @@
     'test.h',
     'random-variable.h',
     'rng-stream.h',
-    'interface.h',
     'default-value.h',
     'command-line.h',
     'type-name.h',
@@ -232,37 +231,37 @@
 ns3.add (node)
 node.add_deps (['core', 'common', 'simulator'])
 node.add_sources ([
-    'i-node.cc',
+    'node.cc',
     'ipv4-address.cc',
     'net-device.cc',
     'mac-address.cc',
     'llc-snap-header.cc',
     'ipv4-route.cc',
     'queue.cc',
-    'drop-tail.cc',
+    'drop-tail-queue.cc',
     'channel.cc',
     'node-list.cc',
     'socket.cc',
-    'i-socket-factory.cc',
-    'i-udp.cc',
-    'i-ipv4.cc',
+    'socket-factory.cc',
+    'udp.cc',
+    'ipv4.cc',
     'application.cc',
     ])
 node.add_inst_headers ([
-    'i-node.h',
+    'node.h',
     'ipv4-address.h',
     'net-device.h',
     'mac-address.h',
     'ipv4-route.h',
     'queue.h',
-    'drop-tail.h',
+    'drop-tail-queue.h',
     'llc-snap-header.h',
     'channel.h',
     'node-list.h',
     'socket.h',
-    'i-socket-factory.h',
-    'i-udp.h',
-    'i-ipv4.h',
+    'socket-factory.h',
+    'udp.h',
+    'ipv4.h',
     'application.h',
     ])
 
@@ -281,7 +280,6 @@
 inode.add_deps (['node'])
 inode.add_sources ([
     'internet-node.cc',
-    'i-node-impl.cc',
     'l3-demux.cc',
     'l3-protocol.cc',
     'ipv4-l4-demux.cc',
@@ -290,23 +288,23 @@
     'udp-header.cc',
     'ipv4-checksum.cc',
     'ipv4-interface.cc',
-    'ipv4.cc',
+    'ipv4-l3-protocol.cc',
     'ipv4-end-point.cc',
-    'udp.cc',
+    'udp-l4-protocol.cc',
     'arp-header.cc',
     'arp-cache.cc',
     'arp-ipv4-interface.cc',
-    'arp.cc',
+    'arp-l3-protocol.cc',
     'ipv4-loopback-interface.cc',
     'header-utils.cc',
     'udp-socket.cc',
     'ipv4-end-point-demux.cc',
-    'i-arp-private.cc',
-    'i-ipv4-impl.cc',
-    'i-ipv4-private.cc',
+    'arp-private.cc',
+    'ipv4-impl.cc',
+    'ipv4-private.cc',
     'ascii-trace.cc',
     'pcap-trace.cc',
-    'i-udp-impl.cc',
+    'udp-impl.cc',
 ])
 inode.add_headers ([
     'ipv4-header.h',
@@ -314,17 +312,17 @@
     'ipv4-checksum.h',
     'arp-header.h',
     'arp-cache.h',
-    'arp.h',
+    'arp-l3-protocol.h',
     'ipv4-loopback-interface.h',
     'l3-demux.h',
     'header-utils.h',
     'arp-ipv4-interface.h',
     'udp-socket.h',
-    'udp.h',
-    'i-arp-private.h',
-    'i-ipv4-impl.h',
-    'i-ipv4-private.h',
-    'ipv4.h',
+    'udp-l4-protocol.h',
+    'arp-private.h',
+    'ipv4-impl.h',
+    'ipv4-private.h',
+    'ipv4-l3-protocol.h',
     'l3-protocol.h',
     'ipv4-l4-protocol.h',
     'ipv4-l4-demux.h',
@@ -334,8 +332,7 @@
     'udp-header.h',
     'ipv4-interface.h',
     'sgi-hashmap.h',
-    'i-node-impl.h',
-    'i-udp-impl.h',
+    'udp-impl.h',
 ])
 inode.add_inst_headers ([
     'internet-node.h',
@@ -367,6 +364,12 @@
 run_tests.add_deps(['core', 'simulator', 'common'])
 run_tests.add_source('run-tests.cc')
 
+bench_object = build.Ns3Module('bench-object', 'utils')
+ns3.add(bench_object)
+bench_object.set_executable()
+bench_object.add_deps(['core'])
+bench_object.add_source('bench-object.cc')
+
 bench_packets = build.Ns3Module('bench-packets', 'utils')
 ns3.add(bench_packets)
 bench_packets.set_executable()
@@ -448,6 +451,18 @@
 sample_default_value.add_deps(['core', 'simulator', 'node', 'p2p'])
 sample_default_value.add_source('main-default-value.cc')
 
+sample_object = build.Ns3Module('sample-object', 'samples')
+sample_object.set_executable()
+ns3.add(sample_object)
+sample_object.add_deps(['core'])
+sample_object.add_source('main-object.cc')
+
+sample_component_manager = build.Ns3Module('sample-component-manager', 'samples')
+sample_component_manager.set_executable()
+ns3.add(sample_component_manager)
+sample_component_manager.add_deps(['core'])
+sample_component_manager.add_source('main-component-manager.cc')
+
 # examples
 example_simple_p2p = build.Ns3Module('simple-p2p', 'examples')
 example_simple_p2p.set_executable()
--- a/doc/main.txt	Thu Jun 07 13:19:25 2007 +0200
+++ b/doc/main.txt	Tue Jun 12 22:54:10 2007 +0200
@@ -22,8 +22,10 @@
  *    - \ref randomvariable
  *    - \ref config
  *    - a base class for objects which need to support reference counting 
- *      and QueryInterface: ns3::Interface and ns3::InterfaceId
- *    - a smart-pointer class ns3::Ptr designed to work together with ns3::Interface
+ *      and QueryInterface: ns3::Object and ns3::InterfaceId
+ *    - a ns3::ComponentManager which can be used to manage the creation
+ *      of any object which derives from ns3::Object through an ns3::ClassId
+ *    - a smart-pointer class ns3::Ptr designed to work together with ns3::Object
  *
  * The "simulator" module contains:
  *    - a time management class to hold a time and convert between various time units: ns3::Time
@@ -38,20 +40,18 @@
  *    - a set of low-level trace facilities: \ref lowleveltracing
  *
  * The "node" module contains:
- *    - a ns3::INode base class which should be subclassed by any new type of
+ *    - a ns3::Node base class which should be subclassed by any new type of
  *      network Node.
  *    - models which abstract the MAC-layer from the IP layer protocols:
  *      ns3::NetDevice and ns3::Channel.
  *    - models which abstract the application-layer API: ns3::Application,
- *      ns3::Socket, ns3::ISocketFactory, and, ns3::IUdp
+ *      ns3::Socket, ns3::SocketFactory, and, ns3::Udp
  *
  * The "internet-node" module contains a set of classes which implement the
  * APIs defined in the "node" module:
  *    - an Ipv4/Udp stack with socket support
  *    - an ARP module
- *    - an INode subclass. 
- *    - and finally, a function used to instantiate nodes
- *      which contain this implementation: ns3::MakeInternetNode
+ *    - an InternetNode class which is a Node subclass. 
  *
  * The "devices" module contains:
  *    - a PointToPoint MAC device: ns3::PointToPointNetDevice, ns3::PointToPointChannel,
--- a/examples/simple-p2p.cc	Thu Jun 07 13:19:25 2007 +0200
+++ b/examples/simple-p2p.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -42,10 +42,10 @@
 #include <string>
 #include <cassert>
 
-#include "ns3/debug.h"
 #include "ns3/command-line.h"
 #include "ns3/default-value.h"
 #include "ns3/ptr.h"
+#include "ns3/random-variable.h"
 
 #include "ns3/simulator.h"
 #include "ns3/nstime.h"
@@ -58,15 +58,11 @@
 #include "ns3/p2p-net-device.h"
 #include "ns3/mac-address.h"
 #include "ns3/ipv4-address.h"
-#include "ns3/i-ipv4.h"
+#include "ns3/ipv4.h"
 #include "ns3/socket.h"
 #include "ns3/ipv4-route.h"
-#include "ns3/drop-tail.h"
-#include "ns3/node-list.h"
-#include "ns3/trace-root.h"
 #include "ns3/p2p-topology.h"
 #include "ns3/onoff-application.h"
-#include "ns3/random-variable.h"
 
 using namespace ns3;
 
@@ -103,10 +99,10 @@
 
   // Here, we will explicitly create four nodes.  In more sophisticated
   // topologies, we could configure a node factory.
-  Ptr<INode> n0 = MakeInternetNode ();
-  Ptr<INode> n1 = MakeInternetNode (); 
-  Ptr<INode> n2 = MakeInternetNode (); 
-  Ptr<INode> n3 = MakeInternetNode ();
+  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<PointToPointChannel> channel0 = 
@@ -145,11 +141,11 @@
 
   // Create the OnOff application to send UDP datagrams of size
   // 210 bytes at a rate of 448 Kb/s
-  Ptr<OnOffApplication> ooff = MakeNewObject<OnOffApplication> (
+  Ptr<OnOffApplication> ooff = Create<OnOffApplication> (
     n0, 
     Ipv4Address("10.1.3.2"), 
     80, 
-    "IUdp",
+    "Udp",
     ConstantVariable(1), 
     ConstantVariable(0));
   // Start the application
@@ -157,11 +153,11 @@
   ooff->Stop (Seconds(10.0));
 
   // Create a similar flow from n3 to n1, starting at time 1.1 seconds
-  ooff = MakeNewObject<OnOffApplication> (
+  ooff = Create<OnOffApplication> (
     n3, 
     Ipv4Address("10.1.2.1"), 
     80, 
-    "IUdp",
+    "Udp",
     ConstantVariable(1), 
     ConstantVariable(0));
   // Start the application
@@ -170,10 +166,10 @@
 
   // Here, finish off packet routing configuration
   // This will likely set by some global StaticRouting object in the future
-  Ptr<IIpv4> ipv4;
-  ipv4 = n0->QueryInterface<IIpv4> (IIpv4::iid);
+  Ptr<Ipv4> ipv4;
+  ipv4 = n0->QueryInterface<Ipv4> (Ipv4::iid);
   ipv4->SetDefaultRoute (Ipv4Address ("10.1.1.2"), 1);
-  ipv4 = n3->QueryInterface<IIpv4> (IIpv4::iid);
+  ipv4 = n3->QueryInterface<Ipv4> (Ipv4::iid);
   ipv4->SetDefaultRoute (Ipv4Address ("10.1.3.1"), 1);
   
   // Configure tracing of all enqueue, dequeue, and NetDevice receive events
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/main-component-manager.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -0,0 +1,38 @@
+#include "ns3/object.h"
+#include "ns3/component-manager.h"
+
+using namespace ns3;
+
+class AnObject : public Object
+{
+public:
+  static const InterfaceId iid;
+  static const ClassId cid;
+  AnObject (int a, double b);
+protected:
+  virtual void DoDispose (void);
+};
+
+const InterfaceId AnObject::iid = MakeInterfaceId ("AnObject", Object::iid);
+const ClassId AnObject::cid = MakeClassId<AnObject, int, double> ("AnObject", AnObject::iid);
+
+AnObject::AnObject (int a, double b)
+{
+  // enable our interface
+  SetInterfaceId (AnObject::iid);
+}
+void
+AnObject::DoDispose (void)
+{
+  // Do your work here.
+  // chain up
+  Object::DoDispose ();
+}
+
+
+int main (int argc, char *argv[])
+{
+  Ptr<AnObject> anObject = ComponentManager::Create<AnObject,int,double> (AnObject::cid, AnObject::iid, 10, 20.0);
+  NS_ASSERT (anObject != 0);
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/main-object.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -0,0 +1,121 @@
+#include "ns3/object.h"
+
+using namespace ns3;
+
+class AnObject : public Object
+{
+public:
+  static const InterfaceId iid;
+  AnObject ();
+protected:
+  virtual void DoDispose (void);
+};
+
+const InterfaceId AnObject::iid = MakeInterfaceId ("AnObject", Object::iid);
+
+AnObject::AnObject ()
+{
+  // enable our interface
+  SetInterfaceId (AnObject::iid);
+}
+void
+AnObject::DoDispose (void)
+{
+  // Do your work here.
+  // chain up
+  Object::DoDispose ();
+}
+
+class AnotherObject : public Object
+{
+public:
+  static const InterfaceId iid;
+  AnotherObject (int a);
+private:
+  virtual void DoDispose (void);
+};
+
+const InterfaceId AnotherObject::iid = MakeInterfaceId ("AnotherObject", Object::iid);
+
+AnotherObject::AnotherObject (int a)
+{
+  // enable our interface
+  SetInterfaceId (AnotherObject::iid);
+}
+void
+AnotherObject::DoDispose (void)
+{
+  // Do your work here.
+  // chain up
+  Object::DoDispose ();
+}
+
+
+
+class YetAnotherObject : public Object
+{
+public:
+  static const InterfaceId iid;
+  YetAnotherObject (int a);
+private:
+  virtual void DoDispose (void);
+};
+
+const InterfaceId YetAnotherObject::iid = MakeInterfaceId ("YetAnotherObject", Object::iid);
+
+YetAnotherObject::YetAnotherObject (int a)
+{
+  // enable our interface
+  SetInterfaceId (YetAnotherObject::iid);
+  // aggregated directly to another object.
+  AddInterface (Create<AnObject> ());
+}
+void
+YetAnotherObject::DoDispose (void)
+{
+  // Do your work here.
+  // chain up
+  Object::DoDispose ();
+}
+
+
+
+int main (int argc, char *argv[])
+{
+  Ptr<Object> p;
+  Ptr<AnObject> anObject;
+  Ptr<AnotherObject> anotherObject;
+  Ptr<YetAnotherObject> yetAnotherObject;
+
+  p = Create<AnObject> ();
+  // p gives you access to AnObject's interface
+  anObject = p->QueryInterface<AnObject> (AnObject::iid);
+  NS_ASSERT (anObject != 0);
+  // p does not give you access to AnotherObject's interface
+  anotherObject = p->QueryInterface<AnotherObject> (AnotherObject::iid);
+  NS_ASSERT (anotherObject == 0);
+
+  anotherObject = Create<AnotherObject> (1);
+  // AnotherObject does not give you access to AnObject's interface
+  anObject = anotherObject->QueryInterface<AnObject> (AnObject::iid);
+  NS_ASSERT (anObject == 0);
+
+  // aggregate the two objects
+  p->AddInterface (anotherObject);
+  // p gives you access to AnObject's interface
+  anObject = p->QueryInterface<AnObject> (AnObject::iid);
+  NS_ASSERT (anObject != 0);
+  // p gives you access to AnotherObject's interface
+  anotherObject = p->QueryInterface<AnotherObject> (AnotherObject::iid);
+  NS_ASSERT (anotherObject != 0);
+
+
+  yetAnotherObject = Create<YetAnotherObject> (2);
+  // gives you acess to AnObject interface too.
+  anObject = yetAnotherObject->QueryInterface<AnObject> (AnObject::iid);
+  NS_ASSERT (anObject != 0);
+
+
+  return 0;
+}
+
--- a/samples/main-ptr.cc	Thu Jun 07 13:19:25 2007 +0200
+++ b/samples/main-ptr.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -49,7 +49,7 @@
   {
     // Create a new object of type A, store it in global 
     // variable g_a
-    Ptr<A> a = MakeNewObject<A> ();
+    Ptr<A> a = Create<A> ();
     a->Method ();
     Ptr<A> prev = StoreA (a);
     NS_ASSERT (prev == 0);
@@ -58,7 +58,7 @@
   {
     // Create a new object of type A, store it in global 
     // variable g_a, get a hold on the previous A object.
-    Ptr<A> a = MakeNewObject<A> ();
+    Ptr<A> a = Create<A> ();
     Ptr<A> prev = StoreA (a);
     // call method on object
     prev->Method ();
--- a/samples/main-simple.cc	Thu Jun 07 13:19:25 2007 +0200
+++ b/samples/main-simple.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -2,7 +2,7 @@
 
 #include "ns3/internet-node.h"
 #include "ns3/simulator.h"
-#include "ns3/i-socket-factory.h"
+#include "ns3/socket-factory.h"
 #include "ns3/socket.h"
 #include "ns3/nstime.h"
 
@@ -38,10 +38,10 @@
 void
 RunSimulation (void)
 {
-  Ptr<INode> a = MakeInternetNode ();
+  Ptr<Node> a = Create<InternetNode> ();
 
-  InterfaceId iid = InterfaceId::LookupByName ("IUdp");
-  Ptr<ISocketFactory> socketFactory = a->QueryInterface<ISocketFactory> (iid);
+  InterfaceId iid = InterfaceId::LookupByName ("Udp");
+  Ptr<SocketFactory> socketFactory = a->QueryInterface<SocketFactory> (iid);
 
   Ptr<Socket> sink = socketFactory->CreateSocket ();
   sink->Bind (80);
--- a/src/applications/onoff-application.cc	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/applications/onoff-application.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -23,13 +23,13 @@
 // Adapted from ApplicationOnOff in GTNetS.
 
 #include "ns3/ipv4-address.h"
-#include "ns3/i-node.h"
+#include "ns3/node.h"
 #include "ns3/nstime.h"
 #include "ns3/data-rate.h"
 #include "ns3/random-variable.h"
 #include "ns3/socket.h"
 #include "ns3/simulator.h"
-#include "ns3/i-socket-factory.h"
+#include "ns3/socket-factory.h"
 #include "ns3/default-value.h"
 #include "onoff-application.h"
 
@@ -46,7 +46,7 @@
                                                     512, 1);
 // Constructors
 
-OnOffApplication::OnOffApplication(Ptr<INode> n, 
+OnOffApplication::OnOffApplication(Ptr<Node> n, 
                                    const Ipv4Address  rip,
                                    uint16_t rport,
                                    std::string iid,
@@ -60,7 +60,7 @@
              g_defaultSize.GetValue ());
 }
 
-OnOffApplication::OnOffApplication(Ptr<INode> n, 
+OnOffApplication::OnOffApplication(Ptr<Node> n, 
                                    const Ipv4Address  rip,
                                    uint16_t rport,
                                    std::string iid,
@@ -76,7 +76,7 @@
 }
 
 void
-OnOffApplication::Construct (Ptr<INode> n, 
+OnOffApplication::Construct (Ptr<Node> n, 
                              const Ipv4Address  rip,
                              uint16_t rport,
                              std::string iid,
@@ -141,7 +141,7 @@
   if (!m_socket)
     {
       InterfaceId iid = InterfaceId::LookupByName (m_iid);
-      Ptr<ISocketFactory> socketFactory = GetINode ()->QueryInterface<ISocketFactory> (iid);
+      Ptr<SocketFactory> socketFactory = GetNode ()->QueryInterface<SocketFactory> (iid);
       m_socket = socketFactory->CreateSocket ();
       m_socket->Bind ();
       m_socket->Connect (m_peerIp, m_peerPort);
--- a/src/applications/onoff-application.h	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/applications/onoff-application.h	Tue Jun 12 22:54:10 2007 +0200
@@ -58,7 +58,7 @@
    * \param ontime on time random variable
    * \param offtime off time random variable
    */
-  OnOffApplication(Ptr<INode> n,
+  OnOffApplication(Ptr<Node> n,
                    const Ipv4Address rip,
                    uint16_t rport,
                    std::string iid,
@@ -75,7 +75,7 @@
    * \param rate data rate when on
    * \param size size of packets when sending data.
    */
-  OnOffApplication(Ptr<INode> n,
+  OnOffApplication(Ptr<Node> n,
                    const Ipv4Address rip,
                    uint16_t rport,
                    std::string iid,
@@ -111,7 +111,7 @@
   virtual void StartApplication (void);    // Called at time specified by Start
   virtual void StopApplication (void);     // Called at time specified by Stop
 
-  void Construct (Ptr<INode> n,
+  void Construct (Ptr<Node> n,
                   const Ipv4Address rip,
                   uint16_t rport,
                   std::string iid,
--- a/src/core/callback.h	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/core/callback.h	Tue Jun 12 22:54:10 2007 +0200
@@ -24,6 +24,7 @@
 
 #include "ptr.h"
 #include "fatal-error.h"
+#include "empty.h"
 
 namespace ns3 {
 
@@ -56,8 +57,6 @@
  * and relies on a reference list rather than autoPtr to hold
  * the pointer.
  */
-class empty {};
-
 template <typename T>
 struct CallbackTraits;
 
@@ -268,12 +267,12 @@
   // always properly disambiguited by the c++ compiler
   template <typename FUNCTOR>
   Callback (FUNCTOR const &functor, bool, bool) 
-      : m_impl (MakeNewObject<FunctorCallbackImpl<FUNCTOR,R,T1,T2,T3,T4,T5> > (functor))
+      : m_impl (Create<FunctorCallbackImpl<FUNCTOR,R,T1,T2,T3,T4,T5> > (functor))
   {}
 
   template <typename OBJ_PTR, typename MEM_PTR>
   Callback (OBJ_PTR const &objPtr, MEM_PTR mem_ptr)
-      : m_impl (MakeNewObject<MemPtrCallbackImpl<OBJ_PTR,MEM_PTR,R,T1,T2,T3,T4,T5> > (objPtr, mem_ptr))
+      : m_impl (Create<MemPtrCallbackImpl<OBJ_PTR,MEM_PTR,R,T1,T2,T3,T4,T5> > (objPtr, mem_ptr))
   {}
 
   Callback (Ptr<CallbackImpl<R,T1,T2,T3,T4,T5> > const &impl)
@@ -642,33 +641,33 @@
 template <typename R, typename TX>
 Callback<R> MakeBoundCallback (R (*fnPtr) (TX), TX a) {
   Ptr<CallbackImpl<R,empty,empty,empty,empty,empty> > impl =
-    MakeNewObject<BoundFunctorCallbackImpl<R (*) (TX),R,TX,empty,empty,empty,empty,empty> >(fnPtr, a);
+    Create<BoundFunctorCallbackImpl<R (*) (TX),R,TX,empty,empty,empty,empty,empty> >(fnPtr, a);
   return Callback<R> (impl);
 }
 
 template <typename R, typename TX, typename T1>
 Callback<R,T1> MakeBoundCallback (R (*fnPtr) (TX,T1), TX a) {
   Ptr<CallbackImpl<R,T1,empty,empty,empty,empty> > impl =
-    MakeNewObject<BoundFunctorCallbackImpl<R (*) (TX,T1),R,TX,T1,empty,empty,empty,empty> > (fnPtr, a);
+    Create<BoundFunctorCallbackImpl<R (*) (TX,T1),R,TX,T1,empty,empty,empty,empty> > (fnPtr, a);
   return Callback<R,T1> (impl);
 }
 template <typename R, typename TX, typename T1, typename T2>
 Callback<R,T1,T2> MakeBoundCallback (R (*fnPtr) (TX,T1,T2), TX a) {
   Ptr<CallbackImpl<R,T1,T2,empty,empty,empty> > impl =
-    MakeNewObject<BoundFunctorCallbackImpl<R (*) (TX,T1,T2),R,TX,T1,T2,empty,empty,empty> > (fnPtr, a);
+    Create<BoundFunctorCallbackImpl<R (*) (TX,T1,T2),R,TX,T1,T2,empty,empty,empty> > (fnPtr, a);
   return Callback<R,T1,T2> (impl);
 }
 template <typename R, typename TX, typename T1, typename T2,typename T3,typename T4>
 Callback<R,T1,T2,T3,T4> MakeBoundCallback (R (*fnPtr) (TX,T1,T2,T3,T4), TX a) {
   Ptr<CallbackImpl<R,T1,T2,T3,T4,empty> > impl =
-    MakeNewObject<BoundFunctorCallbackImpl<R (*) (TX,T1,T2,T3,T4),R,TX,T1,T2,T3,T4,empty> > (fnPtr, a);
+    Create<BoundFunctorCallbackImpl<R (*) (TX,T1,T2,T3,T4),R,TX,T1,T2,T3,T4,empty> > (fnPtr, a);
   return Callback<R,T1,T2,T3,T4> (impl);
 }
 
 template <typename R, typename TX, typename T1, typename T2,typename T3,typename T4,typename T5>
 Callback<R,T1,T2,T3,T4,T5> MakeBoundCallback (R (*fnPtr) (TX,T1,T2,T3,T4,T5), TX a) {
   Ptr<CallbackImpl<R,T1,T2,T3,T4,T5> > impl =
-    MakeNewObject<BoundFunctorCallbackImpl<R (*) (TX,T1,T2,T3,T4,T5),R,TX,T1,T2,T3,T4,T5> > (fnPtr, a);
+    Create<BoundFunctorCallbackImpl<R (*) (TX,T1,T2,T3,T4,T5),R,TX,T1,T2,T3,T4,T5> > (fnPtr, a);
   return Callback<R,T1,T2,T3,T4,T5> (impl);
 }
 
--- a/src/core/component-manager.cc	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/core/component-manager.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -39,7 +39,7 @@
 {}
 
 std::string 
-ClassId::GetName (void)
+ClassId::GetName (void) const
 {
   return Singleton<CidManager>::Get ()->LookupByUid (m_classId);
 }
@@ -49,10 +49,14 @@
   return a.m_classId == b.m_classId;
 }
 
-Ptr<Interface>
+ComponentManager::ClassIdEntry::ClassIdEntry (ClassId classId)
+  : m_classId (classId)
+{}
+
+Ptr<Object>
 ComponentManager::Create (ClassId classId)
 {
-  Callback<Ptr<Interface> > callback = DoGetCallback<empty,empty,empty,empty,empty> (classId);
+  Callback<Ptr<Object> > callback = DoGetCallback<empty,empty,empty,empty,empty> (classId);
   return callback ();
 }
 
@@ -62,9 +66,9 @@
   List *list = Singleton<List>::Get ();
   for (List::const_iterator i = list->begin (); i != list->end (); i++)
     {
-      if (i->first == classId)
+      if (i->m_classId == classId)
 	{
-	  return i->second;
+	  return i->m_callback;
 	}
     }
   return 0;
@@ -75,15 +79,146 @@
 {
   return ClassId (Singleton<CidManager>::Get ()->LookupByName (name));
 }
+ClassId 
+ComponentManager::LookupByName (std::string name, bool *ok)
+{
+  uint32_t cid = Singleton<CidManager>::Get ()->LookupByName (name);
+  if (cid == 0)
+    {
+      *ok = false;
+    }
+  else
+    {
+      *ok = true;
+    }
+  return ClassId (cid);
+}
+std::vector<ClassId> 
+ComponentManager::LookupByInterfaceId (InterfaceId iid)
+{
+  std::vector<ClassId> classIdList;
+  List *list = Singleton<List>::Get ();
+  for (List::const_iterator i = list->begin (); i != list->end (); i++)
+    {
+      for (std::vector<const InterfaceId *>::const_iterator j = i->m_supportedInterfaces.begin ();
+           j != i->m_supportedInterfaces.end (); j++)
+        {
+          if (*(*j) == iid)
+            {
+              classIdList.push_back (i->m_classId);
+              break;
+            }
+        }
+    }
+  unique (classIdList.begin (), classIdList.end ());
+  return classIdList;
+}
 
-ClassId
-ComponentManager::Register (std::string name, CallbackBase *callback)
+void
+ComponentManager::Register (ClassId classId, CallbackBase *callback, 
+                            std::vector<const InterfaceId *> supportedInterfaces)
+{
+  List *list = Singleton<List>::Get ();
+  struct ClassIdEntry entry = ClassIdEntry (classId);
+  entry.m_callback = callback;
+  bool foundObject = false;
+  for (std::vector<const InterfaceId *>::iterator i = supportedInterfaces.begin ();
+       i != supportedInterfaces.end (); i++)
+    {
+      if (*i == &Object::iid)
+        {
+          foundObject = true;
+        }
+    }
+  if (!foundObject)
+    {
+      supportedInterfaces.push_back (&Object::iid);
+    }
+  entry.m_supportedInterfaces = supportedInterfaces;
+  list->push_back (entry);
+}
+
+void
+RegisterCallback (ClassId classId, CallbackBase *callback, std::vector<const InterfaceId *> supportedInterfaces)
 {
-  ClassId classId = ClassId (name);
-  List *list = Singleton<List>::Get ();
-  list->push_back (std::make_pair (classId, callback));
-  return classId;
+  return ComponentManager::Register (classId, callback, supportedInterfaces);
+}
+
+
+ClassIdDefaultValue::ClassIdDefaultValue (std::string name, 
+                                          std::string help,
+                                          const InterfaceId &iid,
+                                          std::string defaultValue)
+  : DefaultValueBase (name, help),
+    m_defaultName (defaultValue),
+    m_name (defaultValue),
+    m_interfaceId (&iid)
+{
+  DefaultValueList::Add (this);
+}
+ClassId 
+ClassIdDefaultValue::GetValue (void) const
+{
+  return ComponentManager::LookupByName (m_name);
+}
+void 
+ClassIdDefaultValue::SetValue (ClassId classId)
+{
+  m_name = classId.GetName ();
+}
+void 
+ClassIdDefaultValue::SetValue (std::string name)
+{
+  m_name = name;
 }
+bool 
+ClassIdDefaultValue::DoParseValue (const std::string &value)
+{
+  bool ok;
+  ClassId classId = ComponentManager::LookupByName (value, &ok);
+  if (!ok)
+    {
+      return false;
+    }
+  std::vector<ClassId> classIdList = ComponentManager::LookupByInterfaceId (*m_interfaceId);
+  for (std::vector<ClassId>::const_iterator i = classIdList.begin ();
+       i != classIdList.end (); i++)
+    {
+      if (*i == classId)
+        {
+          m_name = value;
+          return true;
+        }
+    }
+  return false;
+}
+
+std::string 
+ClassIdDefaultValue::DoGetType (void) const
+{
+  std::vector<ClassId> classIdList = ComponentManager::LookupByInterfaceId (*m_interfaceId);
+  std::ostringstream oss;
+  oss << "(";
+  for (std::vector<ClassId>::const_iterator i = classIdList.begin ();
+       i != classIdList.end (); i++)
+    {
+      if (i != classIdList.begin ())
+        {
+          oss << "|";
+        }
+      oss << i->GetName ();
+    }
+  oss << ")";
+  return oss.str ();
+}
+
+std::string 
+ClassIdDefaultValue::DoGetDefaultValue (void) const
+{
+  return m_name;
+}
+
+
 
 
 } // namespace ns3
@@ -91,31 +226,33 @@
 #ifdef RUN_SELF_TESTS
 
 #include "test.h"
-#include "interface.h"
+#include "object.h"
 
 namespace {
 
 
-class B : public ns3::Interface
+class B : public ns3::Object
 {
 public:
   static const ns3::InterfaceId iid;
   B ();
 };
 
-const ns3::InterfaceId B::iid ("IB");
+const ns3::InterfaceId B::iid = MakeInterfaceId ("B", Object::iid);
 
 B::B ()
-  : Interface (B::iid)
-{}
+{
+  SetInterfaceId (B::iid);
+}
 
 
-class A : public ns3::Interface
+class A : public ns3::Object
 {
 public:
   static const ns3::ClassId cidZero;
   static const ns3::ClassId cidOneBool;
   static const ns3::ClassId cidOneUi32;
+  static const ns3::ClassId cidOther;
   static const ns3::InterfaceId iid;
 
   A ();
@@ -130,43 +267,65 @@
   int m_ui32;
 };
 
-const ns3::ClassId A::cidZero = ns3::ComponentManager::RegisterConstructor <A> ("A");
-const ns3::ClassId A::cidOneBool = ns3::ComponentManager::RegisterConstructor <A,bool> ("ABool");
-const ns3::ClassId A::cidOneUi32 = ns3::ComponentManager::RegisterConstructor <A,uint32_t> ("AUi32");
-const ns3::InterfaceId A::iid ("IA");
+const ns3::ClassId A::cidZero = ns3::MakeClassId<A> ("A", A::iid);
+const ns3::ClassId A::cidOneBool = ns3::MakeClassId <A,bool> ("ABool", A::iid);
+const ns3::ClassId A::cidOneUi32 = ns3::MakeClassId <A,uint32_t> ("AUi32", A::iid);
+const ns3::InterfaceId A::iid = ns3::MakeInterfaceId ("A", Object::iid);
 
 A::A ()
-  : Interface (A::iid),
-    m_zeroInvoked (true),
+  : m_zeroInvoked (true),
     m_oneBoolInvoked (false),
     m_oneUi32Invoked (false)
 {
-  ns3::Ptr<B> b = ns3::MakeNewObject<B> ();
+  SetInterfaceId (A::iid);
+  ns3::Ptr<B> b = ns3::Create<B> ();
   AddInterface (b);
 }
 
 A::A (bool bo)
-  : Interface (A::iid),
-    m_zeroInvoked (false),
+  : m_zeroInvoked (false),
     m_oneBoolInvoked (true),
     m_oneUi32Invoked (false),
     m_bool (bo)
 {
-  ns3::Ptr<B> b = ns3::MakeNewObject<B> ();
+  SetInterfaceId (A::iid);
+  ns3::Ptr<B> b = ns3::Create<B> ();
   AddInterface (b);
 }
 
 A::A (uint32_t i)
-  : Interface (A::iid),
-    m_zeroInvoked (false),
+  : m_zeroInvoked (false),
     m_oneBoolInvoked (false),
     m_oneUi32Invoked (true),
     m_ui32 (i)
 {
-  ns3::Ptr<B> b = ns3::MakeNewObject<B> ();
+  SetInterfaceId (A::iid);
+  ns3::Ptr<B> b = ns3::Create<B> ();
   AddInterface (b);
 }
 
+class X : public A
+{
+public:
+  static const ns3::InterfaceId iid;
+};
+class C : public X
+{
+public:
+  static const ns3::InterfaceId iid;
+};
+class D : public C
+{
+public:
+  static const ns3::InterfaceId iid;
+  static const ns3::ClassId cid;
+};
+
+const ns3::InterfaceId X::iid = ns3::MakeInterfaceId ("X", A::iid);
+const ns3::InterfaceId C::iid = ns3::MakeInterfaceId ("C", X::iid);
+const ns3::InterfaceId D::iid = ns3::MakeInterfaceId ("D", C::iid);
+const ns3::ClassId D::cid = ns3::MakeClassId<D> ("D", A::iid, X::iid, C::iid, D::iid);
+
 }
 
 namespace ns3 {
--- a/src/core/component-manager.h	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/core/component-manager.h	Tue Jun 12 22:54:10 2007 +0200
@@ -18,16 +18,25 @@
  *
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
  */
-#ifndef NS_UNKNOWN_MANAGER_H
-#define NS_UNKNOWN_MANAGER_H
+#ifndef COMPONENT_MANAGER_H
+#define COMPONENT_MANAGER_H
 
 #include <string>
 #include <vector>
 #include <stdint.h>
 #include "callback.h"
-#include "interface.h"
+#include "object.h"
 #include "fatal-error.h"
 #include "ptr.h"
+#include "empty.h"
+#include "default-value.h"
+
+namespace {
+  // anonymous namespace for implementation code.
+template <typename T, typename T1 = ns3::empty, typename T2 = ns3::empty,
+          typename T3 = ns3::empty, typename T4 = ns3::empty, typename T5 = ns3::empty>
+struct ObjectMaker;
+}
 
 namespace ns3 {
 
@@ -35,7 +44,7 @@
  * \brief Unique Identifier for class constructors.
  *
  * Instances of this type must be allocated through
- * the ns3::Ns3UnknownManager::RegisterConstructor methods
+ * the ns3::MakeClassId class.
  */
 class ClassId
 {
@@ -48,16 +57,106 @@
    * This name is also the name which is expected to be input
    * to ns3::UnknownManager::LookupByName.
    */
-  std::string GetName (void);
+  std::string GetName (void) const;
+protected:
+  ClassId (std::string name);
 private:
-  ClassId (std::string name);
   ClassId (uint32_t classId);
   friend class ComponentManager;
+  friend ClassId AllocateClassId (std::string name);
   friend bool operator == (const ClassId &a, const ClassId &b);
   uint32_t m_classId;
 };
 
 /**
+ * \brief a class used to create ClassIds
+ *
+ * 
+ */
+template <typename T, typename T1 = empty, typename T2 = empty,
+          typename T3 = empty, typename T4 = empty, typename T5 = empty>
+class MakeClassId : public ClassId
+{
+public:
+  /**
+   * \param name name of ClassId
+   *
+   * Create a ClassId with specified name.
+   */
+  MakeClassId (std::string name);
+  /**
+   * \param name name of ClassId
+   * \param iid interface id
+   *
+   * Create a ClassId with specified name. Register iid
+   * as a supported interface.
+   */
+  MakeClassId (std::string name, 
+               const InterfaceId &iid);
+  /**
+   * \param name name of ClassId
+   * \param iid0 interface id
+   * \param iid1 interface id
+   *
+   * Create a ClassId with specified name. Register iid0 and iid1
+   * as supported interfaces.
+   */
+  MakeClassId (std::string name, 
+               const InterfaceId &iid0, 
+               const InterfaceId iid1);
+  /**
+   * \param name name of ClassId
+   * \param iid0 interface id
+   * \param iid1 interface id
+   * \param iid2 interface id
+   *
+   * Create a ClassId with specified name. Register iid0, iid1
+   * and iid2 as supported interfaces.
+   */
+  MakeClassId (std::string name, 
+               const InterfaceId &iid0, 
+               const InterfaceId &iid1,
+               const InterfaceId &iid2);
+  /**
+   * \param name name of ClassId
+   * \param iid0 interface id
+   * \param iid1 interface id
+   * \param iid2 interface id
+   * \param iid3 interface id
+   *
+   * Create a ClassId with specified name. Register iid0, iid1
+   * iid2, and iid3 as supported interfaces.
+   */
+  MakeClassId (std::string name, 
+               const InterfaceId &iid0, 
+               const InterfaceId &iid1,
+               const InterfaceId &iid2,
+               const InterfaceId &iid3);
+  /**
+   * \param name name of ClassId
+   * \param iid0 interface id
+   * \param iid1 interface id
+   * \param iid2 interface id
+   * \param iid3 interface id
+   * \param iid4 interface id
+   *
+   * Create a ClassId with specified name. Register iid0, iid1
+   * iid2, iid3, and iid4 as supported interfaces.
+   */
+  MakeClassId (std::string name, 
+               const InterfaceId &iid0, 
+               const InterfaceId &iid1,
+               const InterfaceId &iid2,
+               const InterfaceId &iid3,
+               const InterfaceId &iid4);
+private:
+  typedef ObjectMaker<T,T1,T2,T3,T4,T5> MakerType;
+  static Callback<Ptr<Object>,T1,T2,T3,T4,T5> m_callback;
+  void Register (const InterfaceId *array [], uint32_t n);
+};
+
+
+/**
  * \brief Create any Interface
  *
  * This class keeps track of a set of ClassId, each
@@ -75,6 +174,19 @@
    * \returns the ClassId associated to the input name.
    */
   static ClassId LookupByName (std::string name);
+  static ClassId LookupByName (std::string name, bool *ok);
+  /**
+   * \param iid interface id to lookup
+   * \returns the list of ClassId which can be used to
+   *          create objects which support the requested 
+   *          interface.
+   *
+   * Note that this method will not necessarily return the
+   * complete list of objects which support a given interface
+   * since dynamic aggregation of objects is not under
+   * the control of this class.
+   */
+  static std::vector<ClassId> LookupByInterfaceId (InterfaceId iid);
 
   /**
    * \param classId class id of the constructor to invoke.
@@ -83,7 +195,7 @@
    * Create an instance of the object identified by its
    * ClassId. This method invokes the default constructor.
    */
-  static Ptr<Interface> Create (ClassId classId);
+  static Ptr<Object> Create (ClassId classId);
 
   /**
    * \param classId class id of the constructor to invoke.
@@ -94,7 +206,7 @@
    * ClassId.
    */
   template <typename T1>
-  static Ptr<Interface> Create (ClassId classId, T1 a1);
+  static Ptr<Object> Create (ClassId classId, T1 a1);
 
   /**
    * \param classId class id of the constructor to invoke.
@@ -106,7 +218,50 @@
    * ClassId.
    */
   template <typename T1, typename T2>
-  static Ptr<Interface> Create (ClassId classId, T1 a1, T2 a2);
+  static Ptr<Object> Create (ClassId classId, T1 a1, T2 a2);
+
+
+  /**
+   * \param classId class id of the constructor to invoke.
+   * \param a1 first argument to pass to the constructor.
+   * \param a2 second argument to pass to the constructor.
+   * \param a3 third argument to pass to the constructor.
+   * \return a pointer to the instance created.
+   *
+   * Create an instance of the object identified by its
+   * ClassId.
+   */
+  template <typename T1, typename T2, typename T3>
+  static Ptr<Object> Create (ClassId classId, T1 a1, T2 a2, T3 a3);
+
+  /**
+   * \param classId class id of the constructor to invoke.
+   * \param a1 first argument to pass to the constructor.
+   * \param a2 second argument to pass to the constructor.
+   * \param a3 third argument to pass to the constructor.
+   * \param a4 fourth argument to pass to the constructor.
+   * \return a pointer to the instance created.
+   *
+   * Create an instance of the object identified by its
+   * ClassId.
+   */
+  template <typename T1, typename T2, typename T3, typename T4>
+  static Ptr<Object> Create (ClassId classId, T1 a1, T2 a2, T3 a3, T4 a4);
+
+  /**
+   * \param classId class id of the constructor to invoke.
+   * \param a1 first argument to pass to the constructor.
+   * \param a2 second argument to pass to the constructor.
+   * \param a3 third argument to pass to the constructor.
+   * \param a4 fourth argument to pass to the constructor.
+   * \param a5 fifth argument to pass to the constructor.
+   * \return a pointer to the instance created.
+   *
+   * Create an instance of the object identified by its
+   * ClassId.
+   */
+  template <typename T1, typename T2, typename T3, typename T4, typename T5>
+  static Ptr<Object> Create (ClassId classId, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
 
   /**
    * \param classId class id of the constructor to invoke.
@@ -120,79 +275,303 @@
   template <typename T>
   static Ptr<T> Create (ClassId classId, InterfaceId iid);
 
+  /**
+   * \param classId class id of the constructor to invoke.
+   * \param iid interface id to query for
+   * \param a1 first argument to pass to constructor
+   * \return a pointer to the instance created.
+   *
+   * Create an instance of the object identified by its
+   * ClassId, call QueryInterface on it, and return the 
+   * result.
+   */
   template <typename T, typename T1>
   static Ptr<T> Create (ClassId classId, InterfaceId iid, T1 a1);
 
+  /**
+   * \param classId class id of the constructor to invoke.
+   * \param iid interface id to query for
+   * \param a1 first argument to pass to constructor
+   * \param a2 second argument to pass to constructor
+   * \return a pointer to the instance created.
+   *
+   * Create an instance of the object identified by its
+   * ClassId, call QueryInterface on it, and return the 
+   * result.
+   */
   template <typename T, typename T1, typename T2>
   static Ptr<T> Create (ClassId classId, InterfaceId iid, T1 a1, T2 a2);
 
   /**
-   * \param name the symbolic name to associate to this
-   *        constructor
-   * \returns a ClassId which uniquely identifies this constructor.
+   * \param classId class id of the constructor to invoke.
+   * \param iid interface id to query for
+   * \param a1 first argument to pass to constructor
+   * \param a2 second argument to pass to constructor
+   * \param a3 third argument to pass to constructor
+   * \return a pointer to the instance created.
+   *
+   * Create an instance of the object identified by its
+   * ClassId, call QueryInterface on it, and return the 
+   * result.
    */
-  template <typename T>
-  static ClassId RegisterConstructor (std::string name)
-  {
-    static Callback<Ptr<Interface> > callback = 
-      MakeCallback (&ComponentManager::MakeObjectZero<T>);
-    return ComponentManager::Register (name, &callback);
-  }
+  template <typename T, typename T1, typename T2, typename T3>
+  static Ptr<T> Create (ClassId classId, InterfaceId iid, T1 a1, T2 a2, T3 a3);
 
   /**
-   * \param name the symbolic name to associate to this
-   *        constructor
-   * \returns a ClassId which uniquely identifies this constructor.
+   * \param classId class id of the constructor to invoke.
+   * \param iid interface id to query for
+   * \param a1 first argument to pass to constructor
+   * \param a2 second argument to pass to constructor
+   * \param a3 third argument to pass to constructor
+   * \param a4 fourth argument to pass to constructor
+   * \return a pointer to the instance created.
+   *
+   * Create an instance of the object identified by its
+   * ClassId, call QueryInterface on it, and return the 
+   * result.
    */
-  template <typename T, typename T1>
-  static ClassId RegisterConstructor (std::string name)
-  {
-    static Callback<Ptr<Interface> ,T1> callback = MakeCallback (&ComponentManager::MakeObjectOne<T,T1>);
-    return ComponentManager::Register (name, &callback);
-  }
+  template <typename T, typename T1, typename T2, typename T3, typename T4>
+  static Ptr<T> Create (ClassId classId, InterfaceId iid, T1 a1, T2 a2, T3 a3, T4 a4);
 
   /**
-   * \param name the symbolic name to associate to this
-   *        constructor
-   * \returns a ClassId which uniquely identifies this constructor.
+   * \param classId class id of the constructor to invoke.
+   * \param iid interface id to query for
+   * \param a1 first argument to pass to constructor
+   * \param a2 second argument to pass to constructor
+   * \param a3 third argument to pass to constructor
+   * \param a4 fourth argument to pass to constructor
+   * \param a5 fifth argument to pass to constructor
+   * \return a pointer to the instance created.
+   *
+   * Create an instance of the object identified by its
+   * ClassId, call QueryInterface on it, and return the 
+   * result.
    */
-  template <typename T, typename T1, typename T2>
-  static ClassId RegisterConstructor (std::string name)
-  {
-    static Callback<Ptr<Interface>,T1,T2> callback = MakeCallback (&ComponentManager::MakeObjectTwo<T,T1,T2>);
-    return ComponentManager::Register (name, &callback);
-  }
+  template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
+  static Ptr<T> Create (ClassId classId, InterfaceId iid, T1 a1, T2 a2, T3 a3, T4 a4, T5);
+
 private:
-  static ClassId Register (std::string name, CallbackBase *callback);
+  friend void RegisterCallback (ClassId classId, CallbackBase *callback, 
+                                   std::vector<const InterfaceId *> supportedInterfaces);
+  static void Register (ClassId classId, CallbackBase *callback, 
+                        std::vector<const InterfaceId *> supportedInterfaces);
 
   template <typename T1, typename T2,
             typename T3, typename T4,
             typename T5>
-  static Callback<Ptr<Interface>,T1,T2,T3,T4,T5> DoGetCallback (ClassId classId);
-
-  template <typename T>
-  static Ptr<Interface> MakeObjectZero (void);
+  static Callback<Ptr<Object>,T1,T2,T3,T4,T5> DoGetCallback (ClassId classId);
 
-  template <typename T, typename T1>
-  static Ptr<Interface> MakeObjectOne (T1 a1);
+  struct ClassIdEntry {
+    ClassIdEntry (ClassId classId);
+    ClassId m_classId;
+    CallbackBase *m_callback;
+    std::vector<const InterfaceId *> m_supportedInterfaces;
+  };
 
-  template <typename T, typename T1, typename T2>
-  static Ptr<Interface> MakeObjectTwo (T1 a1, T2 a2);
-
-  typedef std::vector<std::pair<ClassId, CallbackBase *> > List;
+  typedef std::vector<struct ClassIdEntry> List;
   static List *GetList (void);
   static CallbackBase *Lookup (ClassId classId);
 };
 
+/**
+ * \brief a DefaultValue class to handle ClassIds
+ *
+ * This class provides the necessary glue to allow
+ * the Bind function and the command-line arguments
+ * to control the type of an object to create.
+ */
+class ClassIdDefaultValue : public DefaultValueBase
+{
+public:
+  /**
+   * \param name the name of this default value.
+   * \param help the help text associated to this default value
+   * \param iid the interface id which all objects created
+   *        through this "default value" must support.
+   * \param defaultValue the name of the object to create
+   *        by default.
+   */
+  ClassIdDefaultValue (std::string name, 
+                       std::string help,
+                       const InterfaceId &iid,
+                       std::string defaultValue);
+  /**
+   * \returns the ClassId of the object selected by the user.
+   */
+  ClassId GetValue (void) const;
+  /**
+   * \param classId the new ClassId selected.
+   *
+   * Override the currently-selected value.
+   */
+  void SetValue (ClassId classId);
+  /**
+   * \param name the new object selected.
+   *
+   * Override the currently-selected value.
+   */
+  void SetValue (std::string name);
+private:
+  virtual bool DoParseValue (const std::string &value);
+  virtual std::string DoGetType (void) const;
+  virtual std::string DoGetDefaultValue (void) const;
+  std::string m_defaultName;
+  std::string m_name;
+  const InterfaceId *m_interfaceId;
+};
+
 } // namespace ns3 
 
 
+namespace {
+
+template <typename T>
+struct ObjectMaker<T,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty> {
+  static ns3::Ptr<ns3::Object> 
+  MakeObject (void) {
+    return ns3::Create<T> ();
+  }
+};
+
+template <typename T, typename T1>
+struct ObjectMaker<T,T1,ns3::empty,ns3::empty,ns3::empty,ns3::empty> {
+  static ns3::Ptr<ns3::Object> 
+  MakeObject (T1 a1) {
+    return ns3::Create<T> (a1);
+  }
+};
+
+template <typename T, typename T1, typename T2>
+struct ObjectMaker<T,T1,T2,ns3::empty,ns3::empty,ns3::empty> {
+  static ns3::Ptr<ns3::Object> 
+  MakeObject (T1 a1, T2 a2) {
+    return ns3::Create<T> (a1, a2);
+  }
+};
+
+template <typename T, typename T1, typename T2, typename T3>
+struct ObjectMaker<T,T1,T2,T3,ns3::empty,ns3::empty> {
+  static ns3::Ptr<ns3::Object> 
+  MakeObject (T1 a1, T2 a2, T3 a3) {
+    return ns3::Create<T> (a1, a2, a3);
+  }
+};
+
+template <typename T, typename T1, typename T2, typename T3,
+          typename T4>
+struct ObjectMaker<T,T1,T2,T3,T4,ns3::empty> {
+  static ns3::Ptr<ns3::Object> 
+  MakeObject (T1 a1, T2 a2, T3 a3, T4 a4) {
+    return ns3::Create<T> (a1, a2, a3, a4);
+  }
+};
+
+template <typename T, typename T1, typename T2, typename T3,
+          typename T4, typename T5>
+struct ObjectMaker {
+  static ns3::Ptr<ns3::Object> 
+  MakeObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) {
+    return ns3::Create<T> (a1, a2, a3, a4, a5);
+  }
+};
+
+} // anonymous namespace
+
 namespace ns3 {
+  
+void RegisterCallback (ClassId classId, ns3::CallbackBase *callback, 
+                       std::vector<const InterfaceId *> supportedInterfaces);
+
+
+
+template <typename T, typename T1, typename T2,
+          typename T3, typename T4, typename T5>
+void 
+MakeClassId<T,T1,T2,T3,T4,T5>::Register (const InterfaceId *array [], uint32_t n) 
+{
+  std::vector<const InterfaceId *> supportedInterfaces;
+  for (uint32_t i = 0; i < n; i++)
+    {
+      supportedInterfaces.push_back (array[i]);
+    }
+  RegisterCallback (*this, &m_callback, supportedInterfaces);
+}
+
+template <typename T, typename T1, typename T2,
+          typename T3, typename T4, typename T5>
+MakeClassId<T,T1,T2,T3,T4,T5>::MakeClassId (std::string name) 
+  : ClassId (name) 
+{
+  const InterfaceId *array[] = {};
+  Register (array, sizeof (array)/sizeof(InterfaceId *));
+}
+template <typename T, typename T1, typename T2,
+          typename T3, typename T4, typename T5>
+MakeClassId<T,T1,T2,T3,T4,T5>::MakeClassId (std::string name, 
+                                   const InterfaceId &iid) 
+  : ClassId (name) 
+{
+  const InterfaceId *array[] = {&iid};
+  Register (array, sizeof (array)/sizeof(InterfaceId *));
+}
+template <typename T, typename T1, typename T2,
+          typename T3, typename T4, typename T5>
+MakeClassId<T,T1,T2,T3,T4,T5>::MakeClassId (std::string name, 
+                                   const InterfaceId &iid0, 
+                                   const InterfaceId iid1) 
+  : ClassId (name) 
+{
+  const InterfaceId *array[] = {&iid0, &iid1};
+  Register (array, sizeof (array)/sizeof(InterfaceId *));
+}
+template <typename T, typename T1, typename T2,
+          typename T3, typename T4, typename T5>
+MakeClassId<T,T1,T2,T3,T4,T5>::MakeClassId (std::string name, 
+                                   const InterfaceId &iid0, 
+                                   const InterfaceId &iid1,
+                                   const InterfaceId &iid2)
+  : ClassId (name) 
+{
+  const InterfaceId *array[] = {&iid0, &iid1, &iid2};
+  Register (array, sizeof (array)/sizeof(InterfaceId *));
+}
+template <typename T, typename T1, typename T2,
+          typename T3, typename T4, typename T5>
+MakeClassId<T,T1,T2,T3,T4,T5>::MakeClassId (std::string name, 
+                                   const InterfaceId &iid0, 
+                                   const InterfaceId &iid1,
+                                   const InterfaceId &iid2,
+                                   const InterfaceId &iid3)
+  : ClassId (name) 
+{
+  const InterfaceId *array[] = {&iid0, &iid1, &iid2, &iid3};
+  Register (array, sizeof (array)/sizeof(InterfaceId *));
+}
+template <typename T, typename T1, typename T2,
+          typename T3, typename T4, typename T5>
+MakeClassId<T,T1,T2,T3,T4,T5>::MakeClassId (std::string name, 
+                                   const InterfaceId &iid0, 
+                                   const InterfaceId &iid1,
+                                   const InterfaceId &iid2,
+                                   const InterfaceId &iid3,
+                                   const InterfaceId &iid4)
+  : ClassId (name) 
+{
+  const InterfaceId *array[] = {&iid0, &iid1, iid2, &iid3, &iid4};
+  Register (array, sizeof (array)/sizeof(InterfaceId *));
+}
+
+template <typename T, typename T1, typename T2,
+          typename T3, typename T4, typename T5>
+Callback<Ptr<Object>,T1,T2,T3,T4,T5> MakeClassId<T,T1,T2,T3,T4,T5>::m_callback = 
+  MakeCallback (&MakeClassId::MakerType::MakeObject);
+
+
 
 template <typename T1, typename T2,
           typename T3, typename T4,
           typename T5>
-Callback<Ptr<Interface>,T1,T2,T3,T4,T5>
+Callback<Ptr<Object>,T1,T2,T3,T4,T5>
 ComponentManager::DoGetCallback (ClassId classId)
 {
   CallbackBase *callback = Lookup (classId);
@@ -200,33 +579,58 @@
     {
       NS_FATAL_ERROR ("Invalid Class Id.");
     }
-  Callback<Ptr<Interface>, T1,T2,T3,T4,T5> reference;
+  Callback<Ptr<Object>,T1,T2,T3,T4,T5> reference;
   reference.Assign (*callback);
   return reference;
 }
 
 
 template <typename T1>
-Ptr<Interface>
+Ptr<Object>
 ComponentManager::Create (ClassId classId, T1 a1)
 {
-  Callback<Ptr<Interface>, T1> callback = DoGetCallback<T1,empty,empty,empty,empty> (classId);
+  Callback<Ptr<Object>,T1> callback = DoGetCallback<T1,empty,empty,empty,empty> (classId);
   return callback (a1);
 }
 
 template <typename T1, typename T2>
-Ptr<Interface> 
+Ptr<Object> 
 ComponentManager::Create (ClassId classId, T1 a1, T2 a2)
 {
-  Callback<Ptr<Interface> , T1,T2> callback = DoGetCallback<T1,T2,empty,empty,empty> (classId);
+  Callback<Ptr<Object>,T1,T2> callback = DoGetCallback<T1,T2,empty,empty,empty> (classId);
   return callback (a1, a2);
 }
 
+template <typename T1, typename T2, typename T3>
+Ptr<Object> 
+ComponentManager::Create (ClassId classId, T1 a1, T2 a2, T3 a3)
+{
+  Callback<Ptr<Object>,T1,T2,T3> callback = DoGetCallback<T1,T2,T3,empty,empty> (classId);
+  return callback (a1, a2, a3);
+}
+
+template <typename T1, typename T2, typename T3, typename T4>
+Ptr<Object> 
+ComponentManager::Create (ClassId classId, T1 a1, T2 a2, T3 a3, T4 a4)
+{
+  Callback<Ptr<Object>,T1,T2,T3,T4> callback = DoGetCallback<T1,T2,T3,T4,empty> (classId);
+  return callback (a1, a2, a3, a4);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+Ptr<Object> 
+ComponentManager::Create (ClassId classId, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
+{
+  Callback<Ptr<Object>,T1,T2,T3,T4,T5> callback = DoGetCallback<T1,T2,T3,T4,T5> (classId);
+  return callback (a1, a2, a3, a4, a5);
+}
+
+
 template <typename T>
 Ptr<T>
 ComponentManager::Create (ClassId classId, InterfaceId iid)
 {
-  Ptr<Interface> obj = Create (classId);
+  Ptr<Object> obj = Create (classId);
   Ptr<T> i = obj->QueryInterface<T> (iid);
   return i;
 }
@@ -235,7 +639,7 @@
 Ptr<T>
 ComponentManager::Create (ClassId classId, InterfaceId iid, T1 a1)
 {
-  Ptr<Interface> obj = Create (classId, a1);
+  Ptr<Object> obj = Create (classId, a1);
   Ptr<T> i = obj->QueryInterface<T> (iid);
   return i;
 }
@@ -244,31 +648,39 @@
 Ptr<T>
 ComponentManager::Create (ClassId classId, InterfaceId iid, T1 a1, T2 a2)
 {
-  Ptr<Interface> obj = Create (classId, a1, a2);
+  Ptr<Object> obj = Create (classId, a1, a2);
   Ptr<T> i = obj->QueryInterface<T> (iid);
   return i;
 }
 
 
-template <typename T>
-Ptr<Interface> 
-ComponentManager::MakeObjectZero (void)
+template <typename T, typename T1, typename T2, typename T3>
+Ptr<T>
+ComponentManager::Create (ClassId classId, InterfaceId iid, T1 a1, T2 a2, T3 a3)
 {
-  return MakeNewObject<T> ();
+  Ptr<Object> obj = Create (classId, a1, a2, a3);
+  Ptr<T> i = obj->QueryInterface<T> (iid);
+  return i;
 }
-template <typename T, typename T1>
-Ptr<Interface> 
-ComponentManager::MakeObjectOne (T1 a1)
+
+template <typename T, typename T1, typename T2, typename T3, typename T4>
+Ptr<T>
+ComponentManager::Create (ClassId classId, InterfaceId iid, T1 a1, T2 a2, T3 a3, T4 a4)
 {
-  return MakeNewObject<T> (a1);
+  Ptr<Object> obj = Create (classId, a1, a2, a3, a4);
+  Ptr<T> i = obj->QueryInterface<T> (iid);
+  return i;
 }
-template <typename T, typename T1, typename T2>
-Ptr<Interface> 
-ComponentManager::MakeObjectTwo (T1 a1, T2 a2)
+
+template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
+Ptr<T>
+ComponentManager::Create (ClassId classId, InterfaceId iid, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
 {
-  return MakeNewObject<T> (a1, a2);
+  Ptr<Object> obj = Create (classId, a1, a2, a3, a4, a5);
+  Ptr<T> i = obj->QueryInterface<T> (iid);
+  return i;
 }
 
 } // namespace ns3
 
-#endif /* NS_UNKNOWN_MANAGER_H */
+#endif /* COMPONENT_MANAGER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/core/empty.h	Tue Jun 12 22:54:10 2007 +0200
@@ -0,0 +1,8 @@
+#ifndef EMPTY_H
+#define EMPTY_H
+
+namespace ns3 {
+class empty {};
+}
+
+#endif /* EMPTY_H */
--- a/src/core/interface.cc	Thu Jun 07 13:19:25 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,396 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#include "interface.h"
-#include "singleton.h"
-#include "uid-manager.h"
-#include <string>
-#include <list>
-#include <stdint.h>
-#include "assert.h"
-#include "debug.h"
-
-NS_DEBUG_COMPONENT_DEFINE ("Interface");
-
-namespace ns3 {
-
-class IidManager : public UidManager
-{};
-
-InterfaceId::InterfaceId (std::string name)
-  : m_iid (Singleton<IidManager>::Get ()->Allocate (name))
-{}
-
-InterfaceId::InterfaceId (uint32_t iid)
-  : m_iid (iid)
-{}
-
-InterfaceId 
-InterfaceId::LookupByName (std::string name)
-{
-  return InterfaceId (Singleton<IidManager>::Get ()->LookupByName (name));
-}
-
-bool operator == (const InterfaceId &a, const InterfaceId &b)
-{
-  return a.m_iid == b.m_iid;
-}
-
-
-class InterfaceImpl
-{
-public:
-  InterfaceImpl (InterfaceId iid, Interface *interface);
-  ~InterfaceImpl ();
-  void Ref (void);
-  void RefAll (InterfaceImpl *other);
-  void Unref (void);
-  void UnrefAll (void);
-  Interface *PeekQueryInterface (InterfaceId iid) const;
-  void DoDisposeAll (void);
-  void AddInterface (Interface * interface);
-  void AddSelfInterface (InterfaceId iid, Interface *interface);
-private:
-  typedef std::list<std::pair<InterfaceId,Interface *> > List;
-  uint32_t m_ref;
-  List m_list;
-  bool m_disposed;
-};
-
-InterfaceImpl::InterfaceImpl (InterfaceId iid, Interface * interface)
-  : m_ref (1),
-    m_disposed (false)
-{
-  NS_DEBUG ("new " << this << " ref=" << m_ref);
-  m_list.push_back (std::make_pair (iid, interface));
-}
-InterfaceImpl::~InterfaceImpl ()
-{
-  for (List::const_iterator i = m_list.begin ();
-       i != m_list.end (); i++)
-    {
-      i->second->UnrefInternal ();
-    }
-  m_list.clear ();
-}
-void 
-InterfaceImpl::Ref (void)
-{
-  m_ref++;
-  NS_DEBUG ("inc " << this << " ref=" << m_ref);
-}
-void 
-InterfaceImpl::RefAll (InterfaceImpl *other)
-{
-  m_ref += other->m_ref;
-  NS_DEBUG ("inc all " << this << " o=" << other->m_ref << " ref=" << m_ref);
-}
-void 
-InterfaceImpl::Unref (void)
-{
-  NS_ASSERT (m_ref > 0);
-  m_ref--;
-  NS_DEBUG ("dec " << this << " ref=" << m_ref);
-  if (m_ref == 0)
-    {
-      delete this;
-    }
-}
-void
-InterfaceImpl::UnrefAll (void)
-{
-  NS_ASSERT (m_ref > 0);
-  m_ref = 0;
-  delete this;
-  NS_DEBUG ("dec all " << this);
-}
-void
-InterfaceImpl::DoDisposeAll (void)
-{
-  NS_ASSERT (!m_disposed);
-  for (List::const_iterator i = m_list.begin ();
-       i != m_list.end (); i++)
-    {
-      Interface *interface = i->second;
-      interface->DoDispose ();
-    }
-  m_disposed = true;
-}
-Interface *
-InterfaceImpl::PeekQueryInterface (InterfaceId iid) const
-{
-  for (List::const_iterator i = m_list.begin ();
-       i != m_list.end (); i++)
-    {
-      if (i->first == iid)
-	{
-	  return i->second;
-	}
-    }
-  return 0;
-}
-void 
-InterfaceImpl::AddInterface (Interface *interface)
-{
-  for (List::const_iterator i = interface->m_impl->m_list.begin ();
-       i != interface->m_impl->m_list.end (); i++)
-    {
-      // XXX here, we should check that we have only one 
-      // instance of each interface
-      i->second->RefInternal ();
-      m_list.push_back (std::make_pair (i->first, i->second));
-    }
-}
-void 
-InterfaceImpl::AddSelfInterface (InterfaceId iid, Interface *interface)
-{
-  interface->RefInternal ();
-  m_list.push_back (std::make_pair (iid, interface));
-}
-
-
-Interface::Interface (InterfaceId iid)
-  : m_impl (new InterfaceImpl (iid, this)),
-    m_ref (1)
-{}
-Interface::~Interface ()
-{
-  m_impl = 0;
-  m_ref = 0xffffffff;
-}
-void 
-Interface::Ref (void) const
-{
-  m_impl->Ref ();
-}
-void 
-Interface::Unref (void) const
-{
-  m_impl->Unref ();
-}
-
-void 
-Interface::Dispose (void)
-{
-  m_impl->DoDisposeAll ();
-}
-
-void 
-Interface::DoDispose (void)
-{
-  // we do not do anything by default.
-}
-
-void
-Interface::RefInternal (void)
-{
-  m_ref++;
-}
-
-void
-Interface::UnrefInternal (void)
-{
-  NS_ASSERT (m_ref != 0);
-  m_ref--;
-  if (m_ref == 0)
-    {
-      delete this;
-    }
-}
-
-Ptr<Interface>
-Interface::DoQueryInterface (InterfaceId iid) const
-{
-  return m_impl->PeekQueryInterface (iid);
-}
-
-void 
-Interface::AddInterface (Ptr<Interface> interface)
-{
-  Interface *p = PeekPointer (interface);
-  m_impl->AddInterface (p);
-  m_impl->RefAll (p->m_impl);
-  p->m_impl->UnrefAll ();
-  p->m_impl = m_impl;
-}
-
-void
-Interface::AddSelfInterface (InterfaceId iid, Ptr<Interface> interface)
-{
-  m_impl->AddSelfInterface (iid, PeekPointer (interface));
-}
-
-
-}//namespace ns3
-
-#ifdef RUN_SELF_TESTS
-
-#include "test.h"
-
-namespace {
-
-class A : public ns3::Interface
-{
-public:
-  static const ns3::InterfaceId iid;
-  A ()
-    : Interface (A::iid)
-  {}
-};
-class B : public ns3::Interface
-{
-public:
-  static const ns3::InterfaceId iid;
-  B ()
-    : Interface (B::iid)
-  {}
-};
-class BaseA : public ns3::Interface
-{
-public:
-  static const ns3::InterfaceId iid;
-  BaseA ()
-    : Interface (BaseA::iid)
-  {}
-};
-class BaseB : public ns3::Interface
-{
-public:
-  static const ns3::InterfaceId iid;
-  BaseB ()
-    : Interface (BaseB::iid)
-  {}
-};
-class Base : public ns3::Interface
-{
-public:
-  static const ns3::InterfaceId iid;
-  Base ()
-    : Interface (Base::iid)
-  {}
-};
-class Derived : public Base
-{
-public:
-  static const ns3::InterfaceId iid;
-  Derived ()
-  {
-    AddSelfInterface (Derived::iid, this);
-  }
-};
-
-const ns3::InterfaceId A::iid ("A");
-const ns3::InterfaceId B::iid ("B");
-const ns3::InterfaceId BaseA::iid ("BaseA");
-const ns3::InterfaceId BaseB::iid ("BaseB");
-const ns3::InterfaceId Base::iid ("Base");
-const ns3::InterfaceId Derived::iid ("Derived");
-
-}//namespace
-
-
-namespace ns3 {
-
-class InterfaceTest : public Test
-{
-public:
-  InterfaceTest ();
-  virtual bool RunTests (void);
-};
-
-InterfaceTest::InterfaceTest ()
-  : Test ("Interface")
-{}
-bool 
-InterfaceTest::RunTests (void)
-{
-  bool ok = true;
-
-  //DerivedAB *derivedAB;
-
-
-  Ptr<A> a = MakeNewObject<A> ();
-
-  a = MakeNewObject<A> ();
-  Ptr<A> a1 = a->QueryInterface<A> (A::iid);
-  if (a1 == 0 || a1 != a)
-    {
-      ok = false;
-    }
-  a1 = a->QueryInterface<A> (A::iid);
-  if (a1 == 0 || a1 != a)
-    {
-      ok = false;
-    }
-
-  Ptr<B> b = MakeNewObject<B> ();
-  Ptr<B> b1 = b->QueryInterface<B> (B::iid);
-  if (b1 == 0 || b1 != b)
-    {
-      ok = false;
-    }
-  
-  a = MakeNewObject<A> ();
-  a->AddInterface (b);
-  b1 = b->QueryInterface<B> (B::iid);
-  if (b1 == 0 || b1 != b)
-    {
-      ok = false;
-    }
-  a1 = b->QueryInterface<A> (A::iid);
-  if (a1 == 0 || a1 != a)
-    {
-      ok = false;
-    }
-  a1 = a->QueryInterface<A> (A::iid);
-  if (a1 == 0 || a1 != a)
-    {
-      ok = false;
-    }
-  b1 = a->QueryInterface<B> (B::iid);
-  if (b1 == 0 || b1 != b)
-    {
-      ok = false;
-    }
-
-  Ptr<Derived> derived = MakeNewObject<Derived> ();
-  Ptr<Base> base = derived->QueryInterface<Base> (Base::iid);
-  if (base == 0)
-    {
-      ok = false;
-    }
-  Ptr<Derived> derived1 = base->QueryInterface<Derived> (Derived::iid);
-  if (derived1 == 0 || derived1 != derived)
-    {
-      ok = false;
-    }
-
-  // the following cannot work and it is on purpose
-  // delete derived;
-
-  return ok;
-}
-
-
-static InterfaceTest g_interface_test;
-
-}// namespace ns3
-
-#endif /* RUN_SELF_TESTS */
--- a/src/core/interface.h	Thu Jun 07 13:19:25 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,130 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef INTERFACE_H
-#define INTERFACE_H
-
-#include <string>
-#include "ptr.h"
-
-namespace ns3 {
-
-class InterfaceImpl;
-
-class InterfaceId
-{
-public:
-  InterfaceId (std::string name);
-  static InterfaceId LookupByName (std::string);
-private:
-  InterfaceId (uint32_t iid);
-  friend bool operator == (const InterfaceId &a, const InterfaceId &b);
-  uint32_t m_iid;
-};
-
-/**
- * \brief COM-like IUnknown
- *
- * This class should be used as a base class for every object which
- * wishes to provide a COM-like QueryInterface API. Multiple 
- * inheritance where this base class is at the top of the dreaded 
- * "diamond" shape is not allowed.
- */
-class Interface
-{
-public:
-  virtual ~Interface ();
-  void Ref (void) const;
-  void Unref (void) const;
-
-  /**
-   * \param iid the Interface id of the requested interface
-   */
-  template <typename T>
-  Ptr<T> QueryInterface (InterfaceId iid) const;
-
-  /**
-   * \param interface another interface
-   * 
-   * Aggregate together the two interfaces. After this call,
-   * the two interface objects are tied together: each of them
-   * will be able to perform QI on each other and their lifetimes
-   * will be found by the same reference count.
-   */
-  void AddInterface (Ptr<Interface> interface);
-
-  void Dispose (void);
-protected:
-  /**
-   * \param iid the Interface Id of the interface defined by a direct subclass
-   * of this base class
-   *
-   * If you are a direct subclass of this class, you _must_ register
-   * the name of your interface with this constructor.
-   */
-  Interface (InterfaceId iid);
-  /**
-   * \param iid the Interface id of the interface
-   * \param interface a pointer to the interface object
-   *
-   * If you are not a direct subclass of the ns3::Interface base class,
-   * and if you want to register yourself as another accessible interface
-   * (typically, your subclass has added API), you need to call
-   * this method to associate an interface id to your interface.
-   */
-  void AddSelfInterface (InterfaceId iid, Ptr<Interface> interface);
-protected:
-  /**
-   * Subclasses who want to handle the "dispose" event should
-   * override this method. They are also responsible for
-   * "chaining up" to their parent class' DoDispose method
-   * once they have done their own "dispose".
-   */
-  virtual void DoDispose (void);
-private:
-  friend class InterfaceImpl;
-  Interface ();
-  Ptr<Interface> DoQueryInterface (InterfaceId iid) const;
-  void RefInternal (void);
-  void UnrefInternal (void);
-  InterfaceImpl *m_impl;
-  uint32_t m_ref;
-};
-
-}//namespace ns3
-
-namespace ns3 {
-
-template <typename T>
-Ptr<T>
-Interface::QueryInterface (InterfaceId iid) const
-{
-  Ptr<Interface> found = DoQueryInterface (iid);
-  if (found != 0)
-    {
-      return Ptr<T> (dynamic_cast<T *> (PeekPointer (found)));
-    }
-  return 0;
-}
-
-
-}//namespace ns3
-
-#endif /* INTERFACE_H */
--- a/src/core/object.cc	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/core/object.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -1,7 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
+ * Copyright (c) 2007 INRIA, Gustavo Carneiro
  *
  * 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
@@ -16,63 +15,405 @@
  * 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>
+ * Authors: Gustavo Carneiro <gjcarneiro@gmail.com>,
+ *          Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
  */
 #include "object.h"
-#include "debug.h"
 #include "assert.h"
+#include "singleton.h"
+#include "uid-manager.h"
+#include <vector>
 
-NS_DEBUG_COMPONENT_DEFINE ("Object");
+namespace {
+
+class IidManager : public ns3::UidManager
+{};
+
+class IidTree
+{
+public:
+  void SetParent (uint16_t child, const uint16_t *parent);
+  uint16_t LookupParent (uint16_t child);
+private:
+  std::vector<const uint16_t *> m_parents;
+};
+
+void 
+IidTree::SetParent (uint16_t child, const uint16_t *parent)
+{
+  m_parents.resize (child+1);
+  m_parents[child] = parent;
+}
+uint16_t 
+IidTree::LookupParent (uint16_t child)
+{
+  NS_ASSERT (child < m_parents.size ());
+  return *(m_parents[child]);
+}
+
+} // anonymous namespace
 
 namespace ns3 {
 
+InterfaceId::InterfaceId (uint16_t iid)
+  : m_iid (iid)
+{}
+InterfaceId::~InterfaceId ()
+{}
+InterfaceId 
+InterfaceId::LookupByName (std::string name)
+{
+  uint32_t uid = Singleton<IidManager>::Get ()->LookupByName (name);
+  NS_ASSERT (uid != 0 && uid <= 0xffff);
+  return InterfaceId (uid);
+}
+InterfaceId 
+InterfaceId::LookupParent (InterfaceId iid)
+{
+  return Singleton<IidTree>::Get ()->LookupParent (iid.m_iid);
+}
+
+bool operator == (const InterfaceId &a, const InterfaceId &b)
+{
+  return a.m_iid == b.m_iid;
+}
+
+bool operator != (const InterfaceId &a, const InterfaceId &b)
+{
+  return a.m_iid != b.m_iid;
+}
+
+InterfaceId
+MakeInterfaceId (std::string name, const InterfaceId &parent)
+{
+  uint32_t uid = Singleton<IidManager>::Get ()->Allocate (name);
+  NS_ASSERT (uid <= 0xffff);
+  InterfaceId iid = uid;
+  Singleton<IidTree>::Get ()->SetParent (iid.m_iid, &parent.m_iid);
+  return iid;
+}
+
+InterfaceId
+MakeObjectInterfaceId (void)
+{
+  InterfaceId iid = Singleton<IidManager>::Get ()->Allocate ("Object");
+  Singleton<IidTree>::Get ()->SetParent (iid.m_iid, &iid.m_iid);
+  return iid;
+}
+
+
+const InterfaceId Object::iid = MakeObjectInterfaceId ();
+
+
 Object::Object ()
   : m_count (1),
-    m_disposed (false)
+    m_iid (Object::iid),
+    m_disposed (false),
+    m_next (this)
+{}
+Object::~Object () 
+{
+  m_next = 0;
+}
+Ptr<Object>
+Object::DoQueryInterface (InterfaceId iid) const
 {
-  NS_DEBUG ("Object::Object: m_count=0");
+  NS_ASSERT (Check ());
+  const Object *currentObject = this;
+  do {
+    NS_ASSERT (currentObject != 0);
+    InterfaceId cur = currentObject->m_iid;
+    while (cur != iid && cur != Object::iid)
+      {
+        cur = InterfaceId::LookupParent (cur);
+      }
+    if (cur == iid)
+      {
+        return const_cast<Object *> (currentObject);
+      }
+    currentObject = currentObject->m_next;
+  } while (currentObject != this);
+  return 0;
+}
+void 
+Object::Dispose (void)
+{
+  Object *current = this;
+  do {
+    NS_ASSERT (current != 0);
+    NS_ASSERT (!current->m_disposed);
+    current->DoDispose ();
+    current->m_disposed = true;
+    current = current->m_next;
+  } while (current != this);
 }
 
-Object::~Object ()
-{}
-
 void 
-Object::Ref (void) const
+Object::AddInterface (Ptr<Object> o)
 {
-  m_count++;
-  NS_DEBUG("Object::Ref (): this == 0x" << this << " m_count=" << m_count);
+  NS_ASSERT (!m_disposed);
+  NS_ASSERT (!o->m_disposed);
+  NS_ASSERT (Check ());
+  NS_ASSERT (o->Check ());
+  Object *other = PeekPointer (o);
+  Object *next = m_next;
+  m_next = other->m_next;
+  other->m_next = next;
+  NS_ASSERT (Check ());
+  NS_ASSERT (o->Check ());
 }
 
 void 
-Object::Unref (void) const
+Object::SetInterfaceId (InterfaceId iid)
 {
-  NS_ASSERT (m_count > 0);
-  m_count--;
-  NS_DEBUG("Object::Unref (): this == 0x" << this << " m_count=" << m_count);
+  NS_ASSERT (Check ());
+  m_iid = iid;
+}
 
-  if (m_count == 0)
-    {
-      NS_DEBUG("Object::Unref (): delete");
-      delete this;
-    }
+void
+Object::DoDispose (void)
+{
+  NS_ASSERT (!m_disposed);
 }
 
 bool 
-Object::IsSingle (void) const
+Object::Check (void) const
 {
-  NS_DEBUG("Object::IsSingle (): m_count == " << m_count);
-  return m_count == 1;
+  return (m_count > 0);
 }
 
 void
-Object::Dispose (void)
+Object::MaybeDelete (void) const
 {
-  NS_ASSERT (!m_disposed);
-  DoDispose ();
+  // First, check if any of the attached
+  // Object has a non-zero count.
+  const Object *current = this;
+  do {
+    NS_ASSERT (current != 0);
+    if (current->m_count != 0)
+      {
+        return;
+      }
+    current = current->m_next;
+  } while (current != this);
+
+  // all attached objects have a zero count so, 
+  // we can delete all attached objects.
+  current = this;
+  const Object *end = this;
+  do {
+    NS_ASSERT (current != 0);
+    Object *next = current->m_next;
+    delete current;
+    current = next;
+  } while (current != end);
 }
 
-void 
-Object::DoDispose (void)
+} // namespace ns3
+
+
+#ifdef RUN_SELF_TESTS
+
+#include "test.h"
+
+namespace {
+
+class BaseA : public ns3::Object
+{
+public:
+  static const ns3::InterfaceId iid;
+  BaseA ()
+  {
+    SetInterfaceId (BaseA::iid);
+  }
+  virtual void Dispose (void) {}
+};
+
+class DerivedA : public BaseA
+{
+public:
+  static const ns3::InterfaceId iid;
+  DerivedA (int v)
+  {
+    SetInterfaceId (DerivedA::iid);
+  }
+  virtual void Dispose (void) {
+    BaseA::Dispose ();
+  }
+};
+
+const ns3::InterfaceId BaseA::iid = 
+  ns3::MakeInterfaceId ("BaseA", Object::iid);
+const ns3::InterfaceId DerivedA::iid = 
+  ns3::MakeInterfaceId ("DerivedA", BaseA::iid);;
+
+class BaseB : public ns3::Object
+{
+public:
+  static const ns3::InterfaceId iid;
+  BaseB ()
+  {
+    SetInterfaceId (BaseB::iid);
+  }
+  virtual void Dispose (void) {}
+};
+
+class DerivedB : public BaseB
+{
+public:
+  static const ns3::InterfaceId iid;
+  DerivedB (int v)
+  {
+    SetInterfaceId (DerivedB::iid);
+  }
+  virtual void Dispose (void) {
+    BaseB::Dispose ();
+  }
+};
+
+const ns3::InterfaceId BaseB::iid = 
+  ns3::MakeInterfaceId ("BaseB", Object::iid);
+const ns3::InterfaceId DerivedB::iid = 
+  ns3::MakeInterfaceId ("DerivedB", BaseB::iid);;
+
+} // namespace anonymous
+
+namespace ns3 {
+
+class ObjectTest : public Test
+{
+public:
+  ObjectTest ();
+  virtual bool RunTests (void);
+};
+
+ObjectTest::ObjectTest ()
+  : Test ("Object")
 {}
+bool 
+ObjectTest::RunTests (void)
+{
+  bool ok = true;
 
-}//namespace ns3
+  Ptr<BaseA> baseA = Create<BaseA> ();
+  if (baseA->QueryInterface<BaseA> (BaseA::iid) != baseA)
+    {
+      ok = false;
+    }
+  if (baseA->QueryInterface<BaseA> (DerivedA::iid) != 0)
+    {
+      ok = false;
+    }
+  if (baseA->QueryInterface<DerivedA> (DerivedA::iid) != 0)
+    {
+      ok = false;
+    }
+  baseA = Create<DerivedA> (10);
+  if (baseA->QueryInterface<BaseA> (BaseA::iid) != baseA)
+    {
+      ok = false;
+    }
+  if (baseA->QueryInterface<BaseA> (DerivedA::iid) != baseA)
+    {
+      ok = false;
+    }
+  if (baseA->QueryInterface<DerivedA> (DerivedA::iid) == 0)
+    {
+      ok = false;
+    }
+
+  baseA = Create<BaseA> ();
+  Ptr<BaseB> baseB = Create<BaseB> ();
+  Ptr<BaseB> baseBCopy = baseB;
+  baseA->AddInterface (baseB);
+  if (baseA->QueryInterface<BaseA> (BaseA::iid) == 0)
+    {
+      ok = false;
+    }
+  if (baseA->QueryInterface<DerivedA> (DerivedA::iid) != 0)
+    {
+      ok = false;
+    }
+  if (baseA->QueryInterface<BaseB> (BaseB::iid) == 0)
+    {
+      ok = false;
+    }
+  if (baseA->QueryInterface<DerivedB> (DerivedB::iid) != 0)
+    {
+      ok = false;
+    }
+  if (baseB->QueryInterface<BaseB> (BaseB::iid) == 0)
+    {
+      ok = false;
+    }
+  if (baseB->QueryInterface<DerivedB> (DerivedB::iid) != 0)
+    {
+      ok = false;
+    }
+  if (baseB->QueryInterface<BaseA> (BaseA::iid) == 0)
+    {
+      ok = false;
+    }
+  if (baseB->QueryInterface<DerivedA> (DerivedA::iid) != 0)
+    {
+      ok = false;
+    }
+  if (baseBCopy->QueryInterface<BaseA> (BaseA::iid) == 0)
+    {
+      ok = false;
+    }
+
+  baseA = Create<DerivedA> (1);
+  baseB = Create<DerivedB> (1);
+  baseBCopy = baseB;
+  baseA->AddInterface (baseB);
+  if (baseA->QueryInterface<DerivedB> (DerivedB::iid) == 0)
+    {
+      ok = false;
+    }
+  if (baseA->QueryInterface<BaseB> (BaseB::iid) == 0)
+    {
+      ok = false;
+    }
+  if (baseB->QueryInterface<DerivedA> (DerivedA::iid) == 0)
+    {
+      ok = false;
+    }
+  if (baseB->QueryInterface<BaseA> (BaseA::iid) == 0)
+    {
+      ok = false;
+    }
+  if (baseBCopy->QueryInterface<DerivedA> (DerivedA::iid) == 0)
+    {
+      ok = false;
+    }
+  if (baseBCopy->QueryInterface<BaseA> (BaseA::iid) == 0)
+    {
+      ok = false;
+    }
+  if (baseB->QueryInterface<DerivedB> (DerivedB::iid) == 0)
+    {
+      ok = false;
+    }
+  if (baseB->QueryInterface<BaseB> (BaseB::iid) == 0)
+    {
+      ok = false;
+    }
+
+  baseA = Create<BaseA> ();
+  baseB = Create<BaseB> ();
+  baseA->AddInterface (baseB);
+  baseA = 0;
+  baseA = baseB->QueryInterface<BaseA> (BaseA::iid);
+
+  return ok;
+}
+
+static ObjectTest g_interfaceObjectTests;
+
+
+} // namespace ns3
+
+#endif /* RUN_SELF_TESTS */
+
+
--- a/src/core/object.h	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/core/object.h	Tue Jun 12 22:54:10 2007 +0200
@@ -1,7 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
+ * Copyright (c) 2007 INRIA, Gustavo Carneiro
  *
  * 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
@@ -16,52 +15,180 @@
  * 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>
+ * Authors: Gustavo Carneiro <gjcarneiro@gmail.com>,
+ *          Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
  */
 #ifndef OBJECT_H
 #define OBJECT_H
 
 #include <stdint.h>
+#include <string>
+#include "ptr.h"
 
 namespace ns3 {
 
 /**
- * \brief Base class that supports reference counting for memory management
+ * \brief a unique identifier for an interface.
  *
- * Many objects in the system derive from this class in order to use its
- * reference counting implementation.
+ * Instances of this class can be created only through
+ * calls to ns3::MakeInterfaceId.
+ *
+ * Note: This class is quite similar to COM's UUIDs.
  */
-class Object 
+class InterfaceId
 {
 public:
   /**
-   * \brief Constructor
+   * \param name the name of the requested interface
+   * \returns the unique id associated with the requested
+   *          name. 
+   *
+   * This method cannot fail: it will crash if the input 
+   * name is not a valid interface name.
+   */
+  static InterfaceId LookupByName (std::string name);
+  /**
+   * \param iid a unique id 
+   * \returns the parent of the requested id, as registered
+   *          by ns3::MakeInterfaceId.
    *
-   * Creates an object with a single reference count
+   * This method cannot fail: it will crash if the input
+   * id is not a valid interface id.
    */
+  static InterfaceId LookupParent (InterfaceId iid);
+  ~InterfaceId ();
+private:
+  InterfaceId (uint16_t iid);
+  friend InterfaceId MakeInterfaceId (std::string name, const InterfaceId &parent);
+  friend InterfaceId MakeObjectInterfaceId (void);
+  friend bool operator == (const InterfaceId &a, const InterfaceId &b);
+  friend bool operator != (const InterfaceId &a, const InterfaceId &b);
+  uint16_t m_iid;
+};
+
+/**
+ * \param name of the new InterfaceId to create.
+ * \param parent the "parent" of the InterfaceId to create.
+ * \returns a new InterfaceId
+ * \relates InterfaceId
+ *
+ * Every InterfaceId is a child of another InterfaceId. The
+ * top-most InterfaceId is Object::iid and its parent is 
+ * itself.
+ */
+InterfaceId
+MakeInterfaceId (std::string name, const InterfaceId &parent);
+
+/**
+ * \brief a base class which provides memory management and object aggregation
+ *
+ * Note: This base class is quite similar in spirit to IUnknown in COM or
+ * BonoboObject in Bonobo: it provides three main methods: Ref, Unref and
+ * QueryInterface.
+ */
+class Object
+{
+public:
+  static const InterfaceId iid;
+
   Object ();
   virtual ~Object ();
   /**
-   * \brief Increments the reference count of this object
+   * Increment the reference count. This method should not be called
+   * by user code. Object instances are expected to be used in conjunction
+   * of the Ptr template which would make calling Ref unecessary and 
+   * dangerous.
    */
-  void Ref (void) const;
+  inline void Ref (void) const;
   /**
-   * \brief Decrements the reference count of this object
+   * Decrement the reference count. This method should not be called
+   * by user code. Object instances are expected to be used in conjunction
+   * of the Ptr template which would make calling Ref unecessary and 
+   * dangerous.
+   */
+  inline void Unref (void) const;
+  /**
+   * \param iid the interface requested
+   * \returns a pointer to the requested interface or zero if it could not be found.
+   * 
    */
-  void Unref (void) const;
+  template <typename T>
+  Ptr<T> QueryInterface (InterfaceId iid) const;
+  /**
+   * Run the DoDispose methods of this object and all the
+   * objects aggregated to it.
+   * After calling this method, the object is expected to be
+   * totally unusable except for the Ref and Unref methods.
+   * It is an error to call Dispose twice on the same object 
+   * instance
+   */
+  void Dispose (void);
   /**
-   * \return true if there is only a single reference to this object anywhere
-   * in the system; false otherwise.
+   * \param other another object pointer
+   *
+   * This method aggregates the two objects together: after this
+   * method returns, it becomes possible to call QueryInterface
+   * on one to get the other, and vice-versa. 
    */
-  bool IsSingle (void) const;
-  void Dispose (void);
+  void AddInterface (Ptr<Object> other);
 protected:
+  /**
+   * \param iid an InterfaceId
+   *
+   * Every subclass which defines a new InterfaceId for itself
+   * should register this InterfaceId by calling this method
+   * from its constructor.
+   */
+  void SetInterfaceId (InterfaceId iid);
+  /**
+   * This method is called by Object::Dispose.
+   * Subclasses are expected to override this method and chain
+   * up to their parent's implementation once they are done.
+   */
   virtual void DoDispose (void);
 private:
+  Ptr<Object> DoQueryInterface (InterfaceId iid) const;
+  bool Check (void) const;
+  void MaybeDelete (void) const;
   mutable uint32_t m_count;
+  InterfaceId m_iid;
   bool m_disposed;
+  Object *m_next;
 };
 
-}//namespace ns3
+} // namespace ns3
+
+namespace ns3 {
+
+void
+Object::Ref (void) const
+{
+  m_count++;
+}
+void
+Object::Unref (void) const
+{
+  NS_ASSERT (Check ());
+  m_count--;
+  if (m_count == 0)
+    {
+      MaybeDelete ();
+    }
+}
+
+template <typename T>
+Ptr<T> 
+Object::QueryInterface (InterfaceId iid) const
+{
+  Ptr<Object> found = DoQueryInterface (iid);
+  if (found != 0)
+    {
+      return Ptr<T> (dynamic_cast<T *> (PeekPointer (found)));
+    }
+  return 0;
+}
+
+} // namespace ns3
 
 #endif /* OBJECT_H */
+
--- a/src/core/ptr.cc	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/core/ptr.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -93,7 +93,7 @@
   Callback<void> cb = MakeCallback (&PtrTest::DestroyNotify, this);
   m_nDestroyed = false;
   {
-    Ptr<NoCount> p = MakeNewObject<NoCount> (cb);
+    Ptr<NoCount> p = Create<NoCount> (cb);
   }
   if (m_nDestroyed != 1)
     {
@@ -103,7 +103,7 @@
   m_nDestroyed = 0;
   {
     Ptr<NoCount> p;
-    p = MakeNewObject<NoCount> (cb);
+    p = Create<NoCount> (cb);
     p = p;
   }
   if (m_nDestroyed != 1)
@@ -114,7 +114,7 @@
   m_nDestroyed = 0;
   {
     Ptr<NoCount> p1;
-    p1 = MakeNewObject<NoCount> (cb);
+    p1 = Create<NoCount> (cb);
     Ptr<NoCount> p2 = p1;
   }
   if (m_nDestroyed != 1)
@@ -125,7 +125,7 @@
   m_nDestroyed = 0;
   {
     Ptr<NoCount> p1;
-    p1 = MakeNewObject<NoCount> (cb);
+    p1 = Create<NoCount> (cb);
     Ptr<NoCount> p2;
     p2 = p1;
   }
@@ -137,8 +137,8 @@
   m_nDestroyed = 0;
   {
     Ptr<NoCount> p1;
-    p1 = MakeNewObject<NoCount> (cb);
-    Ptr<NoCount> p2 = MakeNewObject<NoCount> (cb);
+    p1 = Create<NoCount> (cb);
+    Ptr<NoCount> p2 = Create<NoCount> (cb);
     p2 = p1;
   }
   if (m_nDestroyed != 2)
@@ -149,9 +149,9 @@
   m_nDestroyed = 0;
   {
     Ptr<NoCount> p1;
-    p1 = MakeNewObject<NoCount> (cb);
+    p1 = Create<NoCount> (cb);
     Ptr<NoCount> p2;
-    p2 = MakeNewObject<NoCount> (cb);
+    p2 = Create<NoCount> (cb);
     p2 = p1;
   }
   if (m_nDestroyed != 2)
@@ -162,8 +162,8 @@
   m_nDestroyed = 0;
   {
     Ptr<NoCount> p1;
-    p1 = MakeNewObject<NoCount> (cb);
-    p1 = MakeNewObject<NoCount> (cb);
+    p1 = Create<NoCount> (cb);
+    p1 = Create<NoCount> (cb);
   }
   if (m_nDestroyed != 2)
     {
@@ -175,8 +175,8 @@
     Ptr<NoCount> p1;
     {
       Ptr<NoCount> p2;
-      p1 = MakeNewObject<NoCount> (cb);
-      p2 = MakeNewObject<NoCount> (cb);
+      p1 = Create<NoCount> (cb);
+      p2 = Create<NoCount> (cb);
       p2 = p1;
     }
     if (m_nDestroyed != 1)
@@ -194,8 +194,8 @@
     Ptr<NoCount> p1;
     {
       Ptr<NoCount> p2;
-      p1 = MakeNewObject<NoCount> (cb);
-      p2 = MakeNewObject<NoCount> (cb);
+      p1 = Create<NoCount> (cb);
+      p2 = Create<NoCount> (cb);
       p2 = CallTest (p1);
     }
     if (m_nDestroyed != 1)
@@ -237,7 +237,7 @@
   {
     NoCount *raw;
     {
-      Ptr<NoCount> p = MakeNewObject<NoCount> (cb);
+      Ptr<NoCount> p = Create<NoCount> (cb);
       {
         Ptr<NoCount const> p1 = p;
       }
@@ -254,7 +254,7 @@
 
   m_nDestroyed = 0;
   {
-    Ptr<NoCount> p = MakeNewObject<NoCount> (cb);
+    Ptr<NoCount> p = Create<NoCount> (cb);
     const NoCount *v1 = PeekPointer (p);
     NoCount *v2 = PeekPointer (p);
     v1->Nothing ();
@@ -266,8 +266,8 @@
     }
 
   {
-    Ptr<Object> p0 = MakeNewObject<NoCount> (cb);
-    Ptr<NoCount> p1 = MakeNewObject<NoCount> (cb);
+    Ptr<Object> p0 = Create<NoCount> (cb);
+    Ptr<NoCount> p1 = Create<NoCount> (cb);
     if (p0 == p1)
       {
         ok = false;
@@ -282,12 +282,12 @@
   }
 
   {
-    Ptr<NoCount> p = MakeNewObject<NoCount> (cb);
+    Ptr<NoCount> p = Create<NoCount> (cb);
     Callback<void> callback = MakeCallback (&NoCount::Nothing, p);
     callback ();
   }
   {
-    Ptr<const NoCount> p = MakeNewObject<NoCount> (cb);
+    Ptr<const NoCount> p = Create<NoCount> (cb);
     Callback<void> callback = MakeCallback (&NoCount::Nothing, p);
     callback ();
   }
@@ -295,7 +295,7 @@
 #if 0
   // as expected, fails compilation.
   {
-    Ptr<const Object> p = MakeNewObject<NoCount> (cb);
+    Ptr<const Object> p = Create<NoCount> (cb);
     Callback<void> callback = MakeCallback (&NoCount::Nothing, p);
   }
 #endif
--- a/src/core/ptr.h	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/core/ptr.h	Tue Jun 12 22:54:10 2007 +0200
@@ -43,7 +43,7 @@
  * smart pointer with the GetPointer and PeekPointer methods.
  *
  * If you want to store a newed object into a smart pointer,
- * we recommend you to use the MakeNewObject template functions
+ * we recommend you to use the Create template functions
  * to create the object and store it in a smart pointer to avoid
  * memory leaks. These functions are really small conveniance
  * functions and their goal is just is save you a small
@@ -98,28 +98,28 @@
 };
 
 template <typename T>
-Ptr<T> MakeNewObject (void);
+Ptr<T> Create (void);
 
 template <typename T, typename T1>
-Ptr<T> MakeNewObject (T1 a1);
+Ptr<T> Create (T1 a1);
 
 template <typename T, typename T1, typename T2>
-Ptr<T> MakeNewObject (T1 a1, T2 a2);
+Ptr<T> Create (T1 a1, T2 a2);
 
 template <typename T, typename T1, typename T2, typename T3>
-Ptr<T> MakeNewObject (T1 a1, T2 a2, T3 a3);
+Ptr<T> Create (T1 a1, T2 a2, T3 a3);
 
 template <typename T, typename T1, typename T2, typename T3, typename T4>
-Ptr<T> MakeNewObject (T1 a1, T2 a2, T3 a3, T4 a4);
+Ptr<T> Create (T1 a1, T2 a2, T3 a3, T4 a4);
 
 template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
-Ptr<T> MakeNewObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
+Ptr<T> Create (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
 
 template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
-Ptr<T> MakeNewObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6);
+Ptr<T> Create (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6);
 
 template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
-Ptr<T> MakeNewObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7);
+Ptr<T> Create (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7);
 
 /**
  * \relates Ptr
@@ -206,7 +206,7 @@
    ************************************************/
 
 template <typename T>
-Ptr<T> MakeNewObject (void)
+Ptr<T> Create (void)
 {
   T *obj = new T ();
   Ptr<T> p = obj;
@@ -215,7 +215,7 @@
 }
 
 template <typename T, typename T1>
-Ptr<T> MakeNewObject (T1 a1)
+Ptr<T> Create (T1 a1)
 {
   T *obj = new T (a1);
   Ptr<T> p = obj;
@@ -224,7 +224,7 @@
 }
 
 template <typename T, typename T1, typename T2>
-Ptr<T> MakeNewObject (T1 a1, T2 a2)
+Ptr<T> Create (T1 a1, T2 a2)
 {
   T *obj = new T (a1, a2);
   Ptr<T> p = obj;
@@ -233,7 +233,7 @@
 }
 
 template <typename T, typename T1, typename T2, typename T3>
-Ptr<T> MakeNewObject (T1 a1, T2 a2, T3 a3)
+Ptr<T> Create (T1 a1, T2 a2, T3 a3)
 {
   T *obj = new T (a1, a2, a3);
   Ptr<T> p = obj;
@@ -242,7 +242,7 @@
 }
 
 template <typename T, typename T1, typename T2, typename T3, typename T4>
-Ptr<T> MakeNewObject (T1 a1, T2 a2, T3 a3, T4 a4)
+Ptr<T> Create (T1 a1, T2 a2, T3 a3, T4 a4)
 {
   T *obj = new T (a1, a2, a3, a4);
   Ptr<T> p = obj;
@@ -251,7 +251,7 @@
 }
 
 template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
-Ptr<T> MakeNewObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
+Ptr<T> Create (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
 {
   T *obj = new T (a1, a2, a3, a4, a5);
   Ptr<T> p = obj;
@@ -260,7 +260,7 @@
 }
 
 template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
-Ptr<T> MakeNewObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6)
+Ptr<T> Create (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6)
 {
   T *obj = new T (a1, a2, a3, a4, a5, a6);
   Ptr<T> p = obj;
@@ -269,7 +269,7 @@
 }
 
 template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
-Ptr<T> MakeNewObject (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7)
+Ptr<T> Create (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7)
 {
   T *obj = new T (a1, a2, a3, a4, a5, a6, a7);
   Ptr<T> p = obj;
--- a/src/core/uid-manager.cc	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/core/uid-manager.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -58,7 +58,7 @@
 UidManager::LookupByUid (uint32_t uid)
 {
   NS_ASSERT (uid > 0);
-  NS_ASSERT (m_nameList.size () > uid);
+  NS_ASSERT (m_nameList.size () >= uid);
   return m_nameList[uid-1];
 }
 
--- a/src/core/wscript	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/core/wscript	Tue Jun 12 22:54:10 2007 +0200
@@ -32,7 +32,6 @@
         'test.cc',
         'random-variable.cc',
         'rng-stream.cc',
-        'interface.cc',
         'uid-manager.cc',
         'default-value.cc',
         'command-line.cc',
@@ -52,6 +51,7 @@
     headers = bld.create_obj('ns3header')
     headers.source = [
         'system-wall-clock-ms.h',
+        'empty.h',
         'callback.h',
         'ptr.h',
         'object.h',
@@ -61,7 +61,6 @@
         'test.h',
         'random-variable.h',
         'rng-stream.h',
-        'interface.h',
         'default-value.h',
         'command-line.h',
         'type-name.h',
--- a/src/devices/p2p/p2p-net-device.cc	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/devices/p2p/p2p-net-device.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -32,7 +32,7 @@
 
 namespace ns3 {
 
-PointToPointNetDevice::PointToPointNetDevice (Ptr<INode> node) 
+PointToPointNetDevice::PointToPointNetDevice (Ptr<Node> node) 
 : 
   NetDevice(node, MacAddress ("00:00:00:00:00:00")), 
   m_txMachineState (READY),
--- a/src/devices/p2p/p2p-net-device.h	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/devices/p2p/p2p-net-device.h	Tue Jun 12 22:54:10 2007 +0200
@@ -23,7 +23,7 @@
 
 #include <string.h>
 #include "ns3/mac-address.h"
-#include "ns3/i-node.h"
+#include "ns3/node.h"
 #include "ns3/net-device.h"
 #include "ns3/callback.h"
 #include "ns3/packet.h"
@@ -74,13 +74,13 @@
    * Construct a PointToPointNetDevice
    *
    * This is the constructor for the PointToPointNetDevice.  It takes as a
-   * parameter the INode to which this device is connected.  Ownership of the
-   * INode pointer is not implied and the node must not be deleded.
+   * 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 INode to which this device is connected.
+   * @param node the Node to which this device is connected.
    */
-  PointToPointNetDevice (Ptr<INode> node);
+  PointToPointNetDevice (Ptr<Node> node);
   /**
    * Copy Construct a PointToPointNetDevice
    *
--- a/src/devices/p2p/p2p-topology.cc	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/devices/p2p/p2p-topology.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -29,7 +29,7 @@
 #include "ns3/nstime.h"
 #include "ns3/internet-node.h"
 #include "ns3/ipv4-address.h"
-#include "ns3/i-ipv4.h"
+#include "ns3/ipv4.h"
 #include "ns3/queue.h"
 
 #include "p2p-channel.h"
@@ -40,20 +40,20 @@
 
 Ptr<PointToPointChannel>
 PointToPointTopology::AddPointToPointLink(
-  Ptr<INode> n1,
-  Ptr<INode> n2,
+  Ptr<Node> n1,
+  Ptr<Node> n2,
   const DataRate& bps,
   const Time& delay)
 {
-  Ptr<PointToPointChannel> channel = MakeNewObject<PointToPointChannel> (bps, delay);
+  Ptr<PointToPointChannel> channel = Create<PointToPointChannel> (bps, delay);
 
-  Ptr<PointToPointNetDevice> net1 = MakeNewObject<PointToPointNetDevice> (n1);
+  Ptr<PointToPointNetDevice> net1 = Create<PointToPointNetDevice> (n1);
 
   Ptr<Queue> q = Queue::CreateDefault ();
   net1->AddQueue(q);
   net1->Attach (channel);
   
-  Ptr<PointToPointNetDevice> net2 = MakeNewObject<PointToPointNetDevice> (n2);
+  Ptr<PointToPointNetDevice> net2 = Create<PointToPointNetDevice> (n2);
 
   q = Queue::CreateDefault ();
   net2->AddQueue(q);
@@ -65,8 +65,8 @@
 void
 PointToPointTopology::AddIpv4Addresses(
   Ptr<const PointToPointChannel> chan,
-  Ptr<INode> n1, const Ipv4Address& addr1,
-  Ptr<INode> n2, const Ipv4Address& addr2)
+  Ptr<Node> n1, const Ipv4Address& addr1,
+  Ptr<Node> n2, const Ipv4Address& addr2)
 {
 
   // Duplex link is assumed to be subnetted as a /30
@@ -79,22 +79,22 @@
   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->GetINode ()->GetId () == n2->GetId () ) && 
-       (nd2->GetINode ()->GetId () == n1->GetId () ) )
+  if ( (nd1->GetNode ()->GetId () == n2->GetId () ) && 
+       (nd2->GetNode ()->GetId () == n1->GetId () ) )
     {
       std::swap(nd1, nd2);
     }
-  NS_ASSERT (nd1->GetINode ()->GetId () == n1->GetId ());
-  NS_ASSERT (nd2->GetINode ()->GetId () == n2->GetId ());
+  NS_ASSERT (nd1->GetNode ()->GetId () == n1->GetId ());
+  NS_ASSERT (nd2->GetNode ()->GetId () == n2->GetId ());
   
-  Ptr<IIpv4> ip1 = n1->QueryInterface<IIpv4> (IIpv4::iid);
+  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<IIpv4> ip2 = n2->QueryInterface<IIpv4> (IIpv4::iid);
+  Ptr<Ipv4> ip2 = n2->QueryInterface<Ipv4> (Ipv4::iid);
   uint32_t index2 = ip2->AddInterface (nd2);
 
   ip2->SetAddress (index2, addr2);
@@ -105,38 +105,38 @@
 
 void
 PointToPointTopology::AddIpv4Routes (
-  Ptr<INode> n1, Ptr<INode> n2, Ptr<const PointToPointChannel> chan)
+  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 INode owning one of the two NetDevices
+  // Assert that n1 is the Node owning one of the two NetDevices
   // and make sure that nd1 corresponds to it
-  if (nd1->GetINode ()->GetId () == n1->GetId ())
+  if (nd1->GetNode ()->GetId () == n1->GetId ())
     {
       ; // Do nothing
     }
-  else if (nd2->GetINode ()->GetId () == n1->GetId ())
+  else if (nd2->GetNode ()->GetId () == n1->GetId ())
     {
       std::swap(nd1, nd2);
     }
   else
     {
-      NS_FATAL_ERROR("P2PTopo: INode does not contain an interface on Channel");
+      NS_FATAL_ERROR("P2PTopo: Node does not contain an interface on Channel");
     }
 
-   // Assert that n2 is the INode owning one of the two NetDevices
+   // Assert that n2 is the Node owning one of the two NetDevices
    // and make sure that nd2 corresponds to it
-  if (nd2->GetINode ()->GetId () != n2->GetId ())
+  if (nd2->GetNode ()->GetId () != n2->GetId ())
     {
-      NS_FATAL_ERROR("P2PTopo: INode does not contain an interface on Channel");
+      NS_FATAL_ERROR("P2PTopo: Node does not contain an interface on Channel");
     }
 
   // Assert that both are Ipv4 nodes
-  Ptr<IIpv4> ip1 = nd1->GetINode ()->QueryInterface<IIpv4> (IIpv4::iid);
-  Ptr<IIpv4> ip2 = nd2->GetINode ()->QueryInterface<IIpv4> (IIpv4::iid);
+  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
--- a/src/devices/p2p/p2p-topology.h	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/devices/p2p/p2p-topology.h	Tue Jun 12 22:54:10 2007 +0200
@@ -30,7 +30,7 @@
 namespace ns3 {
 
 class PointToPointChannel;
-class INode;
+class Node;
 class IPAddr;
 class DataRate;
 class Queue;
@@ -42,8 +42,8 @@
 class PointToPointTopology {
 public:
   /** 
-   * \param n1 INode
-   * \param n2 INode
+   * \param n1 Node
+   * \param n2 Node
    * \param dataRate Maximum transmission link rate 
    * \param delay one-way propagation delay 
    * \return Pointer to the underlying PointToPointChannel
@@ -53,13 +53,13 @@
    * PointToPointChannel.  
    */
   static Ptr<PointToPointChannel> AddPointToPointLink(
-    Ptr<INode> n1, Ptr<INode> n2, const DataRate& dataRate, const Time& delay);
+    Ptr<Node> n1, Ptr<Node> n2, const DataRate& dataRate, const Time& delay);
 
   /** 
    * \param chan PointToPointChannel to use
-   * \param n1 INode
+   * \param n1 Node
    * \param addr1 Ipv4 Address for n1
-   * \param n2 INode
+   * \param n2 Node
    * \param addr2 Ipv4 Address for n2
    * 
    * Add Ipv4Addresses to the Ipv4 interfaces associated with the 
@@ -67,18 +67,18 @@
    */
   static void AddIpv4Addresses(
     Ptr<const PointToPointChannel> chan,
-    Ptr<INode> n1, const Ipv4Address& addr1,
-    Ptr<INode> n2, const Ipv4Address& addr2);
+    Ptr<Node> n1, const Ipv4Address& addr1,
+    Ptr<Node> n2, const Ipv4Address& addr2);
 
   /**
    * \param channel PointToPointChannel to use
-   * \param n1 INode
-   * \param n2 INode
+   * \param n1 Node
+   * \param n2 Node
    * 
-   * For the given PointToPointChannel, for each INode, add an 
+   * For the given PointToPointChannel, for each Node, add an 
    * IPv4 host route to the IPv4 address of the peer node.  
    */
-  static void AddIpv4Routes (Ptr<INode> n1, Ptr<INode> n2, Ptr<const PointToPointChannel> channel);
+  static void AddIpv4Routes (Ptr<Node> n1, Ptr<Node> n2, Ptr<const PointToPointChannel> channel);
 };
 
 } // namespace ns3
--- a/src/internet-node/arp-ipv4-interface.cc	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/internet-node/arp-ipv4-interface.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -22,16 +22,16 @@
 
 #include "ns3/packet.h"
 #include "ns3/composite-trace-resolver.h"
-#include "ns3/i-node.h"
+#include "ns3/node.h"
 #include "ns3/net-device.h"
 
 #include "arp-ipv4-interface.h"
-#include "i-arp-private.h"
-#include "ipv4.h"
+#include "arp-private.h"
+#include "ipv4-l3-protocol.h"
 
 namespace ns3 {
 
-ArpIpv4Interface::ArpIpv4Interface (Ptr<INode> node, Ptr<NetDevice> device)
+ArpIpv4Interface::ArpIpv4Interface (Ptr<Node> node, Ptr<NetDevice> device)
   : Ipv4Interface (device),
     m_node (node)
 {}
@@ -58,17 +58,17 @@
   NS_ASSERT (GetDevice () != 0);
   if (GetDevice ()->NeedsArp ())
     {
-      Ptr<IArpPrivate> arp = m_node->QueryInterface<IArpPrivate> (IArpPrivate::iid);
+      Ptr<ArpPrivate> arp = m_node->QueryInterface<ArpPrivate> (ArpPrivate::iid);
       MacAddress hardwareDestination;
       bool found = arp->Lookup (p, dest, GetDevice (), &hardwareDestination);
       if (found)
         {
-          GetDevice ()->Send (p, hardwareDestination, Ipv4::PROT_NUMBER);
+          GetDevice ()->Send (p, hardwareDestination, Ipv4L3Protocol::PROT_NUMBER);
         }
     }
   else
     {
-      GetDevice ()->Send (p, GetDevice ()->GetBroadcast (), Ipv4::PROT_NUMBER);
+      GetDevice ()->Send (p, GetDevice ()->GetBroadcast (), Ipv4L3Protocol::PROT_NUMBER);
     }
 }
 
--- a/src/internet-node/arp-ipv4-interface.h	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/internet-node/arp-ipv4-interface.h	Tue Jun 12 22:54:10 2007 +0200
@@ -27,7 +27,7 @@
 
 namespace ns3 {
 
-class INode;
+class Node;
 
 /**
  * \brief an Ipv4 Interface which uses ARP
@@ -43,13 +43,13 @@
     NETDEVICE,
     ARP,
   };
-  ArpIpv4Interface (Ptr<INode> node, Ptr<NetDevice> device);
+  ArpIpv4Interface (Ptr<Node> node, Ptr<NetDevice> device);
   virtual ~ArpIpv4Interface ();
 
  private:
   virtual void SendTo (Packet p, Ipv4Address dest);
   virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
-  Ptr<INode> m_node;
+  Ptr<Node> m_node;
 };
 
 }//namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-node/arp-l3-protocol.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -0,0 +1,227 @@
+/* -*-  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 "ns3/packet.h"
+#include "ns3/debug.h"
+#include "ns3/empty-trace-resolver.h"
+#include "ns3/node.h"
+#include "ns3/net-device.h"
+
+#include "arp-l3-protocol.h"
+#include "arp-header.h"
+#include "arp-cache.h"
+#include "ipv4-interface.h"
+#include "ipv4-private.h"
+
+NS_DEBUG_COMPONENT_DEFINE ("ArpL3Protocol");
+
+namespace ns3 {
+
+const uint16_t ArpL3Protocol::PROT_NUMBER = 0x0806;
+
+ArpL3Protocol::ArpL3Protocol (Ptr<Node> node)
+  : L3Protocol (PROT_NUMBER, 0/* XXX: correct version number ? */ ),
+    m_node (node)
+{}
+
+ArpL3Protocol::~ArpL3Protocol ()
+{}
+
+void 
+ArpL3Protocol::DoDispose (void)
+{
+  for (CacheList::const_iterator i = m_cacheList.begin (); i != m_cacheList.end (); i++)
+    {
+      delete *i;
+    }
+  m_cacheList.clear ();
+  m_node = 0;
+  L3Protocol::DoDispose ();
+}
+
+TraceResolver *
+ArpL3Protocol::CreateTraceResolver (TraceContext const &context)
+{
+  return new EmptyTraceResolver (context);
+}
+
+ArpCache *
+ArpL3Protocol::FindCache (Ptr<NetDevice> device)
+{
+  for (CacheList::const_iterator i = m_cacheList.begin (); i != m_cacheList.end (); i++)
+    {
+      if ((*i)->GetDevice () == device)
+	{
+	  return *i;
+	}
+    }
+  Ptr<Ipv4Private> ipv4 = m_node->QueryInterface<Ipv4Private> (Ipv4Private::iid);
+  Ipv4Interface *interface = ipv4->FindInterfaceForDevice (device);
+  ArpCache * cache = new ArpCache (device, interface);
+  NS_ASSERT (device->IsBroadcast ());
+  device->SetLinkChangeCallback (MakeCallback (&ArpCache::Flush, cache));
+  m_cacheList.push_back (cache);
+  return cache;
+}
+
+void 
+ArpL3Protocol::Receive(Packet& packet, Ptr<NetDevice> device)
+{
+  ArpCache *cache = FindCache (device);
+  ArpHeader arp;
+  packet.RemoveHeader (arp);
+  if (arp.IsRequest () && 
+      arp.GetDestinationIpv4Address () == cache->GetInterface ()->GetAddress ()) 
+    {
+      NS_DEBUG ("node="<<m_node->GetId () <<", got request from " << 
+                arp.GetSourceIpv4Address () << " -- send reply");
+      SendArpReply (cache, arp.GetSourceIpv4Address (),
+                    arp.GetSourceHardwareAddress ());
+    } 
+  else if (arp.IsReply () &&
+           arp.GetDestinationIpv4Address ().IsEqual (cache->GetInterface ()->GetAddress ()) &&
+           arp.GetDestinationHardwareAddress ().IsEqual (device->GetAddress ())) 
+    {
+      Ipv4Address from = arp.GetSourceIpv4Address ();
+      ArpCache::Entry *entry = cache->Lookup (from);
+      if (entry != 0)
+        {
+          if (entry->IsWaitReply ()) 
+            {
+              NS_DEBUG ("node="<<m_node->GetId ()<<", got reply from " << 
+                        arp.GetSourceIpv4Address ()
+                     << " for waiting entry -- flush");
+              MacAddress from_mac = arp.GetSourceHardwareAddress ();
+              Packet waiting = entry->MarkAlive (from_mac);
+	      cache->GetInterface ()->Send (waiting, arp.GetSourceIpv4Address ());
+            } 
+          else 
+            {
+              // ignore this reply which might well be an attempt 
+              // at poisening my arp cache.
+              NS_DEBUG ("node="<<m_node->GetId ()<<", got reply from " << 
+                        arp.GetSourceIpv4Address () << 
+                        " for non-waiting entry -- drop");
+	      // XXX report packet as dropped.
+            }
+        } 
+      else 
+        {
+          NS_DEBUG ("node="<<m_node->GetId ()<<", got reply for unknown entry -- drop");
+	  // XXX report packet as dropped.
+        }
+    }
+}
+bool 
+ArpL3Protocol::Lookup (Packet &packet, Ipv4Address destination, 
+	     Ptr<NetDevice> device,
+	     MacAddress *hardwareDestination)
+{
+  ArpCache *cache = FindCache (device);
+  ArpCache::Entry *entry = cache->Lookup (destination);
+  if (entry != 0)
+    {
+      if (entry->IsExpired ()) 
+        {
+          if (entry->IsDead ()) 
+            {
+              NS_DEBUG ("node="<<m_node->GetId ()<<
+                        ", dead entry for " << destination << " expired -- send arp request");
+              entry->MarkWaitReply (packet);
+              SendArpRequest (cache, destination);
+            } 
+          else if (entry->IsAlive ()) 
+            {
+              NS_DEBUG ("node="<<m_node->GetId ()<<
+                        ", alive entry for " << destination << " expired -- send arp request");
+              entry->MarkWaitReply (packet);
+              SendArpRequest (cache, destination);
+            } 
+          else if (entry->IsWaitReply ()) 
+            {
+              NS_DEBUG ("node="<<m_node->GetId ()<<
+                        ", wait reply for " << destination << " expired -- drop");
+              entry->MarkDead ();
+	      // XXX report packet as 'dropped'
+            }
+        } 
+      else 
+        {
+          if (entry->IsDead ()) 
+            {
+              NS_DEBUG ("node="<<m_node->GetId ()<<
+                        ", dead entry for " << destination << " valid -- drop");
+	      // XXX report packet as 'dropped'
+            } 
+          else if (entry->IsAlive ()) 
+            {
+              NS_DEBUG ("node="<<m_node->GetId ()<<
+                        ", alive entry for " << destination << " valid -- send");
+	      *hardwareDestination = entry->GetMacAddress ();
+              return true;
+            } 
+          else if (entry->IsWaitReply ()) 
+            {
+              NS_DEBUG ("node="<<m_node->GetId ()<<
+                        ", wait reply for " << destination << " valid -- drop previous");
+              Packet old = entry->UpdateWaitReply (packet);
+	      // XXX report 'old' packet as 'dropped'
+            }
+        }
+
+    }
+  else
+    {
+      // This is our first attempt to transmit data to this destination.
+      NS_DEBUG ("node="<<m_node->GetId ()<<
+                ", no entry for " << destination << " -- send arp request");
+      entry = cache->Add (destination);
+      entry->MarkWaitReply (packet);
+      SendArpRequest (cache, destination);
+    }
+  return false;
+}
+
+void
+ArpL3Protocol::SendArpRequest (ArpCache const *cache, Ipv4Address to)
+{
+  ArpHeader arp;
+  arp.SetRequest (cache->GetDevice ()->GetAddress (),
+		  cache->GetInterface ()->GetAddress (), 
+                  cache->GetDevice ()->GetBroadcast (),
+                  to);
+  Packet packet;
+  packet.AddHeader (arp);
+  cache->GetDevice ()->Send (packet, cache->GetDevice ()->GetBroadcast (), PROT_NUMBER);
+}
+
+void
+ArpL3Protocol::SendArpReply (ArpCache const *cache, Ipv4Address toIp, MacAddress toMac)
+{
+  ArpHeader arp;
+  arp.SetReply (cache->GetDevice ()->GetAddress (),
+                cache->GetInterface ()->GetAddress (),
+                toMac, toIp);
+  Packet packet;
+  packet.AddHeader (arp);
+  cache->GetDevice ()->Send (packet, toMac, PROT_NUMBER);
+}
+
+}//namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-node/arp-l3-protocol.h	Tue Jun 12 22:54:10 2007 +0200
@@ -0,0 +1,82 @@
+/* -*-  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 ARP_L3_PROTOCOL_H
+#define ARP_L3_PROTOCOL_H
+
+#include <list>
+#include "ns3/ipv4-address.h"
+#include "ns3/mac-address.h"
+#include "ns3/ptr.h"
+#include "l3-protocol.h"
+
+namespace ns3 {
+
+class ArpCache;
+class NetDevice;
+class Node;
+class Packet;
+class TraceResolver;
+class TraceContext;
+/**
+ * \brief An implementation of the ARP protocol
+ */
+class ArpL3Protocol : public L3Protocol
+{
+public:
+  static const uint16_t PROT_NUMBER;
+  /**
+   * \brief Constructor
+   * \param node The node which this ARP object is associated with
+   */
+  ArpL3Protocol (Ptr<Node> node);
+  ~ArpL3Protocol ();
+
+  virtual TraceResolver *CreateTraceResolver (TraceContext const &context);
+  /**
+   * \brief Recieve a packet
+   */
+  virtual void Receive(Packet& p, Ptr<NetDevice> device);
+  /**
+   * \brief Perform an ARP lookup
+   * \param p
+   * \param destination
+   * \param device
+   * \param hardwareDestination
+   * \return 
+   */
+  bool Lookup (Packet &p, Ipv4Address destination, 
+	       Ptr<NetDevice> device,
+	       MacAddress *hardwareDestination);
+protected:
+  virtual void DoDispose (void);
+private:
+  typedef std::list<ArpCache *> CacheList;
+  ArpCache *FindCache (Ptr<NetDevice> device);
+  void SendArpRequest (ArpCache const *cache, Ipv4Address to);
+  void SendArpReply (ArpCache const *cache, Ipv4Address toIp, MacAddress toMac);
+  CacheList m_cacheList;
+  Ptr<Node> m_node;
+};
+
+}//namespace ns3
+
+
+#endif /* ARP_L3_PROTOCOL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-node/arp-private.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -0,0 +1,56 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "arp-private.h"
+#include "arp-l3-protocol.h"
+#include "ns3/assert.h"
+#include "ns3/net-device.h"
+
+namespace ns3 {
+
+const InterfaceId ArpPrivate::iid = MakeInterfaceId ("ArpPrivate", Object::iid);
+
+ArpPrivate::ArpPrivate (Ptr<ArpL3Protocol> arp)
+  : m_arp (arp)
+{
+  SetInterfaceId (ArpPrivate::iid);
+}
+ArpPrivate::~ArpPrivate ()
+{
+  NS_ASSERT (m_arp == 0);
+}
+
+bool 
+ArpPrivate::Lookup (Packet &p, Ipv4Address destination, 
+		     Ptr<NetDevice> device,
+		     MacAddress *hardwareDestination)
+{
+  return m_arp->Lookup (p, destination, device, hardwareDestination);
+}
+
+void
+ArpPrivate::DoDispose (void)
+{
+  m_arp = 0;
+  Object::DoDispose ();
+}
+
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-node/arp-private.h	Tue Jun 12 22:54:10 2007 +0200
@@ -0,0 +1,51 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef ARP_PRIVATE_H
+#define ARP_PRIVATE_H
+
+#include "ns3/object.h"
+#include "ns3/ipv4-address.h"
+
+namespace ns3 {
+
+class NetDevice;
+class MacAddress;
+class Packet;
+class ArpL3Protocol;
+
+class ArpPrivate : public Object
+{
+public:
+  static const InterfaceId iid;
+  ArpPrivate (Ptr<ArpL3Protocol> arp);
+  virtual ~ArpPrivate ();
+  bool Lookup (Packet &p, Ipv4Address destination, 
+	       Ptr<NetDevice> device,
+	       MacAddress *hardwareDestination);
+protected:
+  virtual void DoDispose (void);
+private:
+  Ptr<ArpL3Protocol> m_arp;
+};
+
+} // namespace ns3
+
+#endif /* ARP_PRIVATE_H */
--- a/src/internet-node/arp.cc	Thu Jun 07 13:19:25 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,227 +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 "ns3/packet.h"
-#include "ns3/debug.h"
-#include "ns3/empty-trace-resolver.h"
-#include "ns3/i-node.h"
-#include "ns3/net-device.h"
-
-#include "arp.h"
-#include "arp-header.h"
-#include "arp-cache.h"
-#include "ipv4-interface.h"
-#include "i-ipv4-private.h"
-
-NS_DEBUG_COMPONENT_DEFINE ("Arp");
-
-namespace ns3 {
-
-const uint16_t Arp::PROT_NUMBER = 0x0806;
-
-Arp::Arp (Ptr<INode> node)
-  : L3Protocol (PROT_NUMBER, 0/* XXX: correct version number ? */ ),
-    m_node (node)
-{}
-
-Arp::~Arp ()
-{}
-
-void 
-Arp::DoDispose (void)
-{
-  for (CacheList::const_iterator i = m_cacheList.begin (); i != m_cacheList.end (); i++)
-    {
-      delete *i;
-    }
-  m_cacheList.clear ();
-  m_node = 0;
-  L3Protocol::DoDispose ();
-}
-
-TraceResolver *
-Arp::CreateTraceResolver (TraceContext const &context)
-{
-  return new EmptyTraceResolver (context);
-}
-
-ArpCache *
-Arp::FindCache (Ptr<NetDevice> device)
-{
-  for (CacheList::const_iterator i = m_cacheList.begin (); i != m_cacheList.end (); i++)
-    {
-      if ((*i)->GetDevice () == device)
-	{
-	  return *i;
-	}
-    }
-  Ptr<IIpv4Private> ipv4 = m_node->QueryInterface<IIpv4Private> (IIpv4Private::iid);
-  Ipv4Interface *interface = ipv4->FindInterfaceForDevice (device);
-  ArpCache * cache = new ArpCache (device, interface);
-  NS_ASSERT (device->IsBroadcast ());
-  device->SetLinkChangeCallback (MakeCallback (&ArpCache::Flush, cache));
-  m_cacheList.push_back (cache);
-  return cache;
-}
-
-void 
-Arp::Receive(Packet& packet, Ptr<NetDevice> device)
-{
-  ArpCache *cache = FindCache (device);
-  ArpHeader arp;
-  packet.RemoveHeader (arp);
-  if (arp.IsRequest () && 
-      arp.GetDestinationIpv4Address () == cache->GetInterface ()->GetAddress ()) 
-    {
-      NS_DEBUG ("node="<<m_node->GetId () <<", got request from " << 
-                arp.GetSourceIpv4Address () << " -- send reply");
-      SendArpReply (cache, arp.GetSourceIpv4Address (),
-                    arp.GetSourceHardwareAddress ());
-    } 
-  else if (arp.IsReply () &&
-           arp.GetDestinationIpv4Address ().IsEqual (cache->GetInterface ()->GetAddress ()) &&
-           arp.GetDestinationHardwareAddress ().IsEqual (device->GetAddress ())) 
-    {
-      Ipv4Address from = arp.GetSourceIpv4Address ();
-      ArpCache::Entry *entry = cache->Lookup (from);
-      if (entry != 0)
-        {
-          if (entry->IsWaitReply ()) 
-            {
-              NS_DEBUG ("node="<<m_node->GetId ()<<", got reply from " << 
-                        arp.GetSourceIpv4Address ()
-                     << " for waiting entry -- flush");
-              MacAddress from_mac = arp.GetSourceHardwareAddress ();
-              Packet waiting = entry->MarkAlive (from_mac);
-	      cache->GetInterface ()->Send (waiting, arp.GetSourceIpv4Address ());
-            } 
-          else 
-            {
-              // ignore this reply which might well be an attempt 
-              // at poisening my arp cache.
-              NS_DEBUG ("node="<<m_node->GetId ()<<", got reply from " << 
-                        arp.GetSourceIpv4Address () << 
-                        " for non-waiting entry -- drop");
-	      // XXX report packet as dropped.
-            }
-        } 
-      else 
-        {
-          NS_DEBUG ("node="<<m_node->GetId ()<<", got reply for unknown entry -- drop");
-	  // XXX report packet as dropped.
-        }
-    }
-}
-bool 
-Arp::Lookup (Packet &packet, Ipv4Address destination, 
-	     Ptr<NetDevice> device,
-	     MacAddress *hardwareDestination)
-{
-  ArpCache *cache = FindCache (device);
-  ArpCache::Entry *entry = cache->Lookup (destination);
-  if (entry != 0)
-    {
-      if (entry->IsExpired ()) 
-        {
-          if (entry->IsDead ()) 
-            {
-              NS_DEBUG ("node="<<m_node->GetId ()<<
-                        ", dead entry for " << destination << " expired -- send arp request");
-              entry->MarkWaitReply (packet);
-              SendArpRequest (cache, destination);
-            } 
-          else if (entry->IsAlive ()) 
-            {
-              NS_DEBUG ("node="<<m_node->GetId ()<<
-                        ", alive entry for " << destination << " expired -- send arp request");
-              entry->MarkWaitReply (packet);
-              SendArpRequest (cache, destination);
-            } 
-          else if (entry->IsWaitReply ()) 
-            {
-              NS_DEBUG ("node="<<m_node->GetId ()<<
-                        ", wait reply for " << destination << " expired -- drop");
-              entry->MarkDead ();
-	      // XXX report packet as 'dropped'
-            }
-        } 
-      else 
-        {
-          if (entry->IsDead ()) 
-            {
-              NS_DEBUG ("node="<<m_node->GetId ()<<
-                        ", dead entry for " << destination << " valid -- drop");
-	      // XXX report packet as 'dropped'
-            } 
-          else if (entry->IsAlive ()) 
-            {
-              NS_DEBUG ("node="<<m_node->GetId ()<<
-                        ", alive entry for " << destination << " valid -- send");
-	      *hardwareDestination = entry->GetMacAddress ();
-              return true;
-            } 
-          else if (entry->IsWaitReply ()) 
-            {
-              NS_DEBUG ("node="<<m_node->GetId ()<<
-                        ", wait reply for " << destination << " valid -- drop previous");
-              Packet old = entry->UpdateWaitReply (packet);
-	      // XXX report 'old' packet as 'dropped'
-            }
-        }
-
-    }
-  else
-    {
-      // This is our first attempt to transmit data to this destination.
-      NS_DEBUG ("node="<<m_node->GetId ()<<
-                ", no entry for " << destination << " -- send arp request");
-      entry = cache->Add (destination);
-      entry->MarkWaitReply (packet);
-      SendArpRequest (cache, destination);
-    }
-  return false;
-}
-
-void
-Arp::SendArpRequest (ArpCache const *cache, Ipv4Address to)
-{
-  ArpHeader arp;
-  arp.SetRequest (cache->GetDevice ()->GetAddress (),
-		  cache->GetInterface ()->GetAddress (), 
-                  cache->GetDevice ()->GetBroadcast (),
-                  to);
-  Packet packet;
-  packet.AddHeader (arp);
-  cache->GetDevice ()->Send (packet, cache->GetDevice ()->GetBroadcast (), PROT_NUMBER);
-}
-
-void
-Arp::SendArpReply (ArpCache const *cache, Ipv4Address toIp, MacAddress toMac)
-{
-  ArpHeader arp;
-  arp.SetReply (cache->GetDevice ()->GetAddress (),
-                cache->GetInterface ()->GetAddress (),
-                toMac, toIp);
-  Packet packet;
-  packet.AddHeader (arp);
-  cache->GetDevice ()->Send (packet, toMac, PROT_NUMBER);
-}
-
-}//namespace ns3
--- a/src/internet-node/arp.h	Thu Jun 07 13:19:25 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +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 ARP_H
-#define ARP_H
-
-#include <list>
-#include "ns3/ipv4-address.h"
-#include "ns3/mac-address.h"
-#include "ns3/ptr.h"
-#include "l3-protocol.h"
-
-namespace ns3 {
-
-class ArpCache;
-class NetDevice;
-class INode;
-class Packet;
-class TraceResolver;
-class TraceContext;
-/**
- * \brief An implementation of the ARP protocol
- */
-class Arp : public L3Protocol
-{
-public:
-  static const uint16_t PROT_NUMBER;
-  /**
-   * \brief Constructor
-   * \param node The node which this ARP object is associated with
-   */
-  Arp (Ptr<INode> node);
-  ~Arp ();
-
-  virtual TraceResolver *CreateTraceResolver (TraceContext const &context);
-  /**
-   * \brief Recieve a packet
-   */
-  virtual void Receive(Packet& p, Ptr<NetDevice> device);
-  /**
-   * \brief Perform an ARP lookup
-   * \param p
-   * \param destination
-   * \param device
-   * \param hardwareDestination
-   * \return 
-   */
-  bool Lookup (Packet &p, Ipv4Address destination, 
-	       Ptr<NetDevice> device,
-	       MacAddress *hardwareDestination);
-protected:
-  virtual void DoDispose (void);
-private:
-  typedef std::list<ArpCache *> CacheList;
-  ArpCache *FindCache (Ptr<NetDevice> device);
-  void SendArpRequest (ArpCache const *cache, Ipv4Address to);
-  void SendArpReply (ArpCache const *cache, Ipv4Address toIp, MacAddress toMac);
-  CacheList m_cacheList;
-  Ptr<INode> m_node;
-};
-
-}//namespace ns3
-
-
-#endif /* ARP_H */
--- a/src/internet-node/ascii-trace.cc	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/internet-node/ascii-trace.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -23,12 +23,12 @@
 #include "ns3/trace-context.h"
 #include "ns3/trace-root.h"
 #include "ns3/simulator.h"
-#include "ns3/i-node.h"
+#include "ns3/node.h"
 #include "ns3/queue.h"
 #include "ns3/node-list.h"
 #include "ns3/llc-snap-header.h"
 
-#include "ipv4.h"
+#include "ipv4-l3-protocol.h"
 #include "arp-header.h"
 #include "udp-header.h"
 #include "ipv4-header.h"
@@ -110,8 +110,8 @@
   m_os << Simulator::Now ().GetSeconds () << " ";
   NodeList::NodeIndex nodeIndex;
   context.Get (nodeIndex);
-  m_os << "node=" << NodeList::GetINode (nodeIndex)->GetId () << " ";
-  Ipv4::InterfaceIndex interfaceIndex;
+  m_os << "node=" << NodeList::GetNode (nodeIndex)->GetId () << " ";
+  Ipv4L3Protocol::InterfaceIndex interfaceIndex;
   context.Get (interfaceIndex);
   m_os << "interface=" << interfaceIndex << " ";
   m_os << "pkt-uid=" << packet.GetUid () << " ";
@@ -124,8 +124,8 @@
   m_os << "r " << Simulator::Now ().GetSeconds () << " ";
   NodeList::NodeIndex nodeIndex;
   context.Get (nodeIndex);
-  m_os << "node=" << NodeList::GetINode (nodeIndex)->GetId () << " ";
-  Ipv4::InterfaceIndex interfaceIndex;
+  m_os << "node=" << NodeList::GetNode (nodeIndex)->GetId () << " ";
+  Ipv4L3Protocol::InterfaceIndex interfaceIndex;
   context.Get (interfaceIndex);
   m_os << "interface=" << interfaceIndex << " ";
   m_os << "pkt-uid=" << p.GetUid () << " ";
--- a/src/internet-node/i-arp-private.cc	Thu Jun 07 13:19:25 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#include "i-arp-private.h"
-#include "arp.h"
-#include "ns3/assert.h"
-#include "ns3/net-device.h"
-
-namespace ns3 {
-
-const InterfaceId IArpPrivate::iid ("IArpPrivate");
-
-IArpPrivate::IArpPrivate (Ptr<Arp> arp)
-  : Interface (IArpPrivate::iid),
-    m_arp (arp)
-{}
-IArpPrivate::~IArpPrivate ()
-{
-  NS_ASSERT (m_arp == 0);
-}
-
-bool 
-IArpPrivate::Lookup (Packet &p, Ipv4Address destination, 
-		     Ptr<NetDevice> device,
-		     MacAddress *hardwareDestination)
-{
-  return m_arp->Lookup (p, destination, device, hardwareDestination);
-}
-
-void
-IArpPrivate::DoDispose (void)
-{
-  m_arp = 0;
-  Interface::DoDispose ();
-}
-
-
-} // namespace ns3
--- a/src/internet-node/i-arp-private.h	Thu Jun 07 13:19:25 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef I_ARP_PRIVATE_H
-#define I_ARP_PRIVATE_H
-
-#include "ns3/interface.h"
-#include "ns3/ipv4-address.h"
-
-namespace ns3 {
-
-class NetDevice;
-class MacAddress;
-class Packet;
-class Arp;
-
-class IArpPrivate : public Interface
-{
-public:
-  static const InterfaceId iid;
-  IArpPrivate (Ptr<Arp> arp);
-  virtual ~IArpPrivate ();
-  bool Lookup (Packet &p, Ipv4Address destination, 
-	       Ptr<NetDevice> device,
-	       MacAddress *hardwareDestination);
-protected:
-  virtual void DoDispose (void);
-private:
-  Ptr<Arp> m_arp;
-};
-
-} // namespace ns3
-
-#endif /* I_ARP_PRIVATE_H */
--- a/src/internet-node/i-ipv4-impl.cc	Thu Jun 07 13:19:25 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,148 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#include "i-ipv4-impl.h"
-#include "ipv4.h"
-#include "ipv4-interface.h"
-#include "ns3/assert.h"
-#include "ns3/net-device.h"
-
-namespace ns3 {
-
-IIpv4Impl::IIpv4Impl (Ptr<Ipv4> ipv4)
-  : m_ipv4 (ipv4)
-{}
-IIpv4Impl::~IIpv4Impl ()
-{
-  NS_ASSERT (m_ipv4 == 0);
-}
-void 
-IIpv4Impl::DoDispose (void)
-{
-  m_ipv4 = 0;
-}
-
-void 
-IIpv4Impl::AddHostRouteTo (Ipv4Address dest, 
-			   Ipv4Address nextHop, 
-			   uint32_t interface)
-{
-  m_ipv4->AddHostRouteTo (dest, nextHop, interface);
-}
-void 
-IIpv4Impl::AddHostRouteTo (Ipv4Address dest, 
-			   uint32_t interface)
-{
-  m_ipv4->AddHostRouteTo (dest, interface);
-}
-void 
-IIpv4Impl::AddNetworkRouteTo (Ipv4Address network, 
-			      Ipv4Mask networkMask, 
-			      Ipv4Address nextHop, 
-			      uint32_t interface)
-{
-  m_ipv4->AddNetworkRouteTo (network, networkMask, nextHop, interface);
-}
-void 
-IIpv4Impl::AddNetworkRouteTo (Ipv4Address network, 
-			      Ipv4Mask networkMask, 
-			      uint32_t interface)
-{
-  m_ipv4->AddNetworkRouteTo (network, networkMask, interface);
-}
-void 
-IIpv4Impl::SetDefaultRoute (Ipv4Address nextHop, 
-			    uint32_t interface)
-{
-  m_ipv4->SetDefaultRoute (nextHop, interface);
-}
-uint32_t 
-IIpv4Impl::GetNRoutes (void)
-{
-  return m_ipv4->GetNRoutes ();
-}
-Ipv4Route *
-IIpv4Impl::GetRoute (uint32_t i)
-{
-  return m_ipv4->GetRoute (i);
-}
-void 
-IIpv4Impl::RemoveRoute (uint32_t i)
-{
-  return m_ipv4->RemoveRoute (i);
-}
-uint32_t 
-IIpv4Impl::AddInterface (Ptr<NetDevice> device)
-{
-  return m_ipv4->AddInterface (device);
-}
-uint32_t 
-IIpv4Impl::GetNInterfaces (void)
-{
-  return m_ipv4->GetNInterfaces ();
-}
-Ptr<NetDevice>
-IIpv4Impl::GetNetDevice (uint32_t i)
-{
-  return m_ipv4->GetInterface (i)-> GetDevice ();
-}
-
-void 
-IIpv4Impl::SetAddress (uint32_t i, Ipv4Address address)
-{
-  m_ipv4->SetAddress (i, address);
-}
-void 
-IIpv4Impl::SetNetworkMask (uint32_t i, Ipv4Mask mask)
-{
-  m_ipv4->SetNetworkMask (i, mask);
-}
-Ipv4Mask 
-IIpv4Impl::GetNetworkMask (uint32_t i) const
-{
-  return m_ipv4->GetNetworkMask (i);
-}
-Ipv4Address 
-IIpv4Impl::GetAddress (uint32_t i) const
-{
-  return m_ipv4->GetAddress (i);
-}
-uint16_t 
-IIpv4Impl::GetMtu (uint32_t i) const
-{
-  return m_ipv4->GetMtu (i);
-}
-bool 
-IIpv4Impl::IsUp (uint32_t i) const
-{
-  return m_ipv4->IsUp (i);
-}
-void 
-IIpv4Impl::SetUp (uint32_t i)
-{
-  m_ipv4->SetUp (i);
-}
-void 
-IIpv4Impl::SetDown (uint32_t i)
-{
-  m_ipv4->SetDown (i);
-}
-
-}//namespace ns3
--- a/src/internet-node/i-ipv4-impl.h	Thu Jun 07 13:19:25 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef I_IPV4_IMPL_H
-#define I_IPV4_IMPL_H
-
-#include "ns3/i-ipv4.h"
-#include "ns3/ptr.h"
-
-namespace ns3 {
-
-class Ipv4;
-
-class IIpv4Impl : public IIpv4
-{
-public:
-  IIpv4Impl (Ptr<Ipv4> ipv4);
-
-  virtual ~IIpv4Impl ();
-
-  virtual void AddHostRouteTo (Ipv4Address dest, 
-			       Ipv4Address nextHop, 
-			       uint32_t interface);
-  virtual void AddHostRouteTo (Ipv4Address dest, 
-			       uint32_t interface);
-  virtual void AddNetworkRouteTo (Ipv4Address network, 
-				  Ipv4Mask networkMask, 
-				  Ipv4Address nextHop, 
-				  uint32_t interface);
-  virtual void AddNetworkRouteTo (Ipv4Address network, 
-				  Ipv4Mask networkMask, 
-				  uint32_t interface);
-  virtual void SetDefaultRoute (Ipv4Address nextHop, 
-				uint32_t interface);
-  virtual uint32_t GetNRoutes (void);
-  virtual Ipv4Route *GetRoute (uint32_t i);
-  virtual void RemoveRoute (uint32_t i);
-  virtual uint32_t AddInterface (Ptr<NetDevice> device);
-  virtual uint32_t GetNInterfaces (void);  
-  virtual Ptr<NetDevice> GetNetDevice(uint32_t i);
-
-  virtual void SetAddress (uint32_t i, Ipv4Address address);
-  virtual void SetNetworkMask (uint32_t i, Ipv4Mask mask);
-  virtual Ipv4Mask GetNetworkMask (uint32_t t) const;
-  virtual Ipv4Address GetAddress (uint32_t i) const;
-  virtual uint16_t GetMtu (uint32_t i) const;
-  virtual bool IsUp (uint32_t i) const;
-  virtual void SetUp (uint32_t i);
-  virtual void SetDown (uint32_t i);
-protected:
-  virtual void DoDispose (void);
-private:
-  Ptr<Ipv4> m_ipv4;
-};
-
-} // namespace ns3
-
-#endif /* I_IPV4_IMPL_H */
--- a/src/internet-node/i-ipv4-private.cc	Thu Jun 07 13:19:25 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#include "i-ipv4-private.h"
-#include "ipv4.h"
-#include "ns3/assert.h"
-#include "ns3/net-device.h"
-
-namespace ns3 {
-
-const InterfaceId IIpv4Private::iid ("IIpv4Private");
-
-IIpv4Private::IIpv4Private (Ptr<Ipv4> ipv4)
-  : Interface (IIpv4Private::iid),
-    m_ipv4 (ipv4)
-{}
-IIpv4Private::~IIpv4Private ()
-{
-  NS_ASSERT (m_ipv4 == 0);
-}
-TraceResolver *
-IIpv4Private::CreateTraceResolver (TraceContext const &context)
-{
-  return m_ipv4->CreateTraceResolver (context);
-}
-void 
-IIpv4Private::Send (Packet const &packet, Ipv4Address source, 
-		    Ipv4Address destination, uint8_t protocol)
-{
-  m_ipv4->Send (packet, source, destination, protocol);
-}
-Ipv4Interface *
-IIpv4Private::FindInterfaceForDevice (Ptr<const NetDevice>device)
-{
-  return m_ipv4->FindInterfaceForDevice (device);
-}
-void 
-IIpv4Private::Receive(Packet& p, Ptr<NetDevice> device)
-{
-  m_ipv4->Receive (p, device);
-}
-void 
-IIpv4Private::DoDispose (void)
-{
-  m_ipv4 = 0;
-  Interface::DoDispose ();
-}
-
-} // namespace ns3
--- a/src/internet-node/i-ipv4-private.h	Thu Jun 07 13:19:25 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef I_IPV4_PRIVATE_H
-#define I_IPV4_PRIVATE_H
-
-#include "ns3/interface.h"
-#include "ns3/ipv4-address.h"
-#include "ns3/ptr.h"
-#include <stdint.h>
-
-namespace ns3 {
-
-class Packet;
-class Ipv4;
-class TraceContext;
-class TraceResolver;
-class Ipv4Interface;
-class NetDevice;
-
-class IIpv4Private : public Interface
-{
-public:
-  static const InterfaceId iid;
-  IIpv4Private (Ptr<Ipv4> ipv4);
-  virtual ~IIpv4Private ();
-
-  TraceResolver *CreateTraceResolver (TraceContext const &context);
-  void Send (Packet const &packet, Ipv4Address source, 
-	     Ipv4Address destination, uint8_t protocol);
-  Ipv4Interface *FindInterfaceForDevice (Ptr<const NetDevice>device);
-  void Receive(Packet& p, Ptr<NetDevice> device);
-protected:
-  virtual void DoDispose (void);
-private:
-  Ptr<Ipv4> m_ipv4;
-};
-
-} // namespace ns3
-
-#endif /* I_IPV4_PRIVATE_H */
--- a/src/internet-node/i-node-impl.cc	Thu Jun 07 13:19:25 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,121 +0,0 @@
-// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-// 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: George F. Riley<riley@ece.gatech.edu>
-//
-// Implementation of the INodeImpl class for ns3.
-// George F. Riley, Georgia Tech, Fall 2006
-
-#include "ns3/composite-trace-resolver.h"
-#include "ns3/net-device.h"
-
-#include "l3-demux.h"
-#include "ipv4-l4-demux.h"
-#include "i-node-impl.h"
-#include "udp.h"
-#include "ipv4.h"
-#include "arp.h"
-#include "i-udp-impl.h"
-#include "i-arp-private.h"
-#include "i-ipv4-impl.h"
-#include "i-ipv4-private.h"
-
-namespace ns3 {
-
-
-INodeImpl::INodeImpl()
-{
-  Construct ();
-}
-
-INodeImpl::INodeImpl(uint32_t systemId)
-{
-  Construct ();
-}
-
-INodeImpl::~INodeImpl ()
-{}
-
-void
-INodeImpl::Construct (void)
-{
-  Ptr<Ipv4> ipv4 = MakeNewObject<Ipv4> (this);
-  Ptr<Arp> arp = MakeNewObject<Arp> (this);
-  Ptr<Udp> udp = MakeNewObject<Udp> (this);
-
-  Ptr<L3Demux> l3Demux = MakeNewObject<L3Demux> (this);
-  Ptr<Ipv4L4Demux> ipv4L4Demux = MakeNewObject<Ipv4L4Demux> (this);
-
-  l3Demux->Insert (ipv4);
-  l3Demux->Insert (arp);
-  ipv4L4Demux->Insert (udp);
-
-  Ptr<IUdpImpl> udpImpl = MakeNewObject<IUdpImpl> (udp);
-  Ptr<IArpPrivate> arpPrivate = MakeNewObject<IArpPrivate> (arp);
-  Ptr<IIpv4Impl> ipv4Impl = MakeNewObject<IIpv4Impl> (ipv4);
-  Ptr<IIpv4Private> ipv4Private = MakeNewObject<IIpv4Private> (ipv4);
-
-  Interface::AddInterface (ipv4Private);
-  Interface::AddInterface (ipv4Impl);
-  Interface::AddInterface (arpPrivate);
-  Interface::AddInterface (udpImpl);
-  Interface::AddInterface (l3Demux);
-  Interface::AddInterface (ipv4L4Demux);
-}
-
-
-TraceResolver *
-INodeImpl::DoCreateTraceResolver (TraceContext const &context)
-{
-  CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
-  Ptr<IIpv4Private> ipv4 = QueryInterface<IIpv4Private> (IIpv4Private::iid);
-  resolver->Add ("ipv4",
-                 MakeCallback (&IIpv4Private::CreateTraceResolver, PeekPointer (ipv4)),
-                 INodeImpl::IPV4);
-
-  return resolver;
-}
-
-void 
-INodeImpl::DoDispose()
-{
-  INode::DoDispose ();
-}
-
-void 
-INodeImpl::DoAddDevice (Ptr<NetDevice> device) const
-{
-  device->SetReceiveCallback (MakeCallback (&INodeImpl::ReceiveFromDevice, this));
-}
-
-bool
-INodeImpl::ReceiveFromDevice (Ptr<NetDevice> device, const Packet &p, uint16_t protocolNumber) const
-{
-  Ptr<L3Demux> demux = QueryInterface<L3Demux> (L3Demux::iid);
-  Ptr<L3Protocol> target = demux->GetProtocol (protocolNumber);
-  if (target != 0) 
-    {
-      Packet packet = p;
-      target->Receive(packet, device);
-      return true;
-    }
-  return false;
-}
-
-
-}//namespace ns3
--- a/src/internet-node/i-node-impl.h	Thu Jun 07 13:19:25 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-// 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: George F. Riley<riley@ece.gatech.edu>
-//
-// Define a basic "Internet" node, with a protocol stack (l3 and l4),
-// network device list, process list, and routing.
-
-#ifndef I_NODE_IMPL_H
-#define I_NODE_IMPL_H
-
-#include <list>
-#include <string>
-
-#include "ns3/i-node.h"
-
-namespace ns3 {
-
-class Packet;
-
-class INodeImpl : public INode 
-{
-public:
-  enum TraceType {
-    IPV4,
-  };
-  INodeImpl();
-  INodeImpl(uint32_t systemId);
-  virtual ~INodeImpl ();
-
-protected:
-  virtual void DoDispose(void);
-private:
-  virtual void DoAddDevice (Ptr<NetDevice> device) const;
-  virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
-  bool ReceiveFromDevice (Ptr<NetDevice> device, const Packet &p, uint16_t protocolNumber) const;
-  void Construct (void);
-};
-
-}//namespace ns3
-
-#endif /* I_NODE_IMPL_H */
--- a/src/internet-node/i-udp-impl.cc	Thu Jun 07 13:19:25 2007 +0200
+++ /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) 2007 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#include "i-udp-impl.h"
-#include "udp.h"
-#include "ns3/socket.h"
-#include "ns3/assert.h"
-
-namespace ns3 {
-
-IUdpImpl::IUdpImpl (Ptr<Udp> udp)
-  : m_udp (udp)
-{}
-IUdpImpl::~IUdpImpl ()
-{
-  NS_ASSERT (m_udp == 0);
-}
-
-Ptr<Socket>
-IUdpImpl::CreateSocket (void)
-{
-  return m_udp->CreateSocket ();
-}
-
-void 
-IUdpImpl::DoDispose (void)
-{
-  m_udp = 0;
-  IUdp::DoDispose ();
-}
-
-} // namespace ns3
--- a/src/internet-node/i-udp-impl.h	Thu Jun 07 13:19:25 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef I_UDP_IMPL_H
-#define I_UDP_IMPL_H
-
-#include "ns3/i-udp.h"
-#include "ns3/ptr.h"
-
-namespace ns3 {
-
-class Udp;
-
-class IUdpImpl : public IUdp
-{
-public:
-  IUdpImpl (Ptr<Udp> udp);
-  virtual ~IUdpImpl ();
-
-  virtual Ptr<Socket> CreateSocket (void);
-
-protected:
-  virtual void DoDispose (void);
-private:
-  Ptr<Udp> m_udp;
-};
-
-} // namespace ns3
-
-#endif /* I_UDP_IMPL_H */
--- a/src/internet-node/internet-node.cc	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/internet-node/internet-node.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -1,38 +1,121 @@
-/* -*-	Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
+// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+// 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: George F. Riley<riley@ece.gatech.edu>
+//
+// Implementation of the InternetNode class for ns3.
+// George F. Riley, Georgia Tech, Fall 2006
+
+#include "ns3/composite-trace-resolver.h"
+#include "ns3/net-device.h"
+
+#include "l3-demux.h"
+#include "ipv4-l4-demux.h"
 #include "internet-node.h"
-#include "i-node-impl.h"
+#include "udp-l4-protocol.h"
+#include "ipv4-l3-protocol.h"
+#include "arp-l3-protocol.h"
+#include "udp-impl.h"
+#include "arp-private.h"
+#include "ipv4-impl.h"
+#include "ipv4-private.h"
 
 namespace ns3 {
 
-Ptr<INode> 
-MakeInternetNode (void)
+
+InternetNode::InternetNode()
+{
+  Construct ();
+}
+
+InternetNode::InternetNode(uint32_t systemId)
+{
+  Construct ();
+}
+
+InternetNode::~InternetNode ()
+{}
+
+void
+InternetNode::Construct (void)
 {
-  return MakeNewObject<INodeImpl> ();
+  Ptr<Ipv4L3Protocol> ipv4 = Create<Ipv4L3Protocol> (this);
+  Ptr<ArpL3Protocol> arp = Create<ArpL3Protocol> (this);
+  Ptr<UdpL4Protocol> udp = Create<UdpL4Protocol> (this);
+
+  Ptr<L3Demux> l3Demux = Create<L3Demux> (this);
+  Ptr<Ipv4L4Demux> ipv4L4Demux = Create<Ipv4L4Demux> (this);
+
+  l3Demux->Insert (ipv4);
+  l3Demux->Insert (arp);
+  ipv4L4Demux->Insert (udp);
+
+  Ptr<UdpImpl> udpImpl = Create<UdpImpl> (udp);
+  Ptr<ArpPrivate> arpPrivate = Create<ArpPrivate> (arp);
+  Ptr<Ipv4Impl> ipv4Impl = Create<Ipv4Impl> (ipv4);
+  Ptr<Ipv4Private> ipv4Private = Create<Ipv4Private> (ipv4);
+
+  Object::AddInterface (ipv4Private);
+  Object::AddInterface (ipv4Impl);
+  Object::AddInterface (arpPrivate);
+  Object::AddInterface (udpImpl);
+  Object::AddInterface (l3Demux);
+  Object::AddInterface (ipv4L4Demux);
 }
 
-Ptr<INode> 
-MakeInternetNode (uint32_t systemId)
+
+TraceResolver *
+InternetNode::DoCreateTraceResolver (TraceContext const &context)
 {
-  return MakeNewObject<INodeImpl> (systemId);
+  CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
+  Ptr<Ipv4Private> ipv4 = QueryInterface<Ipv4Private> (Ipv4Private::iid);
+  resolver->Add ("ipv4",
+                 MakeCallback (&Ipv4Private::CreateTraceResolver, PeekPointer (ipv4)),
+                 InternetNode::IPV4);
+
+  return resolver;
+}
+
+void 
+InternetNode::DoDispose()
+{
+  Node::DoDispose ();
 }
 
-} // namespace ns3
+void 
+InternetNode::DoAddDevice (Ptr<NetDevice> device) const
+{
+  device->SetReceiveCallback (MakeCallback (&InternetNode::ReceiveFromDevice, this));
+}
+
+bool
+InternetNode::ReceiveFromDevice (Ptr<NetDevice> device, const Packet &p, uint16_t protocolNumber) const
+{
+  Ptr<L3Demux> demux = QueryInterface<L3Demux> (L3Demux::iid);
+  Ptr<L3Protocol> target = demux->GetProtocol (protocolNumber);
+  if (target != 0) 
+    {
+      Packet packet = p;
+      target->Receive(packet, device);
+      return true;
+    }
+  return false;
+}
+
+
+}//namespace ns3
--- a/src/internet-node/internet-node.h	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/internet-node/internet-node.h	Tue Jun 12 22:54:10 2007 +0200
@@ -1,42 +1,57 @@
-/* -*-	Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
+// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+// 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: George F. Riley<riley@ece.gatech.edu>
+//
+// Define a basic "Internet" node, with a protocol stack (l3 and l4),
+// network device list, process list, and routing.
+
 #ifndef INTERNET_NODE_H
 #define INTERNET_NODE_H
 
-#include "ns3/i-node.h"
-#include "ns3/ptr.h"
+#include <list>
+#include <string>
+
+#include "ns3/node.h"
 
 namespace ns3 {
 
-/**
- * \returns a newly-created Node which supports the Ipv4 interfaces
- */
-Ptr<INode> MakeInternetNode (void);
+class Packet;
 
-/**
- * \param systemId a systemId for parallel simulations.
- * \returns a newly-created Node which supports the Ipv4 interfaces
- */
-Ptr<INode> MakeInternetNode (uint32_t systemId);
+class InternetNode : public Node 
+{
+public:
+  enum TraceType {
+    IPV4,
+  };
+  InternetNode();
+  InternetNode(uint32_t systemId);
+  virtual ~InternetNode ();
 
-} // namespace ns3
+protected:
+  virtual void DoDispose(void);
+private:
+  virtual void DoAddDevice (Ptr<NetDevice> device) const;
+  virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
+  bool ReceiveFromDevice (Ptr<NetDevice> device, const Packet &p, uint16_t protocolNumber) const;
+  void Construct (void);
+};
+
+}//namespace ns3
 
 #endif /* INTERNET_NODE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-node/ipv4-impl.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -0,0 +1,148 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "ipv4-impl.h"
+#include "ipv4-l3-protocol.h"
+#include "ipv4-interface.h"
+#include "ns3/assert.h"
+#include "ns3/net-device.h"
+
+namespace ns3 {
+
+Ipv4Impl::Ipv4Impl (Ptr<Ipv4L3Protocol> ipv4)
+  : m_ipv4 (ipv4)
+{}
+Ipv4Impl::~Ipv4Impl ()
+{
+  NS_ASSERT (m_ipv4 == 0);
+}
+void 
+Ipv4Impl::DoDispose (void)
+{
+  m_ipv4 = 0;
+}
+
+void 
+Ipv4Impl::AddHostRouteTo (Ipv4Address dest, 
+			   Ipv4Address nextHop, 
+			   uint32_t interface)
+{
+  m_ipv4->AddHostRouteTo (dest, nextHop, interface);
+}
+void 
+Ipv4Impl::AddHostRouteTo (Ipv4Address dest, 
+			   uint32_t interface)
+{
+  m_ipv4->AddHostRouteTo (dest, interface);
+}
+void 
+Ipv4Impl::AddNetworkRouteTo (Ipv4Address network, 
+			      Ipv4Mask networkMask, 
+			      Ipv4Address nextHop, 
+			      uint32_t interface)
+{
+  m_ipv4->AddNetworkRouteTo (network, networkMask, nextHop, interface);
+}
+void 
+Ipv4Impl::AddNetworkRouteTo (Ipv4Address network, 
+			      Ipv4Mask networkMask, 
+			      uint32_t interface)
+{
+  m_ipv4->AddNetworkRouteTo (network, networkMask, interface);
+}
+void 
+Ipv4Impl::SetDefaultRoute (Ipv4Address nextHop, 
+			    uint32_t interface)
+{
+  m_ipv4->SetDefaultRoute (nextHop, interface);
+}
+uint32_t 
+Ipv4Impl::GetNRoutes (void)
+{
+  return m_ipv4->GetNRoutes ();
+}
+Ipv4Route 
+Ipv4Impl::GetRoute (uint32_t i)
+{
+  return *m_ipv4->GetRoute (i);
+}
+void 
+Ipv4Impl::RemoveRoute (uint32_t i)
+{
+  return m_ipv4->RemoveRoute (i);
+}
+uint32_t 
+Ipv4Impl::AddInterface (Ptr<NetDevice> device)
+{
+  return m_ipv4->AddInterface (device);
+}
+uint32_t 
+Ipv4Impl::GetNInterfaces (void)
+{
+  return m_ipv4->GetNInterfaces ();
+}
+Ptr<NetDevice>
+Ipv4Impl::GetNetDevice (uint32_t i)
+{
+  return m_ipv4->GetInterface (i)-> GetDevice ();
+}
+
+void 
+Ipv4Impl::SetAddress (uint32_t i, Ipv4Address address)
+{
+  m_ipv4->SetAddress (i, address);
+}
+void 
+Ipv4Impl::SetNetworkMask (uint32_t i, Ipv4Mask mask)
+{
+  m_ipv4->SetNetworkMask (i, mask);
+}
+Ipv4Mask 
+Ipv4Impl::GetNetworkMask (uint32_t i) const
+{
+  return m_ipv4->GetNetworkMask (i);
+}
+Ipv4Address 
+Ipv4Impl::GetAddress (uint32_t i) const
+{
+  return m_ipv4->GetAddress (i);
+}
+uint16_t 
+Ipv4Impl::GetMtu (uint32_t i) const
+{
+  return m_ipv4->GetMtu (i);
+}
+bool 
+Ipv4Impl::IsUp (uint32_t i) const
+{
+  return m_ipv4->IsUp (i);
+}
+void 
+Ipv4Impl::SetUp (uint32_t i)
+{
+  m_ipv4->SetUp (i);
+}
+void 
+Ipv4Impl::SetDown (uint32_t i)
+{
+  m_ipv4->SetDown (i);
+}
+
+}//namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-node/ipv4-impl.h	Tue Jun 12 22:54:10 2007 +0200
@@ -0,0 +1,75 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef IPV4_IMPL_H
+#define IPV4_IMPL_H
+
+#include "ns3/ipv4.h"
+#include "ns3/ptr.h"
+
+namespace ns3 {
+
+class Ipv4L3Protocol;
+
+class Ipv4Impl : public Ipv4
+{
+public:
+  Ipv4Impl (Ptr<Ipv4L3Protocol> ipv4);
+
+  virtual ~Ipv4Impl ();
+
+  virtual void AddHostRouteTo (Ipv4Address dest, 
+			       Ipv4Address nextHop, 
+			       uint32_t interface);
+  virtual void AddHostRouteTo (Ipv4Address dest, 
+			       uint32_t interface);
+  virtual void AddNetworkRouteTo (Ipv4Address network, 
+				  Ipv4Mask networkMask, 
+				  Ipv4Address nextHop, 
+				  uint32_t interface);
+  virtual void AddNetworkRouteTo (Ipv4Address network, 
+				  Ipv4Mask networkMask, 
+				  uint32_t interface);
+  virtual void SetDefaultRoute (Ipv4Address nextHop, 
+				uint32_t interface);
+  virtual uint32_t GetNRoutes (void);
+  virtual Ipv4Route GetRoute (uint32_t i);
+  virtual void RemoveRoute (uint32_t i);
+  virtual uint32_t AddInterface (Ptr<NetDevice> device);
+  virtual uint32_t GetNInterfaces (void);  
+  virtual Ptr<NetDevice> GetNetDevice(uint32_t i);
+
+  virtual void SetAddress (uint32_t i, Ipv4Address address);
+  virtual void SetNetworkMask (uint32_t i, Ipv4Mask mask);
+  virtual Ipv4Mask GetNetworkMask (uint32_t t) const;
+  virtual Ipv4Address GetAddress (uint32_t i) const;
+  virtual uint16_t GetMtu (uint32_t i) const;
+  virtual bool IsUp (uint32_t i) const;
+  virtual void SetUp (uint32_t i);
+  virtual void SetDown (uint32_t i);
+protected:
+  virtual void DoDispose (void);
+private:
+  Ptr<Ipv4L3Protocol> m_ipv4;
+};
+
+} // namespace ns3
+
+#endif /* IPV4_IMPL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-node/ipv4-l3-protocol.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -0,0 +1,563 @@
+// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+// 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: George F. Riley<riley@ece.gatech.edu>
+//
+
+#include "ns3/packet.h"
+#include "ns3/debug.h"
+#include "ns3/composite-trace-resolver.h"
+#include "ns3/array-trace-resolver.h"
+#include "ns3/callback.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/ipv4-route.h"
+#include "ns3/node.h"
+#include "ns3/net-device.h"
+
+#include "ipv4-l3-protocol.h"
+#include "ipv4-l4-protocol.h"
+#include "ipv4-header.h"
+#include "ipv4-interface.h"
+#include "ipv4-loopback-interface.h"
+#include "arp-ipv4-interface.h"
+#include "ipv4-l4-demux.h"
+
+NS_DEBUG_COMPONENT_DEFINE ("Ipv4L3Protocol");
+
+namespace ns3 {
+
+const uint16_t Ipv4L3Protocol::PROT_NUMBER = 0x0800;
+
+Ipv4L3Protocol::Ipv4L3Protocol(Ptr<Node> node)
+  : L3Protocol (PROT_NUMBER, 4),
+    m_nInterfaces (0),
+    m_defaultTtl (64),
+    m_identification (0),
+    m_defaultRoute (0),
+    m_node (node)
+{
+  SetupLoopback ();
+}
+Ipv4L3Protocol::~Ipv4L3Protocol ()
+{}
+
+void 
+Ipv4L3Protocol::DoDispose (void)
+{
+  for (Ipv4InterfaceList::iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
+    {
+      delete (*i);
+    }
+  m_interfaces.clear ();
+  for (HostRoutesI i = m_hostRoutes.begin (); 
+       i != m_hostRoutes.end (); 
+       i = m_hostRoutes.erase (i)) 
+    {
+      delete (*i);
+    }
+  for (NetworkRoutesI j = m_networkRoutes.begin (); 
+       j != m_networkRoutes.end (); 
+       j = m_networkRoutes.erase (j)) 
+    {
+      delete (*j);
+    }
+  if (m_defaultRoute != 0)
+    {
+      delete m_defaultRoute;
+      m_defaultRoute = 0;
+    }
+  m_node = 0;
+  L3Protocol::DoDispose ();
+}
+
+void
+Ipv4L3Protocol::SetupLoopback (void)
+{
+  Ipv4LoopbackInterface * interface = new Ipv4LoopbackInterface (m_node);
+  interface->SetAddress (Ipv4Address::GetLoopback ());
+  interface->SetNetworkMask (Ipv4Mask::GetLoopback ());
+  uint32_t index = AddIpv4Interface (interface);
+  AddHostRouteTo (Ipv4Address::GetLoopback (), index);
+  interface->SetUp ();
+}
+
+TraceResolver *
+Ipv4L3Protocol::CreateTraceResolver (TraceContext const &context)
+{
+  CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
+  resolver->Add ("tx", m_txTrace, Ipv4L3Protocol::TX);
+  resolver->Add ("rx", m_rxTrace, Ipv4L3Protocol::RX);
+  resolver->Add ("drop", m_dropTrace, Ipv4L3Protocol::DROP);
+  resolver->Add ("interfaces", 
+                 MakeCallback (&Ipv4L3Protocol::InterfacesCreateTraceResolver, this), 
+                 Ipv4L3Protocol::INTERFACES);
+  return resolver;
+}
+
+TraceResolver *
+Ipv4L3Protocol::InterfacesCreateTraceResolver (TraceContext const &context) const
+{
+  ArrayTraceResolver<Ipv4Interface> *resolver = 
+    new ArrayTraceResolver<Ipv4Interface> 
+    (context,
+     MakeCallback (&Ipv4L3Protocol::GetNInterfaces, this),
+     MakeCallback (&Ipv4L3Protocol::GetInterface, this));
+  return resolver;
+}
+
+void 
+Ipv4L3Protocol::SetDefaultTtl (uint8_t ttl)
+{
+  m_defaultTtl = ttl;
+}
+    
+
+void 
+Ipv4L3Protocol::AddHostRouteTo (Ipv4Address dest, 
+                      Ipv4Address nextHop, 
+                      uint32_t interface)
+{
+  Ipv4Route *route = new Ipv4Route ();
+  *route = Ipv4Route::CreateHostRouteTo (dest, nextHop, interface);
+  m_hostRoutes.push_back (route);
+}
+void 
+Ipv4L3Protocol::AddHostRouteTo (Ipv4Address dest, 
+				uint32_t interface)
+{
+  Ipv4Route *route = new Ipv4Route ();
+  *route = Ipv4Route::CreateHostRouteTo (dest, interface);
+  m_hostRoutes.push_back (route);
+}
+void 
+Ipv4L3Protocol::AddNetworkRouteTo (Ipv4Address network, 
+				   Ipv4Mask networkMask, 
+				   Ipv4Address nextHop, 
+				   uint32_t interface)
+{
+  Ipv4Route *route = new Ipv4Route ();
+  *route = Ipv4Route::CreateNetworkRouteTo (network,
+                                            networkMask,
+                                            nextHop,
+                                            interface);
+  m_networkRoutes.push_back (route);
+}
+void 
+Ipv4L3Protocol::AddNetworkRouteTo (Ipv4Address network, 
+				   Ipv4Mask networkMask, 
+				   uint32_t interface)
+{
+  Ipv4Route *route = new Ipv4Route ();
+  *route = Ipv4Route::CreateNetworkRouteTo (network,
+                                            networkMask,
+                                            interface);
+  m_networkRoutes.push_back (route);
+}
+void 
+Ipv4L3Protocol::SetDefaultRoute (Ipv4Address nextHop, 
+				 uint32_t interface)
+{
+  Ipv4Route *route = new Ipv4Route ();
+  *route = Ipv4Route::CreateDefaultRoute (nextHop, interface);
+  delete m_defaultRoute;
+  m_defaultRoute = route;
+}
+
+Ipv4Route *
+Ipv4L3Protocol::Lookup (Ipv4Address dest)
+{
+  for (HostRoutesCI i = m_hostRoutes.begin (); 
+       i != m_hostRoutes.end (); 
+       i++) 
+    {
+      NS_ASSERT ((*i)->IsHost ());
+      if ((*i)->GetDest ().IsEqual (dest)) 
+        {
+          return (*i);
+        }
+    }
+  for (NetworkRoutesI j = m_networkRoutes.begin (); 
+       j != m_networkRoutes.end (); 
+       j++) 
+    {
+      NS_ASSERT ((*j)->IsNetwork ());
+      Ipv4Mask mask = (*j)->GetDestNetworkMask ();
+      Ipv4Address entry = (*j)->GetDestNetwork ();
+      if (mask.IsMatch (dest, entry)) 
+        {
+          return (*j);
+        }
+    }
+  if (m_defaultRoute != 0) 
+    {
+      NS_ASSERT (m_defaultRoute->IsDefault ());
+      return m_defaultRoute;
+    }
+  return 0;
+}
+
+uint32_t 
+Ipv4L3Protocol::GetNRoutes (void)
+{
+  uint32_t n = 0;
+  if (m_defaultRoute != 0)
+    {
+      n++;
+    }
+  n += m_hostRoutes.size ();
+  n += m_networkRoutes.size ();
+  return n;
+}
+Ipv4Route *
+Ipv4L3Protocol::GetRoute (uint32_t index)
+{
+  if (index == 0 && m_defaultRoute != 0)
+    {
+      return m_defaultRoute;
+    }
+  if (index > 0 && m_defaultRoute != 0)
+    {
+      index--;
+    }
+  if (index < m_hostRoutes.size ())
+    {
+      uint32_t tmp = 0;
+      for (HostRoutesCI i = m_hostRoutes.begin (); 
+           i != m_hostRoutes.end (); 
+           i++) 
+        {
+          if (tmp  == index)
+            {
+              return *i;
+            }
+          tmp++;
+        }
+    }
+  index -= m_hostRoutes.size ();
+  uint32_t tmp = 0;
+  for (NetworkRoutesI j = m_networkRoutes.begin (); 
+       j != m_networkRoutes.end (); 
+       j++) 
+    {
+      if (tmp == index)
+        {
+          return *j;
+        }
+      tmp++;
+    }
+  NS_ASSERT (false);
+  // quiet compiler.
+  return 0;
+}
+void 
+Ipv4L3Protocol::RemoveRoute (uint32_t index)
+{
+  if (index == 0 && m_defaultRoute != 0)
+    {
+      delete m_defaultRoute;
+      m_defaultRoute = 0;
+    }
+  if (index > 0 && m_defaultRoute != 0)
+    {
+      index--;
+    }
+  if (index < m_hostRoutes.size ())
+    {
+      uint32_t tmp = 0;
+      for (HostRoutesI i = m_hostRoutes.begin (); 
+           i != m_hostRoutes.end (); 
+           i++) 
+        {
+          if (tmp  == index)
+            {
+              delete *i;
+              m_hostRoutes.erase (i);
+              return;
+            }
+          tmp++;
+        }
+    }
+  index -= m_hostRoutes.size ();
+  uint32_t tmp = 0;
+  for (NetworkRoutesI j = m_networkRoutes.begin (); 
+       j != m_networkRoutes.end (); 
+       j++) 
+    {
+      if (tmp == index)
+        {
+          delete *j;
+          m_networkRoutes.erase (j);
+          return;
+        }
+      tmp++;
+    }
+  NS_ASSERT (false);
+}
+
+
+uint32_t 
+Ipv4L3Protocol::AddInterface (Ptr<NetDevice> device)
+{
+  Ipv4Interface *interface = new ArpIpv4Interface (m_node, device);
+  return AddIpv4Interface (interface);
+}
+uint32_t 
+Ipv4L3Protocol::AddIpv4Interface (Ipv4Interface *interface)
+{
+  uint32_t index = m_nInterfaces;
+  m_interfaces.push_back (interface);
+  m_nInterfaces++;
+  return index;
+}
+Ipv4Interface *
+Ipv4L3Protocol::GetInterface (uint32_t index) const
+{
+  uint32_t tmp = 0;
+  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
+    {
+      if (index == tmp) 
+	{
+	  return *i;
+	}
+      tmp++;
+    }
+  return 0;
+}
+uint32_t 
+Ipv4L3Protocol::GetNInterfaces (void) const
+{
+  return m_nInterfaces;
+}
+
+Ipv4Interface *
+Ipv4L3Protocol::FindInterfaceForDevice (Ptr<const NetDevice> device)
+{
+  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
+    {
+      if ((*i)->GetDevice () == device)
+        {
+          return *i;
+        }
+    }
+  return 0;
+}  
+
+void 
+Ipv4L3Protocol::Receive(Packet& packet, Ptr<NetDevice> device)
+{
+  uint32_t index = 0;
+  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
+    {
+      if ((*i)->GetDevice () == device)
+        {
+          m_rxTrace (packet, index);
+          break;
+        }
+      index++;
+    }
+  Ipv4Header ipHeader;
+  packet.RemoveHeader (ipHeader);
+
+  if (!ipHeader.IsChecksumOk ()) 
+    {
+      return;
+    }
+
+  if (Forwarding (packet, ipHeader, device)) 
+    {
+      return;
+    }
+
+  ForwardUp (packet, ipHeader);
+}
+
+void 
+Ipv4L3Protocol::Send (Packet const &packet, 
+            Ipv4Address source, 
+            Ipv4Address destination,
+            uint8_t protocol)
+{
+  Ipv4Header ipHeader;
+
+  ipHeader.SetSource (source);
+  ipHeader.SetDestination (destination);
+  ipHeader.SetProtocol (protocol);
+  ipHeader.SetPayloadSize (packet.GetSize ());
+  ipHeader.SetTtl (m_defaultTtl);
+  ipHeader.SetMayFragment ();
+  ipHeader.SetIdentification (m_identification);
+
+  m_identification ++;
+
+  // XXX Note here that in most ipv4 stacks in the world,
+  // the route calculation for an outgoing packet is not
+  // done in the ip layer. It is done within the application
+  // socket when the first packet is sent to avoid this
+  // costly lookup on a per-packet basis.
+  // That would require us to get the route from the packet,
+  // most likely with a packet tag. The higher layers do not
+  // do this yet for us.
+  Ipv4Route *route = Lookup (ipHeader.GetDestination ());
+  if (route == 0) 
+    {
+      NS_DEBUG ("not for me -- forwarding but no route to host. drop.");
+      m_dropTrace (packet);
+      return;
+    }
+
+  SendRealOut (packet, ipHeader, *route);
+}
+
+void
+Ipv4L3Protocol::SendRealOut (Packet const &p, Ipv4Header const &ip, Ipv4Route const &route)
+{
+  Packet packet = p;
+  packet.AddHeader (ip);
+  Ipv4Interface *outInterface = GetInterface (route.GetInterface ());
+  NS_ASSERT (packet.GetSize () <= outInterface->GetMtu ());
+  m_txTrace (packet, route.GetInterface ());
+  if (route.IsGateway ()) 
+    {
+      outInterface->Send (packet, route.GetGateway ());
+    } 
+  else 
+    {
+      outInterface->Send (packet, ip.GetDestination ());
+    }
+}
+
+
+bool
+Ipv4L3Protocol::Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr<NetDevice> device)
+{
+  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
+       i != m_interfaces.end (); i++) 
+    {
+      if ((*i)->GetAddress ().IsEqual (ipHeader.GetDestination ())) 
+        {
+          NS_DEBUG ("for me 1");
+          return false;
+        }
+    }
+  
+  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
+       i != m_interfaces.end (); i++) 
+    {
+      Ipv4Interface *interface = *i;
+      if (interface->GetDevice () == device)
+	{
+	  if (ipHeader.GetDestination ().IsEqual (interface->GetBroadcast ())) 
+	    {
+	      NS_DEBUG ("for me 2");
+	      return false;
+	    }
+	  break;
+	}
+    }
+      
+  if (ipHeader.GetDestination ().IsEqual (Ipv4Address::GetBroadcast ())) 
+    {
+      NS_DEBUG ("for me 3");
+      return false;
+    }
+  if (ipHeader.GetDestination ().IsEqual (Ipv4Address::GetAny ())) 
+    {
+      NS_DEBUG ("for me 4");
+      return false;
+    }
+  if (ipHeader.GetTtl () == 1) 
+    {
+      // Should send ttl expired here
+      // XXX
+      NS_DEBUG ("not for me -- ttl expired. drop.");
+      m_dropTrace (packet);
+      return true;
+    }
+  ipHeader.SetTtl (ipHeader.GetTtl () - 1);
+  Ipv4Route *route = Lookup (ipHeader.GetDestination ());
+  if (route == 0) 
+    {
+      NS_DEBUG ("not for me -- forwarding but no route to host. drop.");
+      m_dropTrace (packet);
+      return true;
+    }
+  NS_DEBUG ("not for me -- forwarding.");
+  SendRealOut (packet, ipHeader, *route);
+  return true;
+}
+
+
+void
+Ipv4L3Protocol::ForwardUp (Packet p, Ipv4Header const&ip)
+{
+  Ptr<Ipv4L4Demux> demux = m_node->QueryInterface<Ipv4L4Demux> (Ipv4L4Demux::iid);
+  Ptr<Ipv4L4Protocol> protocol = demux->GetProtocol (ip.GetProtocol ());
+  protocol->Receive (p, ip.GetSource (), ip.GetDestination ());
+}
+
+void 
+Ipv4L3Protocol::SetAddress (uint32_t i, Ipv4Address address)
+{
+  Ipv4Interface *interface = GetInterface (i);
+  interface->SetAddress (address);
+}
+void 
+Ipv4L3Protocol::SetNetworkMask (uint32_t i, Ipv4Mask mask)
+{
+  Ipv4Interface *interface = GetInterface (i);
+  interface->SetNetworkMask (mask);
+}
+Ipv4Mask 
+Ipv4L3Protocol::GetNetworkMask (uint32_t i) const
+{
+  Ipv4Interface *interface = GetInterface (i);
+  return interface->GetNetworkMask ();
+}
+Ipv4Address 
+Ipv4L3Protocol::GetAddress (uint32_t i) const
+{
+  Ipv4Interface *interface = GetInterface (i);
+  return interface->GetAddress ();
+}
+uint16_t 
+Ipv4L3Protocol::GetMtu (uint32_t i) const
+{
+  Ipv4Interface *interface = GetInterface (i);
+  return interface->GetMtu ();
+}
+bool 
+Ipv4L3Protocol::IsUp (uint32_t i) const
+{
+  Ipv4Interface *interface = GetInterface (i);
+  return interface->IsUp ();
+}
+void 
+Ipv4L3Protocol::SetUp (uint32_t i)
+{
+  Ipv4Interface *interface = GetInterface (i);
+  interface->SetUp ();
+}
+void 
+Ipv4L3Protocol::SetDown (uint32_t i)
+{
+  Ipv4Interface *interface = GetInterface (i);
+  interface->SetDown ();
+}
+
+
+}//namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-node/ipv4-l3-protocol.h	Tue Jun 12 22:54:10 2007 +0200
@@ -0,0 +1,180 @@
+// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+// 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: George F. Riley<riley@ece.gatech.edu>
+//
+
+#ifndef IPV4_L3_PROTOCOL_H
+#define IPV4_L3_PROTOCOL_H
+
+#include <list>
+#include <stdint.h>
+#include "ns3/callback-trace-source.h"
+#include "ns3/array-trace-resolver.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/ptr.h"
+#include "l3-protocol.h"
+
+namespace ns3 {
+
+class Packet;
+class NetDevice;
+class Ipv4Interface;
+class Ipv4Address;
+class Ipv4Header;
+class Ipv4Route;
+class Node;
+class TraceResolver;
+class TraceContext;
+
+
+class Ipv4L3Protocol : public L3Protocol 
+{
+public:
+  static const uint16_t PROT_NUMBER;
+
+  enum TraceType {
+    TX,
+    RX,
+    DROP,
+    INTERFACES,
+  };
+  typedef ArrayTraceResolver<Ipv4Interface>::Index InterfaceIndex;
+
+  Ipv4L3Protocol(Ptr<Node> node);
+  virtual ~Ipv4L3Protocol ();
+
+  /**
+   * \param context the trace context to use to construct the
+   *        TraceResolver to return
+   * \returns a TraceResolver which can resolve all traces
+   *          performed in this object. The caller must
+   *          delete the returned object.
+   */
+  virtual TraceResolver *CreateTraceResolver (TraceContext const &context);
+
+  /**
+   * \param ttl default ttl to use
+   *
+   * When we need to send an ipv4 packet, we use this default
+   * ttl value.
+   */
+  void SetDefaultTtl (uint8_t ttl);
+
+  /**
+   * \param device the device to match
+   * \returns the matching interface, zero if not found.
+   *
+   * Try to find an Ipv4Interface whose NetDevice is equal to
+   * the input NetDevice.
+   */
+  Ipv4Interface *FindInterfaceForDevice (Ptr<const NetDevice> device);
+
+  /**
+   * Lower layer calls this method after calling L3Demux::Lookup
+   * The ARP subclass needs to know from which NetDevice this
+   * packet is coming to:
+   *    - implement a per-NetDevice ARP cache
+   *    - send back arp replies on the right device
+   */
+  virtual void Receive(Packet& p, Ptr<NetDevice> device);
+
+  /**
+   * \param packet packet to send
+   * \param source source address of packet
+   * \param destination address of packet
+   * \param protocol number of packet
+   *
+   * Higher-level layers call this method to send a packet
+   * down the stack to the MAC and PHY layers.
+   */
+  void Send (Packet const &packet, Ipv4Address source, 
+	     Ipv4Address destination, uint8_t protocol);
+
+
+    
+  void AddHostRouteTo (Ipv4Address dest, 
+                       Ipv4Address nextHop, 
+                       uint32_t interface);
+  void AddHostRouteTo (Ipv4Address dest, 
+                       uint32_t interface);
+
+  void AddNetworkRouteTo (Ipv4Address network, 
+                          Ipv4Mask networkMask, 
+                          Ipv4Address nextHop, 
+                          uint32_t interface);
+  void AddNetworkRouteTo (Ipv4Address network, 
+                          Ipv4Mask networkMask, 
+                          uint32_t interface);
+  void SetDefaultRoute (Ipv4Address nextHop, 
+                        uint32_t interface);
+
+  Ipv4Route *Lookup (Ipv4Address dest);
+  uint32_t GetNRoutes (void);
+  Ipv4Route *GetRoute (uint32_t i);
+  void RemoveRoute (uint32_t i);
+
+  uint32_t AddInterface (Ptr<NetDevice> device);
+  Ipv4Interface * GetInterface (uint32_t i) const;
+  uint32_t GetNInterfaces (void) const;
+
+  
+  void SetAddress (uint32_t i, Ipv4Address address);
+  void SetNetworkMask (uint32_t i, Ipv4Mask mask);
+  Ipv4Mask GetNetworkMask (uint32_t t) const;
+  Ipv4Address GetAddress (uint32_t i) const;
+  uint16_t GetMtu (uint32_t i) const;
+  bool IsUp (uint32_t i) const;
+  void SetUp (uint32_t i);
+  void SetDown (uint32_t i);
+
+
+protected:
+  virtual void DoDispose (void);
+private:
+  void SendRealOut (Packet const &packet, Ipv4Header const &ip, Ipv4Route const &route);
+  bool Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr<NetDevice> device);
+  void ForwardUp (Packet p, Ipv4Header const&ip);
+  uint32_t AddIpv4Interface (Ipv4Interface *interface);
+  void SetupLoopback (void);
+  TraceResolver *InterfacesCreateTraceResolver (TraceContext const &context) const;
+
+  typedef std::list<Ipv4Interface*> Ipv4InterfaceList;
+  typedef std::list<Ipv4Route *> HostRoutes;
+  typedef std::list<Ipv4Route *>::const_iterator HostRoutesCI;
+  typedef std::list<Ipv4Route *>::iterator HostRoutesI;
+  typedef std::list<Ipv4Route *> NetworkRoutes;
+  typedef std::list<Ipv4Route *>::const_iterator NetworkRoutesCI;
+  typedef std::list<Ipv4Route *>::iterator NetworkRoutesI;
+
+  Ipv4InterfaceList m_interfaces;
+  uint32_t m_nInterfaces;
+  uint8_t m_defaultTtl;
+  uint16_t m_identification;
+  HostRoutes m_hostRoutes;
+  NetworkRoutes m_networkRoutes;
+  Ipv4Route *m_defaultRoute;
+  Ptr<Node> m_node;
+  CallbackTraceSource<Packet const &, uint32_t> m_txTrace;
+  CallbackTraceSource<Packet const &, uint32_t> m_rxTrace;
+  CallbackTraceSource<Packet const &> m_dropTrace;
+};
+
+} // Namespace ns3
+
+#endif /* IPV$_L3_PROTOCOL_H */
--- a/src/internet-node/ipv4-l4-demux.cc	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/internet-node/ipv4-l4-demux.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -24,18 +24,19 @@
 
 #include <sstream>
 #include "ns3/composite-trace-resolver.h"
-#include "ns3/i-node.h"
+#include "ns3/node.h"
 #include "ipv4-l4-demux.h"
 #include "ipv4-l4-protocol.h"
 
 namespace ns3 {
 
-const InterfaceId Ipv4L4Demux::iid ("Ipv4L4Demux");
+const InterfaceId Ipv4L4Demux::iid = MakeInterfaceId ("Ipv4L4Demux", Object::iid);
 
-Ipv4L4Demux::Ipv4L4Demux (Ptr<INode> node)
-  : Interface (Ipv4L4Demux::iid),
-    m_node (node)
-{}
+Ipv4L4Demux::Ipv4L4Demux (Ptr<Node> node)
+  : m_node (node)
+{
+  SetInterfaceId (Ipv4L4Demux::iid);
+}
 
 Ipv4L4Demux::~Ipv4L4Demux()
 {}
@@ -50,7 +51,7 @@
     }
   m_protocols.clear ();
   m_node = 0;
-  Interface::DoDispose ();
+  Object::DoDispose ();
 }
 
 TraceResolver *
--- a/src/internet-node/ipv4-l4-demux.h	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/internet-node/ipv4-l4-demux.h	Tue Jun 12 22:54:10 2007 +0200
@@ -26,25 +26,25 @@
 #define IPV4_L4_DEMUX_H
 
 #include <list>
-#include "ns3/interface.h"
+#include "ns3/object.h"
 #include "ns3/ptr.h"
 
 namespace ns3 {
 
 class Ipv4L4Protocol;
-class INode;
+class Node;
 class TraceResolver;
 class TraceContext;
 
 /**
  * \brief L4 Ipv4 Demux
  */
-class Ipv4L4Demux : public Interface
+class Ipv4L4Demux : public Object
 {
 public:
   static const InterfaceId iid;
   typedef int Ipv4L4ProtocolTraceType;
-  Ipv4L4Demux (Ptr<INode> node);
+  Ipv4L4Demux (Ptr<Node> node);
   virtual ~Ipv4L4Demux();
 
   /**
@@ -60,7 +60,7 @@
    * \returns the L4Protocol effectively added.
    *
    * Invoke Copy on the input template to get a copy of the input
-   * protocol which can be used on the INode on which this L4 Demux 
+   * protocol which can be used on the Node on which this L4 Demux 
    * is running. The new L4Protocol is registered internally as
    * a working L4 Protocol and returned from this method.
    * The caller does not get ownership of the returned pointer.
@@ -73,7 +73,7 @@
    *
    * This method is typically called by lower layers
    * to forward packets up the stack to the right protocol.
-   * It is also called from INodeImpl::GetUdp for example.
+   * It is also called from NodeImpl::GetUdp for example.
    */
   Ptr<Ipv4L4Protocol> GetProtocol(int protocolNumber);
   /**
@@ -87,7 +87,7 @@
   virtual void DoDispose (void);
   typedef std::list<Ptr<Ipv4L4Protocol> > L4List_t;
   L4List_t m_protocols;
-  Ptr<INode> m_node;
+  Ptr<Node> m_node;
 };
 
 } //namespace ns3
--- a/src/internet-node/ipv4-loopback-interface.cc	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/internet-node/ipv4-loopback-interface.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -21,13 +21,13 @@
  */
 #include "ns3/empty-trace-resolver.h"
 #include "ns3/net-device.h"
-#include "ns3/i-node.h"
+#include "ns3/node.h"
 #include "ipv4-loopback-interface.h"
-#include "i-ipv4-private.h"
+#include "ipv4-private.h"
 
 namespace ns3 {
 
-Ipv4LoopbackInterface::Ipv4LoopbackInterface (Ptr<INode> node)
+Ipv4LoopbackInterface::Ipv4LoopbackInterface (Ptr<Node> node)
   : Ipv4Interface (0),
     m_node (node)
 {}
@@ -43,7 +43,7 @@
 void 
 Ipv4LoopbackInterface::SendTo (Packet packet, Ipv4Address dest)
 {
-  Ptr<IIpv4Private> ipv4 = m_node->QueryInterface<IIpv4Private> (IIpv4Private::iid);
+  Ptr<Ipv4Private> ipv4 = m_node->QueryInterface<Ipv4Private> (Ipv4Private::iid);
   ipv4->Receive (packet, GetDevice ());
 }
 
--- a/src/internet-node/ipv4-loopback-interface.h	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/internet-node/ipv4-loopback-interface.h	Tue Jun 12 22:54:10 2007 +0200
@@ -27,7 +27,7 @@
 
 namespace ns3 {
 
-class INode;
+class Node;
 /**
  * \brief An IPv4 loopback interface
  */
@@ -38,14 +38,14 @@
    * \brief Constructor
    * \param node Pointer to a node associated with this IPv4 interface
    */
-  Ipv4LoopbackInterface (Ptr<INode> node);
+  Ipv4LoopbackInterface (Ptr<Node> node);
   virtual ~Ipv4LoopbackInterface ();
 
  private:
   virtual void SendTo (Packet p, Ipv4Address dest);
   virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
 
-  Ptr<INode> m_node;
+  Ptr<Node> m_node;
 };
 
 }//namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-node/ipv4-private.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -0,0 +1,67 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "ipv4-private.h"
+#include "ipv4-l3-protocol.h"
+#include "ns3/assert.h"
+#include "ns3/net-device.h"
+
+namespace ns3 {
+
+const InterfaceId Ipv4Private::iid = MakeInterfaceId ("Ipv4Private", Object::iid);
+
+Ipv4Private::Ipv4Private (Ptr<Ipv4L3Protocol> ipv4)
+  : m_ipv4 (ipv4)
+{
+  SetInterfaceId (Ipv4Private::iid);
+}
+Ipv4Private::~Ipv4Private ()
+{
+  NS_ASSERT (m_ipv4 == 0);
+}
+TraceResolver *
+Ipv4Private::CreateTraceResolver (TraceContext const &context)
+{
+  return m_ipv4->CreateTraceResolver (context);
+}
+void 
+Ipv4Private::Send (Packet const &packet, Ipv4Address source, 
+		    Ipv4Address destination, uint8_t protocol)
+{
+  m_ipv4->Send (packet, source, destination, protocol);
+}
+Ipv4Interface *
+Ipv4Private::FindInterfaceForDevice (Ptr<const NetDevice>device)
+{
+  return m_ipv4->FindInterfaceForDevice (device);
+}
+void 
+Ipv4Private::Receive(Packet& p, Ptr<NetDevice> device)
+{
+  m_ipv4->Receive (p, device);
+}
+void 
+Ipv4Private::DoDispose (void)
+{
+  m_ipv4 = 0;
+  Object::DoDispose ();
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-node/ipv4-private.h	Tue Jun 12 22:54:10 2007 +0200
@@ -0,0 +1,58 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef IPV4_PRIVATE_H
+#define IPV4_PRIVATE_H
+
+#include "ns3/object.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/ptr.h"
+#include <stdint.h>
+
+namespace ns3 {
+
+class Packet;
+class Ipv4L3Protocol;
+class TraceContext;
+class TraceResolver;
+class Ipv4Interface;
+class NetDevice;
+
+class Ipv4Private : public Object
+{
+public:
+  static const InterfaceId iid;
+  Ipv4Private (Ptr<Ipv4L3Protocol> ipv4);
+  virtual ~Ipv4Private ();
+
+  TraceResolver *CreateTraceResolver (TraceContext const &context);
+  void Send (Packet const &packet, Ipv4Address source, 
+	     Ipv4Address destination, uint8_t protocol);
+  Ipv4Interface *FindInterfaceForDevice (Ptr<const NetDevice>device);
+  void Receive(Packet& p, Ptr<NetDevice> device);
+protected:
+  virtual void DoDispose (void);
+private:
+  Ptr<Ipv4L3Protocol> m_ipv4;
+};
+
+} // namespace ns3
+
+#endif /* IPV4_PRIVATE_H */
--- a/src/internet-node/ipv4.cc	Thu Jun 07 13:19:25 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,563 +0,0 @@
-// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-// 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: George F. Riley<riley@ece.gatech.edu>
-//
-
-#include "ns3/packet.h"
-#include "ns3/debug.h"
-#include "ns3/composite-trace-resolver.h"
-#include "ns3/array-trace-resolver.h"
-#include "ns3/callback.h"
-#include "ns3/ipv4-address.h"
-#include "ns3/ipv4-route.h"
-#include "ns3/i-node.h"
-#include "ns3/net-device.h"
-
-#include "ipv4.h"
-#include "ipv4-l4-protocol.h"
-#include "ipv4-header.h"
-#include "ipv4-interface.h"
-#include "ipv4-loopback-interface.h"
-#include "arp-ipv4-interface.h"
-#include "ipv4-l4-demux.h"
-
-NS_DEBUG_COMPONENT_DEFINE ("Ipv4");
-
-namespace ns3 {
-
-const uint16_t Ipv4::PROT_NUMBER = 0x0800;
-
-Ipv4::Ipv4(Ptr<INode> node)
-  : L3Protocol (PROT_NUMBER, 4),
-    m_nInterfaces (0),
-    m_defaultTtl (64),
-    m_identification (0),
-    m_defaultRoute (0),
-    m_node (node)
-{
-  SetupLoopback ();
-}
-Ipv4::~Ipv4 ()
-{}
-
-void 
-Ipv4::DoDispose (void)
-{
-  for (Ipv4InterfaceList::iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
-    {
-      delete (*i);
-    }
-  m_interfaces.clear ();
-  for (HostRoutesI i = m_hostRoutes.begin (); 
-       i != m_hostRoutes.end (); 
-       i = m_hostRoutes.erase (i)) 
-    {
-      delete (*i);
-    }
-  for (NetworkRoutesI j = m_networkRoutes.begin (); 
-       j != m_networkRoutes.end (); 
-       j = m_networkRoutes.erase (j)) 
-    {
-      delete (*j);
-    }
-  if (m_defaultRoute != 0)
-    {
-      delete m_defaultRoute;
-      m_defaultRoute = 0;
-    }
-  m_node = 0;
-  L3Protocol::DoDispose ();
-}
-
-void
-Ipv4::SetupLoopback (void)
-{
-  Ipv4LoopbackInterface * interface = new Ipv4LoopbackInterface (m_node);
-  interface->SetAddress (Ipv4Address::GetLoopback ());
-  interface->SetNetworkMask (Ipv4Mask::GetLoopback ());
-  uint32_t index = AddIpv4Interface (interface);
-  AddHostRouteTo (Ipv4Address::GetLoopback (), index);
-  interface->SetUp ();
-}
-
-TraceResolver *
-Ipv4::CreateTraceResolver (TraceContext const &context)
-{
-  CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
-  resolver->Add ("tx", m_txTrace, Ipv4::TX);
-  resolver->Add ("rx", m_rxTrace, Ipv4::RX);
-  resolver->Add ("drop", m_dropTrace, Ipv4::DROP);
-  resolver->Add ("interfaces", 
-                 MakeCallback (&Ipv4::InterfacesCreateTraceResolver, this), 
-                 Ipv4::INTERFACES);
-  return resolver;
-}
-
-TraceResolver *
-Ipv4::InterfacesCreateTraceResolver (TraceContext const &context) const
-{
-  ArrayTraceResolver<Ipv4Interface> *resolver = 
-    new ArrayTraceResolver<Ipv4Interface> 
-    (context,
-     MakeCallback (&Ipv4::GetNInterfaces, this),
-     MakeCallback (&Ipv4::GetInterface, this));
-  return resolver;
-}
-
-void 
-Ipv4::SetDefaultTtl (uint8_t ttl)
-{
-  m_defaultTtl = ttl;
-}
-    
-
-void 
-Ipv4::AddHostRouteTo (Ipv4Address dest, 
-                      Ipv4Address nextHop, 
-                      uint32_t interface)
-{
-  Ipv4Route *route = new Ipv4Route ();
-  *route = Ipv4Route::CreateHostRouteTo (dest, nextHop, interface);
-  m_hostRoutes.push_back (route);
-}
-void 
-Ipv4::AddHostRouteTo (Ipv4Address dest, 
-				uint32_t interface)
-{
-  Ipv4Route *route = new Ipv4Route ();
-  *route = Ipv4Route::CreateHostRouteTo (dest, interface);
-  m_hostRoutes.push_back (route);
-}
-void 
-Ipv4::AddNetworkRouteTo (Ipv4Address network, 
-				   Ipv4Mask networkMask, 
-				   Ipv4Address nextHop, 
-				   uint32_t interface)
-{
-  Ipv4Route *route = new Ipv4Route ();
-  *route = Ipv4Route::CreateNetworkRouteTo (network,
-                                            networkMask,
-                                            nextHop,
-                                            interface);
-  m_networkRoutes.push_back (route);
-}
-void 
-Ipv4::AddNetworkRouteTo (Ipv4Address network, 
-				   Ipv4Mask networkMask, 
-				   uint32_t interface)
-{
-  Ipv4Route *route = new Ipv4Route ();
-  *route = Ipv4Route::CreateNetworkRouteTo (network,
-                                            networkMask,
-                                            interface);
-  m_networkRoutes.push_back (route);
-}
-void 
-Ipv4::SetDefaultRoute (Ipv4Address nextHop, 
-				 uint32_t interface)
-{
-  Ipv4Route *route = new Ipv4Route ();
-  *route = Ipv4Route::CreateDefaultRoute (nextHop, interface);
-  delete m_defaultRoute;
-  m_defaultRoute = route;
-}
-
-Ipv4Route *
-Ipv4::Lookup (Ipv4Address dest)
-{
-  for (HostRoutesCI i = m_hostRoutes.begin (); 
-       i != m_hostRoutes.end (); 
-       i++) 
-    {
-      NS_ASSERT ((*i)->IsHost ());
-      if ((*i)->GetDest ().IsEqual (dest)) 
-        {
-          return (*i);
-        }
-    }
-  for (NetworkRoutesI j = m_networkRoutes.begin (); 
-       j != m_networkRoutes.end (); 
-       j++) 
-    {
-      NS_ASSERT ((*j)->IsNetwork ());
-      Ipv4Mask mask = (*j)->GetDestNetworkMask ();
-      Ipv4Address entry = (*j)->GetDestNetwork ();
-      if (mask.IsMatch (dest, entry)) 
-        {
-          return (*j);
-        }
-    }
-  if (m_defaultRoute != 0) 
-    {
-      NS_ASSERT (m_defaultRoute->IsDefault ());
-      return m_defaultRoute;
-    }
-  return 0;
-}
-
-uint32_t 
-Ipv4::GetNRoutes (void)
-{
-  uint32_t n = 0;
-  if (m_defaultRoute != 0)
-    {
-      n++;
-    }
-  n += m_hostRoutes.size ();
-  n += m_networkRoutes.size ();
-  return n;
-}
-Ipv4Route *
-Ipv4::GetRoute (uint32_t index)
-{
-  if (index == 0 && m_defaultRoute != 0)
-    {
-      return m_defaultRoute;
-    }
-  if (index > 0 && m_defaultRoute != 0)
-    {
-      index--;
-    }
-  if (index < m_hostRoutes.size ())
-    {
-      uint32_t tmp = 0;
-      for (HostRoutesCI i = m_hostRoutes.begin (); 
-           i != m_hostRoutes.end (); 
-           i++) 
-        {
-          if (tmp  == index)
-            {
-              return *i;
-            }
-          tmp++;
-        }
-    }
-  index -= m_hostRoutes.size ();
-  uint32_t tmp = 0;
-  for (NetworkRoutesI j = m_networkRoutes.begin (); 
-       j != m_networkRoutes.end (); 
-       j++) 
-    {
-      if (tmp == index)
-        {
-          return *j;
-        }
-      tmp++;
-    }
-  NS_ASSERT (false);
-  // quiet compiler.
-  return 0;
-}
-void 
-Ipv4::RemoveRoute (uint32_t index)
-{
-  if (index == 0 && m_defaultRoute != 0)
-    {
-      delete m_defaultRoute;
-      m_defaultRoute = 0;
-    }
-  if (index > 0 && m_defaultRoute != 0)
-    {
-      index--;
-    }
-  if (index < m_hostRoutes.size ())
-    {
-      uint32_t tmp = 0;
-      for (HostRoutesI i = m_hostRoutes.begin (); 
-           i != m_hostRoutes.end (); 
-           i++) 
-        {
-          if (tmp  == index)
-            {
-              delete *i;
-              m_hostRoutes.erase (i);
-              return;
-            }
-          tmp++;
-        }
-    }
-  index -= m_hostRoutes.size ();
-  uint32_t tmp = 0;
-  for (NetworkRoutesI j = m_networkRoutes.begin (); 
-       j != m_networkRoutes.end (); 
-       j++) 
-    {
-      if (tmp == index)
-        {
-          delete *j;
-          m_networkRoutes.erase (j);
-          return;
-        }
-      tmp++;
-    }
-  NS_ASSERT (false);
-}
-
-
-uint32_t 
-Ipv4::AddInterface (Ptr<NetDevice> device)
-{
-  Ipv4Interface *interface = new ArpIpv4Interface (m_node, device);
-  return AddIpv4Interface (interface);
-}
-uint32_t 
-Ipv4::AddIpv4Interface (Ipv4Interface *interface)
-{
-  uint32_t index = m_nInterfaces;
-  m_interfaces.push_back (interface);
-  m_nInterfaces++;
-  return index;
-}
-Ipv4Interface *
-Ipv4::GetInterface (uint32_t index) const
-{
-  uint32_t tmp = 0;
-  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
-    {
-      if (index == tmp) 
-	{
-	  return *i;
-	}
-      tmp++;
-    }
-  return 0;
-}
-uint32_t 
-Ipv4::GetNInterfaces (void) const
-{
-  return m_nInterfaces;
-}
-
-Ipv4Interface *
-Ipv4::FindInterfaceForDevice (Ptr<const NetDevice> device)
-{
-  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
-    {
-      if ((*i)->GetDevice () == device)
-        {
-          return *i;
-        }
-    }
-  return 0;
-}  
-
-void 
-Ipv4::Receive(Packet& packet, Ptr<NetDevice> device)
-{
-  uint32_t index = 0;
-  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
-    {
-      if ((*i)->GetDevice () == device)
-        {
-          m_rxTrace (packet, index);
-          break;
-        }
-      index++;
-    }
-  Ipv4Header ipHeader;
-  packet.RemoveHeader (ipHeader);
-
-  if (!ipHeader.IsChecksumOk ()) 
-    {
-      return;
-    }
-
-  if (Forwarding (packet, ipHeader, device)) 
-    {
-      return;
-    }
-
-  ForwardUp (packet, ipHeader);
-}
-
-void 
-Ipv4::Send (Packet const &packet, 
-            Ipv4Address source, 
-            Ipv4Address destination,
-            uint8_t protocol)
-{
-  Ipv4Header ipHeader;
-
-  ipHeader.SetSource (source);
-  ipHeader.SetDestination (destination);
-  ipHeader.SetProtocol (protocol);
-  ipHeader.SetPayloadSize (packet.GetSize ());
-  ipHeader.SetTtl (m_defaultTtl);
-  ipHeader.SetMayFragment ();
-  ipHeader.SetIdentification (m_identification);
-
-  m_identification ++;
-
-  // XXX Note here that in most ipv4 stacks in the world,
-  // the route calculation for an outgoing packet is not
-  // done in the ip layer. It is done within the application
-  // socket when the first packet is sent to avoid this
-  // costly lookup on a per-packet basis.
-  // That would require us to get the route from the packet,
-  // most likely with a packet tag. The higher layers do not
-  // do this yet for us.
-  Ipv4Route *route = Lookup (ipHeader.GetDestination ());
-  if (route == 0) 
-    {
-      NS_DEBUG ("not for me -- forwarding but no route to host. drop.");
-      m_dropTrace (packet);
-      return;
-    }
-
-  SendRealOut (packet, ipHeader, *route);
-}
-
-void
-Ipv4::SendRealOut (Packet const &p, Ipv4Header const &ip, Ipv4Route const &route)
-{
-  Packet packet = p;
-  packet.AddHeader (ip);
-  Ipv4Interface *outInterface = GetInterface (route.GetInterface ());
-  NS_ASSERT (packet.GetSize () <= outInterface->GetMtu ());
-  m_txTrace (packet, route.GetInterface ());
-  if (route.IsGateway ()) 
-    {
-      outInterface->Send (packet, route.GetGateway ());
-    } 
-  else 
-    {
-      outInterface->Send (packet, ip.GetDestination ());
-    }
-}
-
-
-bool
-Ipv4::Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr<NetDevice> device)
-{
-  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
-       i != m_interfaces.end (); i++) 
-    {
-      if ((*i)->GetAddress ().IsEqual (ipHeader.GetDestination ())) 
-        {
-          NS_DEBUG ("for me 1");
-          return false;
-        }
-    }
-  
-  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
-       i != m_interfaces.end (); i++) 
-    {
-      Ipv4Interface *interface = *i;
-      if (interface->GetDevice () == device)
-	{
-	  if (ipHeader.GetDestination ().IsEqual (interface->GetBroadcast ())) 
-	    {
-	      NS_DEBUG ("for me 2");
-	      return false;
-	    }
-	  break;
-	}
-    }
-      
-  if (ipHeader.GetDestination ().IsEqual (Ipv4Address::GetBroadcast ())) 
-    {
-      NS_DEBUG ("for me 3");
-      return false;
-    }
-  if (ipHeader.GetDestination ().IsEqual (Ipv4Address::GetAny ())) 
-    {
-      NS_DEBUG ("for me 4");
-      return false;
-    }
-  if (ipHeader.GetTtl () == 1) 
-    {
-      // Should send ttl expired here
-      // XXX
-      NS_DEBUG ("not for me -- ttl expired. drop.");
-      m_dropTrace (packet);
-      return true;
-    }
-  ipHeader.SetTtl (ipHeader.GetTtl () - 1);
-  Ipv4Route *route = Lookup (ipHeader.GetDestination ());
-  if (route == 0) 
-    {
-      NS_DEBUG ("not for me -- forwarding but no route to host. drop.");
-      m_dropTrace (packet);
-      return true;
-    }
-  NS_DEBUG ("not for me -- forwarding.");
-  SendRealOut (packet, ipHeader, *route);
-  return true;
-}
-
-
-void
-Ipv4::ForwardUp (Packet p, Ipv4Header const&ip)
-{
-  Ptr<Ipv4L4Demux> demux = m_node->QueryInterface<Ipv4L4Demux> (Ipv4L4Demux::iid);
-  Ptr<Ipv4L4Protocol> protocol = demux->GetProtocol (ip.GetProtocol ());
-  protocol->Receive (p, ip.GetSource (), ip.GetDestination ());
-}
-
-void 
-Ipv4::SetAddress (uint32_t i, Ipv4Address address)
-{
-  Ipv4Interface *interface = GetInterface (i);
-  interface->SetAddress (address);
-}
-void 
-Ipv4::SetNetworkMask (uint32_t i, Ipv4Mask mask)
-{
-  Ipv4Interface *interface = GetInterface (i);
-  interface->SetNetworkMask (mask);
-}
-Ipv4Mask 
-Ipv4::GetNetworkMask (uint32_t i) const
-{
-  Ipv4Interface *interface = GetInterface (i);
-  return interface->GetNetworkMask ();
-}
-Ipv4Address 
-Ipv4::GetAddress (uint32_t i) const
-{
-  Ipv4Interface *interface = GetInterface (i);
-  return interface->GetAddress ();
-}
-uint16_t 
-Ipv4::GetMtu (uint32_t i) const
-{
-  Ipv4Interface *interface = GetInterface (i);
-  return interface->GetMtu ();
-}
-bool 
-Ipv4::IsUp (uint32_t i) const
-{
-  Ipv4Interface *interface = GetInterface (i);
-  return interface->IsUp ();
-}
-void 
-Ipv4::SetUp (uint32_t i)
-{
-  Ipv4Interface *interface = GetInterface (i);
-  interface->SetUp ();
-}
-void 
-Ipv4::SetDown (uint32_t i)
-{
-  Ipv4Interface *interface = GetInterface (i);
-  interface->SetDown ();
-}
-
-
-}//namespace ns3
--- a/src/internet-node/ipv4.h	Thu Jun 07 13:19:25 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,180 +0,0 @@
-// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-// 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: George F. Riley<riley@ece.gatech.edu>
-//
-
-#ifndef IPV4_H
-#define IPV4_H
-
-#include <list>
-#include <stdint.h>
-#include "ns3/callback-trace-source.h"
-#include "ns3/array-trace-resolver.h"
-#include "ns3/ipv4-address.h"
-#include "ns3/ptr.h"
-#include "l3-protocol.h"
-
-namespace ns3 {
-
-class Packet;
-class NetDevice;
-class Ipv4Interface;
-class Ipv4Address;
-class Ipv4Header;
-class Ipv4Route;
-class INode;
-class TraceResolver;
-class TraceContext;
-
-
-class Ipv4 : public L3Protocol 
-{
-public:
-  static const uint16_t PROT_NUMBER;
-
-  enum TraceType {
-    TX,
-    RX,
-    DROP,
-    INTERFACES,
-  };
-  typedef ArrayTraceResolver<Ipv4Interface>::Index InterfaceIndex;
-
-  Ipv4(Ptr<INode> node);
-  virtual ~Ipv4 ();
-
-  /**
-   * \param context the trace context to use to construct the
-   *        TraceResolver to return
-   * \returns a TraceResolver which can resolve all traces
-   *          performed in this object. The caller must
-   *          delete the returned object.
-   */
-  virtual TraceResolver *CreateTraceResolver (TraceContext const &context);
-
-  /**
-   * \param ttl default ttl to use
-   *
-   * When we need to send an ipv4 packet, we use this default
-   * ttl value.
-   */
-  void SetDefaultTtl (uint8_t ttl);
-
-  /**
-   * \param device the device to match
-   * \returns the matching interface, zero if not found.
-   *
-   * Try to find an Ipv4Interface whose NetDevice is equal to
-   * the input NetDevice.
-   */
-  Ipv4Interface *FindInterfaceForDevice (Ptr<const NetDevice> device);
-
-  /**
-   * Lower layer calls this method after calling L3Demux::Lookup
-   * The ARP subclass needs to know from which NetDevice this
-   * packet is coming to:
-   *    - implement a per-NetDevice ARP cache
-   *    - send back arp replies on the right device
-   */
-  virtual void Receive(Packet& p, Ptr<NetDevice> device);
-
-  /**
-   * \param packet packet to send
-   * \param source source address of packet
-   * \param destination address of packet
-   * \param protocol number of packet
-   *
-   * Higher-level layers call this method to send a packet
-   * down the stack to the MAC and PHY layers.
-   */
-  void Send (Packet const &packet, Ipv4Address source, 
-	     Ipv4Address destination, uint8_t protocol);
-
-
-    
-  void AddHostRouteTo (Ipv4Address dest, 
-                       Ipv4Address nextHop, 
-                       uint32_t interface);
-  void AddHostRouteTo (Ipv4Address dest, 
-                       uint32_t interface);
-
-  void AddNetworkRouteTo (Ipv4Address network, 
-                          Ipv4Mask networkMask, 
-                          Ipv4Address nextHop, 
-                          uint32_t interface);
-  void AddNetworkRouteTo (Ipv4Address network, 
-                          Ipv4Mask networkMask, 
-                          uint32_t interface);
-  void SetDefaultRoute (Ipv4Address nextHop, 
-                        uint32_t interface);
-
-  Ipv4Route *Lookup (Ipv4Address dest);
-  uint32_t GetNRoutes (void);
-  Ipv4Route *GetRoute (uint32_t i);
-  void RemoveRoute (uint32_t i);
-
-  uint32_t AddInterface (Ptr<NetDevice> device);
-  Ipv4Interface * GetInterface (uint32_t i) const;
-  uint32_t GetNInterfaces (void) const;
-
-  
-  void SetAddress (uint32_t i, Ipv4Address address);
-  void SetNetworkMask (uint32_t i, Ipv4Mask mask);
-  Ipv4Mask GetNetworkMask (uint32_t t) const;
-  Ipv4Address GetAddress (uint32_t i) const;
-  uint16_t GetMtu (uint32_t i) const;
-  bool IsUp (uint32_t i) const;
-  void SetUp (uint32_t i);
-  void SetDown (uint32_t i);
-
-
-protected:
-  virtual void DoDispose (void);
-private:
-  void SendRealOut (Packet const &packet, Ipv4Header const &ip, Ipv4Route const &route);
-  bool Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr<NetDevice> device);
-  void ForwardUp (Packet p, Ipv4Header const&ip);
-  uint32_t AddIpv4Interface (Ipv4Interface *interface);
-  void SetupLoopback (void);
-  TraceResolver *InterfacesCreateTraceResolver (TraceContext const &context) const;
-
-  typedef std::list<Ipv4Interface*> Ipv4InterfaceList;
-  typedef std::list<Ipv4Route *> HostRoutes;
-  typedef std::list<Ipv4Route *>::const_iterator HostRoutesCI;
-  typedef std::list<Ipv4Route *>::iterator HostRoutesI;
-  typedef std::list<Ipv4Route *> NetworkRoutes;
-  typedef std::list<Ipv4Route *>::const_iterator NetworkRoutesCI;
-  typedef std::list<Ipv4Route *>::iterator NetworkRoutesI;
-
-  Ipv4InterfaceList m_interfaces;
-  uint32_t m_nInterfaces;
-  uint8_t m_defaultTtl;
-  uint16_t m_identification;
-  HostRoutes m_hostRoutes;
-  NetworkRoutes m_networkRoutes;
-  Ipv4Route *m_defaultRoute;
-  Ptr<INode> m_node;
-  CallbackTraceSource<Packet const &, uint32_t> m_txTrace;
-  CallbackTraceSource<Packet const &, uint32_t> m_rxTrace;
-  CallbackTraceSource<Packet const &> m_dropTrace;
-};
-
-} // Namespace ns3
-
-#endif
--- a/src/internet-node/l3-demux.cc	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/internet-node/l3-demux.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -23,18 +23,19 @@
 #include <sstream>
 #include <string>
 #include "ns3/composite-trace-resolver.h"
-#include "ns3/i-node.h"
+#include "ns3/node.h"
 #include "l3-demux.h"
 #include "l3-protocol.h"
 
 namespace ns3 {
 
-const InterfaceId L3Demux::iid ("L3Demux");
+const InterfaceId L3Demux::iid = MakeInterfaceId ("L3Demux", Object::iid);
 
-L3Demux::L3Demux (Ptr<INode> node)
-  : Interface (L3Demux::iid),
-    m_node (node)
-{}
+L3Demux::L3Demux (Ptr<Node> node)
+  : m_node (node)
+{
+  SetInterfaceId (L3Demux::iid);
+}
 
 L3Demux::~L3Demux()
 {}
@@ -49,7 +50,7 @@
     }
   m_protocols.clear ();
   m_node = 0;
-  Interface::DoDispose ();
+  Object::DoDispose ();
 }
 
 TraceResolver *
--- a/src/internet-node/l3-demux.h	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/internet-node/l3-demux.h	Tue Jun 12 22:54:10 2007 +0200
@@ -28,25 +28,25 @@
 #define L3_DEMUX_H
 
 #include <map>
-#include "ns3/interface.h"
+#include "ns3/object.h"
 #include "ns3/ptr.h"
 
 namespace ns3 {
 
 class L3Protocol;
-class INode;
+class Node;
 class TraceResolver;
 class TraceContext;
 
 /**
  * \brief L3 Demux 
  */
-class L3Demux : public Interface
+class L3Demux : public Object
 {
 public:
   static const InterfaceId iid;
   typedef int ProtocolTraceType;
-  L3Demux(Ptr<INode> node);
+  L3Demux(Ptr<Node> node);
   virtual ~L3Demux();
 
   /**
@@ -63,7 +63,7 @@
    * \param protocol a template for the protocol to add to this L3 Demux.
    *
    * Invoke Copy on the input template to get a copy of the input
-   * protocol which can be used on the INode on which this L3 Demux 
+   * protocol which can be used on the Node on which this L3 Demux 
    * is running. The new L3Protocol is registered internally as
    * a working L3 Protocol and returned from this method.
    * The caller does not get ownership of the returned pointer.
@@ -76,7 +76,7 @@
    *
    * This method is typically called by lower layers
    * to forward packets up the stack to the right protocol.
-   * It is also called from INodeImpl::GetIpv4 for example.
+   * It is also called from NodeImpl::GetIpv4 for example.
    */
   Ptr<L3Protocol> GetProtocol (int protocolNumber);
 protected:
@@ -84,7 +84,7 @@
 private:
   typedef std::map<int, Ptr<ns3::L3Protocol> > L3Map_t;
 
-  Ptr<INode> m_node;
+  Ptr<Node> m_node;
   L3Map_t m_protocols;
 };
 
--- a/src/internet-node/pcap-trace.cc	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/internet-node/pcap-trace.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -27,9 +27,9 @@
 #include "ns3/callback.h"
 #include "ns3/pcap-writer.h"
 #include "ns3/node-list.h"
-#include "ns3/i-node.h"
+#include "ns3/node.h"
 
-#include "ipv4.h"
+#include "ipv4-l3-protocol.h"
 
 
 namespace ns3 {
@@ -84,7 +84,7 @@
 {
   NodeList::NodeIndex nodeIndex;
   context.Get (nodeIndex);
-  uint32_t nodeId = NodeList::GetINode (nodeIndex)->GetId ();
+  uint32_t nodeId = NodeList::GetNode (nodeIndex)->GetId ();
   PcapWriter *writer = GetStream (nodeId, interfaceIndex);
   writer->WritePacket (p);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-node/udp-impl.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -0,0 +1,49 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "udp-impl.h"
+#include "udp-l4-protocol.h"
+#include "ns3/socket.h"
+#include "ns3/assert.h"
+
+namespace ns3 {
+
+UdpImpl::UdpImpl (Ptr<UdpL4Protocol> udp)
+  : m_udp (udp)
+{}
+UdpImpl::~UdpImpl ()
+{
+  NS_ASSERT (m_udp == 0);
+}
+
+Ptr<Socket>
+UdpImpl::CreateSocket (void)
+{
+  return m_udp->CreateSocket ();
+}
+
+void 
+UdpImpl::DoDispose (void)
+{
+  m_udp = 0;
+  Udp::DoDispose ();
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-node/udp-impl.h	Tue Jun 12 22:54:10 2007 +0200
@@ -0,0 +1,47 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef UDP_IMPL_H
+#define UDP_IMPL_H
+
+#include "ns3/udp.h"
+#include "ns3/ptr.h"
+
+namespace ns3 {
+
+class UdpL4Protocol;
+
+class UdpImpl : public Udp
+{
+public:
+  UdpImpl (Ptr<UdpL4Protocol> udp);
+  virtual ~UdpImpl ();
+
+  virtual Ptr<Socket> CreateSocket (void);
+
+protected:
+  virtual void DoDispose (void);
+private:
+  Ptr<UdpL4Protocol> m_udp;
+};
+
+} // namespace ns3
+
+#endif /* UDP_IMPL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-node/udp-l4-protocol.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -0,0 +1,149 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#include "ns3/assert.h"
+#include "ns3/packet.h"
+#include "ns3/empty-trace-resolver.h"
+#include "ns3/node.h"
+
+#include "udp-l4-protocol.h"
+#include "udp-header.h"
+#include "ipv4-end-point-demux.h"
+#include "ipv4-end-point.h"
+#include "ipv4-l3-protocol.h"
+#include "ipv4-private.h"
+#include "l3-demux.h"
+#include "udp-socket.h"
+
+namespace ns3 {
+
+/* see http://www.iana.org/assignments/protocol-numbers */
+const uint8_t UdpL4Protocol::PROT_NUMBER = 17;
+
+UdpL4Protocol::UdpL4Protocol (Ptr<Node> node)
+  : Ipv4L4Protocol (PROT_NUMBER, 2),
+    m_node (node),
+    m_endPoints (new Ipv4EndPointDemux ())
+{}
+
+UdpL4Protocol::~UdpL4Protocol ()
+{}
+
+TraceResolver *
+UdpL4Protocol::CreateTraceResolver (TraceContext const &context)
+{
+  return new EmptyTraceResolver (context);
+}
+
+void
+UdpL4Protocol::DoDispose (void)
+{
+  if (m_endPoints != 0)
+    {
+      delete m_endPoints;
+      m_endPoints = 0;
+    }
+  m_node = 0;
+  Ipv4L4Protocol::DoDispose ();
+}
+
+Ptr<Socket>
+UdpL4Protocol::CreateSocket (void)
+{
+  Ptr<Socket> socket = Create<UdpSocket> (m_node, this);
+  return socket;
+}
+
+Ipv4EndPoint *
+UdpL4Protocol::Allocate (void)
+{
+  return m_endPoints->Allocate ();
+}
+Ipv4EndPoint *
+UdpL4Protocol::Allocate (Ipv4Address address)
+{
+  return m_endPoints->Allocate (address);
+}
+Ipv4EndPoint *
+UdpL4Protocol::Allocate (uint16_t port)
+{
+  return m_endPoints->Allocate (port);
+}
+Ipv4EndPoint *
+UdpL4Protocol::Allocate (Ipv4Address address, uint16_t port)
+{
+  return m_endPoints->Allocate (address, port);
+}
+Ipv4EndPoint *
+UdpL4Protocol::Allocate (Ipv4Address localAddress, uint16_t localPort,
+               Ipv4Address peerAddress, uint16_t peerPort)
+{
+  return m_endPoints->Allocate (localAddress, localPort,
+                                peerAddress, peerPort);
+}
+
+void 
+UdpL4Protocol::DeAllocate (Ipv4EndPoint *endPoint)
+{
+  m_endPoints->DeAllocate (endPoint);
+}
+
+void 
+UdpL4Protocol::Receive(Packet& packet, 
+             Ipv4Address const &source,
+             Ipv4Address const &destination)
+{
+  UdpHeader udpHeader;
+  packet.RemoveHeader (udpHeader);
+  Ipv4EndPoint *endPoint = m_endPoints->Lookup (destination, udpHeader.GetDestination (),
+                                                source, udpHeader.GetSource ());
+  if (endPoint == 0)
+    {
+      return;
+    }
+  endPoint->ForwardUp (packet, source, udpHeader.GetSource ());
+}
+
+void
+UdpL4Protocol::Send (Packet packet, 
+           Ipv4Address saddr, Ipv4Address daddr, 
+           uint16_t sport, uint16_t dport)
+{
+  UdpHeader udpHeader;
+  udpHeader.SetDestination (dport);
+  udpHeader.SetSource (sport);
+  udpHeader.SetPayloadSize (packet.GetSize ());
+  udpHeader.InitializeChecksum (saddr,
+                               daddr,
+                               PROT_NUMBER);
+
+  packet.AddHeader (udpHeader);
+
+  Ptr<Ipv4Private> ipv4 = m_node->QueryInterface<Ipv4Private> (Ipv4Private::iid);
+  if (ipv4 != 0)
+    {
+      ipv4->Send (packet, saddr, daddr, PROT_NUMBER);
+    }
+}
+
+
+}; // namespace ns3
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-node/udp-l4-protocol.h	Tue Jun 12 22:54:10 2007 +0200
@@ -0,0 +1,99 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005,2006,2007 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#ifndef UDP_L4_PROTOCOL_H
+#define UDP_L4_PROTOCOL_H
+
+#include <stdint.h>
+
+#include "ns3/packet.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/ptr.h"
+#include "ipv4-end-point-demux.h"
+#include "ipv4-l4-protocol.h"
+
+namespace ns3 {
+
+class Node;
+class TraceResolver;
+class TraceContext;
+class Socket;
+/**
+ * \brief Implementation of the UDP protocol
+ */
+class UdpL4Protocol : public Ipv4L4Protocol {
+public:
+  static const uint8_t PROT_NUMBER;
+  /**
+   * \brief Constructor
+   * \param node The node this protocol is associated with
+   */
+  UdpL4Protocol (Ptr<Node> node);
+  virtual ~UdpL4Protocol ();
+
+  virtual TraceResolver *CreateTraceResolver (TraceContext const &context);
+  /**
+   * \return A smart Socket pointer to a UdpSocket, allocated by this instance
+   * of the UDP protocol
+   */
+  Ptr<Socket> CreateSocket (void);
+
+  Ipv4EndPoint *Allocate (void);
+  Ipv4EndPoint *Allocate (Ipv4Address address);
+  Ipv4EndPoint *Allocate (uint16_t port);
+  Ipv4EndPoint *Allocate (Ipv4Address address, uint16_t port);
+  Ipv4EndPoint *Allocate (Ipv4Address localAddress, uint16_t localPort,
+                         Ipv4Address peerAddress, uint16_t peerPort);
+
+  void DeAllocate (Ipv4EndPoint *endPoint);
+
+  // called by UdpSocket.
+  /**
+   * \brief Send a packet via UDP
+   * \param packet The packet to send
+   * \param saddr The source Ipv4Address
+   * \param daddr The destination Ipv4Address
+   * \param sport The source port number
+   * \param dport The destination port number
+   */
+  void Send (Packet packet,
+             Ipv4Address saddr, Ipv4Address daddr, 
+             uint16_t sport, uint16_t dport);
+  /**
+   * \brief Recieve a packet up the protocol stack
+   * \param p The Packet to dump the contents into
+   * \param source The source's Ipv4Address
+   * \param destination The destinations Ipv4Address
+   */
+  // inherited from Ipv4L4Protocol
+  virtual void Receive(Packet& p, 
+                       Ipv4Address const &source,
+                       Ipv4Address const &destination);
+protected:
+  virtual void DoDispose (void);
+private:
+  Ptr<Node> m_node;
+  Ipv4EndPointDemux *m_endPoints;
+};
+
+}; // namespace ns3
+
+#endif /* UDP_L4_PROTOCOL_H */
--- a/src/internet-node/udp-socket.cc	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/internet-node/udp-socket.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -18,15 +18,15 @@
  *
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
  */
-#include "ns3/i-node.h"
+#include "ns3/node.h"
 #include "udp-socket.h"
-#include "udp.h"
+#include "udp-l4-protocol.h"
 #include "ipv4-end-point.h"
 #include "ipv4-l4-demux.h"
 
 namespace ns3 {
 
-UdpSocket::UdpSocket (Ptr<INode> node, Ptr<Udp> udp)
+UdpSocket::UdpSocket (Ptr<Node> node, Ptr<UdpL4Protocol> udp)
   : m_endPoint (0),
     m_node (node),
     m_udp (udp),
@@ -56,8 +56,8 @@
   m_udp = 0;
 }
 
-Ptr<INode>
-UdpSocket::GetINode (void) const
+Ptr<Node>
+UdpSocket::GetNode (void) const
 {
   return m_node;
 }
--- a/src/internet-node/udp-socket.h	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/internet-node/udp-socket.h	Tue Jun 12 22:54:10 2007 +0200
@@ -29,9 +29,9 @@
 namespace ns3 {
 
 class Ipv4EndPoint;
-class INode;
+class Node;
 class Packet;
-class Udp;
+class UdpL4Protocol;
 
 class UdpSocket : public Socket
 {
@@ -39,11 +39,11 @@
   /**
    * Create an unbound udp socket.
    */
-  UdpSocket (Ptr<INode> node, Ptr<Udp> udp);
+  UdpSocket (Ptr<Node> node, Ptr<UdpL4Protocol> udp);
   virtual ~UdpSocket ();
 
   virtual enum SocketErrno GetErrno (void) const;
-  virtual Ptr<INode> GetINode (void) const;
+  virtual Ptr<Node> GetNode (void) const;
   virtual int Bind (void);
   virtual int Bind (Ipv4Address address);
   virtual int Bind (uint16_t port); 
@@ -82,8 +82,8 @@
 		      ns3::Callback<void, Ptr<Socket>, uint32_t> dataSent);
 
   Ipv4EndPoint *m_endPoint;
-  Ptr<INode> m_node;
-  Ptr<Udp> m_udp;
+  Ptr<Node> m_node;
+  Ptr<UdpL4Protocol> m_udp;
   Ipv4Address m_defaultAddress;
   uint16_t m_defaultPort;
   Callback<void,Ptr<Socket>,uint32_t,const Ipv4Address &,uint16_t> m_dummyRxCallback;
--- a/src/internet-node/udp.cc	Thu Jun 07 13:19:25 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,149 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#include "ns3/assert.h"
-#include "ns3/packet.h"
-#include "ns3/empty-trace-resolver.h"
-#include "ns3/i-node.h"
-
-#include "udp.h"
-#include "udp-header.h"
-#include "ipv4-end-point-demux.h"
-#include "ipv4-end-point.h"
-#include "ipv4.h"
-#include "i-ipv4-private.h"
-#include "l3-demux.h"
-#include "udp-socket.h"
-
-namespace ns3 {
-
-/* see http://www.iana.org/assignments/protocol-numbers */
-const uint8_t Udp::PROT_NUMBER = 17;
-
-Udp::Udp (Ptr<INode> node)
-  : Ipv4L4Protocol (PROT_NUMBER, 2),
-    m_node (node),
-    m_endPoints (new Ipv4EndPointDemux ())
-{}
-
-Udp::~Udp ()
-{}
-
-TraceResolver *
-Udp::CreateTraceResolver (TraceContext const &context)
-{
-  return new EmptyTraceResolver (context);
-}
-
-void
-Udp::DoDispose (void)
-{
-  if (m_endPoints != 0)
-    {
-      delete m_endPoints;
-      m_endPoints = 0;
-    }
-  m_node = 0;
-  Ipv4L4Protocol::DoDispose ();
-}
-
-Ptr<Socket>
-Udp::CreateSocket (void)
-{
-  Ptr<Socket> socket = MakeNewObject<UdpSocket> (m_node, this);
-  return socket;
-}
-
-Ipv4EndPoint *
-Udp::Allocate (void)
-{
-  return m_endPoints->Allocate ();
-}
-Ipv4EndPoint *
-Udp::Allocate (Ipv4Address address)
-{
-  return m_endPoints->Allocate (address);
-}
-Ipv4EndPoint *
-Udp::Allocate (uint16_t port)
-{
-  return m_endPoints->Allocate (port);
-}
-Ipv4EndPoint *
-Udp::Allocate (Ipv4Address address, uint16_t port)
-{
-  return m_endPoints->Allocate (address, port);
-}
-Ipv4EndPoint *
-Udp::Allocate (Ipv4Address localAddress, uint16_t localPort,
-               Ipv4Address peerAddress, uint16_t peerPort)
-{
-  return m_endPoints->Allocate (localAddress, localPort,
-                                peerAddress, peerPort);
-}
-
-void 
-Udp::DeAllocate (Ipv4EndPoint *endPoint)
-{
-  m_endPoints->DeAllocate (endPoint);
-}
-
-void 
-Udp::Receive(Packet& packet, 
-             Ipv4Address const &source,
-             Ipv4Address const &destination)
-{
-  UdpHeader udpHeader;
-  packet.RemoveHeader (udpHeader);
-  Ipv4EndPoint *endPoint = m_endPoints->Lookup (destination, udpHeader.GetDestination (),
-                                                source, udpHeader.GetSource ());
-  if (endPoint == 0)
-    {
-      return;
-    }
-  endPoint->ForwardUp (packet, source, udpHeader.GetSource ());
-}
-
-void
-Udp::Send (Packet packet, 
-           Ipv4Address saddr, Ipv4Address daddr, 
-           uint16_t sport, uint16_t dport)
-{
-  UdpHeader udpHeader;
-  udpHeader.SetDestination (dport);
-  udpHeader.SetSource (sport);
-  udpHeader.SetPayloadSize (packet.GetSize ());
-  udpHeader.InitializeChecksum (saddr,
-                               daddr,
-                               PROT_NUMBER);
-
-  packet.AddHeader (udpHeader);
-
-  Ptr<IIpv4Private> ipv4 = m_node->QueryInterface<IIpv4Private> (IIpv4Private::iid);
-  if (ipv4 != 0)
-    {
-      ipv4->Send (packet, saddr, daddr, PROT_NUMBER);
-    }
-}
-
-
-}; // namespace ns3
-
--- a/src/internet-node/udp.h	Thu Jun 07 13:19:25 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,99 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005,2006,2007 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#ifndef UDP_H
-#define UDP_H
-
-#include <stdint.h>
-
-#include "ns3/packet.h"
-#include "ns3/ipv4-address.h"
-#include "ns3/ptr.h"
-#include "ipv4-end-point-demux.h"
-#include "ipv4-l4-protocol.h"
-
-namespace ns3 {
-
-class INode;
-class TraceResolver;
-class TraceContext;
-class Socket;
-/**
- * \brief Implementation of the UDP protocol
- */
-class Udp : public Ipv4L4Protocol {
-public:
-  static const uint8_t PROT_NUMBER;
-  /**
-   * \brief Constructor
-   * \param node The node this protocol is associated with
-   */
-  Udp (Ptr<INode> node);
-  virtual ~Udp ();
-
-  virtual TraceResolver *CreateTraceResolver (TraceContext const &context);
-  /**
-   * \return A smart Socket pointer to a UdpSocket, allocated by this instance
-   * of the UDP protocol
-   */
-  Ptr<Socket> CreateSocket (void);
-
-  Ipv4EndPoint *Allocate (void);
-  Ipv4EndPoint *Allocate (Ipv4Address address);
-  Ipv4EndPoint *Allocate (uint16_t port);
-  Ipv4EndPoint *Allocate (Ipv4Address address, uint16_t port);
-  Ipv4EndPoint *Allocate (Ipv4Address localAddress, uint16_t localPort,
-                         Ipv4Address peerAddress, uint16_t peerPort);
-
-  void DeAllocate (Ipv4EndPoint *endPoint);
-
-  // called by UdpSocket.
-  /**
-   * \brief Send a packet via UDP
-   * \param packet The packet to send
-   * \param saddr The source Ipv4Address
-   * \param daddr The destination Ipv4Address
-   * \param sport The source port number
-   * \param dport The destination port number
-   */
-  void Send (Packet packet,
-             Ipv4Address saddr, Ipv4Address daddr, 
-             uint16_t sport, uint16_t dport);
-  /**
-   * \brief Recieve a packet up the protocol stack
-   * \param p The Packet to dump the contents into
-   * \param source The source's Ipv4Address
-   * \param destination The destinations Ipv4Address
-   */
-  // inherited from Ipv4L4Protocol
-  virtual void Receive(Packet& p, 
-                       Ipv4Address const &source,
-                       Ipv4Address const &destination);
-protected:
-  virtual void DoDispose (void);
-private:
-  Ptr<INode> m_node;
-  Ipv4EndPointDemux *m_endPoints;
-};
-
-}; // namespace ns3
-
-#endif /* UDP_H */
--- a/src/internet-node/wscript	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/internet-node/wscript	Tue Jun 12 22:54:10 2007 +0200
@@ -8,7 +8,6 @@
     obj.uselib_local = ['ns3-node', 'ns3-applications']
     obj.source = [
         'internet-node.cc',
-        'i-node-impl.cc',
         'l3-demux.cc',
         'l3-protocol.cc',
         'ipv4-l4-demux.cc',
@@ -17,23 +16,23 @@
         'udp-header.cc',
         'ipv4-checksum.cc',
         'ipv4-interface.cc',
-        'ipv4.cc',
+        'ipv4-l3-protocol.cc',
         'ipv4-end-point.cc',
-        'udp.cc',
+        'udp-l4-protocol.cc',
         'arp-header.cc',
         'arp-cache.cc',
         'arp-ipv4-interface.cc',
-        'arp.cc',
+        'arp-l3-protocol.cc',
         'ipv4-loopback-interface.cc',
         'header-utils.cc',
         'udp-socket.cc',
         'ipv4-end-point-demux.cc',
-        'i-udp-impl.cc',
-        'i-arp-private.cc',
-        'i-ipv4-impl.cc',
-        'i-ipv4-private.cc',
+        'arp-private.cc',
+        'ipv4-impl.cc',
+        'ipv4-private.cc',
         'ascii-trace.cc',
         'pcap-trace.cc',
+        'udp-impl.cc',
         ]
 
     headers = bld.create_obj('ns3header')
--- a/src/node/application.cc	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/node/application.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -22,7 +22,7 @@
 // George F. Riley, Georgia Tech, Fall 2006
 
 #include "application.h"
-#include "ns3/i-node.h"
+#include "ns3/node.h"
 #include "ns3/nstime.h"
 #include "ns3/random-variable.h"
 #include "ns3/simulator.h"
@@ -34,7 +34,7 @@
 // Application Methods
 
 // \brief Application Constructor
-Application::Application(Ptr<INode> n) 
+Application::Application(Ptr<Node> n) 
     : m_node (n)
 {
   m_node->AddApplication (this);
@@ -77,7 +77,7 @@
   delete v;
 }
   
-Ptr<INode> Application::GetINode() const
+Ptr<Node> Application::GetNode() const
 {
   return m_node;
 }
--- a/src/node/application.h	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/node/application.h	Tue Jun 12 22:54:10 2007 +0200
@@ -25,11 +25,11 @@
 #include "ns3/nstime.h"
 #include "ns3/object.h"
 #include "ns3/ptr.h"
-#include "ns3/i-node.h"
+#include "ns3/node.h"
 
 namespace ns3 {
 
-class INode;
+class Node;
 class RandomVariable;
 
 /**
@@ -52,7 +52,7 @@
 class Application : public Object
 {
 public:
-  Application(Ptr<INode>);
+  Application(Ptr<Node>);
   virtual ~Application();
   
   /**
@@ -98,9 +98,9 @@
   void Stop(const RandomVariable& stopVariable);
 
   /**
-   * \returns the INode to which this Application object is attached.
+   * \returns the Node to which this Application object is attached.
    */
-  Ptr<INode> GetINode() const;
+  Ptr<Node> GetNode() const;
   
 private:
   /**
@@ -128,7 +128,7 @@
 
   EventId         m_startEvent;
   EventId         m_stopEvent;
-  Ptr<INode>       m_node;
+  Ptr<Node>       m_node;
 };
 
 } //namespace ns3
--- a/src/node/channel.cc	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/node/channel.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -27,19 +27,19 @@
 
 namespace ns3 {
 
-const InterfaceId Channel::iid ("Channel");
+const InterfaceId Channel::iid = MakeInterfaceId ("Channel", Object::iid);
 
 Channel::Channel ()
-  : Interface (Channel::iid),
-    m_name("Channel")
+  : m_name("Channel")
 {
+  SetInterfaceId (Channel::iid);
   NS_DEBUG("Channel::Channel ()");
 }
 
 Channel::Channel (std::string name)
-  : Interface (Channel::iid),
-    m_name(name)
+  : m_name(name)
 {
+  SetInterfaceId (Channel::iid);
   NS_DEBUG("Channel::Channel (" << name << ")");
 }
 
--- a/src/node/channel.h	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/node/channel.h	Tue Jun 12 22:54:10 2007 +0200
@@ -24,7 +24,7 @@
 
 #include <string>
 #include <stdint.h>
-#include "ns3/interface.h"
+#include "ns3/object.h"
 #include "ns3/ptr.h"
 
 namespace ns3 {
@@ -37,7 +37,7 @@
  * A channel is a logical path over which information flows.  The path can
  * be as simple as a short piece of wire, or as complicated as space-time.
  */
-class Channel : public Interface
+class Channel : public Object
 {
 public:
   static const InterfaceId iid;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/drop-tail-queue.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -0,0 +1,111 @@
+/* -*- 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
+ */
+
+#include "ns3/debug.h"
+#include "drop-tail-queue.h"
+
+NS_DEBUG_COMPONENT_DEFINE ("DropTailQueue");
+
+namespace ns3 {
+
+const ClassId DropTailQueue::cid = 
+  MakeClassId<DropTailQueue> ("DropTailQueue", Queue::iid);
+
+
+DropTailQueue::DropTailQueue () :
+  Queue (),
+  m_packets (),
+  m_maxPackets(DTQ_NPACKETS_MAX_DEFAULT)
+{
+  NS_DEBUG("DropTailQueue::DropTailQueue ()");
+}
+
+DropTailQueue::~DropTailQueue ()
+{
+  NS_DEBUG("DropTailQueue::~DropTailQueue ()");
+}
+
+void 
+DropTailQueue::SetMaxPackets (uint32_t npackets)
+{
+  NS_DEBUG("DropTailQueue::SetMaxPackets (" << npackets << ")");
+
+  m_maxPackets = npackets;
+}
+
+uint32_t 
+DropTailQueue::GetMaxPackets (void)
+{
+  NS_DEBUG("DropTailQueue::GetMaxPackets () <= " << m_maxPackets);
+
+  return m_maxPackets;
+}
+
+bool 
+DropTailQueue::DoEnqueue (const Packet& p)
+{
+  NS_DEBUG("DropTailQueue::DoEnqueue (" << &p << ")");
+
+  if (m_packets.size () >= m_maxPackets)
+    {
+      NS_DEBUG("DropTailQueue::DoEnqueue (): Queue full -- droppping pkt");
+      Drop (p);
+      return false;
+    }
+
+  m_packets.push(p);
+  return true;
+}
+
+bool
+DropTailQueue::DoDequeue (Packet& p)
+{
+  NS_DEBUG("DropTailQueue::DoDequeue (" << &p << ")");
+
+  if (m_packets.empty()) 
+    {
+      NS_DEBUG("DropTailQueue::DoDequeue (): Queue empty");
+      return false;
+    }
+
+  p = m_packets.front ();
+  m_packets.pop ();
+
+  NS_DEBUG("DropTailQueue::DoDequeue (): Popped " << &p << " <= true");
+
+  return true;
+}
+
+bool
+DropTailQueue::DoPeek (Packet& p)
+{
+  NS_DEBUG("DropTailQueue::DoPeek (" << &p << ")");
+
+  if (m_packets.empty()) 
+    {
+      NS_DEBUG("DropTailQueue::DoPeek (): Queue empty");
+      return false;
+    }
+
+  p = m_packets.front ();
+
+  return true;
+}
+
+}; // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/drop-tail-queue.h	Tue Jun 12 22:54:10 2007 +0200
@@ -0,0 +1,71 @@
+/* -*- 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
+ */
+
+#ifndef DROPTAIL_H
+#define DROPTAIL_H
+
+#include <queue>
+#include "ns3/packet.h"
+#include "ns3/queue.h"
+#include "ns3/component-manager.h"
+
+namespace ns3 {
+
+class TraceContainer;
+
+const int DTQ_NPACKETS_MAX_DEFAULT = 100;
+
+/**
+ * \brief A FIFO packet queue that drops tail-end packets on overflow
+ */
+class DropTailQueue : public Queue {
+public:
+  static const ClassId cid;
+  /**
+   * \brief DropTailQueue Constructor
+   *
+   * Creates a droptail queue with a maximum size of 100 packets by default
+   */
+  DropTailQueue ();
+
+  virtual ~DropTailQueue();
+  /**
+   * \param npackets The maximum number of packets this queue will hold before
+   * dropping packets.
+   */
+  void SetMaxPackets (uint32_t npackets);
+  /**
+   * \return The maximum number of packets this queue will hold before dropping
+   * packets.
+   */
+  uint32_t GetMaxPackets (void);
+
+private:
+  virtual bool DoEnqueue (const Packet& p);
+  virtual bool DoDequeue (Packet &p);
+  virtual bool DoPeek (Packet &p);
+
+private:
+  std::queue<Packet> m_packets;
+  uint32_t m_maxPackets;
+};
+
+}; // namespace ns3
+
+#endif /* DROPTAIL_H */
--- a/src/node/drop-tail.cc	Thu Jun 07 13:19:25 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,118 +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
- */
-
-#include "ns3/debug.h"
-#include "drop-tail.h"
-
-NS_DEBUG_COMPONENT_DEFINE ("DropTailQueue");
-
-namespace ns3 {
-
-static class QueueStackInitializationClass {
-public:
-  QueueStackInitializationClass () {
-    Queue::AddDefault ("DropTailQueue");
-  }
-} queue_stack_initialization_class;
-
-const ClassId DropTailQueue::cid = 
-  ComponentManager::RegisterConstructor<DropTailQueue> ("DropTailQueue");
-
-
-DropTailQueue::DropTailQueue () :
-  Queue (),
-  m_packets (),
-  m_maxPackets(DTQ_NPACKETS_MAX_DEFAULT)
-{
-  NS_DEBUG("DropTailQueue::DropTailQueue ()");
-}
-
-DropTailQueue::~DropTailQueue ()
-{
-  NS_DEBUG("DropTailQueue::~DropTailQueue ()");
-}
-
-void 
-DropTailQueue::SetMaxPackets (uint32_t npackets)
-{
-  NS_DEBUG("DropTailQueue::SetMaxPackets (" << npackets << ")");
-
-  m_maxPackets = npackets;
-}
-
-uint32_t 
-DropTailQueue::GetMaxPackets (void)
-{
-  NS_DEBUG("DropTailQueue::GetMaxPackets () <= " << m_maxPackets);
-
-  return m_maxPackets;
-}
-
-bool 
-DropTailQueue::DoEnqueue (const Packet& p)
-{
-  NS_DEBUG("DropTailQueue::DoEnqueue (" << &p << ")");
-
-  if (m_packets.size () >= m_maxPackets)
-    {
-      NS_DEBUG("DropTailQueue::DoEnqueue (): Queue full -- droppping pkt");
-      Drop (p);
-      return false;
-    }
-
-  m_packets.push(p);
-  return true;
-}
-
-bool
-DropTailQueue::DoDequeue (Packet& p)
-{
-  NS_DEBUG("DropTailQueue::DoDequeue (" << &p << ")");
-
-  if (m_packets.empty()) 
-    {
-      NS_DEBUG("DropTailQueue::DoDequeue (): Queue empty");
-      return false;
-    }
-
-  p = m_packets.front ();
-  m_packets.pop ();
-
-  NS_DEBUG("DropTailQueue::DoDequeue (): Popped " << &p << " <= true");
-
-  return true;
-}
-
-bool
-DropTailQueue::DoPeek (Packet& p)
-{
-  NS_DEBUG("DropTailQueue::DoPeek (" << &p << ")");
-
-  if (m_packets.empty()) 
-    {
-      NS_DEBUG("DropTailQueue::DoPeek (): Queue empty");
-      return false;
-    }
-
-  p = m_packets.front ();
-
-  return true;
-}
-
-}; // namespace ns3
--- a/src/node/drop-tail.h	Thu Jun 07 13:19:25 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +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
- */
-
-#ifndef DROPTAIL_H
-#define DROPTAIL_H
-
-#include <queue>
-#include "ns3/packet.h"
-#include "ns3/queue.h"
-#include "ns3/component-manager.h"
-
-namespace ns3 {
-
-class TraceContainer;
-
-const int DTQ_NPACKETS_MAX_DEFAULT = 100;
-
-/**
- * \brief A FIFO packet queue that drops tail-end packets on overflow
- */
-class DropTailQueue : public Queue {
-public:
-  static const ClassId cid;
-  /**
-   * \brief DropTailQueue Constructor
-   *
-   * Creates a droptail queue with a maximum size of 100 packets by default
-   */
-  DropTailQueue ();
-
-  virtual ~DropTailQueue();
-  /**
-   * \param npackets The maximum number of packets this queue will hold before
-   * dropping packets.
-   */
-  void SetMaxPackets (uint32_t npackets);
-  /**
-   * \return The maximum number of packets this queue will hold before dropping
-   * packets.
-   */
-  uint32_t GetMaxPackets (void);
-
-private:
-  virtual bool DoEnqueue (const Packet& p);
-  virtual bool DoDequeue (Packet &p);
-  virtual bool DoPeek (Packet &p);
-
-private:
-  std::queue<Packet> m_packets;
-  uint32_t m_maxPackets;
-};
-
-}; // namespace ns3
-
-#endif /* DROPTAIL_H */
--- a/src/node/i-ipv4.cc	Thu Jun 07 13:19:25 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#include "i-ipv4.h"
-
-namespace ns3 {
-
-const InterfaceId IIpv4::iid ("IIpv4");
-
-IIpv4::IIpv4 ()
-  : Interface (IIpv4::iid)
-{}
-
-IIpv4::~IIpv4 ()
-{}
-
-} // namespace ns3
--- a/src/node/i-ipv4.h	Thu Jun 07 13:19:25 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,191 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef I_IPV4_H
-#define I_IPV4_H
-
-#include <stdint.h>
-#include "ns3/ipv4-address.h"
-#include "ns3/interface.h"
-
-namespace ns3 {
-
-class NetDevice;
-class Packet;
-class Ipv4Route;
-/**
- * \brief Access to the Ipv4 forwarding table and to the ipv4 interfaces
- *
- * This class allows you to create ipv4 interfaces based on a NetDevice.
- * Multiple interfaces can be created for a single NetDevice, hence
- * achieving multihoming.
- *
- * This class also allows you to control the content of the ipv4 
- * forwarding table.
- */
-class IIpv4 : public Interface
-{
-public:
-  static const InterfaceId iid;
-  IIpv4 ();
-  virtual ~IIpv4 ();
-    
-  /**
-   * \param dest destination address
-   * \param nextHop address of next hop.
-   * \param interface interface of next hop.
-   *
-   * Add route to host dest through host nextHop 
-   * on interface.
-   */
-  virtual void AddHostRouteTo (Ipv4Address dest, 
-			       Ipv4Address nextHop, 
-			       uint32_t interface) = 0;
-  /**
-   * \param dest destination address
-   * \param interface of next hop
-   *
-   * add route to host dest on interface.
-   */
-  virtual void AddHostRouteTo (Ipv4Address dest, 
-			       uint32_t interface) = 0;
-
-  /**
-   * \param network destination network
-   * \param networkMask netmask of destination network
-   * \param nextHop address of next hop
-   * \param interface interface of next hop
-   * 
-   * add route to network dest with netmask 
-   * through host nextHop on interface
-   */
-  virtual void AddNetworkRouteTo (Ipv4Address network, 
-				  Ipv4Mask networkMask, 
-				  Ipv4Address nextHop, 
-				  uint32_t interface) = 0;
-
-  /**
-   * \param network destination network
-   * \param networkMask netmask of destination network
-   * \param interface interface of next hop
-   *
-   * add route to network dest with netmask 
-   * on interface
-   */
-  virtual void AddNetworkRouteTo (Ipv4Address network, 
-				  Ipv4Mask networkMask, 
-				  uint32_t interface) = 0;
-  /**
-   * \param nextHop address of default next hop
-   * \param interface interface of default next hop.
-   * 
-   * set the default route to host nextHop on
-   * interface. 
-   */
-  virtual void SetDefaultRoute (Ipv4Address nextHop, 
-				uint32_t interface) = 0;
-
-  /**
-   * \returns the number of entries in the routing table.
-   */
-  virtual uint32_t GetNRoutes (void) = 0;
-  /**
-   * \param i index of route to return
-   * \returns the route whose index is i
-   */
-  virtual Ipv4Route *GetRoute (uint32_t i) = 0;
-  /**
-   * \param i index of route to remove from routing table.
-   */
-  virtual void RemoveRoute (uint32_t i) = 0;
-  
-  /**
-   * \param device device to add to the list of ipv4 interfaces
-   *        which can be used as output interfaces during packet forwarding.
-   * \returns the index of the ipv4 interface added.
-   *
-   * Once a device has been added, it can never be removed: if you want
-   * to disable it, you can invoke IIpv4::SetDown which will
-   * make sure that it is never used during packet forwarding.
-   */
-  virtual uint32_t AddInterface (Ptr<NetDevice> device) = 0;
-  /**
-   * \returns the number of interfaces added by the user.
-   */
-  virtual uint32_t GetNInterfaces (void) = 0;  
-
-  /**
-   * \param i index of ipv4 interface
-   * \returns the NetDevice associated with the ipv4 interface index
-   */
-  virtual Ptr<NetDevice> GetNetDevice (uint32_t i) = 0;
-
-  /**
-   * \param i index of ipv4 interface
-   * \param address address to associate to the underlying ipv4 interface
-   */
-  virtual void SetAddress (uint32_t i, Ipv4Address address) = 0;
-  /**
-   * \param i index of ipv4 interface
-   * \param mask mask to associate to the underlying ipv4 interface
-   */
-  virtual void SetNetworkMask (uint32_t i, Ipv4Mask mask) = 0;
-  /**
-   * \param i index of ipv4 interface
-   * \returns the mask associated to the underlying ipv4 interface
-   */
-  virtual Ipv4Mask GetNetworkMask (uint32_t i) const = 0;
-  /**
-   * \param i index of ipv4 interface
-   * \returns the address associated to the underlying ipv4 interface
-   */
-  virtual Ipv4Address GetAddress (uint32_t i) const = 0;
-  /**
-   * \param i index of ipv4 interface
-   * \returns the Maximum Transmission Unit (in bytes) associated
-   *          to the underlying ipv4 interface
-   */
-  virtual uint16_t GetMtu (uint32_t i) const = 0;
-  /**
-   * \param i index of ipv4 interface
-   * \returns true if the underlying interface is in the "up" state,
-   *          false otherwise.
-   */
-  virtual bool IsUp (uint32_t i) const = 0;
-  /**
-   * \param i index of ipv4 interface
-   * 
-   * Set the interface into the "up" state. In this state, it is
-   * considered valid during ipv4 forwarding.
-   */
-  virtual void SetUp (uint32_t i) = 0;
-  /**
-   * \param i index of ipv4 interface
-   *
-   * Set the interface into the "down" state. In this state, it is
-   * ignored during ipv4 forwarding.
-   */
-  virtual void SetDown (uint32_t i) = 0;
-  
-};
-
-} // namespace ns3 
-
-#endif /* I_IPV4_H */
--- a/src/node/i-node.cc	Thu Jun 07 13:19:25 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,132 +0,0 @@
-// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-// 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: George F. Riley<riley@ece.gatech.edu>
-//
-
-// Implement the basic INode object for ns3.
-// George F. Riley, Georgia Tech, Fall 2006
-
-#include "i-node.h"
-#include "node-list.h"
-#include "net-device.h"
-#include "application.h"
-#include "ns3/simulator.h"
-
-namespace ns3{
-
-const InterfaceId INode::iid ("INode");
-
-INode::INode()
-  : Interface (INode::iid),
-    m_id(0), 
-    m_sid(0)
-{
-  m_id = NodeList::Add (this);
-}
-
-INode::INode(uint32_t sid)
-  : Interface (INode::iid),
-    m_id(0), 
-    m_sid(sid)
-{ 
-  m_id = NodeList::Add (this);
-}
-  
-INode::~INode ()
-{}
-
-TraceResolver *
-INode::CreateTraceResolver (TraceContext const &context)
-{
-  return DoCreateTraceResolver (context);
-}
-
-uint32_t 
-INode::GetId (void) const
-{
-  return m_id;
-}
-
-uint32_t 
-INode::GetSystemId (void) const
-{
-  return m_sid;
-}
-
-uint32_t 
-INode::AddDevice (Ptr<NetDevice> device)
-{
-  uint32_t index = m_devices.size ();
-  m_devices.push_back (device);
-  DoAddDevice (device);
-  device->SetIfIndex(index);
-  return index;
-}
-Ptr<NetDevice>
-INode::GetDevice (uint32_t index) const
-{
-  return m_devices[index];
-}
-uint32_t 
-INode::GetNDevices (void) const
-{
-  return m_devices.size ();
-}
-
-uint32_t 
-INode::AddApplication (Ptr<Application> application)
-{
-  uint32_t index = m_applications.size ();
-  m_applications.push_back (application);
-  return index;
-}
-Ptr<Application> 
-INode::GetApplication (uint32_t index) const
-{
-  return m_applications[index];
-}
-uint32_t 
-INode::GetNApplications (void) const
-{
-  return m_applications.size ();
-}
-
-
-void INode::DoDispose()
-{
-  for (std::vector<Ptr<NetDevice> >::iterator i = m_devices.begin ();
-       i != m_devices.end (); i++)
-    {
-      Ptr<NetDevice> device = *i;
-      device->Dispose ();
-      *i = 0;
-    }
-  m_devices.clear ();
-  for (std::vector<Ptr<Application> >::iterator i = m_applications.begin ();
-       i != m_applications.end (); i++)
-    {
-      Ptr<Application> application = *i;
-      application->Dispose ();
-      *i = 0;
-    }
-  m_applications.clear ();
-  Interface::DoDispose ();
-}
-
-}//namespace ns3
--- a/src/node/i-node.h	Thu Jun 07 13:19:25 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,173 +0,0 @@
-// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-// 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: George F. Riley<riley@ece.gatech.edu>
-//
-
-// Define the basic INode object for ns3.
-// George F. Riley, Georgia Tech, Fall 2006
-
-#ifndef I_NODE_H
-#define I_NODE_H
-
-#include <vector>
-
-#include "ns3/interface.h"
-
-namespace ns3 {
-
-class TraceContext;
-class TraceResolver;
-class NetDevice;
-class Application;
-
-/**
- * \brief A network INode.
- *
- * This class holds together:
- *   - a list of NetDevice objects which represent the network interfaces
- *     of this node which are connected to other INode instances through
- *     Channel instances.
- *   - a list of Application objects which represent the userspace
- *     traffic generation applications which interact with the INode
- *     through the Socket API.
- *   - a node Id: a unique per-node identifier.
- *   - a system Id: a unique Id used for parallel simulations.
- *   - a trace resolver which can be used to connect user trace sinks
- *     to the node's trace sources.
- *
- * Every INode created is added to the NodeList automatically.
- */
-class INode : public Interface
-{
-public:
-  static const InterfaceId iid;
-
-  virtual ~INode();
-
-  /**
-   * \param context the trace context for the TraceResolver to create
-   * \returns a newly-created TraceResolver. The caller takes
-   *          ownership of the returned pointer.
-   *
-   * Request the INode to create a trace resolver. This method
-   * could be used directly by a user who needs access to very low-level
-   * trace configuration.
-   */
-  TraceResolver *CreateTraceResolver (TraceContext const &context);
-
-  /**
-   * \returns the unique id of this node.
-   * 
-   * This unique id happens to be also the index of the INode into
-   * the NodeList. 
-   */
-  uint32_t GetId (void) const;
-
-  /**
-   * \returns the system id for parallel simulations associated
-   *          to this node.
-   */
-  uint32_t GetSystemId (void) const;
-
-  /**
-   * \param device NetDevice to associate to this node.
-   * \returns the index of the NetDevice into the INode's list of
-   *          NetDevice.
-   *
-   * Associate this device to this node.
-   * This method is called automatically from NetDevice::NetDevice
-   * so the user has little reason to call this method himself.
-   */
-  uint32_t AddDevice (Ptr<NetDevice> device);
-  /**
-   * \param index the index of the requested NetDevice
-   * \returns the requested NetDevice associated to this INode.
-   */
-  Ptr<NetDevice> GetDevice (uint32_t index) const;
-  /**
-   * \returns the number of NetDevice instances associated
-   *          to this INode.
-   */
-  uint32_t GetNDevices (void) const;
-
-  /**
-   * \param application Application to associate to this node.
-   * \returns the index of the Application within the INode's list
-   *          of Application.
-   *
-   * Associated this Application to this INode. This method is called
-   * automatically from Application::Application so the user
-   * has little reasons to call this method directly.
-   */
-  uint32_t AddApplication (Ptr<Application> application);
-  /**
-   * \param index
-   * \returns the application associated to this requested index
-   *          within this INode.
-   */
-  Ptr<Application> GetApplication (uint32_t index) const;
-  /**
-   * \returns the number of applications associated to this INode.
-   */
-  uint32_t GetNApplications (void) const;
-
-protected:
-  /**
-   * Must be invoked by subclasses only.
-   */
-  INode();
-  /**
-   * \param systemId a unique integer used for parallel simulations.
-   *
-   * Must be invoked by subclasses only.
-   */
-  INode(uint32_t systemId);
-  /**
-   * The dispose method. Subclasses must override this method
-   * and must chain up to it by calling INode::DoDispose at the
-   * end of their own DoDispose method.
-   */
-  virtual void DoDispose (void);
-private:
-  /**
-   * \param context the trace context
-   * \returns a trace resolver to the user. The user must delete it.
-   *
-   * Subclasses must implement this method.
-   */
-  virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context) = 0;
-  /**
-   * \param device the device added to this INode.
-   *
-   * This method is invoked whenever a user calls INode::AddDevice.
-   * Subclasses are expected to call NetDevice::SetReceiveCallback
-   * at this point to setup the node's receive function for
-   * the NetDevice packets.
-   */
-  virtual void DoAddDevice (Ptr<NetDevice> device) const = 0;
-
-  uint32_t    m_id;         // INode id for this node
-  uint32_t    m_sid;        // System id for this node
-  std::vector<Ptr<NetDevice> > m_devices;
-  std::vector<Ptr<Application> > m_applications;
-};
-
-} //namespace ns3
-
-#endif /* I_NODE_H */
--- a/src/node/i-socket-factory.cc	Thu Jun 07 13:19:25 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#include "i-socket-factory.h"
-
-namespace ns3 {
-
-const InterfaceId ISocketFactory::iid ("ISocketFactory");
-
-ISocketFactory::ISocketFactory ()
-  : Interface (ISocketFactory::iid)
-{}
-
-} // namespace ns3
--- a/src/node/i-socket-factory.h	Thu Jun 07 13:19:25 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef I_SOCKET_FACTORY_H
-#define I_SOCKET_FACTORY_H
-
-#include "ns3/interface.h"
-#include "ns3/ptr.h"
-
-namespace ns3 {
-
-class Socket;
-
-class ISocketFactory : public Interface
-{
-public:
-  static const InterfaceId iid;
-
-  ISocketFactory ();
-
-  virtual Ptr<Socket> CreateSocket (void) = 0;
-};
-
-} // namespace ns3
-
-
-#endif /* I_SOCKET_FACTORY_H */
--- a/src/node/i-udp.cc	Thu Jun 07 13:19:25 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#include "i-udp.h"
-
-namespace ns3 {
-
-const InterfaceId IUdp::iid ("IUdp");
-
-IUdp::IUdp ()
-{
-  AddSelfInterface (IUdp::iid, this);
-}
-
-} // namespace ns3
--- a/src/node/i-udp.h	Thu Jun 07 13:19:25 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 INRIA
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef I_UDP_H
-#define I_UDP_H
-
-#include "i-socket-factory.h"
-
-namespace ns3 {
-
-class Socket;
-
-class IUdp : public ISocketFactory
-{
-public:
-  static const InterfaceId iid;
-
-  IUdp ();
-
-  virtual Ptr<Socket> CreateSocket (void) = 0;
-};
-
-} // namespace ns3
-
-#endif /* I_UDP_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ipv4.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -0,0 +1,35 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "ipv4.h"
+
+namespace ns3 {
+
+const InterfaceId Ipv4::iid = MakeInterfaceId ("Ipv4", Object::iid);
+
+Ipv4::Ipv4 ()
+{
+  SetInterfaceId (Ipv4::iid);
+}
+
+Ipv4::~Ipv4 ()
+{}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ipv4.h	Tue Jun 12 22:54:10 2007 +0200
@@ -0,0 +1,192 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef IPV4_H
+#define IPV4_H
+
+#include <stdint.h>
+#include "ns3/ipv4-address.h"
+#include "ns3/object.h"
+#include "ipv4-route.h"
+
+namespace ns3 {
+
+class NetDevice;
+class Packet;
+class Ipv4Route;
+/**
+ * \brief Access to the Ipv4 forwarding table and to the ipv4 interfaces
+ *
+ * This class allows you to create ipv4 interfaces based on a NetDevice.
+ * Multiple interfaces can be created for a single NetDevice, hence
+ * achieving multihoming.
+ *
+ * This class also allows you to control the content of the ipv4 
+ * forwarding table.
+ */
+class Ipv4 : public Object
+{
+public:
+  static const InterfaceId iid;
+  Ipv4 ();
+  virtual ~Ipv4 ();
+    
+  /**
+   * \param dest destination address
+   * \param nextHop address of next hop.
+   * \param interface interface of next hop.
+   *
+   * Add route to host dest through host nextHop 
+   * on interface.
+   */
+  virtual void AddHostRouteTo (Ipv4Address dest, 
+			       Ipv4Address nextHop, 
+			       uint32_t interface) = 0;
+  /**
+   * \param dest destination address
+   * \param interface of next hop
+   *
+   * add route to host dest on interface.
+   */
+  virtual void AddHostRouteTo (Ipv4Address dest, 
+			       uint32_t interface) = 0;
+
+  /**
+   * \param network destination network
+   * \param networkMask netmask of destination network
+   * \param nextHop address of next hop
+   * \param interface interface of next hop
+   * 
+   * add route to network dest with netmask 
+   * through host nextHop on interface
+   */
+  virtual void AddNetworkRouteTo (Ipv4Address network, 
+				  Ipv4Mask networkMask, 
+				  Ipv4Address nextHop, 
+				  uint32_t interface) = 0;
+
+  /**
+   * \param network destination network
+   * \param networkMask netmask of destination network
+   * \param interface interface of next hop
+   *
+   * add route to network dest with netmask 
+   * on interface
+   */
+  virtual void AddNetworkRouteTo (Ipv4Address network, 
+				  Ipv4Mask networkMask, 
+				  uint32_t interface) = 0;
+  /**
+   * \param nextHop address of default next hop
+   * \param interface interface of default next hop.
+   * 
+   * set the default route to host nextHop on
+   * interface. 
+   */
+  virtual void SetDefaultRoute (Ipv4Address nextHop, 
+				uint32_t interface) = 0;
+
+  /**
+   * \returns the number of entries in the routing table.
+   */
+  virtual uint32_t GetNRoutes (void) = 0;
+  /**
+   * \param i index of route to return
+   * \returns the route whose index is i
+   */
+  virtual Ipv4Route GetRoute (uint32_t i) = 0;
+  /**
+   * \param i index of route to remove from routing table.
+   */
+  virtual void RemoveRoute (uint32_t i) = 0;
+  
+  /**
+   * \param device device to add to the list of ipv4 interfaces
+   *        which can be used as output interfaces during packet forwarding.
+   * \returns the index of the ipv4 interface added.
+   *
+   * Once a device has been added, it can never be removed: if you want
+   * to disable it, you can invoke Ipv4::SetDown which will
+   * make sure that it is never used during packet forwarding.
+   */
+  virtual uint32_t AddInterface (Ptr<NetDevice> device) = 0;
+  /**
+   * \returns the number of interfaces added by the user.
+   */
+  virtual uint32_t GetNInterfaces (void) = 0;  
+
+  /**
+   * \param i index of ipv4 interface
+   * \returns the NetDevice associated with the ipv4 interface index
+   */
+  virtual Ptr<NetDevice> GetNetDevice (uint32_t i) = 0;
+
+  /**
+   * \param i index of ipv4 interface
+   * \param address address to associate to the underlying ipv4 interface
+   */
+  virtual void SetAddress (uint32_t i, Ipv4Address address) = 0;
+  /**
+   * \param i index of ipv4 interface
+   * \param mask mask to associate to the underlying ipv4 interface
+   */
+  virtual void SetNetworkMask (uint32_t i, Ipv4Mask mask) = 0;
+  /**
+   * \param i index of ipv4 interface
+   * \returns the mask associated to the underlying ipv4 interface
+   */
+  virtual Ipv4Mask GetNetworkMask (uint32_t i) const = 0;
+  /**
+   * \param i index of ipv4 interface
+   * \returns the address associated to the underlying ipv4 interface
+   */
+  virtual Ipv4Address GetAddress (uint32_t i) const = 0;
+  /**
+   * \param i index of ipv4 interface
+   * \returns the Maximum Transmission Unit (in bytes) associated
+   *          to the underlying ipv4 interface
+   */
+  virtual uint16_t GetMtu (uint32_t i) const = 0;
+  /**
+   * \param i index of ipv4 interface
+   * \returns true if the underlying interface is in the "up" state,
+   *          false otherwise.
+   */
+  virtual bool IsUp (uint32_t i) const = 0;
+  /**
+   * \param i index of ipv4 interface
+   * 
+   * Set the interface into the "up" state. In this state, it is
+   * considered valid during ipv4 forwarding.
+   */
+  virtual void SetUp (uint32_t i) = 0;
+  /**
+   * \param i index of ipv4 interface
+   *
+   * Set the interface into the "down" state. In this state, it is
+   * ignored during ipv4 forwarding.
+   */
+  virtual void SetDown (uint32_t i) = 0;
+  
+};
+
+} // namespace ns3 
+
+#endif /* IPV4_H */
--- a/src/node/net-device.cc	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/node/net-device.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -21,19 +21,18 @@
 
 #include <iostream>
 #include "ns3/assert.h"
-#include "ns3/interface.h"
+#include "ns3/object.h"
 
 #include "channel.h"
 #include "net-device.h"
 #include "llc-snap-header.h"
-#include "i-node.h"
+#include "node.h"
 
 namespace ns3 {
 
-const InterfaceId NetDevice::iid ("NetDevice");
+const InterfaceId NetDevice::iid = MakeInterfaceId ("NetDevice", Object::iid);
 
-NetDevice::NetDevice(Ptr<INode> node, const MacAddress& addr) : 
-  Interface (NetDevice::iid),
+NetDevice::NetDevice(Ptr<Node> node, const MacAddress& addr) : 
   m_node (node), 
   m_name(""), 
   m_ifIndex (0), 
@@ -44,6 +43,7 @@
   m_isMulticast (false), 
   m_isPointToPoint (false)
 {
+  SetInterfaceId (NetDevice::iid);
   m_node->AddDevice (this);
 }
 
@@ -229,8 +229,8 @@
     }
 }
 
-Ptr<INode>
-NetDevice::GetINode (void) const
+Ptr<Node>
+NetDevice::GetNode (void) const
 {
   return m_node;
 }
--- a/src/node/net-device.h	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/node/net-device.h	Tue Jun 12 22:54:10 2007 +0200
@@ -25,13 +25,13 @@
 #include <stdint.h>
 #include "ns3/callback.h"
 #include "ns3/packet.h"
-#include "ns3/interface.h"
+#include "ns3/object.h"
 #include "ns3/ptr.h"
 #include "mac-address.h"
 
 namespace ns3 {
 
-class INode;
+class Node;
 class TraceResolver;
 class TraceContext;
 class Channel;
@@ -55,7 +55,7 @@
  * this base class and implement your own version of the
  * NetDevice::SendTo method.
  */
-class NetDevice : public Interface
+class NetDevice : public Object
 {
 public:
   static const InterfaceId iid;
@@ -166,7 +166,7 @@
    * base class to print the nodeid for example, it can invoke
    * this method.
    */
-  Ptr<INode> GetINode (void) const;
+  Ptr<Node> GetNode (void) const;
 
   /**
    * \returns true if ARP is needed, false otherwise.
@@ -187,7 +187,7 @@
    * \param node base class node pointer of device's node 
    * \param addr MAC address of this device.
    */
-  NetDevice(Ptr<INode> node, const MacAddress& addr);
+  NetDevice(Ptr<Node> node, const MacAddress& addr);
   /**
    * Enable broadcast support. This method should be
    * called by subclasses from their constructor
@@ -279,7 +279,7 @@
    */
   virtual Ptr<Channel> DoGetChannel (void) const = 0;
 
-  Ptr<INode>         m_node;
+  Ptr<Node>         m_node;
   std::string   m_name;
   uint16_t      m_ifIndex;
   MacAddress    m_address;
--- a/src/node/node-list.cc	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/node/node-list.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -25,7 +25,7 @@
 #include "ns3/simulator.h"
 #include "ns3/simulation-singleton.h"
 #include "node-list.h"
-#include "i-node.h"
+#include "node.h"
 
 namespace {
 static class Initialization 
@@ -49,26 +49,26 @@
   NodeListPriv ();
   ~NodeListPriv ();
 
-  uint32_t Add (Ptr<INode> node);
+  uint32_t Add (Ptr<Node> node);
   NodeList::Iterator Begin (void);
   NodeList::Iterator End (void);
   TraceResolver *CreateTraceResolver (TraceContext const &context);
-  INode *PeekINode (uint32_t n);
-  Ptr<INode> GetINode (uint32_t n);
-  uint32_t GetNINodes (void);
+  Node *PeekNode (uint32_t n);
+  Ptr<Node> GetNode (uint32_t n);
+  uint32_t GetNNodes (void);
 
 private:
-  std::vector<Ptr<INode> > m_nodes;
+  std::vector<Ptr<Node> > m_nodes;
 };
 
 NodeListPriv::NodeListPriv ()
 {}
 NodeListPriv::~NodeListPriv ()
 {
-  for (std::vector<Ptr<INode> >::iterator i = m_nodes.begin ();
+  for (std::vector<Ptr<Node> >::iterator i = m_nodes.begin ();
        i != m_nodes.end (); i++)
     {
-      Ptr<INode> node = *i;
+      Ptr<Node> node = *i;
       node->Dispose ();
       *i = 0;
     }
@@ -77,7 +77,7 @@
 
 
 uint32_t
-NodeListPriv::Add (Ptr<INode> node)
+NodeListPriv::Add (Ptr<Node> node)
 {
   uint32_t index = m_nodes.size ();
   m_nodes.push_back (node);
@@ -95,18 +95,18 @@
   return m_nodes.end ();
 }
 uint32_t 
-NodeListPriv::GetNINodes (void)
+NodeListPriv::GetNNodes (void)
 {
   return m_nodes.size ();
 }
-INode *
-NodeListPriv::PeekINode (uint32_t n)
+Node *
+NodeListPriv::PeekNode (uint32_t n)
 {
   return PeekPointer (m_nodes[n]);
 }
 
-Ptr<INode>
-NodeListPriv::GetINode (uint32_t n)
+Ptr<Node>
+NodeListPriv::GetNode (uint32_t n)
 {
   return m_nodes[n];
 }
@@ -115,11 +115,11 @@
 TraceResolver *
 NodeListPriv::CreateTraceResolver (TraceContext const &context)
 {
-  ArrayTraceResolver<INode> *resolver =
-    new ArrayTraceResolver<INode>
+  ArrayTraceResolver<Node> *resolver =
+    new ArrayTraceResolver<Node>
     (context, 
-     MakeCallback (&NodeListPriv::GetNINodes, this),
-     MakeCallback (&NodeListPriv::PeekINode, this));
+     MakeCallback (&NodeListPriv::GetNNodes, this),
+     MakeCallback (&NodeListPriv::PeekNode, this));
   return resolver;
 }
 
@@ -133,7 +133,7 @@
 namespace ns3 {
 
 uint32_t
-NodeList::Add (Ptr<INode> node)
+NodeList::Add (Ptr<Node> node)
 {
   return SimulationSingleton<NodeListPriv>::Get ()->Add (node);
 }
@@ -152,10 +152,10 @@
 {
   return SimulationSingleton<NodeListPriv>::Get ()->CreateTraceResolver (context);
 }
-Ptr<INode>
-NodeList::GetINode (uint32_t n)
+Ptr<Node>
+NodeList::GetNode (uint32_t n)
 {
-  return SimulationSingleton<NodeListPriv>::Get ()->GetINode (n);
+  return SimulationSingleton<NodeListPriv>::Get ()->GetNode (n);
 }
 
 
--- a/src/node/node-list.h	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/node/node-list.h	Tue Jun 12 22:54:10 2007 +0200
@@ -28,29 +28,29 @@
 
 namespace ns3 {
 
-class INode;
+class Node;
 class TraceResolver;
 class TraceContext;
 
 /**
  * \brief the list of simulation nodes.
  *
- * Every INode created is automatically added to this list.
+ * Every Node created is automatically added to this list.
  */
 class NodeList
 {
 public:
-  typedef ArrayTraceResolver<INode>::Index NodeIndex;
-  typedef std::vector< Ptr<INode> >::iterator Iterator;
+  typedef ArrayTraceResolver<Node>::Index NodeIndex;
+  typedef std::vector< Ptr<Node> >::iterator Iterator;
 
   /**
    * \param node node to add
    * \returns index of node in list.
    *
-   * This method is called automatically from INode::INode so
+   * This method is called automatically from Node::Node so
    * the user has little reason to call it himself.
    */
-  static uint32_t Add (Ptr<INode> node);
+  static uint32_t Add (Ptr<Node> node);
   /**
    * \returns a C++ iterator located at the beginning of this
    *          list.
@@ -71,9 +71,9 @@
 
   /**
    * \param n index of requested node.
-   * \returns the INode associated to index n.
+   * \returns the Node associated to index n.
    */
-  static Ptr<INode> GetINode (uint32_t n);
+  static Ptr<Node> GetNode (uint32_t n);
 };
 
 }//namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/node.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -0,0 +1,132 @@
+// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+// 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: George F. Riley<riley@ece.gatech.edu>
+//
+
+// Implement the basic Node object for ns3.
+// George F. Riley, Georgia Tech, Fall 2006
+
+#include "node.h"
+#include "node-list.h"
+#include "net-device.h"
+#include "application.h"
+#include "ns3/simulator.h"
+
+namespace ns3{
+
+const InterfaceId Node::iid = MakeInterfaceId ("Node", Object::iid);
+
+Node::Node()
+  : m_id(0), 
+    m_sid(0)
+{
+  SetInterfaceId (Node::iid);
+  m_id = NodeList::Add (this);
+}
+
+Node::Node(uint32_t sid)
+  : m_id(0), 
+    m_sid(sid)
+{ 
+  SetInterfaceId (Node::iid);
+  m_id = NodeList::Add (this);
+}
+  
+Node::~Node ()
+{}
+
+TraceResolver *
+Node::CreateTraceResolver (TraceContext const &context)
+{
+  return DoCreateTraceResolver (context);
+}
+
+uint32_t 
+Node::GetId (void) const
+{
+  return m_id;
+}
+
+uint32_t 
+Node::GetSystemId (void) const
+{
+  return m_sid;
+}
+
+uint32_t 
+Node::AddDevice (Ptr<NetDevice> device)
+{
+  uint32_t index = m_devices.size ();
+  m_devices.push_back (device);
+  DoAddDevice (device);
+  device->SetIfIndex(index);
+  return index;
+}
+Ptr<NetDevice>
+Node::GetDevice (uint32_t index) const
+{
+  return m_devices[index];
+}
+uint32_t 
+Node::GetNDevices (void) const
+{
+  return m_devices.size ();
+}
+
+uint32_t 
+Node::AddApplication (Ptr<Application> application)
+{
+  uint32_t index = m_applications.size ();
+  m_applications.push_back (application);
+  return index;
+}
+Ptr<Application> 
+Node::GetApplication (uint32_t index) const
+{
+  return m_applications[index];
+}
+uint32_t 
+Node::GetNApplications (void) const
+{
+  return m_applications.size ();
+}
+
+
+void Node::DoDispose()
+{
+  for (std::vector<Ptr<NetDevice> >::iterator i = m_devices.begin ();
+       i != m_devices.end (); i++)
+    {
+      Ptr<NetDevice> device = *i;
+      device->Dispose ();
+      *i = 0;
+    }
+  m_devices.clear ();
+  for (std::vector<Ptr<Application> >::iterator i = m_applications.begin ();
+       i != m_applications.end (); i++)
+    {
+      Ptr<Application> application = *i;
+      application->Dispose ();
+      *i = 0;
+    }
+  m_applications.clear ();
+  Object::DoDispose ();
+}
+
+}//namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/node.h	Tue Jun 12 22:54:10 2007 +0200
@@ -0,0 +1,173 @@
+// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+// 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: George F. Riley<riley@ece.gatech.edu>
+//
+
+// Define the basic Node object for ns3.
+// George F. Riley, Georgia Tech, Fall 2006
+
+#ifndef I_NODE_H
+#define I_NODE_H
+
+#include <vector>
+
+#include "ns3/object.h"
+
+namespace ns3 {
+
+class TraceContext;
+class TraceResolver;
+class NetDevice;
+class Application;
+
+/**
+ * \brief A network Node.
+ *
+ * This class holds together:
+ *   - a list of NetDevice objects which represent the network interfaces
+ *     of this node which are connected to other Node instances through
+ *     Channel instances.
+ *   - a list of Application objects which represent the userspace
+ *     traffic generation applications which interact with the Node
+ *     through the Socket API.
+ *   - a node Id: a unique per-node identifier.
+ *   - a system Id: a unique Id used for parallel simulations.
+ *   - a trace resolver which can be used to connect user trace sinks
+ *     to the node's trace sources.
+ *
+ * Every Node created is added to the NodeList automatically.
+ */
+class Node : public Object
+{
+public:
+  static const InterfaceId iid;
+
+  virtual ~Node();
+
+  /**
+   * \param context the trace context for the TraceResolver to create
+   * \returns a newly-created TraceResolver. The caller takes
+   *          ownership of the returned pointer.
+   *
+   * Request the Node to create a trace resolver. This method
+   * could be used directly by a user who needs access to very low-level
+   * trace configuration.
+   */
+  TraceResolver *CreateTraceResolver (TraceContext const &context);
+
+  /**
+   * \returns the unique id of this node.
+   * 
+   * This unique id happens to be also the index of the Node into
+   * the NodeList. 
+   */
+  uint32_t GetId (void) const;
+
+  /**
+   * \returns the system id for parallel simulations associated
+   *          to this node.
+   */
+  uint32_t GetSystemId (void) const;
+
+  /**
+   * \param device NetDevice to associate to this node.
+   * \returns the index of the NetDevice into the Node's list of
+   *          NetDevice.
+   *
+   * Associate this device to this node.
+   * This method is called automatically from NetDevice::NetDevice
+   * so the user has little reason to call this method himself.
+   */
+  uint32_t AddDevice (Ptr<NetDevice> device);
+  /**
+   * \param index the index of the requested NetDevice
+   * \returns the requested NetDevice associated to this Node.
+   */
+  Ptr<NetDevice> GetDevice (uint32_t index) const;
+  /**
+   * \returns the number of NetDevice instances associated
+   *          to this Node.
+   */
+  uint32_t GetNDevices (void) const;
+
+  /**
+   * \param application Application to associate to this node.
+   * \returns the index of the Application within the Node's list
+   *          of Application.
+   *
+   * Associated this Application to this Node. This method is called
+   * automatically from Application::Application so the user
+   * has little reasons to call this method directly.
+   */
+  uint32_t AddApplication (Ptr<Application> application);
+  /**
+   * \param index
+   * \returns the application associated to this requested index
+   *          within this Node.
+   */
+  Ptr<Application> GetApplication (uint32_t index) const;
+  /**
+   * \returns the number of applications associated to this Node.
+   */
+  uint32_t GetNApplications (void) const;
+
+protected:
+  /**
+   * Must be invoked by subclasses only.
+   */
+  Node();
+  /**
+   * \param systemId a unique integer used for parallel simulations.
+   *
+   * Must be invoked by subclasses only.
+   */
+  Node(uint32_t systemId);
+  /**
+   * The dispose method. Subclasses must override this method
+   * and must chain up to it by calling Node::DoDispose at the
+   * end of their own DoDispose method.
+   */
+  virtual void DoDispose (void);
+private:
+  /**
+   * \param context the trace context
+   * \returns a trace resolver to the user. The user must delete it.
+   *
+   * Subclasses must implement this method.
+   */
+  virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context) = 0;
+  /**
+   * \param device the device added to this Node.
+   *
+   * This method is invoked whenever a user calls Node::AddDevice.
+   * Subclasses are expected to call NetDevice::SetReceiveCallback
+   * at this point to setup the node's receive function for
+   * the NetDevice packets.
+   */
+  virtual void DoAddDevice (Ptr<NetDevice> device) const = 0;
+
+  uint32_t    m_id;         // Node id for this node
+  uint32_t    m_sid;        // System id for this node
+  std::vector<Ptr<NetDevice> > m_devices;
+  std::vector<Ptr<Application> > m_applications;
+};
+
+} //namespace ns3
+
+#endif /* I_NODE_H */
--- a/src/node/queue.cc	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/node/queue.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -27,10 +27,11 @@
 
 namespace ns3 {
 
-const InterfaceId Queue::iid ("Queue");
+const InterfaceId Queue::iid = MakeInterfaceId ("Queue", Object::iid);
+static ClassIdDefaultValue g_classIdDefaultValue ("Queue", "Packet Queue",
+                                                  Queue::iid, "DropTailQueue");
 
 Queue::Queue() : 
-  Interface (Queue::iid),
   m_nBytes(0), 
   m_nTotalReceivedBytes(0),
   m_nPackets(0), 
@@ -38,6 +39,7 @@
   m_nTotalDroppedBytes(0),
   m_nTotalDroppedPackets(0)
 {
+  SetInterfaceId (Queue::iid);
   NS_DEBUG("Queue::Queue ()");
 }
 
@@ -199,27 +201,9 @@
 Ptr<Queue>
 Queue::CreateDefault (void)
 {
-  std::string defaultValue = GetDefault ()->GetValue ();
-  ClassId classId = ComponentManager::LookupByName (defaultValue);
+  ClassId classId = g_classIdDefaultValue.GetValue ();
   Ptr<Queue> queue = ComponentManager::Create<Queue> (classId, Queue::iid);
   return queue;
 }
-void 
-Queue::Add (const std::string &name)
-{
-  GetDefault ()->AddPossibleValue (name);
-}
-void 
-Queue::AddDefault (const std::string &name)
-{
-  GetDefault ()->AddDefaultValue (name);
-}
-StringEnumDefaultValue *
-Queue::GetDefault (void)
-{
-  static StringEnumDefaultValue value ("Queue", "Packet Queue");
-  return &value;
-}
-
 
 }; // namespace ns3
--- a/src/node/queue.h	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/node/queue.h	Tue Jun 12 22:54:10 2007 +0200
@@ -28,7 +28,7 @@
 #include <string>
 #include <list>
 #include "ns3/packet.h"
-#include "ns3/interface.h"
+#include "ns3/object.h"
 #include "ns3/callback-trace-source.h"
 #include "ns3/trace-resolver.h"
 
@@ -41,7 +41,7 @@
  * 
  * This class defines the base APIs for packet queues in the ns-3 system
  */
-class Queue : public Interface
+class Queue : public Object
 {
 public:
   static const InterfaceId iid;
@@ -172,10 +172,6 @@
    * \return a Queue smart pointer that is the default Queue type defined
    */
   static Ptr<Queue> CreateDefault (void);
-  static void Add (const std::string &name);
-  static void AddDefault (const std::string &name);
-private:
-  static StringEnumDefaultValue *GetDefault (void);
 };
 
 }; // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/socket-factory.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -0,0 +1,32 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "socket-factory.h"
+
+namespace ns3 {
+
+const InterfaceId SocketFactory::iid = MakeInterfaceId ("SocketFactory", Object::iid);
+
+SocketFactory::SocketFactory ()
+{
+  SetInterfaceId (SocketFactory::iid);
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/socket-factory.h	Tue Jun 12 22:54:10 2007 +0200
@@ -0,0 +1,44 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef SOCKET_FACTORY_H
+#define SOCKET_FACTORY_H
+
+#include "ns3/object.h"
+#include "ns3/ptr.h"
+
+namespace ns3 {
+
+class Socket;
+
+class SocketFactory : public Object
+{
+public:
+  static const InterfaceId iid;
+
+  SocketFactory ();
+
+  virtual Ptr<Socket> CreateSocket (void) = 0;
+};
+
+} // namespace ns3
+
+
+#endif /* SOCKET_FACTORY_H */
--- a/src/node/socket.h	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/node/socket.h	Tue Jun 12 22:54:10 2007 +0200
@@ -29,7 +29,7 @@
 
 namespace ns3 {
 
-class INode;
+class Node;
 
 /**
  * \brief Define a Socket API based on the BSD Socket API.
@@ -66,7 +66,7 @@
   /**
    * \returns the node this socket is associated with.
    */
-  virtual Ptr<INode> GetINode (void) const = 0;
+  virtual Ptr<Node> GetNode (void) const = 0;
 
   /** 
    * Allocate a free port number and
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/udp.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -0,0 +1,32 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "udp.h"
+
+namespace ns3 {
+
+const InterfaceId Udp::iid = MakeInterfaceId ("Udp", SocketFactory::iid);
+
+Udp::Udp ()
+{
+  SetInterfaceId (Udp::iid);
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/udp.h	Tue Jun 12 22:54:10 2007 +0200
@@ -0,0 +1,42 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef UDP_H
+#define UDP_H
+
+#include "socket-factory.h"
+
+namespace ns3 {
+
+class Socket;
+
+class Udp : public SocketFactory
+{
+public:
+  static const InterfaceId iid;
+
+  Udp ();
+
+  virtual Ptr<Socket> CreateSocket (void) = 0;
+};
+
+} // namespace ns3
+
+#endif /* UDP_H */
--- a/src/node/wscript	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/node/wscript	Tue Jun 12 22:54:10 2007 +0200
@@ -7,38 +7,38 @@
     node.target = node.name
     node.uselib_local = ['ns3-core', 'ns3-common', 'ns3-simulator']
     node.source = [
-        'i-node.cc',
+        'node.cc',
         'ipv4-address.cc',
         'net-device.cc',
         'mac-address.cc',
         'llc-snap-header.cc',
         'ipv4-route.cc',
         'queue.cc',
-        'drop-tail.cc',
+        'drop-tail-queue.cc',
         'channel.cc',
         'node-list.cc',
         'socket.cc',
-        'i-socket-factory.cc',
-        'i-udp.cc',
-        'i-ipv4.cc',
+        'socket-factory.cc',
+        'udp.cc',
+        'ipv4.cc',
         'application.cc',
         ]
 
     headers = bld.create_obj('ns3header')
     headers.source = [
-        'i-node.h',
+        'node.h',
         'ipv4-address.h',
         'net-device.h',
         'mac-address.h',
         'ipv4-route.h',
         'queue.h',
-        'drop-tail.h',
+        'drop-tail-queue.h',
         'llc-snap-header.h',
         'channel.h',
         'node-list.h',
         'socket.h',
-        'i-socket-factory.h',
-        'i-udp.h',
-        'i-ipv4.h',
+        'socket-factory.h',
+        'udp.h',
+        'ipv4.h',
         'application.h',
         ]
--- a/src/wscript	Thu Jun 07 13:19:25 2007 +0200
+++ b/src/wscript	Tue Jun 12 22:54:10 2007 +0200
@@ -1,6 +1,6 @@
 ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
 
-import os
+import os, os.path
 import shutil
 
 import Action
@@ -27,16 +27,14 @@
     conf.sub_config('core')
     conf.sub_config('simulator')
 
+    blddir = os.path.abspath(os.path.join(conf.m_blddir, conf.env.variant()))
+    for module in all_modules:
+        conf.env.append_value('NS3_MODULE_PATH', os.path.join(blddir, 'src', module))
+
 
 def build(bld):
     Object.register('ns3header', Ns3Header)
     Action.Action('ns3_headers', func=_ns3_headers_inst, color='BLUE')
-
-    env = bld.env_of_name('default')
-    for module in all_modules:
-        node = bld.m_curdirnode.find_dir(module)
-        node_path = node.abspath(env)
-        env.append_value('NS3_MODULE_PATH', node_path)
     
     bld.add_subdirs(all_modules)
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/utils/bench-object.cc	Tue Jun 12 22:54:10 2007 +0200
@@ -0,0 +1,43 @@
+#include <vector>
+#include <stdlib.h>
+#include "ns3/object.h"
+
+using namespace ns3;
+
+class BaseA : public ns3::Object
+{
+public:
+  static const ns3::InterfaceId iid;
+  BaseA ()
+  {
+    SetInterfaceId (BaseA::iid);
+  }
+  virtual void Dispose (void) {}
+};
+
+const ns3::InterfaceId BaseA::iid = 
+ns3::MakeInterfaceId ("BaseABench", Object::iid);
+
+
+
+int main (int argc, char *argv[])
+{
+  int nobjects = atoi (argv[1]);
+  int nswaps = atoi (argv[2]);
+
+  std::vector< Ptr<BaseA> > objlist;
+
+  for (int i = 0; i < nobjects; ++i)
+    objlist.push_back (Create<BaseA> ());
+
+  for (int swapCounter = nswaps; swapCounter; --swapCounter)
+    {
+      int x1 = swapCounter % nobjects;
+      int x2 = (swapCounter+1) % nobjects;
+      Ptr<BaseA> obj1 = objlist[x1];
+      Ptr<BaseA> obj2 = objlist[x2];
+      objlist[x2] = obj1;
+      objlist[x1] = obj2;
+    }
+}
+
--- a/wscript	Thu Jun 07 13:19:25 2007 +0200
+++ b/wscript	Tue Jun 12 22:54:10 2007 +0200
@@ -93,6 +93,14 @@
     variant_name = bld.env_of_name('default')['NS3_ACTIVE_VARIANT']
     variant_env = bld.env_of_name(variant_name)
     bld.m_allenvs['default'] = variant_env # switch to the active variant
+
+    if Params.g_options.run:
+        run_program(Params.g_options.run)
+        return
+    elif Params.g_options.shell:
+        run_shell()
+        return
+
     # process subfolders from here
     bld.add_subdirs('src')
     bld.add_subdirs('samples utils examples')
@@ -116,12 +124,6 @@
     if Params.g_options.doxygen:
         doxygen()
 
-    if Params.g_options.run:
-        run_program(Params.g_options.run)
-
-    elif Params.g_options.shell:
-        run_shell()
-
 def _find_program(program_name):
     for obj in Object.g_allobjs:
         if obj.target == program_name: