rework the NetDevice <-> Node interface
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Wed, 01 Aug 2007 08:58:18 +0200
changeset 1186 909e9eb2124e
parent 1185 eac7427958e9
child 1187 8ea0f4d4fd34
rework the NetDevice <-> Node interface
src/devices/csma-cd/csma-cd-net-device.cc
src/devices/csma-cd/csma-cd-net-device.h
src/devices/point-to-point/point-to-point-net-device.cc
src/internet-node/arp-l3-protocol.cc
src/internet-node/arp-l3-protocol.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/udp-socket.cc
src/internet-node/udp-socket.h
src/node/net-device.cc
src/node/net-device.h
src/node/node.cc
src/node/node.h
src/node/socket.cc
src/node/socket.h
--- a/src/devices/csma-cd/csma-cd-net-device.cc	Tue Jul 31 11:42:25 2007 +0200
+++ b/src/devices/csma-cd/csma-cd-net-device.cc	Wed Aug 01 08:58:18 2007 +0200
@@ -457,26 +457,62 @@
 }
 
 void
-CsmaCdNetDevice::Receive (Packet& p)
+CsmaCdNetDevice::Receive (const Packet& packet)
 {
+  EthernetHeader header (false);
+  EthernetTrailer trailer;
+  Eui48Address broadcast;
+  Eui48Address destination;
+  Packet p = packet;
+
   NS_DEBUG ("CsmaCdNetDevice::Receive UID is (" << p.GetUid() << ")");
 
   // Only receive if send side of net device is enabled
   if (!IsReceiveEnabled())
-    return;
+    {
+      goto drop;
+    }
 
-  uint16_t param = 0;
-  Packet packet = p;
+  if (m_encapMode == RAW)
+    {
+      ForwardUp (packet, 0, GetBroadcast ());
+      goto drop;
+    }
+  p.RemoveTrailer(trailer);
+  trailer.CheckFcs(p);
+  p.RemoveHeader(header);
 
-  if (ProcessHeader(packet, param))
+  broadcast = Eui48Address::ConvertFrom (GetBroadcast ());
+  destination = Eui48Address::ConvertFrom (GetAddress ());
+  if ((header.GetDestination() != broadcast) &&
+      (header.GetDestination() != destination))
     {
-      m_rxTrace (packet);
-      ForwardUp (packet, param);
-    } 
-  else 
+      // not for us.
+      goto drop;
+    }
+
+  uint16_t protocol;
+  switch (m_encapMode)
     {
-      m_dropTrace (packet);
+    case ETHERNET_V1:
+    case IP_ARP:
+      protocol = header.GetLengthType();
+      break;
+    case LLC: {
+      LlcSnapHeader llc;
+      p.RemoveHeader (llc);
+      protocol = llc.GetType ();
+    } break;
+    case RAW:
+      NS_ASSERT (false);
+      break;
     }
+  
+  m_rxTrace (p);
+  ForwardUp (p, protocol, header.GetSource ().ConvertTo ());
+  return;
+ drop:
+  m_dropTrace (p);
 }
 
 Ptr<Queue>
--- a/src/devices/csma-cd/csma-cd-net-device.h	Tue Jul 31 11:42:25 2007 +0200
+++ b/src/devices/csma-cd/csma-cd-net-device.h	Wed Aug 01 08:58:18 2007 +0200
@@ -173,7 +173,7 @@
    * @see CsmaCdChannel
    * \param p a reference to the received packet
    */
-  void Receive (Packet& p);
+  void Receive (const Packet& p);
 
   bool IsSendEnabled (void);
   bool IsReceiveEnabled (void);
