implement the Node::ProtocolHandler support.
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Tue, 31 Jul 2007 09:09:31 +0200
changeset 1176 4894ea885c0f
parent 1175 00ad4ec69939
child 1177 c7bf3cf186ac
implement the Node::ProtocolHandler support.
src/internet-node/arp-l3-protocol.cc
src/internet-node/arp-l3-protocol.h
src/internet-node/internet-node.cc
src/internet-node/internet-node.h
src/internet-node/ipv4-l3-protocol.cc
src/internet-node/ipv4-l3-protocol.h
src/internet-node/ipv4-loopback-interface.cc
src/internet-node/ipv4-private.cc
src/internet-node/ipv4-private.h
src/internet-node/ipv4-static-routing.h
src/internet-node/l3-demux.cc
src/internet-node/l3-demux.h
src/internet-node/l3-protocol.cc
src/internet-node/l3-protocol.h
src/internet-node/udp-l4-protocol.cc
src/internet-node/wscript
src/node/node.cc
src/node/node.h
--- a/src/internet-node/arp-l3-protocol.cc	Tue Jul 31 07:54:26 2007 +0200
+++ b/src/internet-node/arp-l3-protocol.cc	Tue Jul 31 09:09:31 2007 +0200
@@ -24,11 +24,11 @@
 #include "ns3/node.h"
 #include "ns3/net-device.h"
 
+#include "ipv4-l3-protocol.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");
 
@@ -37,8 +37,7 @@
 const uint16_t ArpL3Protocol::PROT_NUMBER = 0x0806;
 
 ArpL3Protocol::ArpL3Protocol (Ptr<Node> node)
-  : L3Protocol (PROT_NUMBER, 0/* XXX: correct version number ? */ ),
-    m_node (node)
+  : m_node (node)
 {}
 
 ArpL3Protocol::~ArpL3Protocol ()
@@ -53,7 +52,7 @@
     }
   m_cacheList.clear ();
   m_node = 0;
-  L3Protocol::DoDispose ();
+  Object::DoDispose ();
 }
 
 TraceResolver *
@@ -72,7 +71,7 @@
 	  return *i;
 	}
     }
-  Ptr<Ipv4Private> ipv4 = m_node->QueryInterface<Ipv4Private> (Ipv4Private::iid);
+  Ptr<Ipv4L3Protocol> ipv4 = m_node->QueryInterface<Ipv4L3Protocol> (Ipv4L3Protocol::iid);
   Ipv4Interface *interface = ipv4->FindInterfaceForDevice (device);
   ArpCache * cache = new ArpCache (device, interface);
   NS_ASSERT (device->IsBroadcast ());
@@ -82,10 +81,11 @@
 }
 
 void 