--- a/src/devices/point-to-point/point-to-point-net-device.cc	Tue Jul 31 11:42:25 2007 +0200
+++ b/src/devices/point-to-point/point-to-point-net-device.cc	Wed Aug 01 08:58:18 2007 +0200
@@ -220,12 +220,12 @@
 void PointToPointNetDevice::Receive (Packet& p)
 {
   NS_DEBUG ("PointToPointNetDevice::Receive (" << &p << ")");
-  uint16_t param = 0;
+  uint16_t protocol = 0;
   Packet packet = p;
 
-  ProcessHeader(packet, param);
+  ProcessHeader(packet, protocol);
   m_rxTrace (packet);
-  ForwardUp (packet, param);
+  ForwardUp (packet, protocol, GetBroadcast ());
 }
 
 Ptr<Queue> PointToPointNetDevice::GetQueue(void) const 
--- a/src/internet-node/arp-l3-protocol.cc	Tue Jul 31 11:42:25 2007 +0200
+++ b/src/internet-node/arp-l3-protocol.cc	Wed Aug 01 08:58:18 2007 +0200
@@ -84,7 +84,7 @@
 }
 
 void 
-ArpL3Protocol::Receive(const Packet& p, uint16_t protocol, Ptr<NetDevice> device)
+ArpL3Protocol::Receive(Ptr<NetDevice> device, const Packet& p, uint16_t protocol, const Address &from)
 {
   ArpCache *cache = FindCache (device);
   ArpHeader arp;
--- a/src/internet-node/arp-l3-protocol.h	Tue Jul 31 11:42:25 2007 +0200
+++ b/src/internet-node/arp-l3-protocol.h	Wed Aug 01 08:58:18 2007 +0200
@@ -53,7 +53,7 @@
   /**
    * \brief Recieve a packet
    */
-  void Receive(const Packet& p, uint16_t protocol, Ptr<NetDevice> device);
+  void Receive(Ptr<NetDevice> device, const Packet& p, uint16_t protocol, const Address &from);
   /**
    * \brief Perform an ARP lookup
    * \param p
--- a/src/internet-node/ipv4-l3-protocol.cc	Tue Jul 31 11:42:25 2007 +0200
+++ b/src/internet-node/ipv4-l3-protocol.cc	Wed Aug 01 08:58:18 2007 +0200
@@ -241,7 +241,7 @@
 }  
 
 void 
-Ipv4L3Protocol::Receive(const Packet& p, uint16_t protocol, Ptr<NetDevice> device)
+Ipv4L3Protocol::Receive( Ptr<NetDevice> device, const Packet& p, uint16_t protocol, const Address &from)
 {
   uint32_t index = 0;
   for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
--- a/src/internet-node/ipv4-l3-protocol.h	Tue Jul 31 11:42:25 2007 +0200
+++ b/src/internet-node/ipv4-l3-protocol.h	Wed Aug 01 08:58:18 2007 +0200
@@ -95,7 +95,7 @@
    *    - implement a per-NetDevice ARP cache
    *    - send back arp replies on the right device
    */
-  void Receive(const Packet& p, uint16_t protocol, Ptr<NetDevice> device);
+  void Receive( Ptr<NetDevice> device, const Packet& p, uint16_t protocol, const Address &from);
 
   /**
    * \param packet packet to send
--- a/src/internet-node/ipv4-loopback-interface.cc	Tue Jul 31 11:42:25 2007 +0200
+++ b/src/internet-node/ipv4-loopback-interface.cc	Wed Aug 01 08:58:18 2007 +0200
@@ -44,7 +44,7 @@
 Ipv4LoopbackInterface::SendTo (Packet packet, Ipv4Address dest)
 {
   Ptr<Ipv4L3Protocol> ipv4 = m_node->QueryInterface<Ipv4L3Protocol> (Ipv4L3Protocol::iid);
-  ipv4->Receive (packet, Ipv4L3Protocol::PROT_NUMBER, GetDevice ());
+  ipv4->Receive (GetDevice (), packet, Ipv4L3Protocol::PROT_NUMBER, GetDevice ()->GetAddress ());
 }
 
 }//namespace ns3
--- a/src/internet-node/udp-socket.cc	Tue Jul 31 11:42:25 2007 +0200
+++ b/src/internet-node/udp-socket.cc	Wed Aug 01 08:58:18 2007 +0200
@@ -136,20 +136,21 @@
   return 0;
 }
 
-void 
-UdpSocket::DoClose(ns3::Callback<void, Ptr<Socket> > closeCompleted)
+int
+UdpSocket::DoClose(Callback<void, Ptr<Socket> > closeCompleted)
 {
   // XXX: we should set the close state and check it in all API methods.
   if (!closeCompleted.IsNull ())
     {
       closeCompleted (this);
     }
+  return 0;
 }
-void 
+int
 UdpSocket::DoConnect(const Address & address,
-                     ns3::Callback<void, Ptr<Socket> > connectionSucceeded,
-                     ns3::Callback<void, Ptr<Socket> > connectionFailed,
-                     ns3::Callback<void, Ptr<Socket> > halfClose)
+                     Callback<void, Ptr<Socket> > connectionSucceeded,
+                     Callback<void, Ptr<Socket> > connectionFailed,
+                     Callback<void, Ptr<Socket> > halfClose)
 {
   InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
   m_defaultAddress = transport.GetIpv4 ();
@@ -159,11 +160,12 @@
       connectionSucceeded (this);
     }
   m_connected = true;
+  return 0;
 }
 int
-UdpSocket::DoAccept(ns3::Callback<bool, Ptr<Socket>, const Address&> connectionRequest,
-                    ns3::Callback<void, Ptr<Socket>, const Address&> newConnectionCreated,
-                    ns3::Callback<void, Ptr<Socket> > closeRequested)
+UdpSocket::DoAccept(Callback<bool, Ptr<Socket>, const Address&> connectionRequest,
+                    Callback<void, Ptr<Socket>, const Address&> newConnectionCreated,
+                    Callback<void, Ptr<Socket> > closeRequested)
 {
   // calling accept on a udp socket is a programming error.
   m_errno = ERROR_OPNOTSUPP;
@@ -172,7 +174,7 @@
 int 
 UdpSocket::DoSend (const uint8_t* buffer,
                    uint32_t size,
-                   ns3::Callback<void, Ptr<Socket>, uint32_t> dataSent)
+                   Callback<void, Ptr<Socket>, uint32_t> dataSent)
 {
   if (!m_connected)
     {
@@ -192,7 +194,7 @@
 }
 int
 UdpSocket::DoSendPacketTo (const Packet &p, const Address &address,
-                           ns3::Callback<void, Ptr<Socket>, uint32_t> dataSent)
+                           Callback<void, Ptr<Socket>, uint32_t> dataSent)
 {
   InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
   Ipv4Address ipv4 = transport.GetIpv4 ();
@@ -201,7 +203,7 @@
 }
 int
 UdpSocket::DoSendPacketTo (const Packet &p, Ipv4Address ipv4, uint16_t port,
-                           ns3::Callback<void, Ptr<Socket>, uint32_t> dataSent)
+                           Callback<void, Ptr<Socket>, uint32_t> dataSent)
 {
   if (m_endPoint == 0)
     {
@@ -229,7 +231,7 @@
 UdpSocket::DoSendTo(const Address &address,
                     const uint8_t *buffer,
                     uint32_t size,
-                    ns3::Callback<void, Ptr<Socket>, uint32_t> dataSent)
+                    Callback<void, Ptr<Socket>, uint32_t> dataSent)
 {
   if (m_connected)
     {
@@ -251,12 +253,12 @@
   return DoSendPacketTo (p, ipv4, port, dataSent);
 }
 void 
-UdpSocket::DoRecv(ns3::Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Address&> callback)
+UdpSocket::DoRecv(Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Address&> callback)
 {
   m_rxCallback = callback;
 }
 void 
-UdpSocket::DoRecvDummy(ns3::Callback<void, Ptr<Socket>, uint32_t,const Address&> callback)
+UdpSocket::DoRecvDummy(Callback<void, Ptr<Socket>, uint32_t,const Address&> callback)
 {
   m_dummyRxCallback = callback;
 }
--- a/src/internet-node/udp-socket.h	Tue Jul 31 11:42:25 2007 +0200
+++ b/src/internet-node/udp-socket.h	Wed Aug 01 08:58:18 2007 +0200
@@ -51,23 +51,23 @@
   virtual int ShutdownRecv (void);
 
 private:
-  virtual void DoClose(ns3::Callback<void, Ptr<Socket> > closeCompleted);
-  virtual void DoConnect(const Address & address,
-			 ns3::Callback<void, Ptr<Socket> > connectionSucceeded,
-			 ns3::Callback<void, Ptr<Socket> > connectionFailed,
-			 ns3::Callback<void, Ptr<Socket> > halfClose);
-  virtual int DoAccept(ns3::Callback<bool, Ptr<Socket>, const Address&> connectionRequest,
-		       ns3::Callback<void, Ptr<Socket>, const Address&> newConnectionCreated,
-		       ns3::Callback<void, Ptr<Socket> > closeRequested);
+  virtual int DoClose(Callback<void, Ptr<Socket> > closeCompleted);
+  virtual int DoConnect(const Address & address,
+                        Callback<void, Ptr<Socket> > connectionSucceeded,
+                        Callback<void, Ptr<Socket> > connectionFailed,
+                        Callback<void, Ptr<Socket> > halfClose);
+  virtual int DoAccept(Callback<bool, Ptr<Socket>, const Address&> connectionRequest,
+		       Callback<void, Ptr<Socket>, const Address&> newConnectionCreated,
+		       Callback<void, Ptr<Socket> > closeRequested);
   virtual int DoSend (const uint8_t* buffer,
                     uint32_t size,
-                    ns3::Callback<void, Ptr<Socket>, uint32_t> dataSent);
+                    Callback<void, Ptr<Socket>, uint32_t> dataSent);
   virtual int DoSendTo(const Address &address,
                       const uint8_t *buffer,
                       uint32_t size,
-                      ns3::Callback<void, Ptr<Socket>, uint32_t> dataSent);
-  virtual void DoRecv(ns3::Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Address&>);
-  virtual void DoRecvDummy(ns3::Callback<void, Ptr<Socket>, uint32_t,const Address&>);
+                      Callback<void, Ptr<Socket>, uint32_t> dataSent);
+  virtual void DoRecv(Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Address&>);
+  virtual void DoRecvDummy(Callback<void, Ptr<Socket>, uint32_t,const Address&>);
 
 private:
   friend class Udp;
@@ -76,9 +76,9 @@
   void ForwardUp (const Packet &p, Ipv4Address ipv4, uint16_t port);
   void Destroy (void);
   int DoSendPacketTo (const Packet &p, const Address &daddr,
-		      ns3::Callback<void, Ptr<Socket>, uint32_t> dataSent);
+		      Callback<void, Ptr<Socket>, uint32_t> dataSent);
   int DoSendPacketTo (const Packet &p, Ipv4Address daddr, uint16_t dport,
-		      ns3::Callback<void, Ptr<Socket>, uint32_t> dataSent);
+		      Callback<void, Ptr<Socket>, uint32_t> dataSent);
 
   Ipv4EndPoint *m_endPoint;
   Ptr<Node> m_node;
--- a/src/node/net-device.cc	Tue Jul 31 11:42:25 2007 +0200
+++ b/src/node/net-device.cc	Wed Aug 01 08:58:18 2007 +0200
@@ -197,18 +197,19 @@
 
 // Receive packets from below
 bool
-NetDevice::ForwardUp(Packet& p, uint32_t param)
+NetDevice::ForwardUp(const Packet& p, uint32_t param, const Address &from)
 {
   bool retval = false;
-  Packet packet = p;
 
-  NS_DEBUG ("NetDevice::ForwardUp: UID is " << packet.GetUid()
+  NS_DEBUG ("NetDevice::ForwardUp: UID is " << p.GetUid()
             << " device is: " << GetName());
   
   if (!m_receiveCallback.IsNull ())
     {
-      retval = m_receiveCallback (this, packet, param);
-    } else {
+      retval = m_receiveCallback (this, p, param, from);
+    } 
+  else 
+    {
       NS_DEBUG ("NetDevice::Receive call back is NULL");
     }
 
@@ -248,7 +249,7 @@
 }
 
 void 
-NetDevice::SetReceiveCallback (Callback<bool,Ptr<NetDevice>,const Packet &,uint16_t> cb)
+NetDevice::SetReceiveCallback (ReceiveCallback cb)
 {
   m_receiveCallback = cb;
 }
--- a/src/node/net-device.h	Tue Jul 31 11:42:25 2007 +0200
+++ b/src/node/net-device.h	Wed Aug 01 08:58:18 2007 +0200
@@ -178,10 +178,23 @@
   bool NeedsArp (void) const;
 
   /**
+   * \param device a pointer to the net device which is calling this callback
+   * \param packet the packet received
+   * \param protocol the 16 bit protocol number associated with this packet.
+   *        This protocol number is expected to be the same protocol number
+   *        given to the Send method by the user on the sender side.
+   * \param address the address of the sender
+   * \returns true if the callback could handle the packet successfully, false
+   *          otherwise.
+   */
+  typedef Callback<bool,Ptr<NetDevice>,const Packet &,uint16_t,const Address &> ReceiveCallback;
+
+  /**
    * \param cb callback to invoke whenever a packet has been received and must
    *        be forwarded to the higher layers.
+   *
    */
-  void SetReceiveCallback (Callback<bool,Ptr<NetDevice>,const Packet &,uint16_t> cb);
+  void SetReceiveCallback (ReceiveCallback cb);
 
  protected:
   /**
@@ -230,6 +243,7 @@
    * \param p packet sent from below up to Network Device
    * \param param Extra parameter extracted from header and needed by
    * some protocols
+   * \param address the address of the sender of this packet.
    * \returns true if the packet was forwarded successfully,
    *          false otherwise.
    *
@@ -237,7 +251,7 @@
    * forwards it to the higher layers by calling this method
    * which is responsible for passing it up to the Rx callback.
    */
-  bool ForwardUp (Packet& p, uint32_t param);
+  bool ForwardUp (const Packet& p, uint32_t param, const Address &address);
 
 
   /**
@@ -248,8 +262,6 @@
    */
   virtual void DoDispose (void);
 
-  Callback<bool,Ptr<NetDevice>,const Packet &,uint16_t> m_receiveCallback;
-
  private:
   /**
    * \param p packet to send
@@ -297,6 +309,7 @@
   bool          m_isMulticast;
   bool          m_isPointToPoint;
   Callback<void> m_linkChangeCallback;
+  ReceiveCallback m_receiveCallback;
 };
 
 }; // namespace ns3
--- a/src/node/node.cc	Tue Jul 31 11:42:25 2007 +0200
+++ b/src/node/node.cc	Wed Aug 01 08:58:18 2007 +0200
@@ -22,6 +22,7 @@
 #include "node-list.h"
 #include "net-device.h"
 #include "application.h"
+#include "packet-socket-factory.h"
 #include "ns3/simulator.h"
 #include "ns3/empty-trace-resolver.h"
 
@@ -33,16 +34,23 @@
   : m_id(0), 
     m_sid(0)
 {
-  SetInterfaceId (Node::iid);
-  m_id = NodeList::Add (this);
+  Construct ();
 }
 
 Node::Node(uint32_t sid)
   : m_id(0), 
     m_sid(sid)
 { 
+  Construct ();
+}
+
+void
+Node::Construct (void)
+{
   SetInterfaceId (Node::iid);
   m_id = NodeList::Add (this);
+  Ptr<PacketSocketFactory> socketFactory = Create<PacketSocketFactory> ();
+  AddInterface (socketFactory);
 }
   
 Node::~Node ()
@@ -69,8 +77,8 @@
 uint32_t 
 Node::AddDevice (Ptr<NetDevice> device)
 {
+  m_devices.push_back (device);
   uint32_t index = m_devices.size ();
-  m_devices.push_back (device);
   device->SetIfIndex(index);
   device->SetReceiveCallback (MakeCallback (&Node::ReceiveFromDevice, this));
   NotifyDeviceAdded (device);
@@ -79,7 +87,14 @@
 Ptr<NetDevice>
 Node::GetDevice (uint32_t index) const
 {
-  return m_devices[index];
+  if (index == 0)
+    {
+      return 0;
+    }
+  else
+    {
+      return m_devices[index - 1];
+    }
 }
 uint32_t 
 Node::GetNDevices (void) const
@@ -143,24 +158,11 @@
 {
   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)
 {
@@ -176,7 +178,8 @@
 }
 
 bool
-Node::ReceiveFromDevice (Ptr<NetDevice> device, const Packet &packet, uint16_t protocol)
+Node::ReceiveFromDevice (Ptr<NetDevice> device, const Packet &packet, 
+                         uint16_t protocol, const Address &from)
 {
   bool found = false;
   for (ProtocolHandlerList::iterator i = m_handlers.begin ();
@@ -185,10 +188,10 @@
       if (i->device == 0 ||
           (i->device != 0 && i->device == device))
         {
-          if (!i->isSpecificProtocol || 
-              (i->isSpecificProtocol && i->protocol == protocol))
+          if (i->protocol == 0 || 
+              i->protocol == protocol)
             {
-              i->handler (packet, protocol, device);
+              i->handler (device, packet, protocol, from);
               found = true;
             }
         }
--- a/src/node/node.h	Tue Jul 31 11:42:25 2007 +0200
+++ b/src/node/node.h	Wed Aug 01 08:58:18 2007 +0200
@@ -33,6 +33,7 @@
 class NetDevice;
 class Application;
 class Packet;
+class Address;
 
 /**
  * \brief A network Node.
@@ -56,6 +57,17 @@
 public:
   static const InterfaceId iid;
 
+  /**
+   * 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);
+
   virtual ~Node();
 
   /**
@@ -91,11 +103,15 @@
    * 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.
+   * The index returned is always non-zero.
    */
   uint32_t AddDevice (Ptr<NetDevice> device);
   /**
    * \param index the index of the requested NetDevice
    * \returns the requested NetDevice associated to this Node.
+   *
+   * The indexes used by the GetDevice method start at one and
+   * end at GetNDevices ()
    */
   Ptr<NetDevice> GetDevice (uint32_t index) const;
   /**
@@ -128,11 +144,15 @@
   /**
    * A protocol handler
    */
-  typedef Callback<void,const Packet &,uint16_t,Ptr<NetDevice> > ProtocolHandler;
+  typedef Callback<void,Ptr<NetDevice>, const Packet &,uint16_t,const Address &> ProtocolHandler;
   /**
    * \param handler the handler to register
    * \param protocolType the type of protocol this handler is 
-   *        interested in.
+   *        interested in. This protocol type is a so-called
+   *        EtherType, as registered here:
+   *        http://standards.ieee.org/regauth/ethertype/eth.txt
+   *        the value zero is interpreted as matching all
+   *        protocols.
    * \param device the device attached to this handler. If the
    *        value is zero, the handler is attached to all
    *        devices on this node.
@@ -141,18 +161,6 @@
                                 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
@@ -162,16 +170,6 @@
 
 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.
@@ -195,11 +193,12 @@
    */
   virtual void NotifyDeviceAdded (Ptr<NetDevice> device);
 
-  bool ReceiveFromDevice (Ptr<NetDevice> device, const Packet &packet, uint16_t protocol);
+  bool ReceiveFromDevice (Ptr<NetDevice> device, const Packet &packet, 
+                          uint16_t protocol, const Address &from);
+  void Construct (void);
 
   struct ProtocolHandlerEntry {
     ProtocolHandler handler;
-    bool isSpecificProtocol;
     uint16_t protocol;
     Ptr<NetDevice> device;
   };
--- a/src/node/socket.cc	Tue Jul 31 11:42:25 2007 +0200
+++ b/src/node/socket.cc	Wed Aug 01 08:58:18 2007 +0200
@@ -5,19 +5,19 @@
 Socket::~Socket ()
 {}
 
-void 
+int
 Socket::Close(Callback<void, Ptr<Socket> > closeCompleted)
 {
-  DoClose (closeCompleted);
+  return DoClose (closeCompleted);
 }
 
-void 
+int
 Socket::Connect(const Address & address,
                Callback<void, Ptr<Socket> > connectionSucceeded,
                Callback<void, Ptr<Socket> > connectionFailed,
                Callback<void, Ptr<Socket> > halfClose)
 {
-  DoConnect (address, connectionSucceeded, connectionFailed, halfClose);
+  return DoConnect (address, connectionSucceeded, connectionFailed, halfClose);
 }
 int
 Socket::Accept(Callback<bool, Ptr<Socket>, const Address&> connectionRequest,
--- a/src/node/socket.h	Tue Jul 31 11:42:25 2007 +0200
+++ b/src/node/socket.h	Wed Aug 01 08:58:18 2007 +0200
@@ -52,7 +52,9 @@
     ERROR_AGAIN,
     ERROR_SHUTDOWN,
     ERROR_OPNOTSUPP,
+    ERROR_AFNOSUPPORT,
     ERROR_INVAL,
+    ERROR_BADF,
     SOCKET_ERRNO_LAST
   };
 
@@ -92,7 +94,7 @@
    * After the Close call, the socket is no longer valid, and cannot
    * safely be used for subsequent operations.
    */
-  void Close(Callback<void, Ptr<Socket> > closeCompleted = MakeCallback (&Socket::DummyCallbackVoidSocket));
+  int Close(Callback<void, Ptr<Socket> > closeCompleted = MakeCallback (&Socket::DummyCallbackVoidSocket));
 
   /**
    * \returns zero on success, -1 on failure.
@@ -122,10 +124,10 @@
    * \param halfClose XXX When exactly is this callback invoked ? If it invoked when the
    *        other side closes the connection ? Or when I call Close ?
    */
-  void Connect(const Address &address,
-               Callback<void, Ptr<Socket> > connectionSucceeded = MakeCallback(&Socket::DummyCallbackVoidSocket),
-               Callback<void, Ptr<Socket> > connectionFailed = MakeCallback(&Socket::DummyCallbackVoidSocket),
-               Callback<void, Ptr<Socket> > halfClose = MakeCallback(&Socket::DummyCallbackVoidSocket));
+  int Connect(const Address &address,
+              Callback<void, Ptr<Socket> > connectionSucceeded = MakeCallback(&Socket::DummyCallbackVoidSocket),
+              Callback<void, Ptr<Socket> > connectionFailed = MakeCallback(&Socket::DummyCallbackVoidSocket),
+              Callback<void, Ptr<Socket> > halfClose = MakeCallback(&Socket::DummyCallbackVoidSocket));
     
   /**
    * \brief Accept connection requests from remote hosts
@@ -201,11 +203,11 @@
                  MakeCallback (&Socket::DummyCallbackVoidSocketUi32Address));
 
 private:
-  virtual void DoClose(Callback<void, Ptr<Socket> > closeCompleted) = 0;
-  virtual void DoConnect(const Address & address,
-                         Callback<void, Ptr<Socket> > connectionSucceeded,
-                         Callback<void, Ptr<Socket> > connectionFailed,
-                         Callback<void, Ptr<Socket> > halfClose) = 0;
+  virtual int DoClose(Callback<void, Ptr<Socket> > closeCompleted) = 0;
+  virtual int DoConnect(const Address & address,
+                        Callback<void, Ptr<Socket> > connectionSucceeded,
+                        Callback<void, Ptr<Socket> > connectionFailed,
+                        Callback<void, Ptr<Socket> > halfClose) = 0;
   virtual int DoAccept(Callback<bool, Ptr<Socket>, const Address&> connectionRequest,
                        Callback<void, Ptr<Socket>, const Address&> newConnectionCreated,
                        Callback<void, Ptr<Socket> > closeRequested) = 0;