-ArpL3Protocol::Receive(Packet& packet, Ptr<NetDevice> device)
+ArpL3Protocol::Receive(const Packet& p, uint16_t protocol, Ptr<NetDevice> device)
 {
   ArpCache *cache = FindCache (device);
   ArpHeader arp;
+  Packet packet = p;
   packet.RemoveHeader (arp);
   
   NS_DEBUG ("ARP: received "<< (arp.IsRequest ()? "request" : "reply") <<
--- a/src/internet-node/arp-l3-protocol.h	Tue Jul 31 07:54:26 2007 +0200
+++ b/src/internet-node/arp-l3-protocol.h	Tue Jul 31 09:09:31 2007 +0200
@@ -25,7 +25,6 @@
 #include "ns3/ipv4-address.h"
 #include "ns3/address.h"
 #include "ns3/ptr.h"
-#include "l3-protocol.h"
 
 namespace ns3 {
 
@@ -38,7 +37,7 @@
 /**
  * \brief An implementation of the ARP protocol
  */
-class ArpL3Protocol : public L3Protocol
+class ArpL3Protocol : public Object
 {
 public:
   static const uint16_t PROT_NUMBER;
@@ -47,13 +46,13 @@
    * \param node The node which this ARP object is associated with
    */
   ArpL3Protocol (Ptr<Node> node);
-  ~ArpL3Protocol ();
+  virtual ~ArpL3Protocol ();
 
   virtual TraceResolver *CreateTraceResolver (TraceContext const &context);
   /**
    * \brief Recieve a packet
    */
-  virtual void Receive(Packet& p, Ptr<NetDevice> device);
+  void Receive(const Packet& p, uint16_t protocol, Ptr<NetDevice> device);
   /**
    * \brief Perform an ARP lookup
    * \param p
--- a/src/internet-node/internet-node.cc	Tue Jul 31 07:54:26 2007 +0200
+++ b/src/internet-node/internet-node.cc	Tue Jul 31 09:09:31 2007 +0200
@@ -23,8 +23,8 @@
 
 #include "ns3/composite-trace-resolver.h"
 #include "ns3/net-device.h"
+#include "ns3/callback.h"
 
-#include "l3-demux.h"
 #include "ipv4-l4-demux.h"
 #include "internet-node.h"
 #include "udp-l4-protocol.h"
@@ -33,7 +33,6 @@
 #include "udp-impl.h"
 #include "arp-private.h"
 #include "ipv4-impl.h"
-#include "ipv4-private.h"
 
 namespace ns3 {
 
@@ -56,25 +55,25 @@
 {
   Ptr<Ipv4L3Protocol> ipv4 = Create<Ipv4L3Protocol> (this);
   Ptr<ArpL3Protocol> arp = Create<ArpL3Protocol> (this);
-  Ptr<UdpL4Protocol> udp = Create<UdpL4Protocol> (this);
+  // XXX remove the PeekPointer below.
+  RegisterProtocolHandler (MakeCallback (&Ipv4L3Protocol::Receive, PeekPointer (ipv4)), 
+                           Ipv4L3Protocol::PROT_NUMBER, 0);
+  RegisterProtocolHandler (MakeCallback (&ArpL3Protocol::Receive, PeekPointer (arp)),
+                           ArpL3Protocol::PROT_NUMBER, 0);
 
-  Ptr<L3Demux> l3Demux = Create<L3Demux> (this);
+
   Ptr<Ipv4L4Demux> ipv4L4Demux = Create<Ipv4L4Demux> (this);
-
-  l3Demux->Insert (ipv4);
-  l3Demux->Insert (arp);
+  Ptr<UdpL4Protocol> udp = Create<UdpL4Protocol> (this);
   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 (ipv4);
   Object::AddInterface (ipv4Impl);
   Object::AddInterface (arpPrivate);
   Object::AddInterface (udpImpl);
-  Object::AddInterface (l3Demux);
   Object::AddInterface (ipv4L4Demux);
 }
 
@@ -83,9 +82,9 @@
 InternetNode::DoCreateTraceResolver (TraceContext const &context)
 {
   CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
-  Ptr<Ipv4Private> ipv4 = QueryInterface<Ipv4Private> (Ipv4Private::iid);
+  Ptr<Ipv4L3Protocol> ipv4 = QueryInterface<Ipv4L3Protocol> (Ipv4L3Protocol::iid);
   resolver->Add ("ipv4",
-                 MakeCallback (&Ipv4Private::CreateTraceResolver, PeekPointer (ipv4)),
+                 MakeCallback (&Ipv4L3Protocol::CreateTraceResolver, PeekPointer (ipv4)),
                  InternetNode::IPV4);
 
   return resolver;
@@ -97,25 +96,4 @@
   Node::DoDispose ();
 }
 
-void 
-InternetNode::DoAddDevice (Ptr<NetDevice> device)
-{
-  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	Tue Jul 31 07:54:26 2007 +0200
+++ b/src/internet-node/internet-node.h	Tue Jul 31 09:09:31 2007 +0200
@@ -46,7 +46,6 @@
 protected:
   virtual void DoDispose(void);
 private:
-  virtual void DoAddDevice (Ptr<NetDevice> device);
   virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
   bool ReceiveFromDevice (Ptr<NetDevice> device, const Packet &p, uint16_t protocolNumber) const;
   void Construct (void);
--- a/src/internet-node/ipv4-l3-protocol.cc	Tue Jul 31 07:54:26 2007 +0200
+++ b/src/internet-node/ipv4-l3-protocol.cc	Tue Jul 31 09:09:31 2007 +0200
@@ -41,11 +41,11 @@
 
 namespace ns3 {
 
+const InterfaceId Ipv4L3Protocol::iid = MakeInterfaceId ("Ipv4L3Protocol", Object::iid);
 const uint16_t Ipv4L3Protocol::PROT_NUMBER = 0x0800;
 
 Ipv4L3Protocol::Ipv4L3Protocol(Ptr<Node> node)
-  : L3Protocol (PROT_NUMBER, 4),
-    m_nInterfaces (0),
+  : m_nInterfaces (0),
     m_defaultTtl (64),
     m_identification (0),
     m_node (node)
@@ -66,9 +66,9 @@
     }
   m_interfaces.clear ();
   m_node = 0;
-  L3Protocol::DoDispose ();
   m_staticRouting->Dispose ();
   m_staticRouting = 0;
+  Object::DoDispose ();
 }
 
 void
@@ -240,18 +240,19 @@
 }  
 
 void 
-Ipv4L3Protocol::Receive(Packet& packet, Ptr<NetDevice> device)
+Ipv4L3Protocol::Receive(const Packet& p, uint16_t protocol, 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);
+          m_rxTrace (p, index);
           break;
         }
       index++;
     }
+  Packet packet = p;
   Ipv4Header ipHeader;
   packet.RemoveHeader (ipHeader);
 
--- a/src/internet-node/ipv4-l3-protocol.h	Tue Jul 31 07:54:26 2007 +0200
+++ b/src/internet-node/ipv4-l3-protocol.h	Tue Jul 31 09:09:31 2007 +0200
@@ -30,7 +30,6 @@
 #include "ipv4-header.h"
 #include "ns3/ptr.h"
 #include "ns3/ipv4.h"
-#include "l3-protocol.h"
 #include "ipv4-static-routing.h"
 
 namespace ns3 {
@@ -46,9 +45,10 @@
 class TraceContext;
 
 
-class Ipv4L3Protocol : public L3Protocol 
+class Ipv4L3Protocol : public Object
 {
 public:
+  static const InterfaceId iid;
   static const uint16_t PROT_NUMBER;
 
   enum TraceType {
@@ -95,7 +95,7 @@
    *    - implement a per-NetDevice ARP cache
    *    - send back arp replies on the right device
    */
-  virtual void Receive(Packet& p, Ptr<NetDevice> device);
+  void Receive(const Packet& p, uint16_t protocol, Ptr<NetDevice> device);
 
   /**
    * \param packet packet to send
--- a/src/internet-node/ipv4-loopback-interface.cc	Tue Jul 31 07:54:26 2007 +0200
+++ b/src/internet-node/ipv4-loopback-interface.cc	Tue Jul 31 09:09:31 2007 +0200
@@ -23,7 +23,7 @@
 #include "ns3/net-device.h"
 #include "ns3/node.h"
 #include "ipv4-loopback-interface.h"
-#include "ipv4-private.h"
+#include "ipv4-l3-protocol.h"
 
 namespace ns3 {
 
@@ -43,8 +43,8 @@
 void 
 Ipv4LoopbackInterface::SendTo (Packet packet, Ipv4Address dest)
 {
-  Ptr<Ipv4Private> ipv4 = m_node->QueryInterface<Ipv4Private> (Ipv4Private::iid);
-  ipv4->Receive (packet, GetDevice ());
+  Ptr<Ipv4L3Protocol> ipv4 = m_node->QueryInterface<Ipv4L3Protocol> (Ipv4L3Protocol::iid);
+  ipv4->Receive (packet, Ipv4L3Protocol::PROT_NUMBER, GetDevice ());
 }
 
 }//namespace ns3
--- a/src/internet-node/ipv4-private.cc	Tue Jul 31 07:54:26 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 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
--- a/src/internet-node/ipv4-private.h	Tue Jul 31 07:54:26 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 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-static-routing.h	Tue Jul 31 07:54:26 2007 +0200
+++ b/src/internet-node/ipv4-static-routing.h	Tue Jul 31 09:09:31 2007 +0200
@@ -31,7 +31,6 @@
 #include "ipv4-header.h"
 #include "ns3/ptr.h"
 #include "ns3/ipv4.h"
-#include "l3-protocol.h"
 
 namespace ns3 {
 
--- a/src/internet-node/l3-demux.cc	Tue Jul 31 07:54:26 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +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 L3Protocols capability for ns3.
-// George F. Riley, Georgia Tech, Fall 2006
-#include <sstream>
-#include <string>
-#include "ns3/composite-trace-resolver.h"
-#include "ns3/node.h"
-#include "l3-demux.h"
-#include "l3-protocol.h"
-
-namespace ns3 {
-
-const InterfaceId L3Demux::iid = MakeInterfaceId ("L3Demux", Object::iid);
-
-L3Demux::L3Demux (Ptr<Node> node)
-  : m_node (node)
-{
-  SetInterfaceId (L3Demux::iid);
-}
-
-L3Demux::~L3Demux()
-{}
-
-void
-L3Demux::DoDispose (void)
-{
-  for (L3Map_t::iterator i = m_protocols.begin(); i != m_protocols.end(); ++i)
-    {
-      i->second->Dispose ();
-      i->second = 0;
-    }
-  m_protocols.clear ();
-  m_node = 0;
-  Object::DoDispose ();
-}
-
-TraceResolver *
-L3Demux::CreateTraceResolver (TraceContext const &context) const
-{
-  CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
-  for (L3Map_t::const_iterator i = m_protocols.begin(); i != m_protocols.end(); ++i)
-    {
-      std::string protValue;
-      std::ostringstream oss (protValue);
-      oss << i->second->GetProtocolNumber ();
-      ProtocolTraceType context = i->second->GetProtocolNumber ();
-      resolver->Add (protValue, 
-                     MakeCallback (&L3Protocol::CreateTraceResolver, PeekPointer (i->second)),
-                     context);
-    }
-  return resolver;
-}
-  
-void L3Demux::Insert(Ptr<L3Protocol> p)
-{
-  m_protocols.insert(L3Map_t::value_type(p->GetProtocolNumber (), p));
-}
-
-Ptr<L3Protocol>
-L3Demux::GetProtocol (int p)
-{ // Look up a protocol by protocol number
-  L3Map_t::iterator i = m_protocols.find(p);
-  if (i == m_protocols.end()) 
-    {
-      return 0;
-    }
-  return i->second; // Return the protocol
-}
-
-} //namespace ns3  
-  
--- a/src/internet-node/l3-demux.h	Tue Jul 31 07:54:26 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +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 L3Protocols capability for ns3.
-// George F. Riley, Georgia Tech, Fall 2006
-
-// This object manages the different layer 3 protocols for any ns3
-// node that has this capability.  
-
-#ifndef L3_DEMUX_H
-#define L3_DEMUX_H
-
-#include <map>
-#include "ns3/object.h"
-#include "ns3/ptr.h"
-
-namespace ns3 {
-
-class L3Protocol;
-class Node;
-class TraceResolver;
-class TraceContext;
-
-/**
- * \brief L3 Demux 
- */
-class L3Demux : public Object
-{
-public:
-  static const InterfaceId iid;
-  typedef int ProtocolTraceType;
-  L3Demux(Ptr<Node> node);
-  virtual ~L3Demux();
-
-  /**
-   * \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.
-   */
-  TraceResolver *CreateTraceResolver (TraceContext const &context) const;
-
-
-  /**
-   * \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 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.
-   */
-  void Insert(Ptr<L3Protocol> protocol);
-  /**
-   * \param protocolNumber number of protocol to lookup
-   *        in this L4 Demux
-   * \returns a matching L3 Protocol
-   *
-   * This method is typically called by lower layers
-   * to forward packets up the stack to the right protocol.
-   * It is also called from NodeImpl::GetIpv4 for example.
-   */
-  Ptr<L3Protocol> GetProtocol (int protocolNumber);
-protected:
-  virtual void DoDispose (void);
-private:
-  typedef std::map<int, Ptr<ns3::L3Protocol> > L3Map_t;
-
-  Ptr<Node> m_node;
-  L3Map_t m_protocols;
-};
-
-} //namespace ns3
-#endif
-
--- a/src/internet-node/l3-protocol.cc	Tue Jul 31 07:54:26 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +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>
-//
-
-// NS3 - Layer 3 Protocol base class
-// George F. Riley, Georgia Tech, Spring 2007
-
-#include "l3-protocol.h"
-
-
-namespace ns3 {
-
-L3Protocol::L3Protocol(int protocolNumber, int version)
-    : m_protocolNumber (protocolNumber),
-      m_version (version)
-{}
-L3Protocol::~L3Protocol ()
-{}
-
-int 
-L3Protocol::GetProtocolNumber (void) const
-{
-  return m_protocolNumber;
-}
-int 
-L3Protocol::GetVersion() const
-{
-  return m_version;
-}
-
-void
-L3Protocol::DoDispose (void)
-{
-  Object::DoDispose ();
-}
-
-}//namespace ns3
--- a/src/internet-node/l3-protocol.h	Tue Jul 31 07:54:26 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +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>
-//
-
-// NS3 - Layer 3 Protocol base class
-// George F. Riley, Georgia Tech, Spring 2007
-
-#ifndef L3_PROTOCOL_H
-#define L3_PROTOCOL_H
-
-#include "ns3/object.h"
-#include "ns3/ptr.h"
-
-namespace ns3 {
-
-class Packet;
-class NetDevice;
-class TraceResolver;
-class TraceContext;
-
-/**
- * ::Send is always defined in subclasses.
- */
-class L3Protocol : public Object {
-public:
-  L3Protocol(int protocolNumber, int version);
-  virtual ~L3Protocol ();
-  /**
-   * \return The protocol number of this Layer 3 protocol
-   */  
-  int GetProtocolNumber (void) const;
-  /**
-   * \return The version number of this protocol
-   */
-  int GetVersion() const;
-
-  virtual TraceResolver *CreateTraceResolver (TraceContext const &context) = 0;
-  /**
-   * 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) = 0;
-
-protected:
-  virtual void DoDispose (void);
-private:
-  int m_protocolNumber;
-  int m_version;
-};
-
-} // Namespace ns3
-
-#endif
--- a/src/internet-node/udp-l4-protocol.cc	Tue Jul 31 07:54:26 2007 +0200
+++ b/src/internet-node/udp-l4-protocol.cc	Tue Jul 31 09:09:31 2007 +0200
@@ -29,8 +29,6 @@
 #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 {
@@ -138,7 +136,7 @@
 
   packet.AddHeader (udpHeader);
 
-  Ptr<Ipv4Private> ipv4 = m_node->QueryInterface<Ipv4Private> (Ipv4Private::iid);
+  Ptr<Ipv4L3Protocol> ipv4 = m_node->QueryInterface<Ipv4L3Protocol> (Ipv4L3Protocol::iid);
   if (ipv4 != 0)
     {
       ipv4->Send (packet, saddr, daddr, PROT_NUMBER);
--- a/src/internet-node/wscript	Tue Jul 31 07:54:26 2007 +0200
+++ b/src/internet-node/wscript	Tue Jul 31 09:09:31 2007 +0200
@@ -8,8 +8,6 @@
     obj.uselib_local = ['ns3-node', 'ns3-applications']
     obj.source = [
         'internet-node.cc',
-        'l3-demux.cc',
-        'l3-protocol.cc',
         'ipv4-l4-demux.cc',
         'ipv4-l4-protocol.cc',
         'ipv4-header.cc',
@@ -29,7 +27,6 @@
         'ipv4-end-point-demux.cc',
         'arp-private.cc',
         'ipv4-impl.cc',
-        'ipv4-private.cc',
         'ascii-trace.cc',
         'pcap-trace.cc',
         'udp-impl.cc',
--- a/src/node/node.cc	Tue Jul 31 07:54:26 2007 +0200
+++ b/src/node/node.cc	Tue Jul 31 09:09:31 2007 +0200
@@ -1,32 +1,29 @@
-// -*- 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
-
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 Georgia Tech Research Corporation, INRIA
+ *
+ * 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
+ *
+ * Authors: George F. Riley<riley@ece.gatech.edu>
+ *          Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
 #include "node.h"
 #include "node-list.h"
 #include "net-device.h"
 #include "application.h"
 #include "ns3/simulator.h"
+#include "ns3/empty-trace-resolver.h"
 
 namespace ns3{
 
@@ -74,8 +71,9 @@
 {
   uint32_t index = m_devices.size ();
   m_devices.push_back (device);
-  DoAddDevice (device);
   device->SetIfIndex(index);
+  device->SetReceiveCallback (MakeCallback (&Node::ReceiveFromDevice, this));
+  NotifyDeviceAdded (device);
   return index;
 }
 Ptr<NetDevice>
@@ -129,4 +127,73 @@
   Object::DoDispose ();
 }
 
+TraceResolver *
+Node::DoCreateTraceResolver (TraceContext const &context)
+{
+  return new EmptyTraceResolver (context);
+}
+void 
+Node::NotifyDeviceAdded (Ptr<NetDevice> device)
+{}
+
+void
+Node::RegisterProtocolHandler (ProtocolHandler handler, 
+                               uint16_t protocolType,
+                               Ptr<NetDevice> device)
+{
+  struct Node::ProtocolHandlerEntry entry;
+  entry.handler = handler;
+  entry.isSpecificProtocol = true;
+  entry.protocol = protocolType;
+  entry.device = device;
+  m_handlers.push_back (entry);
+}
+
+void 
+Node::RegisterProtocolHandler (ProtocolHandler handler,
+                               Ptr<NetDevice> device)
+{
+  struct Node::ProtocolHandlerEntry entry;
+  entry.handler = handler;
+  entry.isSpecificProtocol = false;
+  entry.protocol = 0;
+  entry.device = device;
+  m_handlers.push_back (entry);
+}
+
+void
+Node::UnregisterProtocolHandler (ProtocolHandler handler)
+{
+  for (ProtocolHandlerList::iterator i = m_handlers.begin ();
+       i != m_handlers.end (); i++)
+    {
+      if (i->handler.IsEqual (handler))
+        {
+          m_handlers.erase (i);
+          break;
+        }
+    }
+}
+
+bool
+Node::ReceiveFromDevice (Ptr<NetDevice> device, const Packet &packet, uint16_t protocol)
+{
+  bool found = false;
+  for (ProtocolHandlerList::iterator i = m_handlers.begin ();
+       i != m_handlers.end (); i++)
+    {
+      if (i->device == 0 ||
+          (i->device != 0 && i->device == device))
+        {
+          if (!i->isSpecificProtocol || 
+              (i->isSpecificProtocol && i->protocol == protocol))
+            {
+              i->handler (packet, protocol, device);
+              found = true;
+            }
+        }
+    }
+  return found;
+}
+
 }//namespace ns3
--- a/src/node/node.h	Tue Jul 31 07:54:26 2007 +0200
+++ b/src/node/node.h	Tue Jul 31 09:09:31 2007 +0200
@@ -24,6 +24,7 @@
 #include <vector>
 
 #include "ns3/object.h"
+#include "ns3/callback.h"
 
 namespace ns3 {
 
@@ -31,6 +32,7 @@
 class TraceResolver;
 class NetDevice;
 class Application;
+class Packet;
 
 /**
  * \brief A network Node.
@@ -123,6 +125,41 @@
    */
   uint32_t GetNApplications (void) const;
 
+  /**
+   * A protocol handler
+   */
+  typedef Callback<void,const Packet &,uint16_t,Ptr<NetDevice> > ProtocolHandler;
+  /**
+   * \param handler the handler to register
+   * \param protocolType the type of protocol this handler is 
+   *        interested in.
+   * \param device the device attached to this handler. If the
+   *        value is zero, the handler is attached to all
+   *        devices on this node.
+   */
+  void RegisterProtocolHandler (ProtocolHandler handler, 
+                                uint16_t protocolType,
+                                Ptr<NetDevice> device);
+  /**
+   * \param handler the handler to register
+   * \param device the device attached to this handler. If the
+   *        value is zero, the handler is attached to all
+   *        devices on this node.
+   *
+   * Register a handler to receive all packets for all
+   * protocols.
+   */
+  void RegisterProtocolHandler (ProtocolHandler handler,
+                                Ptr<NetDevice> device);
+
+  /**
+   * \param handler the handler to unregister
+   *
+   * After this call returns, the input handler will never
+   * be invoked anymore.
+   */
+  void UnregisterProtocolHandler (ProtocolHandler handler);
+
 protected:
   /**
    * Must be invoked by subclasses only.
@@ -147,7 +184,7 @@
    *
    * Subclasses must implement this method.
    */
-  virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context) = 0;
+  virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
   /**
    * \param device the device added to this Node.
    *
@@ -156,12 +193,22 @@
    * at this point to setup the node's receive function for
    * the NetDevice packets.
    */
-  virtual void DoAddDevice (Ptr<NetDevice> device) = 0;
+  virtual void NotifyDeviceAdded (Ptr<NetDevice> device);
+
+  bool ReceiveFromDevice (Ptr<NetDevice> device, const Packet &packet, uint16_t protocol);
 
+  struct ProtocolHandlerEntry {
+    ProtocolHandler handler;
+    bool isSpecificProtocol;
+    uint16_t protocol;
+    Ptr<NetDevice> device;
+  };
+  typedef std::vector<struct Node::ProtocolHandlerEntry> ProtocolHandlerList;
   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;
+  ProtocolHandlerList m_handlers;
 };
 
 } //namespace ns3