merge with HEAD
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Wed, 11 Jun 2008 16:20:04 -0700
changeset 3894 6b3415c550e1
parent 3893 94f771c1373a (current diff)
parent 3261 b0987a6a74c8 (diff)
child 3895 b584563a7781
merge with HEAD
examples/mixed-wireless.cc
src/internet-node/arp-cache.cc
src/internet-node/arp-cache.h
src/internet-node/arp-header.cc
src/internet-node/arp-header.h
src/internet-node/arp-ipv4-interface.cc
src/internet-node/arp-ipv4-interface.h
src/internet-node/arp-l3-protocol.cc
src/internet-node/arp-l3-protocol.h
src/internet-node/internet-stack.cc
src/internet-node/internet-stack.h
src/internet-node/ipv4-checksum.cc
src/internet-node/ipv4-checksum.h
src/internet-node/ipv4-end-point-demux.cc
src/internet-node/ipv4-end-point-demux.h
src/internet-node/ipv4-end-point.cc
src/internet-node/ipv4-end-point.h
src/internet-node/ipv4-impl.cc
src/internet-node/ipv4-impl.h
src/internet-node/ipv4-interface.cc
src/internet-node/ipv4-interface.h
src/internet-node/ipv4-l3-protocol.cc
src/internet-node/ipv4-l3-protocol.h
src/internet-node/ipv4-l4-demux.cc
src/internet-node/ipv4-l4-demux.h
src/internet-node/ipv4-l4-protocol.cc
src/internet-node/ipv4-l4-protocol.h
src/internet-node/ipv4-loopback-interface.cc
src/internet-node/ipv4-loopback-interface.h
src/internet-node/ipv4-static-routing.cc
src/internet-node/ipv4-static-routing.h
src/internet-node/pending-data.cc
src/internet-node/pending-data.h
src/internet-node/rtt-estimator.cc
src/internet-node/rtt-estimator.h
src/internet-node/sequence-number.cc
src/internet-node/sequence-number.h
src/internet-node/sgi-hashmap.h
src/internet-node/tcp-header.cc
src/internet-node/tcp-header.h
src/internet-node/tcp-l4-protocol.cc
src/internet-node/tcp-l4-protocol.h
src/internet-node/tcp-socket-factory-impl.cc
src/internet-node/tcp-socket-factory-impl.h
src/internet-node/tcp-socket-impl.cc
src/internet-node/tcp-socket-impl.h
src/internet-node/tcp-typedefs.h
src/internet-node/udp-header.cc
src/internet-node/udp-header.h
src/internet-node/udp-l4-protocol.cc
src/internet-node/udp-l4-protocol.h
src/internet-node/udp-socket-factory-impl.cc
src/internet-node/udp-socket-factory-impl.h
src/internet-node/udp-socket-impl.cc
src/internet-node/udp-socket-impl.h
src/internet-node/waf
src/internet-node/wscript
--- a/doc/modules	Wed Jun 11 16:19:28 2008 -0700
+++ b/doc/modules	Wed Jun 11 16:20:04 2008 -0700
@@ -42,13 +42,12 @@
  *
  * @defgroup devices Devices
  *
- * @defgroup internetNode InternetNode
+ * @defgroup internetStack InternetStack
  * 
- * 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 
+ * The "internet-stack" module contains:
+ *    - an Ipv4 stack
  *    - an ARP module
- *    - an InternetNode class which is a Node subclass.
+ *    - a UDP and a TCP implementation
  *    
  * @defgroup helper Helpers
  * 
--- a/doc/tutorial/introduction.texi	Wed Jun 11 16:19:28 2008 -0700
+++ b/doc/tutorial/introduction.texi	Wed Jun 11 16:20:04 2008 -0700
@@ -1272,14 +1272,14 @@
 
 @verbatim
   #include "ns3/ptr.h"
-  #include "ns3/internet-node.h"
+  #include "ns3/internet-stack.h"
 @end verbatim
 
 @cindex include files
 The ns-3 build system places the core include files it needs into a 
 directory called @code{ns-3} and so whenever you need to include one of the
 core files you need to explicitly code this.  The file @code{ptr.h} defines
-the generic smart pointer that we use.  The file @code{internet-node.h}
+the generic smart pointer that we use.  The file @code{internet-stack.h}
 defines the class InternetNode which, as described above, represents an IP
 version 4-based computing element in the simulator.
 
@@ -1455,7 +1455,7 @@
 @verbatim
   #include "ns3/log.h"
   #include "ns3/ptr.h"
-  #include "ns3/internet-node.h"
+  #include "ns3/internet-stack.h"
   #include "ns3/csma-channel.h"
   #include "ns3/mac48-address.h"
   #include "ns3/csma-net-device.h"
@@ -1632,7 +1632,7 @@
 @verbatim
   #include "ns3/log.h"
   #include "ns3/ptr.h"
-  #include "ns3/internet-node.h"
+  #include "ns3/internet-stack.h"
   #include "ns3/csma-channel.h"
   #include "ns3/mac48-address.h"
   #include "ns3/csma-net-device.h"
@@ -1883,7 +1883,7 @@
 @verbatim
   #include "ns3/log.h"
   #include "ns3/ptr.h"
-  #include "ns3/internet-node.h"
+  #include "ns3/internet-stack.h"
   #include "ns3/csma-channel.h"
   #include "ns3/mac48-address.h"
   #include "ns3/csma-net-device.h"
--- a/doc/tutorial/other.texi	Wed Jun 11 16:19:28 2008 -0700
+++ b/doc/tutorial/other.texi	Wed Jun 11 16:20:04 2008 -0700
@@ -103,7 +103,7 @@
 
 #include "ns3/log.h"
 #include "ns3/ptr.h"
-#include "ns3/internet-node.h"
+#include "ns3/internet-stack.h"
 #include "ns3/point-to-point-channel.h"
 #include "ns3/mac48-address.h"
 #include "ns3/point-to-point-net-device.h"
@@ -313,7 +313,7 @@
 
 #include "ns3/log.h"
 #include "ns3/ptr.h"
-#include "ns3/internet-node.h"
+#include "ns3/internet-stack.h"
 #include "ns3/point-to-point-channel.h"
 #include "ns3/mac48-address.h"
 #include "ns3/point-to-point-net-device.h"
@@ -1846,7 +1846,7 @@
 call @code{GetObject} on the resulting smart pointer.  Well, I'm afraid that's
 not entirely true.  It's slightly more complicated.
 
-Take a look at @code{src/internet-node/internet-node.h} and find the class
+Take a look at @code{src/internet-stack/internet-stack.h} and find the class
 declaration for @code{InternetNode}.
 
 @verbatim
@@ -1956,7 +1956,7 @@
 methods specified in the @code{Ipv4} class to access the @code{Ipv4 Object}
 methods which are, in turn, implemented in the @code{Ipv4Impl} object.
 
-If you now look in the file, @code{src/internet-node/internet-node.cc} you
+If you now look in the file, @code{src/internet-stack/internet-stack.cc} you
 will see the following code in @code{InternetNode::Construct} that creates the
 @code{Ipv4} Interface and aggregates it.
 
@@ -2013,7 +2013,7 @@
 In the case of @code{Ipv4Impl}, you know that the class inherits somehow 
 from @code{Object} since there is a call to @code{AggregateObject} that
 refers to an instance of an @code{Ipv4Impl}.  You will have to go to
-the header file @code{src/internet-node/ipv4-impl.h} and find that
+the header file @code{src/internet-stack/ipv4-impl.h} and find that
 @code{Ipv4Impl} inherits from class @code{Ipv4}.  You will then have go to
 the file @code{src/node/ipv4.h} and see that it inherits from @code{Object} and
 defines a @code{GetTypeId}.  Thus the @code{Object} for which you can
--- a/doc/tutorial/routing.texi	Wed Jun 11 16:19:28 2008 -0700
+++ b/doc/tutorial/routing.texi	Wed Jun 11 16:20:04 2008 -0700
@@ -2,7 +2,7 @@
 @chapter ns-3 routing overview
 
 This chapter describes the overall design of routing in the 
-@code{src/internet-node}
+@code{src/internet-stack}
 module, and some details about the routing approachs currently
 implemented.
 
@@ -97,7 +97,7 @@
   void AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
                            int16_t priority);
 @end verbatim
-This method is implemented by class Ipv4L3Protocol in the internet-node
+This method is implemented by class Ipv4L3Protocol in the internet-stack
 module.
 
 The priority variable above governs the priority in which the routing
@@ -174,7 +174,7 @@
 @node Static routing
 @section Static routing
 
-The internet-node module provides one routing protocol (Ipv4StaticRouting)
+The internet-stack module provides one routing protocol (Ipv4StaticRouting)
 by default.  This routing protocol allows one to add unicast or multicast
 static routes to a node.
 
@@ -193,7 +193,7 @@
 @uref{http://www.nsnam.org/doxygen/index.html,,Doxygen} documentation
 provides full documentation of these methods.  These methods are forwarding
 functions to the actual implementation in Ipv4StaticRouting, when using
-the internet-node module.
+the internet-stack module.
 
 @node Multicast routing
 @section Multicast routing
--- a/examples/csma-broadcast.cc	Wed Jun 11 16:19:28 2008 -0700
+++ b/examples/csma-broadcast.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -69,7 +69,7 @@
 
   NS_LOG_INFO ("Build Topology.");
   CsmaHelper csma;
-  csma.SetChannelParameter ("BitRate", DataRateValue (DataRate(5000000)));
+  csma.SetChannelParameter ("DataRate", DataRateValue (DataRate(5000000)));
   csma.SetChannelParameter ("Delay", TimeValue (MilliSeconds(2)));
 
   NetDeviceContainer n0 = csma.Install (c0);
--- a/examples/csma-multicast.cc	Wed Jun 11 16:19:28 2008 -0700
+++ b/examples/csma-multicast.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -75,7 +75,7 @@
   
   NS_LOG_INFO ("Build Topology.");
   CsmaHelper csma;
-  csma.SetChannelParameter ("BitRate", DataRateValue (DataRate (5000000)));
+  csma.SetChannelParameter ("DataRate", DataRateValue (DataRate (5000000)));
   csma.SetChannelParameter ("Delay", TimeValue (MilliSeconds (2)));
  
   // We will use these NetDevice containers later, for IP addressing
--- a/examples/csma-one-subnet.cc	Wed Jun 11 16:19:28 2008 -0700
+++ b/examples/csma-one-subnet.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -66,7 +66,7 @@
 
   NS_LOG_INFO ("Build Topology");
   CsmaHelper csma;
-  csma.SetChannelParameter ("BitRate", DataRateValue (5000000));
+  csma.SetChannelParameter ("DataRate", DataRateValue (5000000));
   csma.SetChannelParameter ("Delay", TimeValue (MilliSeconds (2)));
 //
 // Now fill out the topology by creating the net devices required to connect
--- a/examples/csma-packet-socket.cc	Wed Jun 11 16:19:28 2008 -0700
+++ b/examples/csma-packet-socket.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -67,8 +67,9 @@
 
   // create the shared medium used by all csma devices.
   NS_LOG_INFO ("Create channels.");
-  Ptr<CsmaChannel> channel = CreateObject<CsmaChannel> ("BitRate", DataRateValue (DataRate(5000000)), 
-                                                        "Delay", TimeValue (MilliSeconds(2)));
+  Ptr<CsmaChannel> channel = CreateObject<CsmaChannel> (
+    "DataRate", DataRateValue (DataRate(5000000)), 
+    "Delay", TimeValue (MilliSeconds(2)));
 
   // use a helper function to connect our nodes to the shared channel.
   NS_LOG_INFO ("Build Topology.");
--- a/examples/mixed-global-routing.cc	Wed Jun 11 16:19:28 2008 -0700
+++ b/examples/mixed-global-routing.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -83,7 +83,7 @@
 
   // We create the channels first without any IP addressing information
   CsmaHelper csma;
-  csma.SetChannelParameter ("BitRate", StringValue ("5Mbps"));
+  csma.SetChannelParameter ("DataRate", StringValue ("5Mbps"));
   csma.SetChannelParameter ("Delay", StringValue ("2ms"));
   NetDeviceContainer d2345 = csma.Install (n2345);
   
--- a/examples/mixed-wireless.cc	Wed Jun 11 16:19:28 2008 -0700
+++ b/examples/mixed-wireless.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -199,7 +199,8 @@
       // collection.
       //
       CsmaHelper csma;
-      csma.SetChannelParameter ("BitRate", DataRateValue (DataRate (5000000)));
+      csma.SetChannelParameter ("DataRate", 
+        DataRateValue (DataRate (5000000)));
       csma.SetChannelParameter ("Delay", TimeValue (MilliSeconds (2)));
       NetDeviceContainer lanDevices = csma.Install (lan);
       //
--- a/examples/tcp-large-transfer.cc	Wed Jun 11 16:19:28 2008 -0700
+++ b/examples/tcp-large-transfer.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -28,6 +28,10 @@
 //   "tcp-large-transfer.pcap-$n-$i" where n and i represent node and interface numbers respectively
 //  Usage (e.g.): ./waf --run tcp-large-transfer
 
+//XXX this isn't working as described right now
+//it is just blasting away for 10 seconds, with no fixed amount of data
+//being sent
+
 #include <ctype.h>
 #include <iostream>
 #include <fstream>
@@ -73,39 +77,9 @@
 #endif
 }
 
-void CloseConnection (Ptr<Socket> localSocket)
-{
-  localSocket->Close ();
-}
-
-void StartFlow(Ptr<Socket> localSocket, uint32_t nBytes, 
-               Ipv4Address servAddress,
-               uint16_t servPort)
-{
- // NS_LOG_LOGIC("Starting flow at time " <<  Simulator::Now ().GetSeconds ());
-  localSocket->Connect (InetSocketAddress (servAddress, servPort));//connect
-  localSocket->SetConnectCallback (MakeCallback (&CloseConnection),
-                                   Callback<void, Ptr<Socket> > (),
-                                   Callback<void, Ptr<Socket> > ());
-  //we want to close as soon as the connection is established
-  //the tcp state machine and outgoing buffer will assure that
-  //all of the data is delivered
-
-  // Perform series of 1040 byte writes (this is a multiple of 26 since
-  // we want to detect data splicing in the output stream)
-  uint32_t writeSize = 1040;
-  uint8_t data[writeSize];
-  while (nBytes > 0) {
-    uint32_t curSize= nBytes > writeSize ? writeSize : nBytes;
-    for(uint32_t i = 0; i < curSize; ++i)
-    {
-      char m = toascii (97 + i % 26);
-      data[i] = m;
-    }
-    localSocket->Send (data, curSize);
-    nBytes -= curSize;
-  }
-}
+void CloseConnection (Ptr<Socket> localSocket);
+void StartFlow(Ptr<Socket>, uint32_t, Ipv4Address, uint16_t);
+void WriteUntilBufferFull (Ptr<Socket>, uint32_t);
 
 int main (int argc, char *argv[])
 {
@@ -195,3 +169,47 @@
   Simulator::Run ();
   Simulator::Destroy ();
 }
+
+void CloseConnection (Ptr<Socket> localSocket)
+{
+  localSocket->Close ();
+}
+
+void StartFlow(Ptr<Socket> localSocket, uint32_t nBytes, 
+               Ipv4Address servAddress,
+               uint16_t servPort)
+{
+ // NS_LOG_LOGIC("Starting flow at time " <<  Simulator::Now ().GetSeconds ());
+  localSocket->Connect (InetSocketAddress (servAddress, servPort));//connect
+  localSocket->SetConnectCallback (MakeCallback (&CloseConnection),
+                                   Callback<void, Ptr<Socket> > (),
+                                       Callback<void, Ptr<Socket> > ());
+  //we want to close as soon as the connection is established
+  //the tcp state machine and outgoing buffer will assure that
+  //all of the data is delivered
+  localSocket->SetSendCallback (MakeCallback (&WriteUntilBufferFull));
+  WriteUntilBufferFull (localSocket, nBytes);
+}
+
+void WriteUntilBufferFull (Ptr<Socket> localSocket, uint32_t nBytes)
+{
+  // Perform series of 1040 byte writes (this is a multiple of 26 since
+  // we want to detect data splicing in the output stream)
+  uint32_t writeSize = 1040;
+  uint8_t data[writeSize];
+  while (nBytes > 0) {
+    uint32_t curSize= nBytes > writeSize ? writeSize : nBytes;
+    for(uint32_t i = 0; i < curSize; ++i)
+    {
+      char m = toascii (97 + i % 26);
+      data[i] = m;
+    }
+    uint32_t amountSent = localSocket->Send (data, curSize);
+    if(amountSent < curSize)
+      {
+        std::cout << "Socket blocking, returning" << std::endl;
+        return;
+      }
+    nBytes -= curSize;
+  }
+}
--- a/examples/udp-echo.cc	Wed Jun 11 16:19:28 2008 -0700
+++ b/examples/udp-echo.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -87,7 +87,7 @@
 // Explicitly create the channels required by the topology (shown above).
 //
   CsmaHelper csma;
-  csma.SetChannelParameter ("BitRate", DataRateValue (DataRate(5000000)));
+  csma.SetChannelParameter ("DataRate", DataRateValue (DataRate(5000000)));
   csma.SetChannelParameter ("Delay", TimeValue (MilliSeconds (2)));
   NetDeviceContainer d = csma.Install (n);
 
--- a/examples/wscript	Wed Jun 11 16:19:28 2008 -0700
+++ b/examples/wscript	Wed Jun 11 16:20:04 2008 -0700
@@ -3,51 +3,51 @@
 def build(bld):
         
     obj = bld.create_ns3_program('mixed-wireless',
-        ['core', 'simulator', 'mobility', 'wifi', 'point-to-point', 'internet-node'])
+        ['core', 'simulator', 'mobility', 'wifi', 'point-to-point', 'internet-stack'])
     obj.source = 'mixed-wireless.cc'
 
     obj = bld.create_ns3_program('simple-global-routing',
-        ['point-to-point', 'internet-node', 'global-routing'])
+        ['point-to-point', 'internet-stack', 'global-routing'])
     obj.source = 'simple-global-routing.cc'
 
     obj = bld.create_ns3_program('simple-alternate-routing',
-        ['point-to-point', 'internet-node', 'global-routing'])
+        ['point-to-point', 'internet-stack', 'global-routing'])
     obj.source = 'simple-alternate-routing.cc'
 
     obj = bld.create_ns3_program('simple-error-model',
-        ['point-to-point', 'internet-node'])
+        ['point-to-point', 'internet-stack'])
     obj.source = 'simple-error-model.cc'
 
     obj = bld.create_ns3_program('csma-one-subnet',
-        ['csma', 'internet-node'])
+        ['csma', 'internet-stack'])
     obj.source = 'csma-one-subnet.cc'
 
     obj = bld.create_ns3_program('udp-echo',
-        ['csma', 'internet-node'])
+        ['csma', 'internet-stack'])
     obj.source = 'udp-echo.cc'
 
     obj = bld.create_ns3_program('csma-broadcast',
-        ['csma', 'internet-node'])
+        ['csma', 'internet-stack'])
     obj.source = 'csma-broadcast.cc'
 
     obj = bld.create_ns3_program('csma-packet-socket',
-        ['csma', 'internet-node'])
+        ['csma', 'internet-stack'])
     obj.source = 'csma-packet-socket.cc'
 
     obj = bld.create_ns3_program('csma-multicast',
-        ['csma', 'internet-node'])
+        ['csma', 'internet-stack'])
     obj.source = 'csma-multicast.cc'
 
     obj = bld.create_ns3_program( 'mixed-global-routing',
-        ['point-to-point', 'internet-node', 'global-routing' , 'csma-cd'])
+        ['point-to-point', 'internet-stack', 'global-routing' , 'csma-cd'])
     obj.source = 'mixed-global-routing.cc'
 
     obj = bld.create_ns3_program('simple-point-to-point-olsr',
-        ['point-to-point', 'internet-node', 'olsr'])
+        ['point-to-point', 'internet-stack', 'olsr'])
     obj.source = 'simple-point-to-point-olsr.cc'
 
     obj = bld.create_ns3_program('tcp-large-transfer',
-        ['point-to-point', 'internet-node'])
+        ['point-to-point', 'internet-stack'])
     obj.source = 'tcp-large-transfer.cc'
 
     obj = bld.create_ns3_program('wifi-adhoc',
--- a/samples/wscript	Wed Jun 11 16:19:28 2008 -0700
+++ b/samples/wscript	Wed Jun 11 16:20:04 2008 -0700
@@ -20,11 +20,11 @@
     obj.source = 'main-test.cc'
 
     obj = bld.create_ns3_program('main-simple',
-                                 ['node', 'internet-node', 'onoff'])
+                                 ['node', 'internet-stack', 'onoff'])
     obj.source = 'main-simple.cc'
 
     obj = bld.create_ns3_program('main-grid-topology',
-                                 ['core', 'simulator', 'mobility', 'internet-node'])
+                                 ['core', 'simulator', 'mobility', 'internet-stack'])
     obj.source = 'main-grid-topology.cc'
 
     obj = bld.create_ns3_program('main-random-topology',
--- a/src/applications/udp-echo/udp-echo-client.cc	Wed Jun 11 16:19:28 2008 -0700
+++ b/src/applications/udp-echo/udp-echo-client.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -37,19 +37,23 @@
   static TypeId tid = TypeId ("ns3::UdpEchoClient")
     .SetParent<Application> ()
     .AddConstructor<UdpEchoClient> ()
-    .AddAttribute ("MaxPackets", "XXX",
+    .AddAttribute ("MaxPackets", 
+                   "The maximum number of packets the application will send",
                    UintegerValue (100),
                    MakeUintegerAccessor (&UdpEchoClient::m_count),
                    MakeUintegerChecker<uint32_t> ())
-    .AddAttribute ("Interval", "XXX",
+    .AddAttribute ("Interval", 
+                   "The time to wait between packets",
                    TimeValue (Seconds (1.0)),
                    MakeTimeAccessor (&UdpEchoClient::m_interval),
                    MakeTimeChecker ())
-    .AddAttribute ("RemoteIpv4", "XXX",
+    .AddAttribute ("RemoteIpv4", 
+                   "The Ipv4Address of the outbound packets",
                    Ipv4AddressValue (),
                    MakeIpv4AddressAccessor (&UdpEchoClient::m_peerAddress),
                    MakeIpv4AddressChecker ())
-    .AddAttribute ("RemotePort", "XXX",
+    .AddAttribute ("RemotePort", 
+                   "The destination port of the outbound packets",
                    UintegerValue (0),
                    MakeUintegerAccessor (&UdpEchoClient::m_peerPort),
                    MakeUintegerChecker<uint16_t> ())
--- a/src/applications/udp-echo/wscript	Wed Jun 11 16:19:28 2008 -0700
+++ b/src/applications/udp-echo/wscript	Wed Jun 11 16:20:04 2008 -0700
@@ -1,7 +1,7 @@
 ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
 
 def build(bld):
-    module = bld.create_ns3_module('udp-echo', ['internet-node'])
+    module = bld.create_ns3_module('udp-echo', ['internet-stack'])
     module.source = [
         'udp-echo-client.cc',
         'udp-echo-server.cc',
--- a/src/core/random-variable.cc	Wed Jun 11 16:19:28 2008 -0700
+++ b/src/core/random-variable.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -156,9 +156,8 @@
 {
   if (RandomVariableBase::globalSeedSet)
     {
-      cerr << "Random number generator already initialized!" << endl;
-      cerr << "Call to RandomVariableBase::UseGlobalSeed() ignored" << endl;
-      return;
+      NS_FATAL_ERROR ("Random number generator already initialized! "
+                      "Call to RandomVariableBase::UseGlobalSeed() ignored");
     }
   RandomVariableBase::globalSeed[0] = s0;
   RandomVariableBase::globalSeed[1] = s1;
--- a/src/devices/csma/csma-channel.cc	Wed Jun 11 16:19:28 2008 -0700
+++ b/src/devices/csma/csma-channel.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -30,29 +30,15 @@
 
 NS_OBJECT_ENSURE_REGISTERED (CsmaChannel);
 
-CsmaDeviceRec::CsmaDeviceRec()
-{
-  active = false;
-}
-
-CsmaDeviceRec::CsmaDeviceRec(Ptr<CsmaNetDevice> device)
-{
-  devicePtr = device; 
-  active = true;
-}
-
-bool
-CsmaDeviceRec::IsActive() {
-  return active;
-}
-
-TypeId 
+  TypeId 
 CsmaChannel::GetTypeId (void)
 {
   static TypeId tid = TypeId ("ns3::CsmaChannel")
     .SetParent<Channel> ()
     .AddConstructor<CsmaChannel> ()
-    .AddAttribute ("BitRate", "The maximum bitrate of the channel",
+    .AddAttribute ("DataRate", 
+                   "The transmission data rate to be provided to devices "
+                   "connected to the channel",
                    DataRateValue (DataRate (0xffffffff)),
                    MakeDataRateAccessor (&CsmaChannel::m_bps),
                    MakeDataRateChecker ())
@@ -64,10 +50,7 @@
   return tid;
 }
 
-//
-// By default, you get a channel with the name "Csma Channel" that 
-// has an "infitely" fast transmission speed and zero delay.
-CsmaChannel::CsmaChannel()
+CsmaChannel::CsmaChannel ()
 : 
   Channel ("Csma Channel")
 {
@@ -76,26 +59,26 @@
   m_deviceList.clear();
 }
 
-int32_t
-CsmaChannel::Attach(Ptr<CsmaNetDevice> device)
+  int32_t
+CsmaChannel::Attach (Ptr<CsmaNetDevice> device)
 {
   NS_LOG_FUNCTION (this << device);
-  NS_ASSERT(device != 0);
+  NS_ASSERT (device != 0);
 
-  CsmaDeviceRec rec(device);
+  CsmaDeviceRec rec (device);
   
-  m_deviceList.push_back(rec);
-  return (m_deviceList.size() - 1);
+  m_deviceList.push_back (rec);
+  return (m_deviceList.size () - 1);
 }
 
-bool
-CsmaChannel::Reattach(Ptr<CsmaNetDevice> device)
+  bool
+CsmaChannel::Reattach (Ptr<CsmaNetDevice> device)
 {
   NS_LOG_FUNCTION (this << device);
-  NS_ASSERT(device != 0);
+  NS_ASSERT (device != 0);
 
   std::vector<CsmaDeviceRec>::iterator it;
-  for (it = m_deviceList.begin(); it < m_deviceList.end(); it++) 
+  for (it = m_deviceList.begin (); it < m_deviceList.end( ); it++) 
     {
       if (it->devicePtr == device) 
         {
@@ -113,12 +96,12 @@
   return false;
 }
 
-bool
-CsmaChannel::Reattach(uint32_t deviceId)
+  bool
+CsmaChannel::Reattach (uint32_t deviceId)
 {
   NS_LOG_FUNCTION (this << deviceId);
 
-  if (deviceId < m_deviceList.size())
+  if (deviceId < m_deviceList.size ())
     {
       return false;
     }
@@ -134,26 +117,25 @@
     }
 }
 
-bool
-CsmaChannel::Detach(uint32_t deviceId)
+  bool
+CsmaChannel::Detach (uint32_t deviceId)
 {
   NS_LOG_FUNCTION (this << deviceId);
 
-  if (deviceId < m_deviceList.size())
+  if (deviceId < m_deviceList.size ())
     {
       if (!m_deviceList[deviceId].active)
         {
-          NS_LOG_WARN ("CsmaChannel::Detach Device is already detached (" << 
-            deviceId << ")");
+          NS_LOG_WARN ("CsmaChannel::Detach(): "
+            "Device is already detached (" << deviceId << ")");
           return false;
         }
 
       m_deviceList[deviceId].active = false;
       if ((m_state == TRANSMITTING) && (m_currentSrc == deviceId))
         {
-          NS_LOG_WARN ("CsmaChannel::Detach Device is currently" << 
+          NS_LOG_WARN ("CsmaChannel::Detach(): Device is currently" << 
             "transmitting (" << deviceId << ")");
-          // Here we will need to place a warning in the packet
         }
 
       return true;
@@ -164,14 +146,14 @@
     }
 }
 
-bool
-CsmaChannel::Detach(Ptr<CsmaNetDevice> device)
+  bool
+CsmaChannel::Detach (Ptr<CsmaNetDevice> device)
 {
   NS_LOG_FUNCTION (this << device);
-  NS_ASSERT(device != 0);
+  NS_ASSERT (device != 0);
 
   std::vector<CsmaDeviceRec>::iterator it;
-  for (it = m_deviceList.begin(); it < m_deviceList.end(); it++) 
+  for (it = m_deviceList.begin (); it < m_deviceList.end (); it++) 
     {
       if ((it->devicePtr == device) && (it->active)) 
         {
@@ -182,21 +164,22 @@
   return false;
 }
 
-bool
-CsmaChannel::TransmitStart(Ptr<Packet> p, uint32_t srcId)
+  bool
+CsmaChannel::TransmitStart (Ptr<Packet> p, uint32_t srcId)
 {
   NS_LOG_FUNCTION (this << p << srcId);
   NS_LOG_INFO ("UID is " << p->GetUid () << ")");
 
   if (m_state != IDLE)
     {
-      NS_LOG_WARN ("state is not IDLE");
+      NS_LOG_WARN ("CsmaChannel::TransmitStart(): State is not IDLE");
       return false;
     }
 
   if (!IsActive(srcId))
     {
-      NS_LOG_ERROR ("Seclected source is not currently attached to network");
+      NS_LOG_ERROR ("CsmaChannel::TransmitStart(): "
+        "Seclected source is not currently attached to network");
       return false;
     }
 
@@ -207,51 +190,51 @@
   return true;
 }
 
-bool
+  bool
 CsmaChannel::IsActive(uint32_t deviceId) 
 {
-    return (m_deviceList[deviceId].active);
+  return (m_deviceList[deviceId].active);
 }
 
-bool
+  bool
 CsmaChannel::TransmitEnd()
 {
   NS_LOG_FUNCTION (this << m_currentPkt << m_currentSrc);
   NS_LOG_INFO ("UID is " << m_currentPkt->GetUid () << ")");
 
-  NS_ASSERT(m_state == TRANSMITTING);
+  NS_ASSERT (m_state == TRANSMITTING);
   m_state = PROPAGATING;
 
   bool retVal = true;
 
-  if (!IsActive(m_currentSrc)) {
-    NS_LOG_ERROR ("Seclected source was detached before the end of the"
-      "transmission");
-    retVal = false;
-  }
+  if (!IsActive (m_currentSrc))
+    {
+      NS_LOG_ERROR ("CsmaChannel::TransmitEnd(): "
+        "Seclected source was detached before the end of the transmission");
+      retVal = false;
+    }
 
   NS_LOG_LOGIC ("Schedule event in " << m_delay.GetSeconds () << " sec");
 
-  Simulator::Schedule (m_delay,
-                       &CsmaChannel::PropagationCompleteEvent,
-                       this);
+  Simulator::Schedule (m_delay, &CsmaChannel::PropagationCompleteEvent,
+    this);
   return retVal;
 }
 
-void
+  void
 CsmaChannel::PropagationCompleteEvent()
 {
   NS_LOG_FUNCTION (this << m_currentPkt);
   NS_LOG_INFO ("UID is " << m_currentPkt->GetUid () << ")");
 
-  NS_ASSERT(m_state == PROPAGATING);
+  NS_ASSERT (m_state == PROPAGATING);
 
   NS_LOG_LOGIC ("Receive");
   
   std::vector<CsmaDeviceRec>::iterator it;
-  for (it = m_deviceList.begin(); it < m_deviceList.end(); it++) 
+  for (it = m_deviceList.begin (); it < m_deviceList.end(); it++) 
     {
-      if (it->IsActive())
+      if (it->IsActive ())
       {
         it->devicePtr->Receive (m_currentPkt->Copy ());
       }
@@ -259,13 +242,12 @@
   m_state = IDLE;
 }
 
-
-uint32_t 
+  uint32_t 
 CsmaChannel::GetNumActDevices (void)
 {
   int numActDevices = 0;
   std::vector<CsmaDeviceRec>::iterator it;
-  for (it = m_deviceList.begin(); it < m_deviceList.end(); it++) 
+  for (it = m_deviceList.begin (); it < m_deviceList.end (); it++) 
     {
       if (it->active)
         {
@@ -275,29 +257,29 @@
   return numActDevices;
 }
 
+//
 // This is not the number of active devices. This is the total number
 // of devices even if some were detached after.
-uint32_t 
+//
+  uint32_t 
 CsmaChannel::GetNDevices (void) const
 {
-  return (m_deviceList.size());
+  return (m_deviceList.size ());
 }
 
-Ptr<CsmaNetDevice>
+  Ptr<CsmaNetDevice>
 CsmaChannel::GetCsmaDevice (uint32_t i) const
 {
-  Ptr< CsmaNetDevice > netDevice;
-
-  netDevice = m_deviceList[i].devicePtr;
+  Ptr<CsmaNetDevice> netDevice = m_deviceList[i].devicePtr;
   return netDevice;
 }
 
-int32_t
+  int32_t
 CsmaChannel::GetDeviceNum (Ptr<CsmaNetDevice> device)
 {
   std::vector<CsmaDeviceRec>::iterator it;
   int i = 0;
-  for (it = m_deviceList.begin(); it < m_deviceList.end(); it++) 
+  for (it = m_deviceList.begin (); it < m_deviceList.end (); it++) 
     {
       if (it->devicePtr == device)
         {
@@ -315,7 +297,7 @@
   return -1;
 }
 
-bool 
+  bool 
 CsmaChannel::IsBusy (void)
 {
   if (m_state == IDLE) 
@@ -328,28 +310,45 @@
     }
 }
 
-DataRate
+  DataRate
 CsmaChannel::GetDataRate (void)
 {
   return m_bps;
 }
 
-Time
+  Time
 CsmaChannel::GetDelay (void)
 {
   return m_delay;
 }
 
-WireState
-CsmaChannel::GetState(void)
+  WireState
+CsmaChannel::GetState (void)
 {
   return m_state;
 }
 
-Ptr<NetDevice>
+  Ptr<NetDevice>
 CsmaChannel::GetDevice (uint32_t i) const
 {
   return GetCsmaDevice (i);
 }
 
+CsmaDeviceRec::CsmaDeviceRec ()
+{
+  active = false;
+}
+
+CsmaDeviceRec::CsmaDeviceRec (Ptr<CsmaNetDevice> device)
+{
+  devicePtr = device; 
+  active = true;
+}
+
+  bool
+CsmaDeviceRec::IsActive () 
+{
+  return active;
+}
+
 } // namespace ns3
--- a/src/devices/csma/csma-channel.h	Wed Jun 11 16:19:28 2008 -0700
+++ b/src/devices/csma/csma-channel.h	Wed Jun 11 16:20:04 2008 -0700
@@ -73,27 +73,14 @@
  * flag to indicate if the channel is currently in use. It does not
  * take into account the distances between stations or the speed of
  * light to determine collisions.
- *
- * Each net device must query the state of the channel and make sure
- * that it is IDLE before writing a packet to the channel.
- *
- * When the channel is instaniated, the constructor takes parameters
- * for a single speed, in bits per second, and a speed-of-light delay
- * time as a Time object.  When a net device is attached to a channel,
- * it is assigned a device ID, this is in order to facilitate the
- * check that makes sure that a net device that is trying to send a
- * packet to the channel is really connected to this channel
- *
  */
 class CsmaChannel : public Channel 
 {
 public:
   static TypeId GetTypeId (void);
+
   /**
    * \brief Create a CsmaChannel
-   *
-   * By default, you get a channel with the name "Csma Channel" that
-   * has an "infitely" fast transmission speed and zero delay.
    */
   CsmaChannel ();
 
@@ -104,6 +91,7 @@
    * \return The assigned device number
    */
   int32_t Attach (Ptr<CsmaNetDevice> device);
+
   /**
    * \brief Detach a given netdevice from this channel
    *
@@ -116,6 +104,7 @@
    * can't be found.
    */
   bool Detach (Ptr<CsmaNetDevice> device);
+
   /**
    * \brief Detach a given netdevice from this channel
    *
@@ -129,6 +118,7 @@
    * can't be found.
    */
   bool Detach (uint32_t deviceId);
+
   /**
    * \brief Reattach a previously detached net device to the channel
    *
@@ -143,6 +133,7 @@
    * channel or can't be found.
    */
   bool Reattach(uint32_t deviceId);
+
   /**
    * \brief Reattach a previously detached net device to the channel
    *
@@ -156,6 +147,7 @@
    * channel or can't be found.
    */
   bool Reattach(Ptr<CsmaNetDevice> device);
+
   /**
    * \brief Start transmitting a packet over the channel
    *
@@ -171,6 +163,7 @@
    * device is currently active.
    */
   bool TransmitStart (Ptr<Packet> p, uint32_t srcId);
+
   /**
    * \brief Indicates that the net device has finished transmitting
    * the packet over the channel
@@ -186,6 +179,7 @@
    * completed its transmission.
    */
   bool TransmitEnd ();
+
   /**
    * \brief Indicates that the channel has finished propagating the
    * current packet. The channel is released and becomes free.
@@ -193,7 +187,8 @@
    * Calls the receive function of every active net device that is
    * attached to the channel.
    */
-  void PropagationCompleteEvent();
+  void PropagationCompleteEvent ();
+
   /**
    * \return Returns the device number assigned to a net device by the
    * channel
@@ -202,11 +197,12 @@
    * number is needed
    */
   int32_t GetDeviceNum (Ptr<CsmaNetDevice> device);
+
   /**
    * \return Returns the state of the channel (IDLE -- free,
    * TRANSMITTING -- busy, PROPAGATING - busy )
    */
-  WireState GetState();
+  WireState GetState ();
 
   /**
    * \brief Indicates if the channel is busy. The channel will only
@@ -215,7 +211,7 @@
    * \return Returns true if the channel is busy and false if it is
    * free.
    */
-  bool IsBusy();
+  bool IsBusy ();
   
   /**
    * \brief Indicates if a net device is currently attached or
@@ -226,19 +222,32 @@
    * \return Returns true if the net device is attached to the
    * channel, false otherwise.
    */
-  bool IsActive(uint32_t deviceId);
+  bool IsActive (uint32_t deviceId);
+
   /**
    * \return Returns the number of net devices that are currently
    * attached to the channel.
    */
   uint32_t GetNumActDevices (void);
+
   /**
    * \return Returns the total number of devices including devices
    * that have been detached from the channel.
    */
   virtual uint32_t GetNDevices (void) const;
+
+  /**
+   * \return Get a NetDevice pointer to a connected network device.
+   *
+   * \param i The index of the net device.
+   * \return Returns the pointer to the net device that is associated
+   * with deviceId i.
+   */
   virtual Ptr<NetDevice> GetDevice (uint32_t i) const;
+
   /**
+   * \return Get a CsmaNetDevice pointer to a connected network device.
+   *
    * \param i The deviceId of the net device for which we want the
    * pointer.
    * \return Returns the pointer to the net device that is associated
@@ -246,13 +255,32 @@
    */
   Ptr<CsmaNetDevice> GetCsmaDevice (uint32_t i) const;
 
+  /**
+   * Get the assigned data rate of the channel
+   *
+   * \return Returns the DataRate to be used by device transmitters.
+   * with deviceId i.
+   */
   virtual DataRate GetDataRate (void);
+
+  /**
+   * Get the assigned speed-of-light delay of the channel
+   *
+   * \return Returns the delay used by the channel.
+   */
   virtual Time GetDelay (void);
 
 private:
 
-  DataRate      m_bps;    /// Data rate of the channel
-  Time          m_delay;  /// Delay of the channel.
+  /**
+   * The assigned data rate of the channel
+   */
+  DataRate      m_bps;
+
+  /**
+   * The assigned speed-of-light delay of the channel
+   */
+  Time          m_delay;
 
   /**
    * List of the net devices that have been or are currently connected
@@ -265,19 +293,22 @@
    * whole list does not have to be searched when making sure that a
    * source is attached to a channel when it is transmitting data.
    */
-  std::vector< CsmaDeviceRec >            m_deviceList;
+  std::vector<CsmaDeviceRec> m_deviceList;
+
   /**
-   * Packet that is currently being transmitted on the channel (or last
+   * The Packet that is currently being transmitted on the channel (or last
    * packet to have been transmitted on the channel if the channel is
    * free.)
    */
-  Ptr<Packet>                         m_currentPkt;
+  Ptr<Packet> m_currentPkt;
+
   /**
    * Device Id of the source that is currently transmitting on the
    * channel. Or last source to have transmitted a packet on the
    * channel, if the channel is currently not busy.
    */
   uint32_t                            m_currentSrc;
+
   /**
    * Current state of the channel
    */
--- a/src/devices/csma/csma-net-device.cc	Wed Jun 11 16:19:28 2008 -0700
+++ b/src/devices/csma/csma-net-device.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -32,7 +32,6 @@
 #include "csma-net-device.h"
 #include "csma-channel.h"
 
-
 NS_LOG_COMPONENT_DEFINE ("CsmaNetDevice");
 
 namespace ns3 {
@@ -45,40 +44,44 @@
   static TypeId tid = TypeId ("ns3::CsmaNetDevice")
     .SetParent<NetDevice> ()
     .AddConstructor<CsmaNetDevice> ()
-    .AddAttribute ("Address", "The address of this device.",
+    .AddAttribute ("Address", 
+                   "The address of this device.",
                    Mac48AddressValue (Mac48Address ("ff:ff:ff:ff:ff:ff")),
                    MakeMac48AddressAccessor (&CsmaNetDevice::m_address),
                    MakeMac48AddressChecker ())
-    .AddAttribute ("EncapsulationMode", "The mode of link-layer encapsulation to use.",
+    .AddAttribute ("EncapsulationMode", 
+                   "The link-layer encapsulation type to use.",
                    EnumValue (LLC),
                    MakeEnumAccessor (&CsmaNetDevice::m_encapMode),
                    MakeEnumChecker (ETHERNET_V1, "EthernetV1",
                                     IP_ARP, "IpArp",
                                     RAW, "Raw",
                                     LLC, "Llc"))
-    .AddAttribute ("SendEnable", "should tx be enabled ?",
+    .AddAttribute ("SendEnable", 
+                   "Enable or disable the transmitter section of the device.",
                    BooleanValue (true),
                    MakeBooleanAccessor (&CsmaNetDevice::m_sendEnable),
                    MakeBooleanChecker ())
-    .AddAttribute ("ReceiveEnable", "should rx be enabled ?",
+    .AddAttribute ("ReceiveEnable",
+                   "Enable or disable the receiver section of the device.",
                    BooleanValue (true),
                    MakeBooleanAccessor (&CsmaNetDevice::m_receiveEnable),
                    MakeBooleanChecker ())
-    .AddAttribute ("DataRate", "XXX",
-                   DataRateValue (DataRate (0xffffffff)),
-                   MakeDataRateAccessor (&CsmaNetDevice::m_bps),
-                   MakeDataRateChecker ())
-    .AddAttribute ("RxErrorModel", "XXX",
+    .AddAttribute ("RxErrorModel", 
+                   "The receiver error model used to simulate packet loss",
                    PointerValue (),
                    MakePointerAccessor (&CsmaNetDevice::m_receiveErrorModel),
                    MakePointerChecker<ErrorModel> ())
-    .AddAttribute ("TxQueue", "XXX",
+    .AddAttribute ("TxQueue", 
+                   "A queue to use as the transmit queue in the device.",
                    PointerValue (),
                    MakePointerAccessor (&CsmaNetDevice::m_queue),
                    MakePointerChecker<Queue> ())
-    .AddTraceSource ("Rx", "Receive MAC packet.",
+    .AddTraceSource ("Rx", 
+                     "Trace source to fire on reception of a MAC packet.",
                      MakeTraceSourceAccessor (&CsmaNetDevice::m_rxTrace))
-    .AddTraceSource ("Drop", "Drop MAC packet.",
+    .AddTraceSource ("Drop", 
+                     "Trace source to fire on when a MAC packet is dropped.",
                      MakeTraceSourceAccessor (&CsmaNetDevice::m_dropTrace))
     ;
   return tid;
@@ -91,7 +94,7 @@
 {
   NS_LOG_FUNCTION (this);
   m_txMachineState = READY;
-  m_tInterframeGap = Seconds(0);
+  m_tInterframeGap = Seconds (0);
   m_channel = 0; 
 }
 
@@ -101,7 +104,7 @@
   m_queue = 0;
 }
 
-void 
+  void 
 CsmaNetDevice::DoDispose ()
 {
   NS_LOG_FUNCTION_NOARGS ();
@@ -110,61 +113,54 @@
   NetDevice::DoDispose ();
 }
 
-void 
+  void 
 CsmaNetDevice::SetAddress (Mac48Address self)
 {
   m_address = self;
 }
 
-void
+  void
 CsmaNetDevice::SetSendEnable (bool sendEnable)
 {
   NS_LOG_FUNCTION_NOARGS ();
   m_sendEnable = sendEnable;
 }
 
-void
+  void
 CsmaNetDevice::SetReceiveEnable (bool receiveEnable)
 {
   NS_LOG_FUNCTION_NOARGS ();
   m_receiveEnable = receiveEnable;
 }
 
-bool
+  bool
 CsmaNetDevice::IsSendEnabled (void)
 {
   NS_LOG_FUNCTION_NOARGS ();
   return (m_sendEnable);
 }
 
-bool
+  bool
 CsmaNetDevice::IsReceiveEnabled (void)
 {
   NS_LOG_FUNCTION_NOARGS ();
   return (m_receiveEnable);
 }
 
-void 
-CsmaNetDevice::SetDataRate (DataRate bps)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  if (!m_channel || bps <= m_channel->GetDataRate ())
-    {
-      m_bps = bps;
-    }
-}
-
-void 
+  void 
 CsmaNetDevice::SetInterframeGap (Time t)
 {
   NS_LOG_FUNCTION_NOARGS ();
   m_tInterframeGap = t;
 }
 
-void 
-CsmaNetDevice::SetBackoffParams (Time slotTime, uint32_t minSlots, 
-                                 uint32_t maxSlots, uint32_t ceiling, 
-                                 uint32_t maxRetries)
+  void 
+CsmaNetDevice::SetBackoffParams (
+  Time slotTime, 
+  uint32_t minSlots, 
+  uint32_t maxSlots, 
+  uint32_t ceiling, 
+  uint32_t maxRetries)
 {
   NS_LOG_FUNCTION_NOARGS ();
   m_backoff.m_slotTime = slotTime;
@@ -174,32 +170,39 @@
   m_backoff.m_maxRetries = maxRetries;
 }
 
-void 
-CsmaNetDevice::AddHeader (Ptr<Packet> p, Mac48Address dest,
-                            uint16_t protocolNumber)
+  void 
+CsmaNetDevice::AddHeader (
+  Ptr<Packet> p, 
+  Mac48Address dest,
+  uint16_t protocolNumber)
 {
   NS_LOG_FUNCTION_NOARGS ();
+
   if (m_encapMode == RAW)
     {
       return;
     }
-  EthernetHeader header (false);
-  EthernetTrailer trailer;
+
   Mac48Address source = Mac48Address::ConvertFrom (GetAddress ());
-  header.SetSource(source);
-  header.SetDestination(dest);
+  EthernetHeader header (false);
+  header.SetSource (source);
+  header.SetDestination (dest);
+
+  EthernetTrailer trailer;
 
   uint16_t lengthType = 0;
   switch (m_encapMode) 
     {
     case ETHERNET_V1:
-      lengthType = p->GetSize() + header.GetSerializedSize() + trailer.GetSerializedSize();
+      lengthType = p->GetSize () + header.GetSerializedSize () + 
+        trailer.GetSerializedSize ();
       break;
     case IP_ARP:
       lengthType = protocolNumber;
       break;
     case LLC: {
-      lengthType = p->GetSize() + header.GetSerializedSize() + trailer.GetSerializedSize();
+      lengthType = p->GetSize () + header.GetSerializedSize () + 
+        trailer.GetSerializedSize ();
       LlcSnapHeader llc;
       llc.SetType (protocolNumber);
       p->AddHeader (llc);
@@ -208,13 +211,15 @@
       NS_ASSERT (false);
       break;
     }
+
   header.SetLengthType (lengthType);
-  p->AddHeader(header);
-  trailer.CalcFcs(p);
-  p->AddTrailer(trailer);
+  p->AddHeader (header);
+
+  trailer.CalcFcs (p);
+  p->AddTrailer (trailer);
 }
 
-bool 
+  bool 
 CsmaNetDevice::ProcessHeader (Ptr<Packet> p, uint16_t & param)
 {
   NS_LOG_FUNCTION_NOARGS ();
@@ -222,15 +227,17 @@
     {
       return true;
     }
-  EthernetHeader header (false);
+
   EthernetTrailer trailer;
       
-  p->RemoveTrailer(trailer);
-  trailer.CheckFcs(p);
-  p->RemoveHeader(header);
+  p->RemoveTrailer (trailer);
+  trailer.CheckFcs (p);
 
-  if ((header.GetDestination() != GetBroadcast ()) &&
-      (header.GetDestination() != GetAddress ()))
+  EthernetHeader header (false);
+  p->RemoveHeader (header);
+
+  if ((header.GetDestination () != GetBroadcast ()) &&
+      (header.GetDestination () != GetAddress ()))
     {
       return false;
     }
@@ -239,7 +246,7 @@
     {
     case ETHERNET_V1:
     case IP_ARP:
-      param = header.GetLengthType();
+      param = header.GetLengthType ();
       break;
     case LLC: {
       LlcSnapHeader llc;
@@ -253,7 +260,7 @@
   return true;
 }
 
-void
+  void
 CsmaNetDevice::TransmitStart ()
 {
   NS_LOG_FUNCTION_NOARGS ();
@@ -265,47 +272,58 @@
 // schedule an event that will be executed when it's time to tell the 
 // channel that we're done wiggling the wire.
 //
-  NS_ASSERT_MSG((m_txMachineState == READY) || (m_txMachineState == BACKOFF), 
-                "Must be READY to transmit. Tx state is: " 
-                << m_txMachineState);
+  NS_ASSERT_MSG ((m_txMachineState == READY) || (m_txMachineState == BACKOFF), 
+    "Must be READY to transmit. Tx state is: " << m_txMachineState);
+
+//
+// Only transmit if send side of net device is enabled
+//
+  if (IsSendEnabled () == false)
+    {
+      return;
+    }
 
-  // Only transmit if send side of net device is enabled
-  if (!IsSendEnabled())
-    return;
+  if (m_channel->GetState () != IDLE)
+    {
+//
+// The channel is busy -- backoff and rechedule TransmitStart ()
+//
+      m_txMachineState = BACKOFF;
 
-  if (m_channel->GetState() != IDLE)
-    { // Channel busy, backoff and rechedule TransmitStart()
-      m_txMachineState = BACKOFF;
-      if (m_backoff.MaxRetriesReached())
-        { // Too many retries reached, abort transmission of packet
-          TransmitAbort();
+      if (m_backoff.MaxRetriesReached ())
+        { 
+//
+// Too many retries, abort transmission of packet
+//
+          TransmitAbort ();
         } 
       else 
         {
-          m_backoff.IncrNumRetries();
-          Time backoffTime = m_backoff.GetBackoffTime();
+          m_backoff.IncrNumRetries ();
+          Time backoffTime = m_backoff.GetBackoffTime ();
 
           NS_LOG_LOGIC ("Channel busy, backing off for " << 
             backoffTime.GetSeconds () << " sec");
 
-          Simulator::Schedule (backoffTime, 
-                               &CsmaNetDevice::TransmitStart, 
-                               this);
+          Simulator::Schedule (backoffTime, &CsmaNetDevice::TransmitStart,
+            this);
         }
     } 
   else 
     {
-      // Channel is free, transmit packet
+//
+// The channel is free, transmit the packet
+//
       m_txMachineState = BUSY;
-      Time tEvent = Seconds (m_bps.CalculateTxTime(m_currentPkt->GetSize()));
+      Time tEvent = Seconds (m_bps.CalculateTxTime (m_currentPkt->GetSize ()));
       
       NS_LOG_LOGIC ("Schedule TransmitCompleteEvent in " << 
         tEvent.GetSeconds () << "sec");
       
-      Simulator::Schedule (tEvent, 
-                           &CsmaNetDevice::TransmitCompleteEvent, 
-                           this);
-      if (!m_channel->TransmitStart (m_currentPkt, m_deviceId))
+      Simulator::Schedule (tEvent, &CsmaNetDevice::TransmitCompleteEvent, 
+        this);
+
+      if (m_channel->TransmitStart (m_currentPkt, m_deviceId) == false)
         {
           NS_LOG_WARN ("Channel transmit start did not work at " << 
             tEvent.GetSeconds () << "sec");
@@ -313,28 +331,38 @@
         } 
       else 
         {
-          // Transmission success, reset backoff time parameters.
-          m_backoff.ResetBackoffTime();
+//
+// Transmission succeeded, reset the backoff time parameters.
+//
+          m_backoff.ResetBackoffTime ();
         }
     }
 }
 
 
-void
+  void
 CsmaNetDevice::TransmitAbort (void)
 {
   NS_LOG_FUNCTION_NOARGS ();
   NS_LOG_LOGIC ("Pkt UID is " << m_currentPkt->GetUid () << ")");
 
-  // Try to transmit a new packet
+//
+// Since we were transmitting a packet, that packet had better be on the
+// transmit queue.
+//
   m_currentPkt = m_queue->Dequeue ();
-  NS_ASSERT_MSG(m_currentPkt != 0, "IsEmpty false but no Packet on queue?");
-  m_backoff.ResetBackoffTime();
+  NS_ASSERT_MSG (m_currentPkt != 0, "No Packet on queue during"
+    "CsmaNetDevice::TransmitAbort()");
+
+//
+// The last one failed.  Let's try to transmit the next one (if there)
+//
+  m_backoff.ResetBackoffTime ();
   m_txMachineState = READY;
   TransmitStart ();
 }
 
-void
+  void
 CsmaNetDevice::TransmitCompleteEvent (void)
 {
   NS_LOG_FUNCTION_NOARGS ();
@@ -344,9 +372,8 @@
 // schedule an event that will be executed when it's time to re-enable
 // the transmitter after the interframe gap.
 //
-  NS_ASSERT_MSG(m_txMachineState == BUSY, "Must be BUSY if transmitting");
-  // Channel should be transmitting
-  NS_ASSERT(m_channel->GetState() == TRANSMITTING);
+  NS_ASSERT_MSG (m_txMachineState == BUSY, "Must be BUSY if transmitting");
+  NS_ASSERT (m_channel->GetState () == TRANSMITTING);
   m_txMachineState = GAP;
 
   NS_LOG_LOGIC ("Pkt UID is " << m_currentPkt->GetUid () << ")");
@@ -355,12 +382,11 @@
   NS_LOG_LOGIC ("Schedule TransmitReadyEvent in "
     << m_tInterframeGap.GetSeconds () << "sec");
 
-  Simulator::Schedule (m_tInterframeGap, 
-                       &CsmaNetDevice::TransmitReadyEvent, 
-                       this);
+  Simulator::Schedule (m_tInterframeGap, &CsmaNetDevice::TransmitReadyEvent, 
+    this);
 }
 
-void
+  void
 CsmaNetDevice::TransmitReadyEvent (void)
 {
   NS_LOG_FUNCTION_NOARGS ();
@@ -369,18 +395,19 @@
 // gap has passed.  If there are pending transmissions, we use this opportunity
 // to start the next transmit.
 //
-  NS_ASSERT_MSG(m_txMachineState == GAP, "Must be in interframe gap");
+  NS_ASSERT_MSG (m_txMachineState == GAP, "Must be in interframe gap");
   m_txMachineState = READY;
 
   // Get the next packet from the queue for transmitting
-  if (m_queue->IsEmpty())
+  if (m_queue->IsEmpty ())
     {
       return;
     }
   else
     {
       m_currentPkt = m_queue->Dequeue ();
-      NS_ASSERT_MSG(m_currentPkt != 0, "IsEmpty false but no Packet on queue?");
+      NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitReadyEvent():"
+        " IsEmpty false but no Packet on queue?");
       TransmitStart ();
     }
 }
@@ -392,47 +419,49 @@
 
   m_channel = ch;
 
-  m_deviceId = m_channel->Attach(this);
+  m_deviceId = m_channel->Attach (this);
+
+//
+// The channel provides us with the transmitter data rate.
+//
   m_bps = m_channel->GetDataRate ();
-  m_tInterframeGap = m_channel->GetDelay ();
 
-  /* 
-   * For now, this device is up whenever a channel is attached to it.
-   */
+//
+// We use the Ethernet interframe gap of 96 bit times.
+//
+  m_tInterframeGap = Seconds (m_bps.CalculateTxTime (96/8));
+
+//
+// This device is up whenever a channel is attached to it.
+//
   NotifyLinkUp ();
   return true;
 }
 
-void
+  void
 CsmaNetDevice::SetQueue (Ptr<Queue> q)
 {
   NS_LOG_FUNCTION (this << q);
-
   m_queue = q;
 }
 
-void CsmaNetDevice::SetReceiveErrorModel (Ptr<ErrorModel> em)
+  void
+CsmaNetDevice::SetReceiveErrorModel (Ptr<ErrorModel> em)
 {
   NS_LOG_FUNCTION (em);
-  
   m_receiveErrorModel = em; 
 }
 
-void
+  void
 CsmaNetDevice::Receive (Ptr<Packet> packet)
 {
   NS_LOG_FUNCTION_NOARGS ();
+  NS_LOG_LOGIC ("UID is " << packet->GetUid ());
 
-  EthernetHeader header (false);
-  EthernetTrailer trailer;
-  Mac48Address broadcast;
-  Mac48Address multicast;
-  Mac48Address destination;
-
-  NS_LOG_LOGIC ("UID is " << packet->GetUid());
-
-  // Only receive if send side of net device is enabled
-  if (!IsReceiveEnabled())
+// 
+// Only receive if the send side of net device is enabled
+//
+  if (IsReceiveEnabled () == false)
     {
       m_dropTrace (packet);
       return;
@@ -443,14 +472,30 @@
   if (m_encapMode == RAW)
     {
       m_rxCallback (this, packet, 0, GetBroadcast ());
-      m_dropTrace (packet);
       return;
     }
-  packet->RemoveTrailer(trailer);
-  trailer.CheckFcs(packet);
-  packet->RemoveHeader(header);
+
+  EthernetTrailer trailer;
+  packet->RemoveTrailer (trailer);
+  trailer.CheckFcs (packet);
+
+  EthernetHeader header (false);
+  packet->RemoveHeader (header);
+
+  NS_LOG_LOGIC ("Pkt source is " << header.GetSource ());
+  NS_LOG_LOGIC ("Pkt destination is " << header.GetDestination ());
 
-  NS_LOG_LOGIC ("Pkt destination is " << header.GetDestination ());
+//
+// We never forward up packets that we sent.  Real devices don't do this since
+// their receivers are disabled during send, so we don't.  Drop the packet 
+// silently (no tracing) since it would really never get here in a real device.
+//
+  if (header.GetSource () == GetAddress ())
+    {
+      NS_LOG_LOGIC ("Dropping packet sourced by this device");
+      return;
+    }
+
 //
 // An IP host group address is mapped to an Ethernet multicast address
 // by placing the low-order 23-bits of the IP address into the low-order
@@ -468,9 +513,9 @@
   mcBuf[5] = 0;
   mcDest.CopyFrom (mcBuf);
 
-  multicast = Mac48Address::ConvertFrom (GetMulticast ());
-  broadcast = Mac48Address::ConvertFrom (GetBroadcast ());
-  destination = Mac48Address::ConvertFrom (GetAddress ());
+  Mac48Address multicast = Mac48Address::ConvertFrom (GetMulticast ());
+  Mac48Address broadcast = Mac48Address::ConvertFrom (GetBroadcast ());
+  Mac48Address destination = Mac48Address::ConvertFrom (GetAddress ());
 
   if ((header.GetDestination () != broadcast) &&
       (mcDest != multicast) &&
@@ -485,13 +530,12 @@
     {
       NS_LOG_LOGIC ("Dropping pkt due to error model ");
       m_dropTrace (packet);
-      // Do not forward up; let this packet go
     }
   else
     {
 //
-// protocol must be initialized to avoid a compiler warning in the RAW
-// case that breaks the optimized build.
+// variable <protocol> must be initialized to avoid a compiler warning in the 
+// RAW case that breaks the optimized build.
 //
       uint16_t protocol = 0;
 
@@ -499,7 +543,7 @@
         {
         case ETHERNET_V1:
         case IP_ARP:
-          protocol = header.GetLengthType();
+          protocol = header.GetLengthType ();
           break;
         case LLC: 
           {
@@ -516,95 +560,109 @@
     }
 }
 
-Ptr<Queue>
-CsmaNetDevice::GetQueue(void) const 
+  Ptr<Queue>
+CsmaNetDevice::GetQueue (void) const 
 { 
   NS_LOG_FUNCTION_NOARGS ();
   return m_queue;
 }
 
-void
+  void
 CsmaNetDevice::NotifyLinkUp (void)
 {
   m_linkUp = true;
-  if (!m_linkChangeCallback.IsNull ())
+  if (m_linkChangeCallback.IsNull () == false)
     {
       m_linkChangeCallback ();
     }
 }
 
-void 
-CsmaNetDevice::SetName(const std::string name)
+  void 
+CsmaNetDevice::SetName (const std::string name)
 {
   m_name = name;
 }
-std::string 
-CsmaNetDevice::GetName(void) const
+
+  std::string 
+CsmaNetDevice::GetName (void) const
 {
   return m_name;
 }
-void 
-CsmaNetDevice::SetIfIndex(const uint32_t index)
+
+  void 
+CsmaNetDevice::SetIfIndex (const uint32_t index)
 {
   m_ifIndex = index;
 }
-uint32_t 
-CsmaNetDevice::GetIfIndex(void) const
+
+  uint32_t 
+CsmaNetDevice::GetIfIndex (void) const
 {
   return m_ifIndex;
 }
-Ptr<Channel> 
+
+  Ptr<Channel> 
 CsmaNetDevice::GetChannel (void) const
 {
   return m_channel;
 }
-Address 
+
+  Address 
 CsmaNetDevice::GetAddress (void) const
 {
   return m_address;
 }
-bool 
+
+  bool 
 CsmaNetDevice::SetMtu (const uint16_t mtu)
 {
   m_mtu = mtu;
   return true;
 }
-uint16_t 
+
+  uint16_t 
 CsmaNetDevice::GetMtu (void) const
 {
   return m_mtu;
 }
-bool 
+
+  bool 
 CsmaNetDevice::IsLinkUp (void) const
 {
   return m_linkUp;
 }
-void 
+
+  void 
 CsmaNetDevice::SetLinkChangeCallback (Callback<void> callback)
 {
   m_linkChangeCallback = callback;
 }
-bool 
+
+  bool 
 CsmaNetDevice::IsBroadcast (void) const
 {
   return true;
 }
-Address
+
+  Address
 CsmaNetDevice::GetBroadcast (void) const
 {
   return Mac48Address ("ff:ff:ff:ff:ff:ff");
 }
-bool 
+
+  bool 
 CsmaNetDevice::IsMulticast (void) const
 {
   return true;
 }
-Address 
+
+  Address 
 CsmaNetDevice::GetMulticast (void) const
 {
   return Mac48Address ("01:00:5e:00:00:00");
 }
-Address 
+
+  Address 
 CsmaNetDevice::MakeMulticastAddress (Ipv4Address multicastGroup) const
 {
   NS_LOG_FUNCTION (this << multicastGroup);
@@ -655,13 +713,18 @@
 
   return etherAddr;
 }
-bool 
+
+  bool 
 CsmaNetDevice::IsPointToPoint (void) const
 {
   return false;
 }
-bool 
-CsmaNetDevice::Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
+
+  bool 
+CsmaNetDevice::Send(
+  Ptr<Packet> packet, 
+  const Address& dest, 
+  uint16_t protocolNumber)
 {
   NS_LOG_FUNCTION_NOARGS ();
   NS_LOG_LOGIC ("p=" << packet);
@@ -669,43 +732,56 @@
 
   NS_ASSERT (IsLinkUp ());
 
-  // Only transmit if send side of net device is enabled
-  if (!IsSendEnabled())
-    return false;
-
-  Mac48Address destination = Mac48Address::ConvertFrom (dest);
-  AddHeader(packet, destination, protocolNumber);
-
-  // Place the packet to be sent on the send queue
-  if (m_queue->Enqueue(packet) == false )
+//
+// Only transmit if send side of net device is enabled
+//
+  if (IsSendEnabled () == false)
     {
       return false;
     }
-  // If the device is idle, we need to start a transmission. Otherwise,
-  // the transmission will be started when the current packet finished
-  // transmission (see TransmitCompleteEvent)
+
+  Mac48Address destination = Mac48Address::ConvertFrom (dest);
+  AddHeader (packet, destination, protocolNumber);
+
+//
+// Place the packet to be sent on the send queue
+//
+  if (m_queue->Enqueue(packet) == false)
+    {
+      return false;
+    }
+//
+// If the device is idle, we need to start a transmission. Otherwise,
+// the transmission will be started when the current packet finished
+// transmission (see TransmitCompleteEvent)
+//
   if (m_txMachineState == READY) 
     {
-      // Store the next packet to be transmitted
+//
+// The next packet to be transmitted goes in m_currentPkt
+//
       m_currentPkt = m_queue->Dequeue ();
       if (m_currentPkt != 0)
         {
-          TransmitStart();
+          TransmitStart ();
         }
     }
   return true;
 }
-Ptr<Node> 
+
+  Ptr<Node> 
 CsmaNetDevice::GetNode (void) const
 {
   return m_node;
 }
-void 
+
+  void 
 CsmaNetDevice::SetNode (Ptr<Node> node)
 {
   m_node = node;
 }
-bool 
+
+  bool 
 CsmaNetDevice::NeedsArp (void) const
 {
   if ((m_encapMode == IP_ARP) || (m_encapMode == LLC))
@@ -717,7 +793,8 @@
       return false;
     }
 }
-void 
+
+  void 
 CsmaNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb)
 {
   m_rxCallback = cb;
--- a/src/devices/csma/csma-net-device.h	Wed Jun 11 16:19:28 2008 -0700
+++ b/src/devices/csma/csma-net-device.h	Wed Jun 11 16:20:04 2008 -0700
@@ -16,7 +16,6 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca
- * Derived from the p2p net device file
  */
 
 #ifndef CSMA_NET_DEVICE_H
@@ -48,18 +47,19 @@
  *
  * The Csma net device class is analogous to layer 1 and 2 of the
  * TCP stack. The NetDevice takes a raw packet of bytes and creates a
- * protocol specific packet from them. The Csma net device class
- * takes this packet and adds and processes the headers/trailers that
- * are associated with EthernetV1, EthernetV2, RAW or LLC
- * protocols. The EthernetV1 packet type adds and removes Ethernet
+ * protocol specific packet from them. 
+ *
+ * The Csma net device class takes a packet and adds (or removes) the 
+ * headers/trailers that are associated with EthernetV1, EthernetV2, RAW
+ * or LLC protocols. The EthernetV1 packet type adds and removes Ethernet
  * destination and source addresses. The LLC packet type adds and
  * removes LLC snap headers. The raw packet type does not add or
- * remove any headers.  Each Csma net device will receive all
- * packets written to the Csma link. The ProcessHeader function can
- * be used to filter out the packets such that higher level layers
- * only receive packets that are addressed to their associated net
- * devices
+ * remove any headers.  
  *
+ * Each Csma net device will receive all packets written to the Csma link. 
+ * The ProcessHeader function can be used to filter out the packets such that
+ * higher level layers only receive packets that are addressed to their
+ * associated net devices
  */
 class CsmaNetDevice : public NetDevice 
 {
@@ -69,49 +69,36 @@
    * Enumeration of the types of packets supported in the class.
    *
    */
-enum CsmaEncapsulationMode {
-  ETHERNET_V1, /**< Version one ethernet packet, length field */
-  IP_ARP,      /**< Ethernet packet encapsulates IP/ARP packet */
-  RAW,         /**< Packet that contains no headers */
-  LLC,         /**< LLC packet encapsulation */  
-};
+  enum CsmaEncapsulationMode {
+    ETHERNET_V1, /**< Version one ethernet packet, length field */
+    IP_ARP,      /**< Ethernet packet encapsulates IP/ARP packet */
+    RAW,         /**< Packet that contains no headers */
+    LLC,         /**< LLC packet encapsulation */  
+  };
 
   /**
    * Construct a CsmaNetDevice
    *
-   * This is the constructor for the CsmaNetDevice.  It takes as a
-   * parameter the Node to which this device is connected.  Ownership of the
-   * Node pointer is not implied and the node must not be deleted.
-   *
+   * This is the default constructor for a CsmaNetDevice.
    */
   CsmaNetDevice ();
 
   /**
    * Destroy a CsmaNetDevice
    *
-   * This is the destructor for the CsmaNetDevice.
+   * This is the destructor for a CsmaNetDevice.
    */
-  virtual ~CsmaNetDevice();
-  /**
-   * Set the Data Rate used for transmission of packets.  The data rate is
-   * set in the Attach () method from the corresponding field in the channel
-   * to which the device is attached.  It can be overridden using this method.
-   *
-   * @see Attach ()
-   * \param bps the data rate at which this object operates
-   */
-  void SetDataRate (DataRate bps);
+  virtual ~CsmaNetDevice ();
+
   /**
    * Set the inteframe gap used to separate packets.  The interframe gap
    * defines the minimum space required between packets sent by this device.
-   * It is usually set in the Attach () method based on the speed of light
-   * delay of the channel to which the device is attached.  It can be 
-   * overridden using this method if desired.
+   * As in Ethernet, it defaults to 96 bit times.
    *
-   * @see Attach ()
    * \param t the interframe gap time
    */
   void SetInterframeGap (Time t);
+
   /**
    * Set the backoff parameters used to determine the wait to retry
    * transmitting a packet when the channel is busy.
@@ -124,43 +111,43 @@
    * \param ceiling Cap on the exponential function when calculating max slots
    */
   void SetBackoffParams (Time slotTime, uint32_t minSlots, uint32_t maxSlots, 
-                        uint32_t maxRetries, uint32_t ceiling);
+    uint32_t maxRetries, uint32_t ceiling);
+
   /**
    * Attach the device to a channel.
    *
-   * The function Attach is used to add a CsmaNetDevice to a
-   * CsmaChannel.
+   * The function Attach is used to add a CsmaNetDevice to a CsmaChannel.
    *
    * @see SetDataRate ()
    * @see SetInterframeGap ()
    * \param ch a pointer to the channel to which this object is being attached.
    */
   bool Attach (Ptr<CsmaChannel> ch);
+
   /**
    * Attach a queue to the CsmaNetDevice.
    *
-   * The CsmaNetDevice "owns" a queue.  This queue is created by the
-   * CsmaTopology object and implements a queueing method such as
-   * DropTail or RED.  The CsmaNetDevice assumes ownership of this
-   * queue and must delete it when the device is destroyed.
+   * The CsmaNetDevice "owns" a queue.  This queue may be set by higher
+   * level topology objects to implement a particular queueing method such as
+   * DropTail or RED.  
    *
-   * @see CsmaTopology::AddCsmaLink ()
    * @see Queue
    * @see DropTailQueue
-   * \param queue a pointer to the queue for which object is assuming
-   *        ownership.
+   * \param queue a Ptr to the queue for being assigned to the device.
    */
   void SetQueue (Ptr<Queue> queue);
+
   /**
    * Attach a receive ErrorModel to the CsmaNetDevice.
    *
    * The CsmaNetDevice may optionally include an ErrorModel in
-   * the packet receive chain.
+   * the packet receive chain to simulate data errors in during transmission.
    *
    * @see ErrorModel
    * @param em a pointer to the ErrorModel 
    */
-  void SetReceiveErrorModel(Ptr<ErrorModel> em);
+  void SetReceiveErrorModel (Ptr<ErrorModel> em);
+
   /**
    * Receive a packet from a connected CsmaChannel.
    *
@@ -174,20 +161,48 @@
    */
   void Receive (Ptr<Packet> p);
 
+  /**
+   * Is the send side of the network device enabled?
+   *
+   * \returns True if the send side is enabled, otherwise false.
+   */
   bool IsSendEnabled (void);
+
+  /**
+   * Enable or disable the send side of the network device.
+   *
+   * \param enable Enable the send side if true, otherwise disable.
+   */
+  void SetSendEnable (bool enable);
+
+  /**
+   * Is the receive side of the network device enabled?
+   *
+   * \returns True if the receiver side is enabled, otherwise false.
+   */
   bool IsReceiveEnabled (void);
 
-  void SetSendEnable (bool);
-  void SetReceiveEnable (bool);
-
-  void SetAddress (Mac48Address self);
-
+  /**
+   * Enable or disable the receive side of the network device.
+   *
+   * \param enable Enable the receive side if true, otherwise disable.
+   */
+  void SetReceiveEnable (bool enable);
 
-  // inherited from NetDevice base class.
-  virtual void SetName(const std::string name);
-  virtual std::string GetName(void) const;
-  virtual void SetIfIndex(const uint32_t index);
-  virtual uint32_t GetIfIndex(void) const;
+  /**
+   * Set the MAC address of the the network device.
+   *
+   * \param addr The Mac48Address to use as the address of the device.
+   */
+  void SetAddress (Mac48Address addr);
+
+//
+// The following methods are inherited from NetDevice base class.
+//
+  virtual void SetName (const std::string name);
+  virtual std::string GetName (void) const;
+  virtual void SetIfIndex (const uint32_t index);
+  virtual uint32_t GetIfIndex (void) const;
   virtual Ptr<Channel> GetChannel (void) const;
   virtual Address GetAddress (void) const;
   virtual bool SetMtu (const uint16_t mtu);
@@ -198,6 +213,7 @@
   virtual Address GetBroadcast (void) const;
   virtual bool IsMulticast (void) const;
   virtual Address GetMulticast (void) const;
+
   /**
    * @brief Make and return a MAC multicast address using the provided
    *        multicast group
@@ -221,14 +237,54 @@
    * @see Address
    */
   virtual Address MakeMulticastAddress (Ipv4Address multicastGroup) const;
+
+  /**
+   * Is this a point to point link?
+   * \returns false.
+   */
   virtual bool IsPointToPoint (void) const;
-  virtual bool Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber);
+
+  /**
+   * Start sending a packet down the channel.
+   */
+  virtual bool Send (Ptr<Packet> packet, const Address& dest, 
+    uint16_t protocolNumber);
+
+  /**
+   * Get the node to which this device is attached.
+   *
+   * \returns Ptr to the Node to which the device is attached.
+   */
   virtual Ptr<Node> GetNode (void) const;
+
+  /**
+   * Set the node to which this device is being attached.
+   *
+   * \param node Ptr to the Node to which the device is being attached.
+   */
   virtual void SetNode (Ptr<Node> node);
+
+  /**
+   * Does this device need to use the address resolution protocol?
+   *
+   * \returns True if the encapsulation mode is set to a value that requires
+   * ARP (IP_ARP or LLC).
+   */
   virtual bool NeedsArp (void) const;
+
+  /**
+   * Set the callback to be used to notify higher layers when a packet has been
+   * received.
+   *
+   * \param cb The callback.
+   */
   virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
 
 protected:
+  /**
+   * Perform any object release functionality required to break reference 
+   * cycles in reference counted objects held by the device.
+   */
   virtual void DoDispose (void);
 
   /**
@@ -240,6 +296,7 @@
    * \return a pointer to the queue.
    */
   Ptr<Queue> GetQueue (void) const; 
+
   /**
    * Adds the necessary headers and trailers to a packet of data in order to
    * respect the packet type
@@ -249,8 +306,8 @@
    * \param protocolNumber In some protocols, identifies the type of
    * payload contained in this packet.
    */
-  void AddHeader (Ptr<Packet> p, Mac48Address dest, 
-                  uint16_t protocolNumber);
+  void AddHeader (Ptr<Packet> p, Mac48Address dest, uint16_t protocolNumber);
+
   /**
    * Removes, from a packet of data, all headers and trailers that
    * relate to the packet type
@@ -264,11 +321,21 @@
   bool ProcessHeader (Ptr<Packet> p, uint16_t & param);
 
 private:
-  // disable copy constructor and operator =
+  /**
+   * Operator = is declared but not implemented.  This disables the assigment
+   * operator for CsmaNetDevice objects.
+
+   */
   CsmaNetDevice &operator = (const CsmaNetDevice &o);
+
+  /**
+   * Copy constructor is declared but not implemented.  This disables the
+   * copy constructor for CsmaNetDevice objects.
+   */
   CsmaNetDevice (const CsmaNetDevice &o);
+
   /**
-   * Initializes variablea when construction object.
+   * Initialization function used during object construction.
    */
   void Init (bool sendEnable, bool receiveEnable);
 
@@ -277,35 +344,38 @@
    *
    * The TransmitStart method is the method that is used internally in
    * the CsmaNetDevice to begin the process of sending a packet
-   * out on the channel.  The corresponding method is called on the
+   * out on the channel.  A corresponding method is called on the
    * channel to let it know that the physical device this class
-   * represents has virually started sending signals, this causes the
-   * channel to become busy.  An event is scheduled for the time at
-   * which the bits have been completely transmitted. If the channel
-   * is busy, the method reschedules itself for a later time (within
-   * the backoff period)
+   * represents has actually started sending signals, this causes the
+   * channel to enter the BUSY state.  An event is scheduled for the time at
+   * which the bits have been completely transmitted. 
+   *
+   * If the channel is found to be BUSY, this method reschedules itself for
+   * execution at a later time (within the backoff period).
    *
    * @see CsmaChannel::TransmitStart ()
    * @see TransmitCompleteEvent ()
    */
   void TransmitStart ();
+
   /**
    * Stop Sending a Packet Down the Wire and Begin the Interframe Gap.
    *
    * The TransmitCompleteEvent method is used internally to finish the process
    * of sending a packet out on the channel.  During execution of this method
    * the TransmitEnd method is called on the channel to let it know that the
-   * physical device this class represents has virually finished sending 
+   * physical device this class represents has finished sending simulated
    * signals.  The channel uses this event to begin its speed of light delay
-   * timer after which it notifies the Net Device at the other end of the 
-   * link that the bits have arrived.  During this method, the net device 
-   * also schedules the TransmitReadyEvent at which time the transmitter 
-   * becomes ready to send the next packet.
+   * timer after which it notifies the Net Device(s) at the other end of the 
+   * link that new bits have arrived (it delivers the Packet).  During this 
+   * method, the net device also schedules the TransmitReadyEvent at which
+   * time the transmitter becomes ready to send the next packet.
    *
    * @see CsmaChannel::TransmitEnd ()
    * @see TransmitReadyEvent ()
    */
   void TransmitCompleteEvent (void);
+
   /**
    * Cause the Transmitter to Become Ready to Send Another Packet.
    *
@@ -328,9 +398,12 @@
    * If the net device has tried to transmit a packet for more times
    * than the maximum allowed number of retries (channel always busy)
    * then the packet is dropped.
-   *
    */
   void TransmitAbort (void);
+
+  /**
+   * Notify any interested parties that the link has come up.
+   */
   void NotifyLinkUp (void);
 
   /** 
@@ -344,10 +417,12 @@
    * Enable net device to send packets. True by default
    */
   bool m_sendEnable;
+
   /**
    * Enable net device to receive packets. True by default
    */
   bool m_receiveEnable;
+
   /**
    * Enumeration of the states of the transmit machine of the net device.
    */
@@ -358,6 +433,7 @@
       GAP,    /**< The transmitter is in the interframe gap time */
       BACKOFF    /**< The transmitter is waiting for the channel to be free */
     };
+
   /**
    * The state of the Net Device transmit state machine.
    * @see TxMachineState
@@ -370,36 +446,42 @@
    * function.
    */
   CsmaEncapsulationMode m_encapMode;
+
   /**
    * The data rate that the Net Device uses to simulate packet transmission
    * timing.
    * @see class DataRate
    */
   DataRate m_bps;
+
   /**
-   * The interframe gap that the Net Device uses to throttle packet
+   * The interframe gap that the Net Device uses insert time between packet
    * transmission
    * @see class Time
    */
   Time m_tInterframeGap;
+
   /**
    * Holds the backoff parameters and is used to calculate the next
    * backoff time to use when the channel is busy and the net device
    * is ready to transmit
    */
   Backoff m_backoff;
+
   /**
    * Next packet that will be transmitted (if transmitter is not
    * currently transmitting) or packet that is currently being
    * transmitted.
    */
   Ptr<Packet> m_currentPkt;
+
   /**
    * The CsmaChannel to which this CsmaNetDevice has been
    * attached.
    * @see class CsmaChannel
    */
   Ptr<CsmaChannel> m_channel;
+
   /**
    * The Queue which this CsmaNetDevice uses as a packet source.
    * Management of this Queue has been delegated to the CsmaNetDevice
@@ -415,26 +497,65 @@
   Ptr<ErrorModel> m_receiveErrorModel;
 
   /**
-   * NOT TESTED
    * The trace source for the packet reception events that the device can
    * fire.
    *
    * @see class CallBackTraceSource
    */
   TracedCallback<Ptr<const Packet> > m_rxTrace;
+
+  /**
+   * The trace source for the packet drop events that the device can
+   * fire.
+   *
+   * @see class CallBackTraceSource
+   */
   TracedCallback<Ptr<const Packet> > m_dropTrace;
 
+  /**
+   * The Node to which this device is attached.
+   */
   Ptr<Node> m_node;
+
+  /**
+   * The MAC address which has been assigned to this device.
+   */
   Mac48Address m_address;
+
+  /**
+   * The callback used to notify higher layers that a packet has been received.
+   */
   NetDevice::ReceiveCallback m_rxCallback;
+
+  /**
+   * The interface index (really net evice index) that has been assigned to 
+   * this network device.
+   */
   uint32_t m_ifIndex;
+
+  /**
+   * The human readable name of this device.
+   */
   std::string m_name;
+
+  /**
+   * Flag indicating whether or not the link is up.  In this case,
+   * whether or not the device is connected to a channel.
+   */
   bool m_linkUp;
+
+  /**
+   * Callback to fire if the link changes state (up or down).
+   */
   Callback<void> m_linkChangeCallback;
+
+  /**
+   * The maximum transmission unit (biggest packet) allowed to be sent or 
+   * received by this network device.
+   */
   uint16_t m_mtu;
 };
 
 }; // namespace ns3
 
 #endif // CSMA_NET_DEVICE_H
-
--- a/src/devices/csma/csma.h	Wed Jun 11 16:19:28 2008 -0700
+++ b/src/devices/csma/csma.h	Wed Jun 11 16:20:04 2008 -0700
@@ -22,8 +22,14 @@
  *
  * The class ns3::CsmaChannel models the actual transmission medium.
  * There is no fixed limit for the number of devices connected to the channel.
- * The ns3::CsmaChannel models a bitrate and a speed-of-light delay which can
- * be accessed via the attributes "BitRate" and "Delay" respectively.
+ * The ns3::CsmaChannel models a data rate and a speed-of-light delay which can
+ * be accessed via the attributes "DataRate" and "Delay" respectively.
+ * The data rate provided to the channel is used to set the data rates
+ * used by the transmitter sections of the CSMA devices connected to the 
+ * channel.  There is no way to independently set data rates in the
+ * devices.  Since the data rate is only used to calculate a delay time, there
+ * is no limitation (other than by the data type holding the value) on the 
+ * speed at which CSMA channels and devices can operate.
  *
  * The ns3::CsmaChannel has three states, IDLE, TRANSMITTING and PROPAGATING.
  * These three states are "seen" instantaneously by all devices on the channel.
@@ -62,7 +68,13 @@
  *
  * The ns3::CsmaChannel models a broadcast medium so the packet is delivered
  * to all of the devices on the channel (including the source) at the end of 
- * the propagation time.
+ * the propagation time.  It is the responsibility of the sending device to 
+ * determine whether or not it receives a packet broadcast over the channel.
+ *
+ * The ns3::CsmaChannel provides following Attributes:
+ *
+ * - DataRate:      The bitrate for packet transmission on connected devices;
+ * - Delay:       The speed of light transmission delay for the channel.
  *
  * \subsection CSMA Net Device Model
  *
@@ -70,7 +82,6 @@
  * ns3::CsmaNetDevice provides following Attributes:
  *
  * - Address:           The ns3::Mac48Address of the device;
- * - DataRate:          The data rate of the device;
  * - SendEnable:        Enable packet transmission if true;
  * - ReceiveEnable:     Enable packet reception if true;
  * - EncapsulationMode: Type of link layer encapsulation to use;
--- a/src/devices/point-to-point/point-to-point.h	Wed Jun 11 16:19:28 2008 -0700
+++ b/src/devices/point-to-point/point-to-point.h	Wed Jun 11 16:20:04 2008 -0700
@@ -30,6 +30,19 @@
  * - Rx:            A trace source for received packets;
  * - Drop:          A trace source for dropped packets.
  *
+ * The ns3::PointToPointNetDevice models a transmitter section that puts bits
+ * on a corresponding channel "wire."  THe DataRate attribute specifies the
+ * number of bits per second that the device will simulate sending over the 
+ * channel.  In reality no bits are sent, but an event is scheduled for an
+ * elapsed time consistent with the number of bits in each packet and the 
+ * specified DataRate.  The implication here is that the receiving device
+ * models a receiver section that can receive any any data rate.  Therefore
+ * there is no need, nor way to set a receive data rate in this model.  By
+ * setting the DataRate on the transmitter of both devices connected to a 
+ * given ns3::PointToPointChannel one can model a symmetric channel; or by 
+ * setting different DataRates one can model an asymmetric channel (e.g., 
+ * ADSL).
+ *
  * The ns3::PointToPointNetDevice supports the assignment of a "receive error 
  * model."  This is an ns3::ErrorModel object that is used to simulate data
  * corruption on the link.
@@ -40,6 +53,7 @@
  * beyond the eight bits per byte of the packet sent.  That is, we do not 
  * model Flag Sequences, Frame Check Sequences nor do we "escape" any data.
  *
- * The ns3::PointToPointChannel does model a speed-of-light or transmission
- * delay which can be set and get via the attribute "Delay."
+ * The ns3::PointToPointNetChannel provides following Attributes:
+ *
+ * - Delay:       The speed of light transmission delay for the channel.
  */
--- a/src/helper/wscript	Wed Jun 11 16:19:28 2008 -0700
+++ b/src/helper/wscript	Wed Jun 11 16:20:04 2008 -0700
@@ -1,7 +1,7 @@
 ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
 
 def build(bld):
-    helper = bld.create_ns3_module('helper', ['internet-node', 'wifi', 'point-to-point', 'csma', 'olsr', 'global-routing', 'onoff', 'packet-sink', 'udp-echo'])
+    helper = bld.create_ns3_module('helper', ['internet-stack', 'wifi', 'point-to-point', 'csma', 'olsr', 'global-routing', 'onoff', 'packet-sink', 'udp-echo'])
     helper.source = [
         'node-container.cc',
         'net-device-container.cc',
--- a/src/internet-node/arp-cache.cc	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,287 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006 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
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#include "ns3/assert.h"
-#include "ns3/packet.h"
-#include "ns3/simulator.h"
-#include "ns3/uinteger.h"
-#include "ns3/log.h"
-
-#include "arp-cache.h"
-#include "arp-header.h"
-#include "ipv4-interface.h"
-
-NS_LOG_COMPONENT_DEFINE ("ArpCache");
-
-namespace ns3 {
-
-TypeId 
-ArpCache::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::ArpCache")
-    .SetParent<Object> ()
-    .AddAttribute ("AliveTimeout",
-                   "When this timeout expires, the matching cache entry needs refreshing",
-                   TimeValue (Seconds (120)),
-                   MakeTimeAccessor (&ArpCache::m_aliveTimeout),
-                   MakeTimeChecker ())
-    .AddAttribute ("DeadTimeout",
-                   "When this timeout expires, a new attempt to resolve the matching entry is made",
-                   TimeValue (Seconds (100)),
-                   MakeTimeAccessor (&ArpCache::m_deadTimeout),
-                   MakeTimeChecker ())
-    .AddAttribute ("WaitReplyTimeout",
-                   "When this timeout expires, the matching cache entry is marked dead",
-                   TimeValue (Seconds (1)),
-                   MakeTimeAccessor (&ArpCache::m_waitReplyTimeout),
-                   MakeTimeChecker ())
-    .AddAttribute ("PendingQueueSize",
-                   "The size of the queue for packets pending an arp reply.",
-                   UintegerValue (3),
-                   MakeUintegerAccessor (&ArpCache::m_pendingQueueSize),
-                   MakeUintegerChecker<uint32_t> ())
-    ;
-  return tid;
-}
-
-ArpCache::ArpCache ()
-  : m_device (0), 
-    m_interface (0)
-{
-  NS_LOG_FUNCTION (this);
-}
-
-ArpCache::~ArpCache ()
-{
-  NS_LOG_FUNCTION (this);
-}
-
-void 
-ArpCache::DoDispose (void)
-{
-  NS_LOG_FUNCTION (this);
-  Flush ();
-  m_device = 0;
-  m_interface = 0;
-  Object::DoDispose ();
-}
-
-void
-ArpCache::SetDevice (Ptr<NetDevice> device, Ptr<Ipv4Interface> interface)
-{
-  m_device = device;
-  m_interface = interface;
-}
-
-Ptr<NetDevice>
-ArpCache::GetDevice (void) const
-{
-  return m_device;
-}
-
-Ptr<Ipv4Interface>
-ArpCache::GetInterface (void) const
-{
-  return m_interface;
-}
-
-void 
-ArpCache::SetAliveTimeout (Time aliveTimeout)
-{
-  m_aliveTimeout = aliveTimeout;
-}
-void 
-ArpCache::SetDeadTimeout (Time deadTimeout)
-{
-  m_deadTimeout = deadTimeout;
-}
-void 
-ArpCache::SetWaitReplyTimeout (Time waitReplyTimeout)
-{
-  m_waitReplyTimeout = waitReplyTimeout;
-}
-
-Time
-ArpCache::GetAliveTimeout (void) const
-{
-  return m_aliveTimeout;
-}
-Time
-ArpCache::GetDeadTimeout (void) const
-{
-  return m_deadTimeout;
-}
-Time
-ArpCache::GetWaitReplyTimeout (void) const
-{
-  return m_waitReplyTimeout;
-}
-
-void 
-ArpCache::Flush (void)
-{
-  for (CacheI i = m_arpCache.begin (); i != m_arpCache.end (); i++) 
-    {
-      delete (*i).second;
-    }
-  m_arpCache.erase (m_arpCache.begin (), m_arpCache.end ());
-}
-
-ArpCache::Entry *
-ArpCache::Lookup (Ipv4Address to)
-{
-  if (m_arpCache.find (to) != m_arpCache.end ()) 
-    {
-      ArpCache::Entry *entry = m_arpCache[to];
-      return entry;
-    }
-  return 0;
-}
-
-ArpCache::Entry *
-ArpCache::Add (Ipv4Address to)
-{
-  NS_ASSERT (m_arpCache.find (to) == m_arpCache.end ());
-
-  ArpCache::Entry *entry = new ArpCache::Entry (this);
-  m_arpCache[to] = entry;  
-  return entry;
-}
-
-ArpCache::Entry::Entry (ArpCache *arp)
-  : m_arp (arp),
-    m_state (ALIVE)
-{}
-
-
-bool 
-ArpCache::Entry::IsDead (void)
-{
-  return (m_state == DEAD)?true:false;
-}
-bool 
-ArpCache::Entry::IsAlive (void)
-{
-  return (m_state == ALIVE)?true:false;
-}
-bool
-ArpCache::Entry::IsWaitReply (void)
-{
-  return (m_state == WAIT_REPLY)?true:false;
-}
-
-
-void 
-ArpCache::Entry::MarkDead (void) 
-{
-  m_state = DEAD;
-  UpdateSeen ();
-}
-void
-ArpCache::Entry::MarkAlive (Address macAddress) 
-{
-  NS_ASSERT (m_state == WAIT_REPLY);
-  m_macAddress = macAddress;
-  m_state = ALIVE;
-  UpdateSeen ();
-}
-
-bool
-ArpCache::Entry::UpdateWaitReply (Ptr<Packet> waiting)
-{
-  NS_ASSERT (m_state == WAIT_REPLY);
-  /* We are already waiting for an answer so
-   * we dump the previously waiting packet and
-   * replace it with this one.
-   */
-  if (m_pending.size () >= m_arp->m_pendingQueueSize)
-    {
-      return false;
-    }
-  m_pending.push_back (waiting);
-  return true;
-}
-void 
-ArpCache::Entry::MarkWaitReply (Ptr<Packet> waiting)
-{
-  NS_ASSERT (m_state == ALIVE || m_state == DEAD);
-  NS_ASSERT (m_pending.empty ());
-  m_state = WAIT_REPLY;
-  m_pending.push_back (waiting);
-  UpdateSeen ();
-}
-
-Address
-ArpCache::Entry::GetMacAddress (void)
-{
-  NS_ASSERT (m_state == ALIVE);
-  return m_macAddress;
-}
-bool 
-ArpCache::Entry::IsExpired (void)
-{
-  Time timeout;
-  switch (m_state) {
-  case ArpCache::Entry::WAIT_REPLY:
-    timeout = m_arp->GetWaitReplyTimeout ();
-    break;
-  case ArpCache::Entry::DEAD:
-    timeout = m_arp->GetDeadTimeout ();
-    break;
-  case ArpCache::Entry::ALIVE:
-    timeout = m_arp->GetAliveTimeout ();
-    break;
-  default:
-    NS_ASSERT (false);
-    timeout = Seconds (0);
-    /* NOTREACHED */
-    break;
-  }
-  Time delta = Simulator::Now () - m_lastSeen;
-  if (delta >= timeout) 
-    {
-      return true;
-    } 
-  else 
-    {
-      return false;
-    }
-}
-Ptr<Packet> 
-ArpCache::Entry::DequeuePending (void)
-{
-  if (m_pending.empty ())
-    {
-      return 0;
-    }
-  else
-    {
-      Ptr<Packet> p = m_pending.front ();
-      m_pending.pop_front ();
-      return p;
-    }
-}
-void 
-ArpCache::Entry::UpdateSeen (void)
-{
-  m_lastSeen = Simulator::Now ();
-}
-
-} // namespace ns3
-
--- a/src/internet-node/arp-cache.h	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,178 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006 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
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef ARP_CACHE_H
-#define ARP_CACHE_H
-
-#include <stdint.h>
-#include <list>
-#include "ns3/packet.h"
-#include "ns3/nstime.h"
-#include "ns3/net-device.h"
-#include "ns3/ipv4-address.h"
-#include "ns3/address.h"
-#include "ns3/ptr.h"
-#include "ns3/object.h"
-#include "sgi-hashmap.h"
-
-namespace ns3 {
-
-class NetDevice;
-class Ipv4Interface;
-
-/**
- * \brief An ARP cache
- *
- * A cached lookup table for translating layer 3 addresses to layer 2.
- * This implementation does lookups from IPv4 to a MAC address
- */
-class ArpCache : public Object
-{
-public:
-  static TypeId GetTypeId (void);
-  class Entry;
-  ArpCache ();
-  ~ArpCache ();
-
-  /**
-   * \param device The hardware NetDevice associated with this ARP chache
-   * \param interface the Ipv4Interface associated with this ARP chache
-   */
-  void SetDevice (Ptr<NetDevice> device, Ptr<Ipv4Interface> interface);
-  /**
-   * \return The NetDevice that this ARP cache is associated with
-   */
-  Ptr<NetDevice> GetDevice (void) const;
-  /**
-   * \return the Ipv4Interface that this ARP cache is associated with
-   */
-  Ptr<Ipv4Interface> GetInterface (void) const;
-  
-  void SetAliveTimeout (Time aliveTimeout);
-  void SetDeadTimeout (Time deadTimeout);
-  void SetWaitReplyTimeout (Time waitReplyTimeout);
-  Time GetAliveTimeout (void) const;
-  Time GetDeadTimeout (void) const;
-  Time GetWaitReplyTimeout (void) const;
-
-  /**
-   * \brief Do lookup in the ARP chache against an IP address
-   * \param destination The destination IPv4 address to lookup the MAC address
-   * of
-   * \return An ArpCache::Entry with info about layer 2
-   */
-  ArpCache::Entry *Lookup (Ipv4Address destination);
-  /**
-   * \brief Add an Ipv4Address to this ARP cache
-   */
-  ArpCache::Entry *Add (Ipv4Address to);
-  /**
-   * \brief Clear the ArpCache of all entries
-   */
-  void Flush (void);
-
-  /**
-   * \brief A record that that holds information about an ArpCache entry
-   */
-  class Entry {
-  public:
-    /**
-     * \brief Constructor
-     * \param arp The ArpCache this entry belongs to
-     */
-    Entry (ArpCache *arp);
-    
-    /**
-     * \brief Changes the state of this entry to dead
-     */
-    void MarkDead (void);
-    /**
-     * \param macAddress
-     */
-    void MarkAlive (Address macAddress);
-    /**
-     * \param waiting
-     */
-    void MarkWaitReply (Ptr<Packet> waiting);
-    /**
-     * \param waiting
-     * \return 
-     */
-    bool UpdateWaitReply (Ptr<Packet> waiting);
-    /**
-     * \return True if the state of this entry is dead; false otherwise.
-     */
-    bool IsDead (void);
-    /**
-     * \return True if the state of this entry is alive; false otherwise.
-     */
-    bool IsAlive (void);
-    /**
-     * \return True if the state of this entry is wait_reply; false otherwise.
-     */
-    bool IsWaitReply (void);
-    
-    /**
-     * \return The MacAddress of this entry
-     */
-    Address GetMacAddress (void);
-    /**
-     * \return True if this entry has timedout; false otherwise.
-     */
-    bool IsExpired (void);
-
-    /**
-     * \returns 0 is no packet is pending, the next packet to send if 
-     *            packets are pending.
-     */
-    Ptr<Packet> DequeuePending (void);
-  private:
-    enum ArpCacheEntryState_e {
-      ALIVE,
-      WAIT_REPLY,
-      DEAD
-    };
-
-    void UpdateSeen (void);
-    ArpCache *m_arp;
-    ArpCacheEntryState_e m_state;
-    Time m_lastSeen;
-    Address m_macAddress;
-    std::list<Ptr<Packet> > m_pending;
-  };
-
-private:
-  typedef sgi::hash_map<Ipv4Address, ArpCache::Entry *, Ipv4AddressHash> Cache;
-  typedef sgi::hash_map<Ipv4Address, ArpCache::Entry *, Ipv4AddressHash>::iterator CacheI;
-
-  virtual void DoDispose (void);
-
-  Ptr<NetDevice> m_device;
-  Ptr<Ipv4Interface> m_interface;
-  Time m_aliveTimeout;
-  Time m_deadTimeout;
-  Time m_waitReplyTimeout;
-  uint32_t m_pendingQueueSize;
-  Cache m_arpCache;
-};
-
-
-}; // namespace ns3
-
-#endif /* ARP_CACHE_H */
--- a/src/internet-node/arp-header.cc	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,161 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005 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
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#include "ns3/assert.h"
-#include "ns3/address-utils.h"
-#include "arp-header.h"
-
-namespace ns3 {
-
-NS_OBJECT_ENSURE_REGISTERED (ArpHeader);
-
-void 
-ArpHeader::SetRequest (Address sourceHardwareAddress,
-                       Ipv4Address sourceProtocolAddress,
-                       Address destinationHardwareAddress,
-                       Ipv4Address destinationProtocolAddress)
-{
-  m_type = ARP_TYPE_REQUEST;
-  m_macSource = sourceHardwareAddress;
-  m_macDest = destinationHardwareAddress;
-  m_ipv4Source = sourceProtocolAddress;
-  m_ipv4Dest = destinationProtocolAddress;
-}
-void 
-ArpHeader::SetReply (Address sourceHardwareAddress,
-                     Ipv4Address sourceProtocolAddress,
-                     Address destinationHardwareAddress,
-                     Ipv4Address destinationProtocolAddress)
-{
-  m_type = ARP_TYPE_REPLY;
-  m_macSource = sourceHardwareAddress;
-  m_macDest = destinationHardwareAddress;
-  m_ipv4Source = sourceProtocolAddress;
-  m_ipv4Dest = destinationProtocolAddress;
-}
-bool 
-ArpHeader::IsRequest (void) const
-{
-  return (m_type == ARP_TYPE_REQUEST)?true:false;
-}
-bool 
-ArpHeader::IsReply (void) const
-{
-  return (m_type == ARP_TYPE_REPLY)?true:false;
-}
-Address 
-ArpHeader::GetSourceHardwareAddress (void)
-{
-  return m_macSource;
-}
-Address 
-ArpHeader::GetDestinationHardwareAddress (void)
-{
-  return m_macDest;
-}
-Ipv4Address 
-ArpHeader::GetSourceIpv4Address (void)
-{
-  return m_ipv4Source;
-}
-Ipv4Address 
-ArpHeader::GetDestinationIpv4Address (void)
-{
-  return m_ipv4Dest;
-}
-
-
-TypeId 
-ArpHeader::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::ArpHeader")
-    .SetParent<Header> ()
-    .AddConstructor<ArpHeader> ()
-    ;
-  return tid;
-}
-TypeId 
-ArpHeader::GetInstanceTypeId (void) const
-{
-  return GetTypeId ();
-}
-void 
-ArpHeader::Print (std::ostream &os) const
-{
-  if (IsRequest ()) 
-    {
-      os << "request "
-         << "source mac: " << m_macSource << " "
-         << "source ipv4: " << m_ipv4Source << " "
-         << "dest ipv4: " << m_ipv4Dest
-        ;
-    } 
-  else 
-    {
-      NS_ASSERT (IsReply ());
-      os << "reply " 
-         << "source mac: " << m_macSource << " "
-         << "source ipv4: " << m_ipv4Source << " "
-         << "dest mac: " << m_macDest << " "
-         << "dest ipv4: " <<m_ipv4Dest
-        ;
-    }
-}
-uint32_t 
-ArpHeader::GetSerializedSize (void) const
-{
-  /* this is the size of an ARP payload. */
-  return 28;
-}
-
-void
-ArpHeader::Serialize (Buffer::Iterator start) const
-{
-  Buffer::Iterator i = start;
-  NS_ASSERT (m_macSource.GetLength () == m_macDest.GetLength ());
-
-  /* ethernet */
-  i.WriteHtonU16 (0x0001);
-  /* ipv4 */
-  i.WriteHtonU16 (0x0800);
-  i.WriteU8 (m_macSource.GetLength ());
-  i.WriteU8 (4);
-  i.WriteHtonU16 (m_type);
-  WriteTo (i, m_macSource);
-  WriteTo (i, m_ipv4Source);
-  WriteTo (i, m_macDest);
-  WriteTo (i, m_ipv4Dest);
-}
-uint32_t
-ArpHeader::Deserialize (Buffer::Iterator start)
-{
-  Buffer::Iterator i = start;
-  i.Next (2+2);
-  uint32_t hardwareAddressLen = i.ReadU8 ();
-  i.Next (1);
-  m_type = i.ReadNtohU16 ();
-  ReadFrom (i, m_macSource, hardwareAddressLen);
-  ReadFrom (i, m_ipv4Source);
-  ReadFrom (i, m_macDest, hardwareAddressLen);
-  ReadFrom (i, m_ipv4Dest);
-  return GetSerializedSize ();
-}
-
-}; // namespace ns3
--- a/src/internet-node/arp-header.h	Wed Jun 11 16:19:28 2008 -0700
+++ /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) 2005 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
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#ifndef ARP_HEADER_H
-#define ARP_HEADER_H
-
-#include "ns3/header.h"
-#include "ns3/address.h"
-#include "ns3/ipv4-address.h"
-#include <string>
-
-namespace ns3 {
-/**
- * \brief The packet header for an ARP packet
- */
-class ArpHeader : public Header 
-{
-public:
-  void SetRequest (Address sourceHardwareAddress,
-                   Ipv4Address sourceProtocolAddress,
-                   Address destinationHardwareAddress,
-                   Ipv4Address destinationProtocolAddress);
-  void SetReply (Address sourceHardwareAddress,
-                 Ipv4Address sourceProtocolAddress,
-                 Address destinationHardwareAddress,
-                 Ipv4Address destinationProtocolAddress);
-  bool IsRequest (void) const;
-  bool IsReply (void) const;
-  Address GetSourceHardwareAddress (void);
-  Address GetDestinationHardwareAddress (void);
-  Ipv4Address GetSourceIpv4Address (void);
-  Ipv4Address GetDestinationIpv4Address (void);
-
-  static TypeId GetTypeId (void);
-  virtual TypeId GetInstanceTypeId (void) const;
-  virtual void Print (std::ostream &os) const;
-  virtual uint32_t GetSerializedSize (void) const;
-  virtual void Serialize (Buffer::Iterator start) const;
-  virtual uint32_t Deserialize (Buffer::Iterator start);
-
-  enum ArpType_e {
-    ARP_TYPE_REQUEST = 1,
-    ARP_TYPE_REPLY   = 2
-  };
-  uint16_t m_type;
-  Address m_macSource;
-  Address m_macDest;
-  Ipv4Address m_ipv4Source;
-  Ipv4Address m_ipv4Dest;
-};
-
-}; // namespace ns3
-
-#endif /* ARP_HEADER_H */
--- a/src/internet-node/arp-ipv4-interface.cc	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,156 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 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: 
- *  Mathieu Lacage <mathieu.lacage@sophia.inria.fr>,
- */
-
-#include "ns3/packet.h"
-#include "ns3/log.h"
-#include "ns3/node.h"
-#include "ns3/net-device.h"
-#include "ns3/address.h"
-#include "ns3/pointer.h"
-
-#include "arp-ipv4-interface.h"
-#include "ipv4-l3-protocol.h"
-#include "arp-l3-protocol.h"
-#include "arp-cache.h"
-
-NS_LOG_COMPONENT_DEFINE ("ArpIpv4Interface");
-
-namespace ns3 {
-
-TypeId 
-ArpIpv4Interface::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::ArpIpv4Interface")
-    .SetParent<Ipv4Interface> ()
-    .AddAttribute ("ArpCache",
-                   "The arp cache for this ipv4 interface",
-                   PointerValue (0),
-                   MakePointerAccessor (&ArpIpv4Interface::m_cache),
-                   MakePointerChecker<ArpIpv4Interface> ())
-    ;
-  return tid;
-}
-
-ArpIpv4Interface::ArpIpv4Interface ()
-  : m_node (0),
-    m_device (0)
-{
-  NS_LOG_FUNCTION (this);
-}
-
-ArpIpv4Interface::~ArpIpv4Interface ()
-{
-  NS_LOG_FUNCTION (this);
-}
-
-void 
-ArpIpv4Interface::DoDispose (void)
-{
-  NS_LOG_FUNCTION (this);
-  m_node = 0;
-  m_device = 0;
-  m_cache = 0;
-  Ipv4Interface::DoDispose ();
-}
-
-void 
-ArpIpv4Interface::SetNode (Ptr<Node> node)
-{
-  m_node = node;
-  DoSetup ();
-}
-void 
-ArpIpv4Interface::SetDevice (Ptr<NetDevice> device)
-{
-  m_device = device;
-  DoSetup ();
-}
-
-Ptr<NetDevice> 
-ArpIpv4Interface::GetDevice (void) const
-{
-  return m_device;
-}
-
-void
-ArpIpv4Interface::DoSetup (void)
-{
-  if (m_node == 0 || m_device == 0)
-    {
-      return;
-    }
-  Ptr<ArpL3Protocol> arp = m_node->GetObject<ArpL3Protocol> ();
-  m_cache = arp->CreateCache (m_device, this);
-}
-
-void 
-ArpIpv4Interface::SendTo (Ptr<Packet> p, Ipv4Address dest)
-{
-  NS_LOG_FUNCTION (this << p << dest);
-
-  NS_ASSERT (GetDevice () != 0);
-  if (m_device->NeedsArp ())
-    {
-      NS_LOG_LOGIC ("Needs ARP");
-      Ptr<ArpL3Protocol> arp = 
-        m_node->GetObject<ArpL3Protocol> ();
-      Address hardwareDestination;
-      bool found;
-      
-      if (dest.IsBroadcast () || 
-          dest.IsSubnetDirectedBroadcast (GetNetworkMask ()) )
-        {
-          NS_LOG_LOGIC ("IsBroadcast");
-          hardwareDestination = GetDevice ()->GetBroadcast ();
-          found = true;
-        }
-      else if (dest.IsMulticast ())
-        {
-          NS_LOG_LOGIC ("IsMulticast");
-          NS_ASSERT_MSG(GetDevice ()->IsMulticast (),
-            "ArpIpv4Interface::SendTo (): Sending multicast packet over "
-            "non-multicast device");
-
-          hardwareDestination = GetDevice ()->MakeMulticastAddress(dest);
-          found = true;
-        }
-      else
-        {
-          NS_LOG_LOGIC ("ARP Lookup");
-          found = arp->Lookup (p, dest, GetDevice (), m_cache, &hardwareDestination);
-        }
-
-      if (found)
-        {
-          NS_LOG_LOGIC ("Address Resolved.  Send.");
-          GetDevice ()->Send (p, hardwareDestination, 
-            Ipv4L3Protocol::PROT_NUMBER);
-        }
-    }
-  else
-    {
-      NS_LOG_LOGIC ("Doesn't need ARP");
-      GetDevice ()->Send (p, GetDevice ()->GetBroadcast (), 
-        Ipv4L3Protocol::PROT_NUMBER);
-    }
-}
-
-}//namespace ns3
--- a/src/internet-node/arp-ipv4-interface.h	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 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: 
- *  Mathieu Lacage <mathieu.lacage@sophia.inria.fr>,
- */
-#ifndef ARP_IPV4_INTERFACE_H
-#define ARP_IPV4_INTERFACE_H
-
-#include "ipv4-interface.h"
-#include "ns3/ptr.h"
-
-namespace ns3 {
-
-class Node;
-class ArpCache;
-
-/**
- * \brief an Ipv4 Interface which uses ARP
- *
- * If you need to use ARP on top of a specific NetDevice, you
- * can use this Ipv4Interface subclass to wrap it for the Ipv4 class
- * when calling Ipv4::AggregateObject.
- */
-class ArpIpv4Interface : public Ipv4Interface
-{
-public:
-  static TypeId GetTypeId (void);
-
-  ArpIpv4Interface ();
-  virtual ~ArpIpv4Interface ();
-
-  void SetNode (Ptr<Node> node);
-  void SetDevice (Ptr<NetDevice> device);
-
-  virtual Ptr<NetDevice> GetDevice (void) const;
-
-private:
-  virtual void SendTo (Ptr<Packet> p, Ipv4Address dest);
-  virtual void DoDispose (void);
-  void DoSetup (void);
-  Ptr<Node> m_node;
-  Ptr<NetDevice> m_device;
-  Ptr<ArpCache> m_cache;
-};
-
-}//namespace ns3
-
-
-#endif /* ARP_IPV4_INTERFACE_H */
--- a/src/internet-node/arp-l3-protocol.cc	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,303 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006 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
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#include "ns3/packet.h"
-#include "ns3/log.h"
-#include "ns3/node.h"
-#include "ns3/net-device.h"
-#include "ns3/object-vector.h"
-#include "ns3/trace-source-accessor.h"
-
-#include "ipv4-l3-protocol.h"
-#include "arp-l3-protocol.h"
-#include "arp-header.h"
-#include "arp-cache.h"
-#include "ipv4-interface.h"
-
-NS_LOG_COMPONENT_DEFINE ("ArpL3Protocol");
-
-namespace ns3 {
-
-const uint16_t ArpL3Protocol::PROT_NUMBER = 0x0806;
-
-NS_OBJECT_ENSURE_REGISTERED (ArpL3Protocol);
-
-TypeId 
-ArpL3Protocol::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::ArpL3Protocol")
-    .SetParent<Object> ()
-    .AddAttribute ("CacheList",
-                   "The list of ARP caches",
-                   ObjectVectorValue (),
-                   MakeObjectVectorAccessor (&ArpL3Protocol::m_cacheList),
-                   MakeObjectVectorChecker<ArpCache> ())
-    .AddTraceSource ("Drop",
-                     "Packet dropped because not enough room in pending queue for a specific cache entry.",
-                     MakeTraceSourceAccessor (&ArpL3Protocol::m_dropTrace))
-    ;
-  return tid;
-}
-
-ArpL3Protocol::ArpL3Protocol ()
-{
-  NS_LOG_FUNCTION (this);
-}
-
-ArpL3Protocol::~ArpL3Protocol ()
-{
-  NS_LOG_FUNCTION (this);
-}
-
-void 
-ArpL3Protocol::SetNode (Ptr<Node> node)
-{
-  m_node = node;
-}
-
-void 
-ArpL3Protocol::DoDispose (void)
-{
-  NS_LOG_FUNCTION (this);
-  for (CacheList::iterator i = m_cacheList.begin (); i != m_cacheList.end (); ++i)
-    {
-      Ptr<ArpCache> cache = *i;
-      cache->Dispose ();
-    }
-  m_cacheList.clear ();
-  m_node = 0;
-  Object::DoDispose ();
-}
-
-Ptr<ArpCache> 
-ArpL3Protocol::CreateCache (Ptr<NetDevice> device, Ptr<Ipv4Interface> interface)
-{
-  Ptr<Ipv4L3Protocol> ipv4 = m_node->GetObject<Ipv4L3Protocol> ();
-  Ptr<ArpCache> cache = CreateObject<ArpCache> ();
-  cache->SetDevice (device, interface);
-  NS_ASSERT (device->IsBroadcast ());
-  device->SetLinkChangeCallback (MakeCallback (&ArpCache::Flush, cache));
-  m_cacheList.push_back (cache);
-  return cache;
-}
-
-Ptr<ArpCache>
-ArpL3Protocol::FindCache (Ptr<NetDevice> device)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  for (CacheList::const_iterator i = m_cacheList.begin (); i != m_cacheList.end (); i++)
-    {
-      if ((*i)->GetDevice () == device)
-	{
-	  return *i;
-	}
-    }
-  NS_ASSERT (false);
-  // quiet compiler
-  return 0;
-}
-
-void 
-ArpL3Protocol::Receive(Ptr<NetDevice> device, Ptr<Packet> packet, uint16_t protocol, const Address &from)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  Ptr<ArpCache> cache = FindCache (device);
-  ArpHeader arp;
-  packet->RemoveHeader (arp);
-  
-  NS_LOG_LOGIC ("ARP: received "<< (arp.IsRequest ()? "request" : "reply") <<
-            " node="<<m_node->GetId ()<<", got request from " <<
-            arp.GetSourceIpv4Address () << " for address " <<
-            arp.GetDestinationIpv4Address () << "; we have address " <<
-            cache->GetInterface ()->GetAddress ());
-
-  /**
-   * Note: we do not update the ARP cache when we receive an ARP request
-   * from an unknown node. See bug #107
-   */
-
-  if (arp.IsRequest () && 
-      arp.GetDestinationIpv4Address () == cache->GetInterface ()->GetAddress ()) 
-    {
-      NS_LOG_LOGIC ("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 () == device->GetAddress ()) 
-    {
-      Ipv4Address from = arp.GetSourceIpv4Address ();
-      ArpCache::Entry *entry = cache->Lookup (from);
-      if (entry != 0)
-        {
-          if (entry->IsWaitReply ()) 
-            {
-              NS_LOG_LOGIC ("node="<<m_node->GetId ()<<", got reply from " << 
-                        arp.GetSourceIpv4Address ()
-                     << " for waiting entry -- flush");
-              Address from_mac = arp.GetSourceHardwareAddress ();
-              entry->MarkAlive (from_mac);
-              Ptr<Packet> pending = entry->DequeuePending();
-              while (pending != 0)
-                {
-                  cache->GetInterface ()->Send (pending,
-                                                arp.GetSourceIpv4Address ());
-                  pending = entry->DequeuePending();
-                }
-            } 
-          else 
-            {
-              // ignore this reply which might well be an attempt 
-              // at poisening my arp cache.
-              NS_LOG_LOGIC("node="<<m_node->GetId ()<<", got reply from " << 
-                        arp.GetSourceIpv4Address () << 
-                        " for non-waiting entry -- drop");
-              m_dropTrace (packet);
-            }
-        } 
-      else 
-        {
-          NS_LOG_LOGIC ("node="<<m_node->GetId ()<<", got reply for unknown entry -- drop");
-          m_dropTrace (packet);
-        }
-    }
-  else
-    {
-      NS_LOG_LOGIC ("node="<<m_node->GetId ()<<", got request from " <<
-                arp.GetSourceIpv4Address () << " for unknown address " <<
-                arp.GetDestinationIpv4Address () << " -- drop");
-    }
-}
-bool 
-ArpL3Protocol::Lookup (Ptr<Packet> packet, Ipv4Address destination, 
-                       Ptr<NetDevice> device,
-                       Ptr<ArpCache> cache,
-                       Address *hardwareDestination)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  ArpCache::Entry *entry = cache->Lookup (destination);
-  if (entry != 0)
-    {
-      if (entry->IsExpired ()) 
-        {
-          if (entry->IsDead ()) 
-            {
-              NS_LOG_LOGIC ("node="<<m_node->GetId ()<<
-                        ", dead entry for " << destination << " expired -- send arp request");
-              entry->MarkWaitReply (packet);
-              SendArpRequest (cache, destination);
-            } 
-          else if (entry->IsAlive ()) 
-            {
-              NS_LOG_LOGIC ("node="<<m_node->GetId ()<<
-                        ", alive entry for " << destination << " expired -- send arp request");
-              entry->MarkWaitReply (packet);
-              SendArpRequest (cache, destination);
-            } 
-          else if (entry->IsWaitReply ()) 
-            {
-              NS_LOG_LOGIC ("node="<<m_node->GetId ()<<
-                        ", wait reply for " << destination << " expired -- drop");
-              entry->MarkDead ();
-              Ptr<Packet> pending = entry->DequeuePending();
-              while (pending != 0)
-                {
-                  m_dropTrace (pending);
-                  pending = entry->DequeuePending();
-                }
-              m_dropTrace (packet);
-            }
-        } 
-      else 
-        {
-          if (entry->IsDead ()) 
-            {
-              NS_LOG_LOGIC ("node="<<m_node->GetId ()<<
-                            ", dead entry for " << destination << " valid -- drop");
-              m_dropTrace (packet);
-            } 
-          else if (entry->IsAlive ()) 
-            {
-              NS_LOG_LOGIC ("node="<<m_node->GetId ()<<
-                            ", alive entry for " << destination << " valid -- send");
-	      *hardwareDestination = entry->GetMacAddress ();
-              return true;
-            } 
-          else if (entry->IsWaitReply ()) 
-            {
-              NS_LOG_LOGIC ("node="<<m_node->GetId ()<<
-                            ", wait reply for " << destination << " valid -- drop previous");
-              if (!entry->UpdateWaitReply (packet))
-                {
-                  m_dropTrace (packet);
-                }
-            }
-        }
-    }
-  else
-    {
-      // This is our first attempt to transmit data to this destination.
-      NS_LOG_LOGIC ("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 (Ptr<const ArpCache> cache, Ipv4Address to)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  ArpHeader arp;
-  NS_LOG_LOGIC ("ARP: sending request from node "<<m_node->GetId ()<<
-            " || src: " << cache->GetDevice ()->GetAddress () <<
-            " / " << cache->GetInterface ()->GetAddress () <<
-            " || dst: " << cache->GetDevice ()->GetBroadcast () <<
-            " / " << to);
-  arp.SetRequest (cache->GetDevice ()->GetAddress (),
-		  cache->GetInterface ()->GetAddress (), 
-                  cache->GetDevice ()->GetBroadcast (),
-                  to);
-  Ptr<Packet> packet = Create<Packet> ();
-  packet->AddHeader (arp);
-  cache->GetDevice ()->Send (packet, cache->GetDevice ()->GetBroadcast (), PROT_NUMBER);
-}
-
-void
-ArpL3Protocol::SendArpReply (Ptr<const ArpCache> cache, Ipv4Address toIp, Address toMac)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  ArpHeader arp;
-  NS_LOG_LOGIC ("ARP: sending reply from node "<<m_node->GetId ()<<
-            "|| src: " << cache->GetDevice ()->GetAddress () << 
-            " / " << cache->GetInterface ()->GetAddress () <<
-            " || dst: " << toMac << " / " << toIp);
-  arp.SetReply (cache->GetDevice ()->GetAddress (),
-                cache->GetInterface ()->GetAddress (),
-                toMac, toIp);
-  Ptr<Packet> packet = Create<Packet> ();
-  packet->AddHeader (arp);
-  cache->GetDevice ()->Send (packet, toMac, PROT_NUMBER);
-}
-
-}//namespace ns3
--- a/src/internet-node/arp-l3-protocol.h	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006 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
- *
- * 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/address.h"
-#include "ns3/ptr.h"
-#include "ns3/traced-callback.h"
-
-#include "ipv4-interface.h"
-
-namespace ns3 {
-
-class ArpCache;
-class NetDevice;
-class Node;
-class Packet;
-
-/**
- * \brief An implementation of the ARP protocol
- */
-class ArpL3Protocol : public Object
-{
-public:
-  static TypeId GetTypeId (void);
-  static const uint16_t PROT_NUMBER;
-
-  ArpL3Protocol ();
-  virtual ~ArpL3Protocol ();
-
-  void SetNode (Ptr<Node> node);
-
-  Ptr<ArpCache> CreateCache (Ptr<NetDevice> device, Ptr<Ipv4Interface> interface);
-
-  /**
-   * \brief Recieve a packet
-   */
-  void Receive(Ptr<NetDevice> device, Ptr<Packet> p, uint16_t protocol, const Address &from);
-  /**
-   * \brief Perform an ARP lookup
-   * \param p
-   * \param destination
-   * \param device
-   * \param cache
-   * \param hardwareDestination
-   * \return 
-   */
-  bool Lookup (Ptr<Packet> p, Ipv4Address destination, 
-	       Ptr<NetDevice> device,
-               Ptr<ArpCache> cache,
-	       Address *hardwareDestination);
-protected:
-  virtual void DoDispose (void);
-private:
-  typedef std::list<Ptr<ArpCache> > CacheList;
-  Ptr<ArpCache> FindCache (Ptr<NetDevice> device);
-  void SendArpRequest (Ptr<const ArpCache>cache, Ipv4Address to);
-  void SendArpReply (Ptr<const ArpCache> cache, Ipv4Address toIp, Address toMac);
-  CacheList m_cacheList;
-  Ptr<Node> m_node;
-  TracedCallback<Ptr<const Packet> > m_dropTrace;
-};
-
-}//namespace ns3
-
-
-#endif /* ARP_L3_PROTOCOL_H */
--- a/src/internet-node/internet-stack.cc	Wed Jun 11 16:19:28 2008 -0700
+++ /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) 2006 Georgia Tech Research Corporation
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//
-// Author: George F. Riley<riley@ece.gatech.edu>
-//
-
-#include "ns3/net-device.h"
-#include "ns3/callback.h"
-#include "ns3/node.h"
-
-#include "ipv4-l4-demux.h"
-#include "udp-l4-protocol.h"
-#include "tcp-l4-protocol.h"
-#include "ipv4-l3-protocol.h"
-#include "arp-l3-protocol.h"
-#include "udp-socket-factory-impl.h"
-#include "tcp-socket-factory-impl.h"
-#include "ipv4-impl.h"
-
-namespace ns3 {
-
-void 
-AddInternetStack (Ptr<Node> node)
-{
-  Ptr<Ipv4L3Protocol> ipv4 = CreateObject<Ipv4L3Protocol> ();
-  Ptr<ArpL3Protocol> arp = CreateObject<ArpL3Protocol> ();
-  ipv4->SetNode (node);
-  arp->SetNode (node);
-
-  Ptr<Ipv4L4Demux> ipv4L4Demux = CreateObject<Ipv4L4Demux> ();
-  Ptr<UdpL4Protocol> udp = CreateObject<UdpL4Protocol> ();
-  Ptr<TcpL4Protocol> tcp = CreateObject<TcpL4Protocol> ();
-
-  ipv4L4Demux->SetNode (node);
-  udp->SetNode (node);
-  tcp->SetNode (node);
-
-  ipv4L4Demux->Insert (udp);
-  ipv4L4Demux->Insert (tcp);
-
-  Ptr<UdpSocketFactoryImpl> udpFactory = CreateObject<UdpSocketFactoryImpl> ();
-  Ptr<TcpSocketFactoryImpl> tcpFactory = CreateObject<TcpSocketFactoryImpl> ();
-  Ptr<Ipv4Impl> ipv4Impl = CreateObject<Ipv4Impl> ();
-
-  udpFactory->SetUdp (udp);
-  tcpFactory->SetTcp (tcp);
-  ipv4Impl->SetIpv4 (ipv4);
-
-  node->AggregateObject (ipv4);
-  node->AggregateObject (arp);
-  node->AggregateObject (ipv4Impl);
-  node->AggregateObject (udpFactory);
-  node->AggregateObject (tcpFactory);
-  node->AggregateObject (ipv4L4Demux);
-}
-
-}//namespace ns3
--- a/src/internet-node/internet-stack.h	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//
-// Author: George F. Riley<riley@ece.gatech.edu>
-
-#ifndef INTERNET_STACK_H
-#define INTERNET_STACK_H
-
-#include "ns3/ptr.h"
-
-namespace ns3 {
-
-class Node;
-
-void AddInternetStack (Ptr<Node> node);
-
-}//namespace ns3
-
-#endif /* INTERNET_STACK_H */
--- a/src/internet-node/ipv4-checksum.cc	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005,2006,2007 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
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#include "ipv4-checksum.h"
-
-namespace ns3 {
-
-uint16_t 
-Ipv4ChecksumCalculate (uint16_t checksum, uint8_t *buffer, uint16_t size)
-{
-  /* see RFC 1071 to understand this code. */
-  uint32_t sum = checksum;
-  uint16_t *data = (uint16_t *) buffer;
-  for (uint16_t i = 0; i < (size/2); i++) {
-    sum += data[i];
-  }
-  if ((size % 2) != 0) {
-    uint8_t tmpBuf[2];
-    tmpBuf[0] = buffer[size-1];
-    tmpBuf[1] = 0;
-    data = (uint16_t *)tmpBuf;
-    sum += *data;
-  }
-  while (sum >> 16) {
-    sum = (sum & 0xffff) + (sum >> 16);
-  }
-  return sum;
-}
-
-uint16_t 
-Ipv4ChecksumComplete (uint16_t checksum)
-{
-  return ~checksum;
-}
-
-}; //namespace ns3
--- a/src/internet-node/ipv4-checksum.h	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005,2006,2007 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
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef IPV4_CHECKSUM_H
-#define IPV4_CHECKSUM_H
-
-#include <stdint.h>
-
-namespace ns3 {
-
-uint16_t Ipv4ChecksumCalculate (uint16_t checksum, uint8_t *buffer, uint16_t size);
-
-uint16_t Ipv4ChecksumComplete (uint16_t checksum);
-
-}; //namespace ns3
-
-#endif /* IPV4_CHECKSUM_H */
--- a/src/internet-node/ipv4-end-point-demux.cc	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,293 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005 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
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#include "ipv4-end-point-demux.h"
-#include "ipv4-end-point.h"
-#include "ns3/log.h"
-
-namespace ns3{
-
-NS_LOG_COMPONENT_DEFINE ("Ipv4EndPointDemux");
-
-Ipv4EndPointDemux::Ipv4EndPointDemux ()
-  : m_ephemeral (49152)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-}
-
-Ipv4EndPointDemux::~Ipv4EndPointDemux ()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++) 
-    {
-      Ipv4EndPoint *endPoint = *i;
-      delete endPoint;
-    }
-  m_endPoints.clear ();
-}
-
-bool
-Ipv4EndPointDemux::LookupPortLocal (uint16_t port)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++) 
-    {
-      if ((*i)->GetLocalPort  () == port) 
-        {
-          return true;
-        }
-    }
-  return false;
-}
-
-bool
-Ipv4EndPointDemux::LookupLocal (Ipv4Address addr, uint16_t port)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++) 
-    {
-      if ((*i)->GetLocalPort () == port &&
-          (*i)->GetLocalAddress () == addr) 
-        {
-          return true;
-        }
-    }
-  return false;
-}
-
-Ipv4EndPoint *
-Ipv4EndPointDemux::Allocate (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  uint16_t port = AllocateEphemeralPort ();
-  if (port == 0) 
-    {
-      NS_LOG_WARN ("Ephemeral port allocation failed.");
-      return 0;
-    }
-  Ipv4EndPoint *endPoint = new Ipv4EndPoint (Ipv4Address::GetAny (), port);
-  m_endPoints.push_back (endPoint);
-  NS_LOG_DEBUG ("Now have >>" << m_endPoints.size () << "<< endpoints.");
-  return endPoint;
-}
-
-Ipv4EndPoint *
-Ipv4EndPointDemux::Allocate (Ipv4Address address)
-{
-  NS_LOG_FUNCTION (this << address);
-  uint16_t port = AllocateEphemeralPort ();
-  if (port == 0) 
-    {
-      NS_LOG_WARN ("Ephemeral port allocation failed.");
-      return 0;
-    }
-  Ipv4EndPoint *endPoint = new Ipv4EndPoint (address, port);
-  m_endPoints.push_back (endPoint);
-  NS_LOG_DEBUG ("Now have >>" << m_endPoints.size () << "<< endpoints.");
-  return endPoint;
-}
-
-Ipv4EndPoint *
-Ipv4EndPointDemux::Allocate (uint16_t port)
-{
-  NS_LOG_FUNCTION (this <<  port);
-
-  return Allocate (Ipv4Address::GetAny (), port);
-}
-
-Ipv4EndPoint *
-Ipv4EndPointDemux::Allocate (Ipv4Address address, uint16_t port)
-{
-  NS_LOG_FUNCTION (this << address << port);
-  if (LookupLocal (address, port)) 
-    {
-      NS_LOG_WARN ("Duplicate address/port; failing.");
-      return 0;
-    }
-  Ipv4EndPoint *endPoint = new Ipv4EndPoint (address, port);
-  m_endPoints.push_back (endPoint);
-  NS_LOG_DEBUG ("Now have >>" << m_endPoints.size () << "<< endpoints.");
-  return endPoint;
-}
-
-Ipv4EndPoint *
-Ipv4EndPointDemux::Allocate (Ipv4Address localAddress, uint16_t localPort,
-			     Ipv4Address peerAddress, uint16_t peerPort)
-{
-  NS_LOG_FUNCTION (this << localAddress << localPort << peerAddress << peerPort);
-  for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++) 
-    {
-      if ((*i)->GetLocalPort () == localPort &&
-          (*i)->GetLocalAddress () == localAddress &&
-          (*i)->GetPeerPort () == peerPort &&
-          (*i)->GetPeerAddress () == peerAddress) 
-        {
-          NS_LOG_WARN ("No way we can allocate this end-point.");
-          /* no way we can allocate this end-point. */
-          return 0;
-        }
-    }
-  Ipv4EndPoint *endPoint = new Ipv4EndPoint (localAddress, localPort);
-  endPoint->SetPeer (peerAddress, peerPort);
-  m_endPoints.push_back (endPoint);
-
-  NS_LOG_DEBUG ("Now have >>" << m_endPoints.size () << "<< endpoints.");
-
-  return endPoint;
-}
-
-void 
-Ipv4EndPointDemux::DeAllocate (Ipv4EndPoint *endPoint)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++) 
-    {
-      if (*i == endPoint)
-        {
-          delete endPoint;
-          m_endPoints.erase (i);
-          break;
-        }
-    }
-}
-
-/*
- * If we have an exact match, we return it.
- * Otherwise, if we find a generic match, we return it.
- * Otherwise, we return 0.
- */
-Ipv4EndPointDemux::EndPoints
-Ipv4EndPointDemux::Lookup (Ipv4Address daddr, uint16_t dport, 
-                           Ipv4Address saddr, uint16_t sport,
-                           Ptr<Ipv4Interface> incomingInterface)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  EndPoints retval1; // Matches exact on local port, wildcards on others
-  EndPoints retval2; // Matches exact on local port/adder, wildcards on others
-  EndPoints retval3; // Matches all but local address
-  EndPoints retval4; // Exact match on all 4
-  
-  NS_LOG_FUNCTION (this << daddr << dport << saddr << sport << incomingInterface);
-  NS_LOG_DEBUG ("Looking up endpoint for destination address " << daddr);
-  for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++) 
-    {
-      Ipv4EndPoint* endP = *i;
-      NS_LOG_DEBUG ("Looking at endpoint dport=" << endP->GetLocalPort ()
-                    << " daddr=" << endP->GetLocalAddress ()
-                    << " sport=" << endP->GetPeerPort ()
-                    << " saddr=" << endP->GetPeerAddress ());
-      if (endP->GetLocalPort () != dport) 
-        {
-          NS_LOG_LOGIC ("Skipping endpoint " << &endP
-                        << " because endpoint dport "
-                        << endP->GetLocalPort ()
-                        << " does not match packet dport " << dport);
-          continue;
-        }
-      bool isBroadcast = (daddr.IsBroadcast () ||
-         daddr.IsSubnetDirectedBroadcast (
-             incomingInterface->GetNetworkMask ()));
-      Ipv4Address incomingInterfaceAddr = incomingInterface->GetAddress ();
-      NS_LOG_DEBUG ("dest addr " << daddr << " broadcast? " << isBroadcast);
-      bool localAddressMatchesWildCard = 
-        endP->GetLocalAddress() == Ipv4Address::GetAny();
-      bool localAddressMatchesExact = endP->GetLocalAddress () == daddr;
-
-      if (isBroadcast)
-        {
-          NS_LOG_DEBUG("Found bcast, localaddr " << endP->GetLocalAddress());
-        }
-
-      if (isBroadcast && (endP->GetLocalAddress() != Ipv4Address::GetAny()))
-        {
-          localAddressMatchesExact = (endP->GetLocalAddress () ==
-                                      incomingInterfaceAddr);
-        }
-      // if no match here, keep looking
-      if (!(localAddressMatchesExact || localAddressMatchesWildCard))
-        continue; 
-      bool remotePeerMatchesExact = endP->GetPeerPort () == sport;
-      bool remotePeerMatchesWildCard = endP->GetPeerPort() == 0;
-      bool remoteAddressMatchesExact = endP->GetPeerAddress () == saddr;
-      bool remoteAddressMatchesWildCard = endP->GetPeerAddress () ==
-        Ipv4Address::GetAny();
-      // If remote does not match either with exact or wildcard,
-      // skip this one
-      if (!(remotePeerMatchesExact || remotePeerMatchesWildCard))
-        continue;
-      if (!(remoteAddressMatchesExact || remoteAddressMatchesWildCard))
-        continue;
-      
-      // Now figure out which return list to add this one to
-      if (localAddressMatchesWildCard &&
-          remotePeerMatchesWildCard &&
-          remoteAddressMatchesWildCard)
-        { // Only local port matches exactly
-          retval1.push_back(endP);
-        }
-      if ((localAddressMatchesExact || (isBroadcast && localAddressMatchesWildCard))&&
-          remotePeerMatchesWildCard &&
-           remoteAddressMatchesWildCard)
-        { // Only local port and local address matches exactly
-          retval2.push_back(endP);
-        }
-      if (localAddressMatchesWildCard &&
-          remotePeerMatchesExact &&
-          remoteAddressMatchesExact)
-        { // All but local address
-          retval3.push_back(endP);
-        }
-      if (localAddressMatchesExact &&
-          remotePeerMatchesExact &&
-          remoteAddressMatchesExact)
-        { // All 4 match
-          retval4.push_back(endP);
-        }
-    }
-
-  // Here we find the most exact match
-  if (!retval4.empty()) return retval4;
-  if (!retval3.empty()) return retval3;
-  if (!retval2.empty()) return retval2;
-  return retval1;  // might be empty if no matches
-}
-
-uint16_t
-Ipv4EndPointDemux::AllocateEphemeralPort (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  uint16_t port = m_ephemeral;
-  do 
-    {
-      port++;
-      if (port == 65535) 
-        {
-          port = 49152;
-        }
-      if (!LookupPortLocal (port)) 
-        {
-          return port;
-        }
-  } while (port != m_ephemeral);
-  return 0;
-}
-
-} //namespace ns3
-
--- a/src/internet-node/ipv4-end-point-demux.h	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005 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
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#ifndef IPV4_END_POINT_DEMUX_H
-#define IPV4_END_POINT_DEMUX_H
-
-#include <stdint.h>
-#include <list>
-#include "ns3/ipv4-address.h"
-#include "ipv4-interface.h"
-
-namespace ns3 {
-
-class Ipv4EndPoint;
-
-class Ipv4EndPointDemux {
-public:
-  typedef std::list<Ipv4EndPoint *> EndPoints;
-  typedef std::list<Ipv4EndPoint *>::iterator EndPointsI;
-
-  Ipv4EndPointDemux ();
-  ~Ipv4EndPointDemux ();
-
-  bool LookupPortLocal (uint16_t port);
-  bool LookupLocal (Ipv4Address addr, uint16_t port);
-  EndPoints Lookup (Ipv4Address daddr, 
-                    uint16_t dport, 
-                    Ipv4Address saddr, 
-                    uint16_t sport,
-                    Ptr<Ipv4Interface> incomingInterface);
-
-  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);
-
- private:
-  uint16_t AllocateEphemeralPort (void);
-
-  uint16_t m_ephemeral;
-  EndPoints m_endPoints;
-};
-
-} // namespace ns3
-
-#endif /* IPV4_END_POINTS_H */
--- a/src/internet-node/ipv4-end-point.cc	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005 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
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#include "ipv4-end-point.h"
-#include "ns3/packet.h"
-
-namespace ns3 {
-
-Ipv4EndPoint::Ipv4EndPoint (Ipv4Address address, uint16_t port)
-  : m_localAddr (address), 
-    m_localPort (port),
-    m_peerAddr (Ipv4Address::GetAny ()),
-    m_peerPort (0)
-{}
-Ipv4EndPoint::~Ipv4EndPoint ()
-{
-  if (!m_destroyCallback.IsNull ())
-    {
-      m_destroyCallback ();
-    }
-}
-
-Ipv4Address 
-Ipv4EndPoint::GetLocalAddress (void)
-{
-  return m_localAddr;
-}
-
-void 
-Ipv4EndPoint::SetLocalAddress (Ipv4Address address)
-{
-  m_localAddr = address;
-}
-
-uint16_t 
-Ipv4EndPoint::GetLocalPort (void)
-{
-  return m_localPort;
-}
-Ipv4Address 
-Ipv4EndPoint::GetPeerAddress (void)
-{
-  return m_peerAddr;
-}
-uint16_t 
-Ipv4EndPoint::GetPeerPort (void)
-{
-  return m_peerPort;
-}
-void 
-Ipv4EndPoint::SetPeer (Ipv4Address address, uint16_t port)
-{
-  m_peerAddr = address;
-  m_peerPort = port;
-}
-
-void 
-Ipv4EndPoint::SetRxCallback (Callback<void,Ptr<Packet>, Ipv4Address, uint16_t> callback)
-{
-  m_rxCallback = callback;
-}
-
-void 
-Ipv4EndPoint::SetDestroyCallback (Callback<void> callback)
-{
-  m_destroyCallback = callback;
-}
-
-void 
-Ipv4EndPoint::ForwardUp (Ptr<Packet> p, Ipv4Address saddr, uint16_t sport)
-{
-  if (!m_rxCallback.IsNull ())
-  {
-    m_rxCallback (p, saddr, sport);
-  }
-}
-
-
-
-}; // namespace ns3
--- a/src/internet-node/ipv4-end-point.h	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005 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
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#ifndef IPV4_END_POINT_H
-#define IPV4_END_POINT_H
-
-#include <stdint.h>
-#include "ns3/ipv4-address.h"
-#include "ns3/callback.h"
-
-namespace ns3 {
-
-class Header;
-class Packet;
-
-class Ipv4EndPoint {
-public:
-  Ipv4EndPoint (Ipv4Address address, uint16_t port);
-  ~Ipv4EndPoint ();
-
-  Ipv4Address GetLocalAddress (void);
-  void SetLocalAddress (Ipv4Address address);
-  uint16_t GetLocalPort (void);
-  Ipv4Address GetPeerAddress (void);
-  uint16_t GetPeerPort (void);
-
-  void SetPeer (Ipv4Address address, uint16_t port);
-
-  void SetRxCallback (Callback<void,Ptr<Packet>, Ipv4Address, uint16_t> callback);
-  void SetDestroyCallback (Callback<void> callback);
-
-  void ForwardUp (Ptr<Packet> p, Ipv4Address saddr, uint16_t sport);
-
-private:
-  Ipv4Address m_localAddr;
-  uint16_t m_localPort;
-  Ipv4Address m_peerAddr;
-  uint16_t m_peerPort;
-  Callback<void,Ptr<Packet>, Ipv4Address, uint16_t> m_rxCallback;
-  Callback<void> m_destroyCallback;
-};
-
-}; // namespace ns3
-
-
-#endif /* IPV4_END_POINT_H */
--- a/src/internet-node/ipv4-impl.cc	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,273 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 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
- *
- * 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 ()
-  : m_ipv4 (0)
-{}
-Ipv4Impl::~Ipv4Impl ()
-{
-  NS_ASSERT (m_ipv4 == 0);
-}
-void 
-Ipv4Impl::SetIpv4 (Ptr<Ipv4L3Protocol> ipv4)
-{
-  m_ipv4 = ipv4;
-}
-void 
-Ipv4Impl::DoDispose (void)
-{
-  m_ipv4 = 0;
-}
-
-void
-Ipv4Impl::AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
-                              int16_t priority)
-{
-  m_ipv4->AddRoutingProtocol (routingProtocol, priority);
-}
-
-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);
-}
-
-void
-Ipv4Impl::AddMulticastRoute (Ipv4Address origin,
-                             Ipv4Address group,
-                             uint32_t inputInterface,
-                             std::vector<uint32_t> outputInterfaces)
-{
-  m_ipv4->AddMulticastRoute (origin, group, inputInterface, outputInterfaces);
-}
-
-void
-Ipv4Impl::SetDefaultMulticastRoute (uint32_t outputInterface)
-{
-  m_ipv4->SetDefaultMulticastRoute (outputInterface);
-}
-
-uint32_t 
-Ipv4Impl::GetNMulticastRoutes (void) const
-{
-  return m_ipv4->GetNMulticastRoutes ();
-}
-
-Ipv4MulticastRoute 
-Ipv4Impl::GetMulticastRoute (uint32_t i) const
-{
-  return *m_ipv4->GetMulticastRoute (i);
-}
-
-void
-Ipv4Impl::RemoveMulticastRoute (Ipv4Address origin,
-                                Ipv4Address group,
-                                uint32_t inputInterface)
-{
-  m_ipv4->RemoveMulticastRoute (origin, group, inputInterface);
-}
-
-void 
-Ipv4Impl::RemoveMulticastRoute (uint32_t i)
-{
-  return m_ipv4->RemoveMulticastRoute (i);
-}
-
-uint32_t 
-Ipv4Impl::AddInterface (Ptr<NetDevice> device)
-{
-  return m_ipv4->AddInterface (device);
-}
-
-uint32_t 
-Ipv4Impl::GetNInterfaces (void)
-{
-  return m_ipv4->GetNInterfaces ();
-}
-
-uint32_t 
-Ipv4Impl::FindInterfaceForAddr (Ipv4Address addr) const
-{
-  return m_ipv4->FindInterfaceForAddr (addr);
-}
-
-uint32_t 
-Ipv4Impl::FindInterfaceForAddr (Ipv4Address addr, Ipv4Mask mask) const
-{
-  return m_ipv4->FindInterfaceForAddr (addr, mask);
-}
-
-int32_t 
-Ipv4Impl::FindInterfaceForDevice (Ptr<NetDevice> device) const
-{
-  return m_ipv4->FindInterfaceIndexForDevice (device);
-}
-
-Ptr<NetDevice>
-Ipv4Impl::GetNetDevice (uint32_t i)
-{
-  return m_ipv4->GetInterface (i)-> GetDevice ();
-}
-
-void 
-Ipv4Impl::JoinMulticastGroup (Ipv4Address origin, Ipv4Address group)
-{
-  m_ipv4->JoinMulticastGroup(origin, group);
-}
-
-void
-Ipv4Impl::LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group)
-{
-  m_ipv4->LeaveMulticastGroup(origin, group);
-}
-
-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);
-}
-
-void
-Ipv4Impl::SetMetric (uint32_t i, uint16_t metric) 
-{
-  m_ipv4->SetMetric (i, metric);
-}
-
-uint16_t
-Ipv4Impl::GetMetric (uint32_t i) const
-{
-  return m_ipv4->GetMetric (i);
-}
-
-bool
-Ipv4Impl::GetIfIndexForDestination (Ipv4Address dest, uint32_t &ifIndex) const
-{
-  return m_ipv4->GetIfIndexForDestination (dest, ifIndex);
-}
-
-Ipv4Address 
-Ipv4Impl::GetSourceAddress (Ipv4Address destination) const
-{
-  uint32_t ifIndex = 0xffffffff;
-
-  bool result = m_ipv4->GetIfIndexForDestination (destination, ifIndex);
-
-  if (result)
-    {
-      return m_ipv4->GetAddress (ifIndex);
-    }
-  else
-    {
-//
-// If we can't find any address, just leave it 0.0.0.0
-//
-      return Ipv4Address::GetAny ();
-    }
-}
-
-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
--- a/src/internet-node/ipv4-impl.h	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,112 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 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
- *
- * 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 ();
-
-  virtual ~Ipv4Impl ();
-
-  void SetIpv4 (Ptr<Ipv4L3Protocol> ipv4);
-
-  virtual void AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
-                                   int16_t priority);
-
-  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 void AddMulticastRoute (Ipv4Address origin,
-                                  Ipv4Address group,
-                                  uint32_t inputInterface,
-                                  std::vector<uint32_t> outputInterfaces);
-
-  virtual void SetDefaultMulticastRoute (uint32_t outputInterface);
-
-  virtual uint32_t GetNMulticastRoutes (void) const;
-  virtual Ipv4MulticastRoute GetMulticastRoute (uint32_t i) const;
-
-  virtual void RemoveMulticastRoute (Ipv4Address origin,
-                                     Ipv4Address group,
-                                     uint32_t inputInterface);
-  virtual void RemoveMulticastRoute (uint32_t i);
-
-  virtual uint32_t AddInterface (Ptr<NetDevice> device);
-  virtual uint32_t GetNInterfaces (void);  
-
-  virtual uint32_t FindInterfaceForAddr (Ipv4Address addr) const;
-  virtual uint32_t FindInterfaceForAddr (Ipv4Address addr, 
-    Ipv4Mask mask) const;
-
-  virtual int32_t FindInterfaceForDevice (Ptr<NetDevice> device) const;
-
-  virtual Ptr<NetDevice> GetNetDevice(uint32_t i);
-
-  virtual void JoinMulticastGroup (Ipv4Address origin, Ipv4Address group);
-  virtual void LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group);
-
-  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 void SetMetric (uint32_t i, uint16_t metric);
-  virtual uint16_t GetMetric (uint32_t i) const;
-  virtual Ipv4Address GetSourceAddress (Ipv4Address destination) const;
-  virtual bool GetIfIndexForDestination (Ipv4Address dest, 
-    uint32_t &ifIndex) 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 */
--- a/src/internet-node/ipv4-interface.cc	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,174 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005,2006,2007 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
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#include "ipv4-interface.h"
-#include "ns3/ipv4-address.h"
-#include "ns3/net-device.h"
-#include "ns3/log.h"
-#include "ns3/packet.h"
-
-NS_LOG_COMPONENT_DEFINE ("Ipv4Interface");
-
-namespace ns3 {
-
-TypeId 
-Ipv4Interface::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::Ipv4Interface")
-    .SetParent<Object> ()
-    ;
-  return tid;
-}
-
-  /**
-   * By default, Ipv4 interface are created in the "down" state
-   * with ip address 192.168.0.1 and a matching mask. Before
-   * becoming useable, the user must invoke SetUp on them
-   * once the final Ipv4 address and mask has been set.
-   */
-Ipv4Interface::Ipv4Interface () 
-  : m_ifup(false),
-    m_metric(1)
-{
-  NS_LOG_FUNCTION (this);
-}
-
-Ipv4Interface::~Ipv4Interface ()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-}
-
-void
-Ipv4Interface::DoDispose (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  Object::DoDispose ();
-}
-
-void 
-Ipv4Interface::SetAddress (Ipv4Address a)
-{
-  NS_LOG_FUNCTION (this << a);
-  m_address = a;
-}
-
-void 
-Ipv4Interface::SetNetworkMask (Ipv4Mask mask)
-{
-  NS_LOG_FUNCTION (this << mask);
-  m_netmask = mask;
-}
-
-Ipv4Address
-Ipv4Interface::GetBroadcast (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  uint32_t mask = m_netmask.Get ();
-  uint32_t address = m_address.Get ();
-  Ipv4Address broadcast = Ipv4Address (address | (~mask));
-  return broadcast;
-}
-
-Ipv4Mask 
-Ipv4Interface::GetNetworkMask (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_netmask;
-}
-
-void
-Ipv4Interface::SetMetric (uint16_t metric)
-{
-  NS_LOG_FUNCTION (metric);
-  m_metric = metric;
-}
-
-uint16_t
-Ipv4Interface::GetMetric (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_metric;
-}
-
-Ipv4Address 
-Ipv4Interface::GetAddress (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_address;
-}
-
-uint16_t 
-Ipv4Interface::GetMtu (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  if (GetDevice () == 0)
-    {
-      uint32_t mtu = (1<<16) - 1;
-      return mtu;
-    }
-  return GetDevice ()->GetMtu ();
-}
-
-/**
- * These are IP interface states and may be distinct from 
- * NetDevice states, such as found in real implementations
- * (where the device may be down but IP interface state is still up).
- */
-bool 
-Ipv4Interface::IsUp (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_ifup;
-}
-
-bool 
-Ipv4Interface::IsDown (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return !m_ifup;
-}
-
-void 
-Ipv4Interface::SetUp (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_ifup = true;
-}
-
-void 
-Ipv4Interface::SetDown (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_ifup = false;
-}
-
-// public wrapper on private virtual function
-void 
-Ipv4Interface::Send(Ptr<Packet> p, Ipv4Address dest)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  if (IsUp()) {
-    NS_LOG_LOGIC ("SendTo");
-    SendTo(p, dest);
-  }
-}
-
-}; // namespace ns3
-
--- a/src/internet-node/ipv4-interface.h	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,156 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005,2006,2007 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: 
- *  Mathieu Lacage <mathieu.lacage@sophia.inria.fr>,
- *  Tom Henderson <tomh@tomh.org>
- */
-#ifndef IPV4_INTERFACE_H
-#define IPV4_INTERFACE_H
-
-#include <list>
-#include "ns3/ipv4-address.h"
-#include "ns3/ptr.h"
-#include "ns3/object.h"
-
-namespace ns3 {
-
-class NetDevice;
-class Packet;
-
-/**
- * \brief The IPv4 representation of a network interface
- *
- * This class roughly corresponds to the struct in_device
- * of Linux; the main purpose is to provide address-family
- * specific information (addresses) about an interface.
- *
- * This class defines two APIs:
- *  - the public API which is expected to be used by both 
- *    the IPv4 layer and the user during forwarding and 
- *    configuration.
- *  - the private API which is expected to be implemented
- *    by subclasses of this base class. One such subclass 
- *    will be a Loopback interface which loops every
- *    packet sent back to the ipv4 layer. Another such 
- *    subclass typically contains the Ipv4 <-> MAC address
- *    translation logic which will use most of the time the
- *    ARP/RARP protocols.
- *
- * By default, Ipv4 interface are created in the "down" state
- * with ip address 192.168.0.1 and a matching mask. Before
- * becoming useable, the user must invoke SetUp on them
- * once the final Ipv4 address and mask has been set.
- *
- * Subclasses must implement the two methods:
- *   - Ipv4Interface::SendTo
- */
-class Ipv4Interface  : public Object
-{
-public:
-  static TypeId GetTypeId (void);
-
-  Ipv4Interface ();
-  virtual ~Ipv4Interface();
-
-  /**
-   * \returns the underlying NetDevice. This method can return
-   *          zero if this interface has no associated NetDevice.
-   */
-  virtual Ptr<NetDevice> GetDevice (void) const = 0;
-
-  /**
-   * \param a set the ipv4 address of this interface.
-   */
-  void SetAddress (Ipv4Address a);
-  /**
-   * \param mask set the ipv4 netmask of this interface.
-   */
-  void SetNetworkMask (Ipv4Mask mask);
-
-  /**
-   * \returns the broadcast ipv4 address associated to this interface
-   */
-  Ipv4Address GetBroadcast (void) const;
-  /**
-   * \returns the ipv4 netmask of this interface
-   */
-  Ipv4Mask GetNetworkMask (void) const;
-  /**
-   * \param metric configured routing metric (cost) of this interface
-   */
-  void SetMetric (uint16_t metric);
-  /**
-   * \returns configured routing metric (cost) of this interface
-   */
-  uint16_t GetMetric (void) const;
-  /**
-   * \returns the ipv4 address of this interface
-   */
-  Ipv4Address GetAddress (void) const;
-
-  /**
-   * This function a pass-through to NetDevice GetMtu, modulo
-   * the  LLC/SNAP header i.e., ipv4MTU = NetDeviceMtu - LLCSNAPSIZE
-   * \returns the Maximum Transmission Unit associated to this interface.
-   */
-  uint16_t GetMtu (void) const;
-
-  /**
-   * These are IP interface states and may be distinct from 
-   * NetDevice states, such as found in real implementations
-   * (where the device may be down but IP interface state is still up).
-   */
-  /**
-   * \returns true if this interface is enabled, false otherwise.
-   */
-  bool IsUp (void) const;
-  /**
-   * \returns true if this interface is disabled, false otherwise.
-   */
-  bool IsDown (void) const;
-  /**
-   * Enable this interface
-   */
-  void SetUp (void);
-  /**
-   * Disable this interface
-   */
-  void SetDown (void);
-
-  /**
-   * \param p packet to send
-   * \param dest next hop address of packet.
-   *
-   * This method will eventually call the private
-   * SendTo method which must be implemented by subclasses.
-   */ 
-  void Send(Ptr<Packet> p, Ipv4Address dest);
-
-protected:
-  virtual void DoDispose (void);
-private:
-  virtual void SendTo (Ptr<Packet> p, Ipv4Address dest) = 0;
-  bool m_ifup;
-  Ipv4Address m_address;
-  Ipv4Mask m_netmask;
-  uint16_t m_metric;
-};
-
-}; // namespace ns3
-
-#endif
--- a/src/internet-node/ipv4-l3-protocol.cc	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,906 +0,0 @@
-// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//
-// Author: George F. Riley<riley@ece.gatech.edu>
-//
-
-#include "ns3/packet.h"
-#include "ns3/log.h"
-#include "ns3/callback.h"
-#include "ns3/ipv4-address.h"
-#include "ns3/ipv4-route.h"
-#include "ns3/node.h"
-#include "ns3/socket.h"
-#include "ns3/net-device.h"
-#include "ns3/uinteger.h"
-#include "ns3/trace-source-accessor.h"
-#include "ns3/object-vector.h"
-#include "ns3/ipv4-header.h"
-#include "ns3/boolean.h"
-#include "arp-l3-protocol.h"
-
-#include "ipv4-l3-protocol.h"
-#include "ipv4-l4-protocol.h"
-#include "ipv4-interface.h"
-#include "ipv4-loopback-interface.h"
-#include "arp-ipv4-interface.h"
-#include "ipv4-l4-demux.h"
-
-NS_LOG_COMPONENT_DEFINE ("Ipv4L3Protocol");
-
-namespace ns3 {
-
-const uint16_t Ipv4L3Protocol::PROT_NUMBER = 0x0800;
-
-NS_OBJECT_ENSURE_REGISTERED (Ipv4L3Protocol);
-
-TypeId 
-Ipv4L3Protocol::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::Ipv4L3Protocol")
-    .SetParent<Object> ()
-    .AddConstructor<Ipv4L3Protocol> ()
-    .AddAttribute ("DefaultTtl", "The TTL value set by default on all outgoing packets generated on this node.",
-                   UintegerValue (64),
-                   MakeUintegerAccessor (&Ipv4L3Protocol::m_defaultTtl),
-                   MakeUintegerChecker<uint8_t> ())
-    .AddAttribute ("CalcChecksum", "If true, we calculate the checksum of outgoing packets"
-                   " and verify the checksum of incoming packets.",
-                   BooleanValue (false),
-                   MakeBooleanAccessor (&Ipv4L3Protocol::m_calcChecksum),
-                   MakeBooleanChecker ())
-    .AddTraceSource ("Tx", "Send ipv4 packet to outgoing interface.",
-                   MakeTraceSourceAccessor (&Ipv4L3Protocol::m_txTrace))
-    .AddTraceSource ("Rx", "Receive ipv4 packet from incoming interface.",
-                     MakeTraceSourceAccessor (&Ipv4L3Protocol::m_rxTrace))
-    .AddTraceSource ("Drop", "Drop ipv4 packet",
-                     MakeTraceSourceAccessor (&Ipv4L3Protocol::m_dropTrace))
-    .AddAttribute ("InterfaceList", "The set of Ipv4 interfaces associated to this Ipv4 stack.",
-                   ObjectVectorValue (),
-                   MakeObjectVectorAccessor (&Ipv4L3Protocol::m_interfaces),
-                   MakeObjectVectorChecker<Ipv4Interface> ())
-    ;
-  return tid;
-}
-
-Ipv4L3Protocol::Ipv4L3Protocol()
-  : m_nInterfaces (0),
-    m_identification (0)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_staticRouting = CreateObject<Ipv4StaticRouting> ();
-  AddRoutingProtocol (m_staticRouting, 0);
-}
-
-Ipv4L3Protocol::~Ipv4L3Protocol ()
-{
-  NS_LOG_FUNCTION (this);
-}
-
-void
-Ipv4L3Protocol::SetNode (Ptr<Node> node)
-{
-  m_node = node;
-  SetupLoopback ();
-}
-
-void 
-Ipv4L3Protocol::DoDispose (void)
-{
-  NS_LOG_FUNCTION (this);
-  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); ++i)
-    {
-      Ptr<Ipv4Interface> interface = *i;
-      interface->Dispose ();
-    }
-  m_interfaces.clear ();
-  m_node = 0;
-  m_staticRouting->Dispose ();
-  m_staticRouting = 0;
-  Object::DoDispose ();
-}
-
-void
-Ipv4L3Protocol::SetupLoopback (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-
-  Ptr<Ipv4LoopbackInterface> interface = CreateObject<Ipv4LoopbackInterface> ();
-  interface->SetNode (m_node);
-  interface->SetAddress (Ipv4Address::GetLoopback ());
-  interface->SetNetworkMask (Ipv4Mask::GetLoopback ());
-  uint32_t index = AddIpv4Interface (interface);
-  AddHostRouteTo (Ipv4Address::GetLoopback (), index);
-  interface->SetUp ();
-}
-
-void 
-Ipv4L3Protocol::SetDefaultTtl (uint8_t ttl)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_defaultTtl = ttl;
-}
-    
-
-void 
-Ipv4L3Protocol::AddHostRouteTo (Ipv4Address dest, 
-                      Ipv4Address nextHop, 
-                      uint32_t interface)
-{
-  NS_LOG_FUNCTION (this << dest << nextHop << interface);
-  m_staticRouting->AddHostRouteTo (dest, nextHop, interface);
-}
-
-void 
-Ipv4L3Protocol::AddHostRouteTo (Ipv4Address dest, 
-				uint32_t interface)
-{
-  NS_LOG_FUNCTION (this << dest << interface);
-  m_staticRouting->AddHostRouteTo (dest, interface);
-}
-
-void 
-Ipv4L3Protocol::AddNetworkRouteTo (Ipv4Address network, 
-				   Ipv4Mask networkMask, 
-				   Ipv4Address nextHop, 
-				   uint32_t interface)
-{
-  NS_LOG_FUNCTION (this << network << networkMask << nextHop << interface);
-  m_staticRouting->AddNetworkRouteTo (network, networkMask, nextHop, interface);
-}
-
-void 
-Ipv4L3Protocol::AddNetworkRouteTo (Ipv4Address network, 
-				   Ipv4Mask networkMask, 
-				   uint32_t interface)
-{
-  NS_LOG_FUNCTION (this << network << networkMask << interface);
-  m_staticRouting->AddNetworkRouteTo (network, networkMask, interface);
-}
-
-void 
-Ipv4L3Protocol::SetDefaultRoute (Ipv4Address nextHop, 
-				 uint32_t interface)
-{
-  NS_LOG_FUNCTION (this << nextHop << interface);
-  m_staticRouting->SetDefaultRoute (nextHop, interface);
-}
-
-void
-Ipv4L3Protocol::Lookup (
-  Ipv4Header const &ipHeader,
-  Ptr<Packet> packet,
-  Ipv4RoutingProtocol::RouteReplyCallback routeReply)
-{
-  NS_LOG_FUNCTION (this << &ipHeader << packet << &routeReply);
-
-  Lookup (Ipv4RoutingProtocol::IF_INDEX_ANY, ipHeader, packet, routeReply);
-}
-
-void
-Ipv4L3Protocol::Lookup (
-  uint32_t ifIndex,
-  Ipv4Header const &ipHeader,
-  Ptr<Packet> packet,
-  Ipv4RoutingProtocol::RouteReplyCallback routeReply)
-{
-  NS_LOG_FUNCTION (this << ifIndex << &ipHeader << packet << &routeReply);
-
-  for (Ipv4RoutingProtocolList::const_iterator rprotoIter = 
-         m_routingProtocols.begin ();
-       rprotoIter != m_routingProtocols.end (); 
-       rprotoIter++)
-    {
-      NS_LOG_LOGIC ("Requesting route");
-      if ((*rprotoIter).second->RequestRoute (ifIndex, ipHeader, packet, 
-                                              routeReply))
-        return;
-    }
-
-  if (ipHeader.GetDestination ().IsMulticast () && 
-      ifIndex == Ipv4RoutingProtocol::IF_INDEX_ANY)
-    {
-      NS_LOG_LOGIC ("Multicast destination with local source");
-//
-// We have a multicast packet originating from the current node and were not
-// able to send it using the usual RequestRoute process.  Since the usual
-// process includes trying to use a default multicast route, this means that
-// there was no specific route out of the node found, and there was no default
-// multicast route set.
-//
-// The fallback position is to look for a default unicast route and use that
-// to get the packet off the node if we have one.
-//
-      Ipv4Route *route = m_staticRouting->GetDefaultRoute ();
-
-      if (route)
-        {
-          NS_LOG_LOGIC ("Local source. Using unicast default route for "
-            "multicast packet");
-
-          routeReply (true, *route, packet, ipHeader);
-          return;
-        }
-    }
-//
-// No route found
-//
-  routeReply (false, Ipv4Route (), packet, ipHeader);
-}
-
-void
-Ipv4L3Protocol::AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
-                                    int priority)
-{
-  NS_LOG_FUNCTION (this << &routingProtocol << priority);
-  m_routingProtocols.push_back
-    (std::pair<int, Ptr<Ipv4RoutingProtocol> > (-priority, routingProtocol));
-  m_routingProtocols.sort ();
-}
-
-uint32_t 
-Ipv4L3Protocol::GetNRoutes (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_staticRouting->GetNRoutes ();
-}
-
-Ipv4Route *
-Ipv4L3Protocol::GetRoute (uint32_t index)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_staticRouting->GetRoute (index);
-}
-
-void 
-Ipv4L3Protocol::RemoveRoute (uint32_t index)
-{
-  NS_LOG_FUNCTION (this << index);
-  m_staticRouting->RemoveRoute (index);
-}
-
-void 
-Ipv4L3Protocol::AddMulticastRoute (Ipv4Address origin,
-                                   Ipv4Address group,
-                                   uint32_t inputInterface,
-                                   std::vector<uint32_t> outputInterfaces)
-{
-  NS_LOG_FUNCTION (this << origin << group << inputInterface << &outputInterfaces);
-
-  m_staticRouting->AddMulticastRoute (origin, group, inputInterface,
-    outputInterfaces);
-}
-
-void 
-Ipv4L3Protocol::SetDefaultMulticastRoute (uint32_t outputInterface)
-{
-  NS_LOG_FUNCTION (this << outputInterface);
-
-  m_staticRouting->SetDefaultMulticastRoute (outputInterface);
-}
-
-uint32_t 
-Ipv4L3Protocol::GetNMulticastRoutes (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_staticRouting->GetNMulticastRoutes ();
-}
-
-Ipv4MulticastRoute *
-Ipv4L3Protocol::GetMulticastRoute (uint32_t index) const
-{
-  NS_LOG_FUNCTION (this << index);
-  return m_staticRouting->GetMulticastRoute (index);
-}
-
-void 
-Ipv4L3Protocol::RemoveMulticastRoute (Ipv4Address origin,
-                                       Ipv4Address group,
-                                       uint32_t inputInterface)
-{
-  NS_LOG_FUNCTION (this << origin << group << inputInterface);
-  m_staticRouting->RemoveMulticastRoute (origin, group, inputInterface);
-}
-
-void 
-Ipv4L3Protocol::RemoveMulticastRoute (uint32_t index)
-{
-  NS_LOG_FUNCTION (this << index);
-  m_staticRouting->RemoveMulticastRoute (index);
-}
-
-uint32_t 
-Ipv4L3Protocol::AddInterface (Ptr<NetDevice> device)
-{
-  NS_LOG_FUNCTION (this << &device);
-
-  Ptr<Node> node = GetObject<Node> ();
-  node->RegisterProtocolHandler (MakeCallback (&Ipv4L3Protocol::Receive, this), 
-                                 Ipv4L3Protocol::PROT_NUMBER, device);
-  node->RegisterProtocolHandler (MakeCallback (&ArpL3Protocol::Receive, PeekPointer (GetObject<ArpL3Protocol> ())),
-                                 ArpL3Protocol::PROT_NUMBER, device);
-
-  Ptr<ArpIpv4Interface> interface = CreateObject<ArpIpv4Interface> ();
-  interface->SetNode (m_node);
-  interface->SetDevice (device);
-  return AddIpv4Interface (interface);
-}
-
-uint32_t 
-Ipv4L3Protocol::AddIpv4Interface (Ptr<Ipv4Interface>interface)
-{
-  NS_LOG_FUNCTION (this << interface);
-  uint32_t index = m_nInterfaces;
-  m_interfaces.push_back (interface);
-  m_nInterfaces++;
-  return index;
-}
-
-Ptr<Ipv4Interface>
-Ipv4L3Protocol::GetInterface (uint32_t index) const
-{
-  NS_LOG_FUNCTION (this << index);
-  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
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_nInterfaces;
-}
-
-uint32_t 
-Ipv4L3Protocol::FindInterfaceForAddr (Ipv4Address addr) const
-{
-  NS_LOG_FUNCTION (this << addr);
-
-  uint32_t ifIndex = 0;
-  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); 
-       i != m_interfaces.end (); 
-       i++, ifIndex++)
-    {
-      if ((*i)->GetAddress () == addr)
-        {
-          return ifIndex;
-        }
-    }
-
-  NS_FATAL_ERROR ("Ipv4L3Protocol::FindInterfaceForAddr (): "
-                  "Interface not found for IP address " << addr);
-  return 0;
-}
-
-uint32_t 
-Ipv4L3Protocol::FindInterfaceForAddr (Ipv4Address addr, Ipv4Mask mask) const
-{
-  NS_LOG_FUNCTION (this << addr << mask);
-
-  uint32_t ifIndex = 0;
-  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); 
-       i != m_interfaces.end (); 
-       i++, ifIndex++)
-    {
-      if ((*i)->GetAddress ().CombineMask (mask) == addr.CombineMask (mask))
-        {
-          return ifIndex;
-        }
-    }
-
-  NS_ASSERT_MSG(false, "Ipv4L3Protocol::FindInterfaceForAddr (): "
-    "Interface not found for masked IP address");
-  return 0;
-}
-
-int32_t 
-Ipv4L3Protocol::FindInterfaceIndexForDevice (Ptr<NetDevice> device) const
-{
-  NS_LOG_FUNCTION (this << device);
-
-  uint32_t ifIndex = 0;
-  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); 
-       i != m_interfaces.end (); 
-       i++, ifIndex++)
-    {
-      if ((*i)->GetDevice () == device)
-        {
-          return ifIndex;
-        }
-    }
-
-  return -1;
-}
-
-Ptr<Ipv4Interface>
-Ipv4L3Protocol::FindInterfaceForDevice (Ptr<const NetDevice> device)
-{
-  NS_LOG_FUNCTION (this << &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( Ptr<NetDevice> device, Ptr<Packet> packet, uint16_t protocol, const Address &from)
-{
-  NS_LOG_FUNCTION (this << &device << packet << protocol <<  from);
-
-  NS_LOG_LOGIC ("Packet from " << from << " received on node " << m_node->GetId ());
-
-  uint32_t index = 0;
-  Ptr<Ipv4Interface> ipv4Interface;
-  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); 
-       i != m_interfaces.end (); 
-       i++)
-    {
-      ipv4Interface = *i;
-      if (ipv4Interface->GetDevice () == device)
-        {
-          m_rxTrace (packet, index);
-          break;
-        }
-      index++;
-    }
-  Ipv4Header ipHeader;
-  if (m_calcChecksum)
-    {
-      ipHeader.EnableChecksum ();
-    }
-  packet->RemoveHeader (ipHeader);
-
-  if (!ipHeader.IsChecksumOk ()) 
-    {
-      m_dropTrace (packet);
-      return;
-    }
-
-  if (Forwarding (index, packet, ipHeader, device)) 
-    {
-      return;
-    }
-
-  ForwardUp (packet, ipHeader, ipv4Interface);
-}
-
-
-void 
-Ipv4L3Protocol::Send (Ptr<Packet> packet, 
-            Ipv4Address source, 
-            Ipv4Address destination,
-            uint8_t protocol)
-{
-  NS_LOG_FUNCTION (this << packet << source << destination << protocol);
-
-  Ipv4Header ipHeader;
-
-  if (m_calcChecksum)
-    {
-      ipHeader.EnableChecksum ();
-    }
-
-  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 ++;
-
-  // Set TTL to 1 if it is a broadcast packet of any type.  Otherwise,
-  // possibly override the default TTL if the packet is tagged
-  SocketIpTtlTag tag;
-  bool found = packet->FindFirstMatchingTag (tag);
-
-  if (destination.IsBroadcast ()) 
-    {
-      ipHeader.SetTtl (1);
-    }
-  else if (found)
-    {
-      ipHeader.SetTtl (tag.GetTtl ());
-      // XXX remove tag here?  
-    }
-  else
-    {
-      uint32_t ifaceIndex = 0;
-      for (Ipv4InterfaceList::iterator ifaceIter = m_interfaces.begin ();
-           ifaceIter != m_interfaces.end (); ifaceIter++, ifaceIndex++)
-        {
-          Ptr<Ipv4Interface> outInterface = *ifaceIter;
-          if (destination.IsSubnetDirectedBroadcast (
-                outInterface->GetNetworkMask ()))
-          {
-            ipHeader.SetTtl (1);
-          }
-        }
-    }
-  if (destination.IsBroadcast ())
-    {
-      uint32_t ifaceIndex = 0;
-      for (Ipv4InterfaceList::iterator ifaceIter = m_interfaces.begin ();
-           ifaceIter != m_interfaces.end (); ifaceIter++, ifaceIndex++)
-        {
-          Ptr<Ipv4Interface> outInterface = *ifaceIter;
-          Ptr<Packet> packetCopy = packet->Copy ();
-
-          NS_ASSERT (packetCopy->GetSize () <= outInterface->GetMtu ());
-          packetCopy->AddHeader (ipHeader);
-          m_txTrace (packetCopy, ifaceIndex);
-          outInterface->Send (packetCopy, destination);
-        }
-    }
-  else
-    {
-      // 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.
-      Lookup (ipHeader, packet,
-              MakeCallback (&Ipv4L3Protocol::SendRealOut, this));
-    }
-}
-
-void
-Ipv4L3Protocol::SendRealOut (bool found,
-                             Ipv4Route const &route,
-                             Ptr<Packet> packet,
-                             Ipv4Header const &ipHeader)
-{
-  NS_LOG_FUNCTION (this << found << &route << packet << &ipHeader);
-
-  packet->AddHeader (ipHeader);
-  if (!found)
-    {
-      NS_LOG_WARN ("No route to host.  Drop.");
-      m_dropTrace (packet);
-      return;
-    }
-
-  NS_LOG_LOGIC ("Send via interface " << route.GetInterface ());
-
-  Ptr<Ipv4Interface> outInterface = GetInterface (route.GetInterface ());
-  NS_ASSERT (packet->GetSize () <= outInterface->GetMtu ());
-  m_txTrace (packet, route.GetInterface ());
-  if (route.IsGateway ()) 
-    {
-      NS_LOG_LOGIC ("Send to gateway " << route.GetGateway ());
-      outInterface->Send (packet, route.GetGateway ());
-    } 
-  else 
-    {
-      NS_LOG_LOGIC ("Send to destination " << ipHeader.GetDestination ());
-      outInterface->Send (packet, ipHeader.GetDestination ());
-    }
-}
-
-bool
-Ipv4L3Protocol::Forwarding (
-  uint32_t ifIndex, 
-  Ptr<Packet> packet, 
-  Ipv4Header &ipHeader, 
-  Ptr<NetDevice> device)
-{
-  NS_LOG_FUNCTION (ifIndex << packet << &ipHeader<< device);
-  NS_LOG_LOGIC ("Forwarding logic for node: " << m_node->GetId ());
-
-  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
-       i != m_interfaces.end (); i++) 
-    {
-      if ((*i)->GetAddress ().IsEqual (ipHeader.GetDestination ())) 
-        {
-          NS_LOG_LOGIC ("For me (destination match)");
-          return false;
-        }
-    }
-  
-  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
-       i != m_interfaces.end (); i++) 
-    {
-      Ptr<Ipv4Interface> interface = *i;
-      if (interface->GetDevice () == device)
-	{
-	  if (ipHeader.GetDestination ().IsEqual (interface->GetBroadcast ())) 
-	    {
-              NS_LOG_LOGIC ("For me (interface broadcast address)");
-	      return false;
-	    }
-	  break;
-	}
-    }
-      
-  if (ipHeader.GetDestination ().IsBroadcast ()) 
-    {
-      NS_LOG_LOGIC ("For me (Ipv4Addr broadcast address)");
-      return false;
-    }
-
-  if (ipHeader.GetDestination ().IsEqual (Ipv4Address::GetAny ())) 
-    {
-      NS_LOG_LOGIC ("For me (Ipv4Addr any address)");
-      return false;
-    }
-
-  if (ipHeader.GetTtl () == 1) 
-    {
-      // Should send ttl expired here
-      // XXX
-      NS_LOG_LOGIC ("Not for me (TTL expired).  Drop");
-      m_dropTrace (packet);
-      return true;
-    }
-  ipHeader.SetTtl (ipHeader.GetTtl () - 1);
-
-//  
-// If this is a to a multicast address and this node is a member of the 
-// indicated group we need to return false so the multicast is forwarded up.
-//        
-  for (Ipv4MulticastGroupList::const_iterator i = m_multicastGroups.begin ();
-       i != m_multicastGroups.end (); i++)
-    {
-      if ((*i).first.IsEqual (ipHeader.GetSource ()) &&
-          (*i).second.IsEqual (ipHeader.GetDestination ()))
-        {
-          NS_LOG_LOGIC ("For me (Joined multicast group)");
-          // We forward with a packet copy, since forwarding may change
-          // the packet, affecting our local delivery
-          NS_LOG_LOGIC ("Forwarding (multicast).");
-          Lookup (ifIndex, ipHeader, packet->Copy (),
-          MakeCallback (&Ipv4L3Protocol::SendRealOut, this));
-          return false;
-        }   
-    }     
-  NS_LOG_LOGIC ("Not for me, forwarding.");
-  Lookup (ifIndex, ipHeader, packet,
-  MakeCallback (&Ipv4L3Protocol::SendRealOut, this));
-  
-  return true;
-}
-
-void
-Ipv4L3Protocol::ForwardUp (Ptr<Packet> p, Ipv4Header const&ip,
-                           Ptr<Ipv4Interface> incomingInterface)
-{
-  NS_LOG_FUNCTION (this << p << &ip);
-
-  Ptr<Ipv4L4Demux> demux = m_node->GetObject<Ipv4L4Demux> ();
-  Ptr<Ipv4L4Protocol> protocol = demux->GetProtocol (ip.GetProtocol ());
-  protocol->Receive (p, ip.GetSource (), ip.GetDestination (), incomingInterface);
-}
-
-void 
-Ipv4L3Protocol::JoinMulticastGroup (Ipv4Address origin, Ipv4Address group)
-{
-  NS_LOG_FUNCTION (this << origin << group);
-  m_multicastGroups.push_back(
-    std::pair<Ipv4Address, Ipv4Address> (origin, group));
-}
-
-void
-Ipv4L3Protocol::LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group)
-{
-  NS_LOG_FUNCTION (this << origin << group);
-
-  for (Ipv4MulticastGroupList::iterator i = m_multicastGroups.begin ();
-       i != m_multicastGroups.end (); 
-       i++)
-    {
-      if ((*i).first.IsEqual(origin) && (*i).second.IsEqual(group))
-        {
-          m_multicastGroups.erase (i);
-          return;
-        }
-    }
-}
-
-void 
-Ipv4L3Protocol::SetAddress (uint32_t i, Ipv4Address address)
-{
-  NS_LOG_FUNCTION (this << i << address);
-  Ptr<Ipv4Interface> interface = GetInterface (i);
-  interface->SetAddress (address);
-}
-
-void 
-Ipv4L3Protocol::SetNetworkMask (uint32_t i, Ipv4Mask mask)
-{
-  NS_LOG_FUNCTION (this << i << mask);
-  Ptr<Ipv4Interface> interface = GetInterface (i);
-  interface->SetNetworkMask (mask);
-}
-
-Ipv4Mask 
-Ipv4L3Protocol::GetNetworkMask (uint32_t i) const
-{
-  NS_LOG_FUNCTION (this << i);
-  Ptr<Ipv4Interface> interface = GetInterface (i);
-  return interface->GetNetworkMask ();
-}
-
-Ipv4Address 
-Ipv4L3Protocol::GetAddress (uint32_t i) const
-{
-  NS_LOG_FUNCTION (this << i);
-  Ptr<Ipv4Interface> interface = GetInterface (i);
-  return interface->GetAddress ();
-}
-
-void 
-Ipv4L3Protocol::SetMetric (uint32_t i, uint16_t metric)
-{
-  NS_LOG_FUNCTION (i << metric);
-  Ptr<Ipv4Interface> interface = GetInterface (i);
-  interface->SetMetric (metric);
-}
-
-uint16_t
-Ipv4L3Protocol::GetMetric (uint32_t i) const
-{
-  NS_LOG_FUNCTION (i);
-  Ptr<Ipv4Interface> interface = GetInterface (i);
-  return interface->GetMetric ();
-}
-
-bool
-Ipv4L3Protocol::GetIfIndexForDestination (
-  Ipv4Address destination, uint32_t& ifIndex) const
-{
-  NS_LOG_FUNCTION (this << destination << &ifIndex);
-//
-// The first thing we do in trying to determine a source address is to 
-// consult the routing protocols.  These will also check for a default route
-// if one has been set.
-//
-  for (Ipv4RoutingProtocolList::const_iterator i = m_routingProtocols.begin ();
-       i != m_routingProtocols.end (); 
-       i++)
-    {
-      NS_LOG_LOGIC ("Requesting Source Address");
-      uint32_t ifIndexTmp;
-
-      if ((*i).second->RequestIfIndex (destination, ifIndexTmp))
-        {
-          NS_LOG_LOGIC ("Found ifIndex " << ifIndexTmp);
-          ifIndex = ifIndexTmp;
-          return true;
-        }
-    }
-//
-// If there's no routing table entry telling us what *single* interface will 
-// be used to send a packet to this destination, we'll have to just pick one.  
-// If there's only one interface on this node, a good answer isn't very hard
-// to come up with.  Before jumping to any conclusions, remember that the 
-// zeroth interface is the loopback interface, so what we actually want is
-// a situation where there are exactly two interfaces on the node, in which
-// case interface one is the "single" interface connected to the outside world.
-//
-  if (GetNInterfaces () == 2)
-    {
-      NS_LOG_LOGIC ("One Interface.  Using interface 1.");
-      ifIndex = 1;
-      return true;
-    }
-//
-// If we fall through to here, we have a node with multiple interfaces and
-// no routes to guide us in determining what interface to choose.  Either
-// no default route was found (for unicast or multicast), or in the case of a
-// multicast, the default route contained multiple outbound interfaces.
-//
-// The fallback position is to just get the unicast default route and use 
-// the outgoing interface specified there.  We don't want to leave the source
-// address unset, so we just assert here.
-//
-// N.B. that in the case of a multicast with a route containing multiple
-// outgoing interfaces, the source address of packets from that node will be
-// set to the IP address of the interface set in the default unicast route.
-// Also, in the case of a broadcast, the same will be true.
-//
-  NS_LOG_LOGIC ("Using default unicast route");
-  Ipv4Route *route = m_staticRouting->GetDefaultRoute ();
-
-  if (route == NULL)
-    {
-      NS_LOG_LOGIC ("Ipv4L3Protocol::GetIfIndexForDestination (): "
-                    "Unable to determine outbound interface.  No default route set");
-      return false;
-    }
-
-  ifIndex = route->GetInterface ();
-
-  NS_LOG_LOGIC ("Default route specifies interface " << ifIndex);
-  return true;
-}
-
-uint16_t 
-Ipv4L3Protocol::GetMtu (uint32_t i) const
-{
-  NS_LOG_FUNCTION (this << i);
-  Ptr<Ipv4Interface> interface = GetInterface (i);
-  return interface->GetMtu ();
-}
-
-bool 
-Ipv4L3Protocol::IsUp (uint32_t i) const
-{
-  NS_LOG_FUNCTION (this << i);
-  Ptr<Ipv4Interface> interface = GetInterface (i);
-  return interface->IsUp ();
-}
-
-void 
-Ipv4L3Protocol::SetUp (uint32_t i)
-{
-  NS_LOG_FUNCTION (this << i);
-  Ptr<Ipv4Interface> interface = GetInterface (i);
-  interface->SetUp ();
-
-  // If interface address and network mask have been set, add a route
-  // to the network of the interface (like e.g. ifconfig does on a
-  // Linux box)
-  if ((interface->GetAddress ()) != (Ipv4Address ())
-      && (interface->GetNetworkMask ()) != (Ipv4Mask ()))
-    {
-      AddNetworkRouteTo (interface->GetAddress ().CombineMask (interface->GetNetworkMask ()),
-                         interface->GetNetworkMask (), i);
-    }
-}
-
-void 
-Ipv4L3Protocol::SetDown (uint32_t ifaceIndex)
-{
-  NS_LOG_FUNCTION (this << ifaceIndex);
-  Ptr<Ipv4Interface> interface = GetInterface (ifaceIndex);
-  interface->SetDown ();
-
-  // Remove all routes that are going through this interface
-  bool modified = true;
-  while (modified)
-    {
-      modified = false;
-      for (uint32_t i = 0; i < GetNRoutes (); i++)
-        {
-          Ipv4Route *route = GetRoute (i);
-          if (route->GetInterface () == ifaceIndex)
-            {
-              RemoveRoute (i);
-              modified = true;
-              break;
-            }
-        }
-    }
-}
-
-}//namespace ns3
--- a/src/internet-node/ipv4-l3-protocol.h	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,209 +0,0 @@
-// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//
-// Author: George F. Riley<riley@ece.gatech.edu>
-//
-
-#ifndef IPV4_L3_PROTOCOL_H
-#define IPV4_L3_PROTOCOL_H
-
-#include <list>
-#include <stdint.h>
-#include "ns3/ipv4-address.h"
-#include "ns3/ptr.h"
-#include "ns3/ipv4.h"
-#include "ns3/traced-callback.h"
-#include "ns3/ipv4-header.h"
-#include "ipv4-static-routing.h"
-
-namespace ns3 {
-
-class Packet;
-class NetDevice;
-class Ipv4Interface;
-class Ipv4Address;
-class Ipv4Header;
-class Ipv4Route;
-class Node;
-
-
-/**
- * \brief Implement the Ipv4 layer.
- */
-class Ipv4L3Protocol : public Object
-{
-public:
-  static TypeId GetTypeId (void);
-  static const uint16_t PROT_NUMBER;
-
-  Ipv4L3Protocol();
-  virtual ~Ipv4L3Protocol ();
-
-  void SetNode (Ptr<Node> node);
-
-  /**
-   * \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.
-   */
-  Ptr<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
-   */
-  void Receive( Ptr<NetDevice> device, Ptr<Packet> p, uint16_t protocol, const Address &from);
-
-  /**
-   * \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 (Ptr<Packet> 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);
-
-  void Lookup (Ipv4Header const &ipHeader,
-               Ptr<Packet> packet,
-               Ipv4RoutingProtocol::RouteReplyCallback routeReply);
-
-  uint32_t GetNRoutes (void);
-  Ipv4Route *GetRoute (uint32_t i);
-  void RemoveRoute (uint32_t i);
-
-  void AddMulticastRoute (Ipv4Address origin,
-                          Ipv4Address group,
-                          uint32_t inputInterface,
-                          std::vector<uint32_t> outputInterfaces);
-
-  void SetDefaultMulticastRoute (uint32_t onputInterface);
-
-  uint32_t GetNMulticastRoutes (void) const;
-  Ipv4MulticastRoute *GetMulticastRoute (uint32_t i) const;
-
-  void RemoveMulticastRoute (Ipv4Address origin,
-                             Ipv4Address group,
-                             uint32_t inputInterface);
-  void RemoveMulticastRoute (uint32_t i);
-
-  uint32_t AddInterface (Ptr<NetDevice> device);
-  Ptr<Ipv4Interface> GetInterface (uint32_t i) const;
-  uint32_t GetNInterfaces (void) const;
-
-  uint32_t FindInterfaceForAddr (Ipv4Address addr) const;
-  uint32_t FindInterfaceForAddr (Ipv4Address addr, Ipv4Mask mask) const;
-  int32_t FindInterfaceIndexForDevice (Ptr<NetDevice> device) const;
-  
-  void JoinMulticastGroup (Ipv4Address origin, Ipv4Address group);
-  void LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group);
-
-  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;
-  void SetMetric (uint32_t i, uint16_t metric);
-  uint16_t GetMetric (uint32_t i) const;
-  bool GetIfIndexForDestination (Ipv4Address destination, 
-                                 uint32_t& ifIndex) const;
-  uint16_t GetMtu (uint32_t i) const;
-  bool IsUp (uint32_t i) const;
-  void SetUp (uint32_t i);
-  void SetDown (uint32_t i);
-
-  void AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
-                           int priority);
-
-protected:
-
-  virtual void DoDispose (void);
-
-private:
-  void Lookup (uint32_t ifIndex,
-               Ipv4Header const &ipHeader,
-               Ptr<Packet> packet,
-               Ipv4RoutingProtocol::RouteReplyCallback routeReply);
-
-  void SendRealOut (bool found,
-                    Ipv4Route const &route,
-                    Ptr<Packet> packet,
-                    Ipv4Header const &ipHeader);
-  bool Forwarding (uint32_t ifIndex, 
-                   Ptr<Packet> packet, 
-                   Ipv4Header &ipHeader, 
-                   Ptr<NetDevice> device);
-  void ForwardUp (Ptr<Packet> p, Ipv4Header const&ip, Ptr<Ipv4Interface> incomingInterface);
-  uint32_t AddIpv4Interface (Ptr<Ipv4Interface> interface);
-  void SetupLoopback (void);
-
-  typedef std::list<Ptr<Ipv4Interface> > Ipv4InterfaceList;
-  typedef std::list<std::pair<Ipv4Address, Ipv4Address> > 
-    Ipv4MulticastGroupList;
-  typedef std::list< std::pair< int, Ptr<Ipv4RoutingProtocol> > > Ipv4RoutingProtocolList;
-
-  Ipv4InterfaceList m_interfaces;
-  uint32_t m_nInterfaces;
-  uint8_t m_defaultTtl;
-  bool m_calcChecksum;
-  uint16_t m_identification;
-  Ptr<Node> m_node;
-  TracedCallback<Ptr<const Packet>, uint32_t> m_txTrace;
-  TracedCallback<Ptr<const Packet>, uint32_t> m_rxTrace;
-  TracedCallback<Ptr<const Packet> > m_dropTrace;
-
-  Ipv4RoutingProtocolList m_routingProtocols;
-
-  Ptr<Ipv4StaticRouting> m_staticRouting;
-  Ipv4MulticastGroupList m_multicastGroups;
-};
-
-} // Namespace ns3
-
-#endif /* IPV4_L3_PROTOCOL_H */
--- a/src/internet-node/ipv4-l4-demux.cc	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//
-// Author: George F. Riley<riley@ece.gatech.edu>
-//
-
-// Define the layer 4 demultiplexer object for ns3.
-// George F. Riley, Georgia Tech, Fall 2006
-
-#include <sstream>
-#include "ns3/node.h"
-#include "ns3/object-vector.h"
-#include "ipv4-l4-demux.h"
-#include "ipv4-l4-protocol.h"
-
-namespace ns3 {
-
-NS_OBJECT_ENSURE_REGISTERED (Ipv4L4Demux);
-
-TypeId 
-Ipv4L4Demux::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::Ipv4L4Demux")
-    .SetParent<Object> ()
-    .AddAttribute ("Protocols", "The set of protocols registered with this demux.",
-                   ObjectVectorValue (),
-                   MakeObjectVectorAccessor (&Ipv4L4Demux::m_protocols),
-                   MakeObjectVectorChecker<Ipv4L4Protocol> ())
-    ;
-  return tid;
-}
-
-Ipv4L4Demux::Ipv4L4Demux ()
-{}
-
-Ipv4L4Demux::~Ipv4L4Demux()
-{}
-
-void 
-Ipv4L4Demux::SetNode (Ptr<Node> node)
-{
-  m_node = node;
-}
-
-void
-Ipv4L4Demux::DoDispose (void)
-{
-  for (L4List_t::iterator i = m_protocols.begin(); i != m_protocols.end(); ++i)
-    {
-      (*i)->Dispose ();
-      *i = 0;
-    }
-  m_protocols.clear ();
-  m_node = 0;
-  Object::DoDispose ();
-}
-
-void
-Ipv4L4Demux::Insert(Ptr<Ipv4L4Protocol> protocol)
-{
-  m_protocols.push_back (protocol);
-}
-Ptr<Ipv4L4Protocol>
-Ipv4L4Demux::GetProtocol(int protocolNumber)
-{
-  for (L4List_t::iterator i = m_protocols.begin(); i != m_protocols.end(); ++i)
-    {
-      if ((*i)->GetProtocolNumber () == protocolNumber)
-	{
-	  return *i;
-	}
-    }
-  return 0;
-}
-void
-Ipv4L4Demux::Remove (Ptr<Ipv4L4Protocol> protocol)
-{
-  m_protocols.remove (protocol);
-}
-
-
-
-}//namespace ns3
--- a/src/internet-node/ipv4-l4-demux.h	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//
-// Author: George F. Riley<riley@ece.gatech.edu>
-//
-
-// Define the layer 4 demultiplexer object for ns3.
-// George F. Riley, Georgia Tech, Fall 2006
-
-#ifndef IPV4_L4_DEMUX_H
-#define IPV4_L4_DEMUX_H
-
-#include <list>
-#include "ns3/object.h"
-#include "ns3/ptr.h"
-
-namespace ns3 {
-
-class Ipv4L4Protocol;
-class Node;
-
-/**
- * \brief L4 Ipv4 Demux
- */
-class Ipv4L4Demux : public Object
-{
-public:
-  static TypeId GetTypeId (void);
-  Ipv4L4Demux ();
-  virtual ~Ipv4L4Demux();
-
-  void SetNode (Ptr<Node> node);
-
-  /**
-   * \param protocol a template for the protocol to add to this L4 Demux.
-   * \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 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.
-   */
-  void Insert(Ptr<Ipv4L4Protocol> protocol);
-  /**
-   * \param protocolNumber number of protocol to lookup
-   *        in this L4 Demux
-   * \returns a matching L4 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::GetUdp for example.
-   */
-  Ptr<Ipv4L4Protocol> GetProtocol(int protocolNumber);
-  /**
-   * \param protocol protocol to remove from this demux.
-   *
-   * The input value to this method should be the value
-   * returned from the Ipv4L4Protocol::Insert method.
-   */
-  void Remove (Ptr<Ipv4L4Protocol> protocol);
-protected:
-  virtual void DoDispose (void);
-private:
-  typedef std::list<Ptr<Ipv4L4Protocol> > L4List_t;
-  L4List_t m_protocols;
-  Ptr<Node> m_node;
-};
-
-} //namespace ns3
-#endif
--- a/src/internet-node/ipv4-l4-protocol.cc	Wed Jun 11 16:19:28 2008 -0700
+++ /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) 2006 Georgia Tech Research Corporation
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//
-// Author: George F. Riley<riley@ece.gatech.edu>
-//
-
-// NS3 - Layer 4 Protocol base class
-// George F. Riley, Georgia Tech, Spring 2007
-
-#include "ipv4-l4-protocol.h"
-#include "ns3/uinteger.h"
-
-namespace ns3 {
-
-NS_OBJECT_ENSURE_REGISTERED (Ipv4L4Protocol);
-
-TypeId 
-Ipv4L4Protocol::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::Ipv4L4Protocol")
-    .SetParent<Object> ()
-    .AddAttribute ("ProtocolNumber", "The Ipv4 protocol number.",
-                   UintegerValue (0),
-                   MakeUintegerAccessor (&Ipv4L4Protocol::GetProtocolNumber),
-                   MakeUintegerChecker<int> ())
-    .AddAttribute ("Version", "The version of the protocol.",
-                   UintegerValue (0),
-                   MakeUintegerAccessor (&Ipv4L4Protocol::GetVersion),
-                   MakeUintegerChecker<int> ())
-    ;
-  return tid;
-}
-
-Ipv4L4Protocol::~Ipv4L4Protocol ()
-{}
-
-}//namespace ns3
--- a/src/internet-node/ipv4-l4-protocol.h	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//
-// Author: George F. Riley<riley@ece.gatech.edu>
-//
-
-// NS3 - Layer 4 Protocol base class
-// George F. Riley, Georgia Tech, Spring 2007
-
-#ifndef IPV4_L4_PROTOCOL_H
-#define IPV4_L4_PROTOCOL_H
-
-#include "ns3/object.h"
-#include "ipv4-interface.h"
-
-namespace ns3 {
-
-class Packet;
-class Ipv4Address;
-
-/**
- * \brief L4 Protocol base class 
- *
- * If you want to implement a new L4 protocol, all you have to do is
- * implement a subclass of this base class and add it to an L4Demux.
- */  
-class Ipv4L4Protocol : public Object
-{
-public:
-  static TypeId GetTypeId (void);
-
-  virtual ~Ipv4L4Protocol ();
-
-  /**
-   * \returns the protocol number of this protocol.
-   */
-  virtual int GetProtocolNumber (void) const = 0;
-  /**
-   * \returns the version number of this protocol.
-   */
-  virtual int GetVersion (void) const = 0;
-
-  /**
-   * \param p packet to forward up
-   * \param source source address of packet received
-   * \param destination address of packet received
-   * \param incomingInterface the Ipv4Interface on which the packet arrived
-   * 
-   * Called from lower-level layers to send the packet up
-   * in the stack. 
-   */
-  virtual void Receive(Ptr<Packet> p, 
-                       Ipv4Address const &source,
-                       Ipv4Address const &destination,
-                       Ptr<Ipv4Interface> incomingInterface) = 0;
-};
-
-} // Namespace ns3
-
-#endif
--- a/src/internet-node/ipv4-loopback-interface.cc	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 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: 
- *  Mathieu Lacage <mathieu.lacage@sophia.inria.fr>,
- */
-
-#include "ns3/log.h"
-#include "ns3/net-device.h"
-#include "ns3/node.h"
-#include "ns3/mac48-address.h"
-#include "ns3/packet.h"
-#include "ipv4-loopback-interface.h"
-#include "ipv4-l3-protocol.h"
-
-NS_LOG_COMPONENT_DEFINE ("Ipv4LoopbackInterface");
-
-namespace ns3 {
-
-TypeId 
-Ipv4LoopbackInterface::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::Ipv4LoopbackInterface")
-    .SetParent<Ipv4Interface> ()
-    ;
-  return tid;
-}
-
-Ipv4LoopbackInterface::Ipv4LoopbackInterface ()
-  : m_node (0)
-{
-  NS_LOG_FUNCTION (this);
-}
-
-Ipv4LoopbackInterface::~Ipv4LoopbackInterface ()
-{
-  NS_LOG_FUNCTION (this);
-  NS_ASSERT (m_node != 0);
-}
-
-Ptr<NetDevice> 
-Ipv4LoopbackInterface::GetDevice (void) const
-{
-  return 0;
-}
-
-void 
-Ipv4LoopbackInterface::SetNode (Ptr<Node> node)
-{
-  m_node = node;
-}
-
-void 
-Ipv4LoopbackInterface::SendTo (Ptr<Packet> packet, Ipv4Address dest)
-{
-  NS_LOG_FUNCTION (this << packet << dest);
-
-  Ptr<Ipv4L3Protocol> ipv4 = 
-    m_node->GetObject<Ipv4L3Protocol> ();
-
-  ipv4->Receive (0, packet, Ipv4L3Protocol::PROT_NUMBER, 
-                 Mac48Address ("ff:ff:ff:ff:ff:ff"));
-}
-
-}//namespace ns3
--- a/src/internet-node/ipv4-loopback-interface.h	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 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: 
- *  Mathieu Lacage <mathieu.lacage@sophia.inria.fr>,
- */
-#ifndef IPV4_LOOPBACK_INTERFACE_H
-#define IPV4_LOOPBACK_INTERFACE_H
-
-#include "ipv4-interface.h"
-#include "ns3/ptr.h"
-
-namespace ns3 {
-
-class Node;
-/**
- * \brief An IPv4 loopback interface
- */
-class Ipv4LoopbackInterface : public Ipv4Interface 
-{
-public:
-  static TypeId GetTypeId (void);
-  Ipv4LoopbackInterface ();
-  virtual ~Ipv4LoopbackInterface ();
-
-  virtual Ptr<NetDevice> GetDevice (void) const;
-
-  void SetNode (Ptr<Node> node);
-
- private:
-  virtual void SendTo (Ptr<Packet> p, Ipv4Address dest);
-
-  Ptr<Node> m_node;
-};
-
-}//namespace ns3
-
-
-#endif /* IPV4_LOOPBACK_INTERFACE_H */
--- a/src/internet-node/ipv4-static-routing.cc	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,654 +0,0 @@
-// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//
-// Author: George F. Riley<riley@ece.gatech.edu>
-//         Gustavo Carneiro <gjc@inescporto.pt>
-
-#include "ns3/log.h"
-#include "ipv4-static-routing.h"
-#include "ns3/packet.h"
-
-NS_LOG_COMPONENT_DEFINE ("Ipv4StaticRouting");
-
-namespace ns3 {
-
-Ipv4StaticRouting::Ipv4StaticRouting () 
-: m_defaultRoute (0), m_defaultMulticastRoute (0)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-}
-
-void 
-Ipv4StaticRouting::AddHostRouteTo (Ipv4Address dest, 
-                                   Ipv4Address nextHop, 
-                                   uint32_t interface)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  Ipv4Route *route = new Ipv4Route ();
-  *route = Ipv4Route::CreateHostRouteTo (dest, nextHop, interface);
-  m_hostRoutes.push_back (route);
-}
-
-void 
-Ipv4StaticRouting::AddHostRouteTo (Ipv4Address dest, 
-                                   uint32_t interface)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  Ipv4Route *route = new Ipv4Route ();
-  *route = Ipv4Route::CreateHostRouteTo (dest, interface);
-  m_hostRoutes.push_back (route);
-}
-
-void 
-Ipv4StaticRouting::AddNetworkRouteTo (Ipv4Address network, 
-                                      Ipv4Mask networkMask, 
-                                      Ipv4Address nextHop, 
-                                      uint32_t interface)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  Ipv4Route *route = new Ipv4Route ();
-  *route = Ipv4Route::CreateNetworkRouteTo (network,
-                                            networkMask,
-                                            nextHop,
-                                            interface);
-  m_networkRoutes.push_back (route);
-}
-
-void 
-Ipv4StaticRouting::AddNetworkRouteTo (Ipv4Address network, 
-                                      Ipv4Mask networkMask, 
-                                      uint32_t interface)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  Ipv4Route *route = new Ipv4Route ();
-  *route = Ipv4Route::CreateNetworkRouteTo (network,
-                                            networkMask,
-                                            interface);
-  m_networkRoutes.push_back (route);
-}
-
-void 
-Ipv4StaticRouting::SetDefaultRoute (Ipv4Address nextHop, 
-                                    uint32_t interface)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  Ipv4Route *route = new Ipv4Route ();
-  *route = Ipv4Route::CreateDefaultRoute (nextHop, interface);
-  delete m_defaultRoute;
-  m_defaultRoute = route;
-}
-
-void 
-Ipv4StaticRouting::AddMulticastRoute(Ipv4Address origin,
-                                     Ipv4Address group,
-                                     uint32_t inputInterface,
-                                     std::vector<uint32_t> outputInterfaces)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  Ipv4MulticastRoute *route = new Ipv4MulticastRoute ();
-  *route = Ipv4MulticastRoute::CreateMulticastRoute (origin, group, 
-    inputInterface, outputInterfaces);
-  m_multicastRoutes.push_back (route);
-}
-
-void 
-Ipv4StaticRouting::SetDefaultMulticastRoute(uint32_t outputInterface)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  Ipv4Address origin = Ipv4Address::GetAny ();
-  Ipv4Address group = Ipv4Address::GetAny ();
-  uint32_t inputInterface = Ipv4RoutingProtocol::IF_INDEX_ANY;
-
-  std::vector<uint32_t> outputInterfaces (1);
-  outputInterfaces[0] = outputInterface;
-  
-  Ipv4MulticastRoute *route = new Ipv4MulticastRoute ();
-  *route = Ipv4MulticastRoute::CreateMulticastRoute (origin, group, 
-    inputInterface, outputInterfaces);
-
-  delete m_defaultMulticastRoute;
-  m_defaultMulticastRoute = route;
-}
-
-uint32_t 
-Ipv4StaticRouting::GetNMulticastRoutes (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_multicastRoutes.size () + m_defaultMulticastRoute ? 1 : 0;
-}
-
-Ipv4MulticastRoute *
-Ipv4StaticRouting::GetMulticastRoute (uint32_t index) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  NS_ASSERT_MSG(index < m_multicastRoutes.size (),
-    "Ipv4StaticRouting::GetMulticastRoute ():  Index out of range");
-//
-// From an external point of view the default route appears to be in slot 0
-// of the routing table.  The implementation, however, puts it in a separate 
-// place.  So, if a client asks for index 0 and we have a default multicast
-// route, we have to return it from that different place 
-// (m_defaultMulticastRoute).
-//
-  if (index == 0 && m_defaultMulticastRoute != 0)
-    {
-      return m_defaultMulticastRoute;
-    }
-//
-// If there is a default multicast route present, a client will just assume
-// that it is in slot zero and there is one "extra" zeroth route in the table.
-// To return the correct indexed entry in our list, we have to decrement the
-// index to take into account the default route not being in the actual list.
-// Since we fell through to here, we've taken care of the case where the
-// index was zero.
-//
-  if (m_defaultMulticastRoute != 0)
-    {
-      NS_ASSERT(index > 0);
-      index--;
-    }
-
-  if (index < m_multicastRoutes.size ())
-    {
-      uint32_t tmp = 0;
-      for (MulticastRoutesCI i = m_multicastRoutes.begin (); 
-           i != m_multicastRoutes.end (); 
-           i++) 
-        {
-          if (tmp  == index)
-            {
-              return *i;
-            }
-          tmp++;
-        }
-    }
-  return 0;
-}
-
-Ipv4MulticastRoute *
-Ipv4StaticRouting::GetDefaultMulticastRoute () const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  if (m_defaultMulticastRoute != 0)
-    {
-      return m_defaultMulticastRoute;
-    }
-  return 0;
-}
-
-bool
-Ipv4StaticRouting::RemoveMulticastRoute(Ipv4Address origin,
-                                        Ipv4Address group,
-                                        uint32_t inputInterface)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  for (MulticastRoutesI i = m_multicastRoutes.begin (); 
-       i != m_multicastRoutes.end (); 
-       i++) 
-    {
-      Ipv4MulticastRoute *route = *i;
-      if (origin == route->GetOrigin () &&
-          group == route->GetGroup () &&
-          inputInterface == route->GetInputInterface ())
-        {
-          delete *i;
-          m_multicastRoutes.erase (i);
-          return true;
-        }
-    }
-  return false;
-}
-
-void 
-Ipv4StaticRouting::RemoveMulticastRoute(uint32_t index)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-//
-// From an external point of view the default route appears to be in slot 0
-// of the routing table.  The implementation, however, puts it in a separate 
-// place.  So, if a client asks to delete index 0 and we have a default
-// multicast route set, we have to delete it from that different place 
-// (m_defaultMulticastRoute).
-//
-  if (index == 0 && m_defaultMulticastRoute != 0)
-    {
-      delete m_defaultMulticastRoute;
-      m_defaultMulticastRoute = 0;
-    }
-//
-// If there is a default multicast route present, a client will just assume
-// that it is in slot zero and there is one "extra" zeroth route in the table.
-// To return the correct indexed entry in our list, we have to decrement the
-// index to take into account the default route not being in the actual list.
-// Since we fell through to here, we've taken care of the case where the
-// index was zero.
-//
-  if (m_defaultMulticastRoute != 0)
-    {
-      NS_ASSERT(index > 0);
-      index--;
-    }
-
-  uint32_t tmp = 0;
-  for (MulticastRoutesI i = m_multicastRoutes.begin (); 
-       i != m_multicastRoutes.end (); 
-       i++) 
-    {
-      if (tmp  == index)
-        {
-          delete *i;
-          m_multicastRoutes.erase (i);
-          return;
-        }
-      tmp++;
-    }
-}
-
-Ipv4Route *
-Ipv4StaticRouting::LookupStatic (Ipv4Address dest)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  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;
-}
-
-Ipv4MulticastRoute *
-Ipv4StaticRouting::LookupStatic (
-  Ipv4Address origin, 
-  Ipv4Address group,
-  uint32_t    ifIndex)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-//
-// We treat the "any" address (typically 0.0.0.0) as a wildcard in our matching
-// scheme.
-//
-  Ipv4Address wildcard = Ipv4Address::GetAny ();
-
-  for (MulticastRoutesI i = m_multicastRoutes.begin (); 
-       i != m_multicastRoutes.end (); 
-       i++) 
-    {
-      Ipv4MulticastRoute *route = *i;
-//
-// We've been passed an origin address, a multicast group address and an 
-// interface index.  We have to decide if the current route in the list is
-// a match.
-//
-// The first case is the restrictive case where the origin, group and index
-// matches.  This picks up exact routes during forwarded and exact routes from
-// the local node (in which case the ifIndex is a wildcard).
-//
-      if (origin == route->GetOrigin () && group == route->GetGroup ())
-        {
-          if (ifIndex == Ipv4RoutingProtocol::IF_INDEX_ANY || 
-              ifIndex == route->GetInputInterface ())
-            {
-              return *i;
-            }
-        }
-    }
-//
-// If the input interface index is not a wildcard (that means that the packet 
-// did not originally come from this node), we're done.  We don't
-// just happily forward packets we don't really know what to do with.  
-// Multicast storms are not generally considered a good thing.
-//
-  if (ifIndex != Ipv4RoutingProtocol::IF_INDEX_ANY)
-    {
-      return 0;
-    }
-//
-// Now, we're going to get a litle less restricive.  This only applies in the
-// case where the packet in question is coming from the local node.  In order
-// to avoid dependencies on the order in which routes were added, we will 
-// actually walk the list two more times, the first time looking for routes
-// with a single wildcard, and the last time looking for the first route
-// with two wildcards.
-//
-  for (MulticastRoutesI i = m_multicastRoutes.begin (); 
-       i != m_multicastRoutes.end (); 
-       i++) 
-    {
-      Ipv4MulticastRoute *route = *i;
-//
-// Here we will ignore the origin.  We know that a single source address must
-// be picked for a packet, but we may want to send multicast packets out
-// multiple interfaces.  To support this case, a user would need to add
-// a Multicast route with the route's origin set to wildcard.  N.B As a
-// result, packets sourced from a node with multiple interface may have a
-// source IP address different from that of the interface actually used to
-// send the packet.
-//
-      if (route->GetOrigin () == wildcard && group == route->GetGroup ())
-        {
-          return *i;
-        }
-    }
-//
-// Finally we want to allow users to specify a default route that specifies
-// sending all multicast packets out multiple interfaces.  The standard
-// default multicast route is patterned after other systems and limits the 
-// number of outputs to one.  If, however a client manually adds a multicast
-// route with the origin, the multicast group and the input interface index
-// all set to wildcard, she has created a default route with multiple output
-// interfaces.
-//
-  for (MulticastRoutesI i = m_multicastRoutes.begin (); 
-       i != m_multicastRoutes.end (); 
-       i++) 
-    {
-      Ipv4MulticastRoute *route = *i;
-
-      if (route->GetOrigin () == wildcard && route->GetGroup () == wildcard)
-        {
-          return *i;
-        }
-    }
-//
-// We also allow users to specify a typical default multicast route.  This
-// default route is limited to specifying a single output interface.
-//
-  if (m_defaultMulticastRoute != 0) 
-    {
-      return m_defaultMulticastRoute;
-    }
-
-  return 0;
-}
-
-uint32_t 
-Ipv4StaticRouting::GetNRoutes (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  uint32_t n = 0;
-  if (m_defaultRoute != 0)
-    {
-      n++;
-    }
-  n += m_hostRoutes.size ();
-  n += m_networkRoutes.size ();
-  return n;
-}
-
-Ipv4Route *
-Ipv4StaticRouting::GetDefaultRoute ()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  if (m_defaultRoute != 0)
-    {
-      return m_defaultRoute;
-    }
-  else
-    {
-      return 0;
-    }
-}
-
-Ipv4Route *
-Ipv4StaticRouting::GetRoute (uint32_t index)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  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 
-Ipv4StaticRouting::RemoveRoute (uint32_t index)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  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);
-}
-
-bool
-Ipv4StaticRouting::RequestRoute (
-  uint32_t ifIndex,
-  Ipv4Header const &ipHeader,
-  Ptr<Packet> packet,
-  RouteReplyCallback routeReply)
-{
-  NS_LOG_FUNCTION (this << ifIndex << &ipHeader << packet << &routeReply);
-
-  NS_LOG_LOGIC ("source = " << ipHeader.GetSource ());
-
-  NS_LOG_LOGIC ("destination = " << ipHeader.GetDestination ());
-
-  if (ipHeader.GetDestination ().IsMulticast ())
-    {
-      NS_LOG_LOGIC ("Multicast destination");
-
-      Ipv4MulticastRoute *mRoute = LookupStatic(ipHeader.GetSource (),
-        ipHeader.GetDestination (), ifIndex);
-
-      if (mRoute)
-        {
-          NS_LOG_LOGIC ("Multicast route found");
-
-          for (uint32_t i = 0; i < mRoute->GetNOutputInterfaces (); ++i)
-            {
-              Ptr<Packet> p = packet->Copy ();
-              Ipv4Header h = ipHeader;
-              Ipv4Route route = 
-                Ipv4Route::CreateHostRouteTo(h.GetDestination (), 
-                  mRoute->GetOutputInterface(i));
-              NS_LOG_LOGIC ( "Send via interface " << 
-                mRoute->GetOutputInterface(i));
-              routeReply (true, route, p, h);
-            }
-          return true;
-        }
-      return false; // Let other routing protocols try to handle this
-    }
-//
-// This is a unicast packet.  Check to see if we have a route for it.
-//
-  NS_LOG_LOGIC ("Unicast destination");
-  Ipv4Route *route = LookupStatic (ipHeader.GetDestination ());
-  if (route != 0)
-    {
-      routeReply (true, *route, packet, ipHeader);
-      return true;
-    }
-  else
-    {
-      return false; // Let other routing protocols try to handle this
-                    // route request.
-    }
-}
-
-bool
-Ipv4StaticRouting::RequestIfIndex (Ipv4Address destination, uint32_t& ifIndex)
-{
-  NS_LOG_FUNCTION (this << destination << &ifIndex);
-//
-// First, see if this is a multicast packet we have a route for.  If we
-// have a route, then send the packet down each of the specified interfaces.
-//
-  if (destination.IsMulticast ())
-    {
-      NS_LOG_LOGIC ("Multicast destination");
-
-      Ipv4MulticastRoute *mRoute = LookupStatic(Ipv4Address::GetAny (),
-        destination, Ipv4RoutingProtocol::IF_INDEX_ANY);
-
-      if (mRoute)
-        {
-          NS_LOG_LOGIC ("Multicast route found");
-
-          if (mRoute->GetNOutputInterfaces () != 1)
-            {
-              NS_LOG_LOGIC ("Route is to multiple interfaces.  Ignoring.");
-              return false;
-            }
-
-          ifIndex = mRoute->GetOutputInterface(0);
-          NS_LOG_LOGIC ("Found ifIndex " << ifIndex);
-          return true;
-        }
-      return false; // Let other routing protocols try to handle this
-    }
-//
-// See if this is a unicast packet we have a route for.
-//
-  NS_LOG_LOGIC ("Unicast destination");
-  Ipv4Route *route = LookupStatic (destination);
-  if (route)
-    {
-      ifIndex = route->GetInterface ();
-      return true;
-    }
-  else
-    {
-      return false;
-    }
-}
-
-void
-Ipv4StaticRouting::DoDispose (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  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;
-    }
-  for (MulticastRoutesI i = m_multicastRoutes.begin (); 
-       i != m_multicastRoutes.end (); 
-       i = m_multicastRoutes.erase (i)) 
-    {
-      delete (*i);
-    }
-  if (m_defaultMulticastRoute != 0)
-    {
-      delete m_defaultMulticastRoute;
-      m_defaultMulticastRoute = 0;
-    }
-  Ipv4RoutingProtocol::DoDispose ();
-}
-
-}//namespace ns3
--- a/src/internet-node/ipv4-static-routing.h	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,506 +0,0 @@
-// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//
-// Author: George F. Riley<riley@ece.gatech.edu>
-//         Gustavo Carneiro <gjc@inescporto.pt>
-//
-
-#ifndef IPV4_STATIC_ROUTING_H
-#define IPV4_STATIC_ROUTING_H
-
-#include <list>
-#include <stdint.h>
-#include "ns3/ipv4-address.h"
-#include "ns3/ipv4-header.h"
-#include "ns3/ptr.h"
-#include "ns3/ipv4.h"
-
-namespace ns3 {
-
-class Packet;
-class NetDevice;
-class Ipv4Interface;
-class Ipv4Address;
-class Ipv4Header;
-class Ipv4Route;
-class Node;
-
-
-/**
- * @brief Static routing protocol for IP version 4 stacks.
- *
- * In ns-3 we have the concept of a pluggable routing protocol.  Routing
- * protocols are added to a list maintained by the Ipv4L3Protocol.  Every 
- * stack gets one routing protocol for free -- the Ipv4StaticRouting routing
- * protocol is added in the constructor of the Ipv4L3Protocol (this is the 
- * piece of code that implements the functionality of the IP layer).
- *
- * The Ipv4StaticRouting class inherits from the abstract base class 
- * Ipv4RoutingProtocol that defines the interface methods that a routing 
- * protocol must support.
- *
- * When a packet arrives in the Ipv4L3Protocol for transmission, it comes
- * either from a local source via Ipv4L3Protocol::Send or from a remote 
- * source via Ipv4L3Protocol::Forwarding.  In both cases, a function is called
- * (Ipv4L3Protocol::Lookup) to look up the routing information for the packet.
- *
- * The lookup function iterates through the list of routing protocols asking
- * each to see if it can find a route and send the packet.  A callback is 
- * provided during each of these calls that should be considered a pre-
- * packaged send call.  This is done to allow asynchronous calls into 
- * routing subsystems in order to support on-demand routing, for example.  The
- * method for requesting this operation is Ipv4StaticRouting::RequestRoute for
- * the static routing protocol.
- *
- * Each routing protocol is also free to implement its own methods for managing
- * routes which you will find below.  This class manages a set of "static" or
- * manually configured routes for host, network and multicast routes.
- *
- * @see Ipv4RoutingProtocol
- * @see Ipv4L3Protocol::AddRoutingProtocol
- * @see Ipv4L3Protocol::Ipv4L3Protocol
- */
-class Ipv4StaticRouting : public Ipv4RoutingProtocol
-{
-public:
-/**
- * @brief Construct an empty Ipv4StaticRouting routing protocol,
- * @internal
- *
- * The Ipv4StaticRouting class supports host, network and multicast routes.
- * This method initializes the lists containing these routes to empty.
- *
- * @see Ipv4StaticRouting
- */
-  Ipv4StaticRouting ();
-
-/**
- * @brief Request that a check for a route bw performed and if a route is found
- * that the packet be sent on its way using the pre-packaged send callback.
- *
- * The source and destination IP addresses for the packet in question are found
- * in the provided Ipv4Header.  There are two major processing forks depending
- * on the type of destination address.  
- *
- * If the destination address is unicast then the routing table is consulted 
- * for a route to the destination and if it is found, the routeReply callback
- * is executed to send the packet (with the found route).
- * 
- * If the destination address is a multicast, then the exact processing steps
- * depend on whether or not the packet has been sourced locally.  This is 
- * determined by the parameter ifIndex.  This is the interface index over which
- * this packet was received.  If the packet has not been received over a
- * network interface, this index will be set to 
- * Ipv4RoutingProtocol::IF_INDEX_ANY (a very large number).  In that case, 
- * we want to avoid the requirement that an explicit route out of each node 
- * must be set, so we don't do anything here.
- * 
- * If the packet is a multicast destination and has been received over a 
- * network interface, a call to this method implies that the packet is being
- * forwarded.  In that case, there must be an explicit route out of the node.
- * A multicast route references the source address, the destination address
- * (the multicast group) and the input interface in order to find a route.
- * We consult the multicast routing table and, if a route is found, send the
- * packet out of as many interfaces as required using the provided callback
- * (think of it as a pre-packaged send call).
- *
- * @param ifIndex The network interface index over which the packed was 
- * received.  If the packet is from a local source, ifIndex will be set to
- * Ipv4RoutingProtocol::IF_INDEX_ANY.
- * @param ipHeader the Ipv4Header containing the source and destination IP
- * addresses for the packet.
- * @param packet The packet to be sent if a route is found.
- * @param routeReply A callback that packaged up the call to actually send the
- * packet.
- * @return Returns true if a route is found and the packet has been sent,
- * otherwise returns false indicating that the next routing protocol should
- * be consulted.  In practice, the static routing protocol is the last chance
- * protocol.
- *
- * @see Ipv4StaticRouting
- * @see Ipv4RoutingProtocol
- */
-  virtual bool RequestRoute (uint32_t ifIndex,
-                             Ipv4Header const &ipHeader,
-                             Ptr<Packet> packet,
-                             RouteReplyCallback routeReply);
-
-/**
- * @brief Check to see if we can determine the interface index that will be
- * used if a packet is sent to this destination.
- *
- * This method addresses a problem in the IP stack where a destination address
- * must be present and checksummed into the IP header before the actual 
- * interface over which the packet is sent can be determined.  The answer is
- * to implement a known and intentional cross-layer violation.  This is the
- * endpoint of a call chain that started up quite high in the stack (sockets)
- * and has found its way down to the Ipv4L3Protocol which is consulting the
- * routing protocols for what they would do if presented with a packet of the
- * given destination.
- *
- * Note that the a single interface index is returned.  This means that if
- * the destination address is a multicast, and an explicit route is present
- * that includeds multiple output interfaces, that route cannot be used.
- * 
- * If there are multiple paths out of the node, the resolution is performed
- * by Ipv4L3Protocol::GetIfIndexforDestination which has access to more 
- * contextual information that is useful for making a determination.
- *
- * @param destination The Ipv4Address if the destination of a hypothetical 
- * packet.  This may be a multicast group address.
- * @param ifIndex A reference to the interface index over which a packet
- * sent to this destination would be sent.
- * @return Returns true if a route is found to the destination that involves
- * a single output interface index, otherwise returns false indicating that
- * the next routing protocol should be consulted.  In practice, the static 
- * routing protocol is the last chance protocol.
- *
- * @see Ipv4StaticRouting
- * @see Ipv4RoutingProtocol
- * @see Ipv4L3Protocol
- */
-  virtual bool RequestIfIndex (Ipv4Address destination, uint32_t& ifIndex);
-
-/**
- * @brief Add a host route to the static routing table.
- *
- * @param dest The Ipv4Address destination for this route.
- * @param nextHop The Ipv4Address of the next hop in the route.
- * @param interface The network interface index used to send packets to the
- * destination.
- *
- * @see Ipv4Address
- */
-  void AddHostRouteTo (Ipv4Address dest, 
-                       Ipv4Address nextHop, 
-                       uint32_t interface);
-/**
- * @brief Add a host route to the static routing table.
- *
- * @param dest The Ipv4Address destination for this route.
- * @param interface The network interface index used to send packets to the
- * destination.
- *
- * @see Ipv4Address
- */
-  void AddHostRouteTo (Ipv4Address dest, 
-                       uint32_t interface);
-
-/**
- * @brief Add a network route to the static routing table.
- *
- * @param network The Ipv4Address network for this route.
- * @param networkMask The Ipv4Mask to extract the network.
- * @param nextHop The next hop in the route to the destination network.
- * @param interface The network interface index used to send packets to the
- * destination.
- *
- * @see Ipv4Address
- */
-  void AddNetworkRouteTo (Ipv4Address network, 
-                          Ipv4Mask networkMask, 
-                          Ipv4Address nextHop, 
-                          uint32_t interface);
-
-/**
- * @brief Add a network route to the static routing table.
- *
- * @param network The Ipv4Address network for this route.
- * @param networkMask The Ipv4Mask to extract the network.
- * @param interface The network interface index used to send packets to the
- * destination.
- *
- * @see Ipv4Address
- */
-  void AddNetworkRouteTo (Ipv4Address network, 
-                          Ipv4Mask networkMask, 
-                          uint32_t interface);
-
-/**
- * @brief Add a default route to the static routing table.
- *
- * This method tells the routing system what to do in the case where a specific
- * route to a destination is not found.  The system forwards packets to the
- * specified node in the hope that it knows better how to route the packet.
- * 
- * If the default route is set, it is returned as the selected route from 
- * LookupStatic irrespective of destination address if no specific route is
- * found.
- *
- * @param nextHop The Ipv4Address to send packets to in the hope that they
- * will be forwarded correctly.
- * @param interface The network interface index used to send packets.
- *
- * @see Ipv4Address
- * @see Ipv4StaticRouting::Lookup
- */
-  void SetDefaultRoute (Ipv4Address nextHop, 
-                        uint32_t interface);
-
-/**
- * @brief Get the number of individual unicast routes that have been added
- * to the routing table.
- *
- * @warning The default route counts as one of the routes.
- */
-  uint32_t GetNRoutes (void);
-
-/**
- * @brief Get the default route from the static routing table.
- *
- * @return If the default route is set, a pointer to that Ipv4Route is
- * returned, otherwise a zero pointer is returned.
- *
- * @see Ipv4Route
- */
-  Ipv4Route *GetDefaultRoute (void);
-
-/**
- * @brief Get a route from the static unicast routing table.
- *
- * Externally, the unicast static routing table appears simply as a table with
- * n entries.  The one sublety of note is that if a default route has been set
- * it will appear as the zeroth entry in the table.  This means that if you
- * add only a default route, the table will have one entry that can be accessed
- * either by explicity calling GetDefaultRoute () or by calling GetRoute (0).
- * 
- * Similarly, if the default route has been set, calling RemoveRoute (0) will
- * remove the default route.
- *
- * @param i The index (into the routing table) of the route to retrieve.  If
- * the default route has been set, it will occupy index zero.
- * @return If route is set, a pointer to that Ipv4Route is returned, otherwise
- * a zero pointer is returned.
- *
- * @see Ipv4Route
- * @see Ipv4StaticRouting::RemoveRoute
- */
-  Ipv4Route *GetRoute (uint32_t i);
-
-/**
- * @brief Remove a route from the static unicast routing table.
- *
- * Externally, the unicast static routing table appears simply as a table with
- * n entries.  The one sublety of note is that if a default route has been set
- * it will appear as the zeroth entry in the table.  This means that if the
- * default route has been set, calling RemoveRoute (0) will remove the
- * default route.
- *
- * @param i The index (into the routing table) of the route to remove.  If
- * the default route has been set, it will occupy index zero.
- *
- * @see Ipv4Route
- * @see Ipv4StaticRouting::GetRoute
- * @see Ipv4StaticRouting::AddRoute
- */
-  void RemoveRoute (uint32_t i);
-
-/**
- * @brief Add a multicast route to the static routing table.
- *
- * A multicast route must specify an origin IP address, a multicast group and
- * an input network interface index as conditions and provide a vector of
- * output network interface indices over which packets matching the conditions
- * are sent.
- *
- * Typically there are two main types of multicast routes:  routes of the 
- * first kind are used during forwarding.  All of the conditions must be
- * exlicitly provided.  The second kind of routes are used to get packets off
- * of a local node.  The difference is in the input interface.  Routes for
- * forwarding will always have an explicit input interface specified.  Routes
- * off of a node will always set the input interface to a wildcard specified
- * by the index Ipv4RoutingProtocol::IF_INDEX_ANY.
- *
- * For routes off of a local node wildcards may be used in the origin and
- * multicast group addresses.  The wildcard used for Ipv4Adresses is that 
- * address returned by Ipv4Address::GetAny () -- typically "0.0.0.0".  Usage
- * of a wildcard allows one to specify default behavior to varying degrees.
- *
- * For example, making the origin address a wildcard, but leaving the 
- * multicast group specific allows one (in the case of a node with multiple
- * interfaces) to create different routes using different output interfaces
- * for each multicast group.
- *
- * If the origin and multicast addresses are made wildcards, you have created
- * essentially a default multicast address that can forward to multiple 
- * interfaces.  Compare this to the actual default multicast address that is
- * limited to specifying a single output interface for compatibility with
- * existing functionality in other systems.
- * 
- * @param origin The Ipv4Address of the origin of packets for this route.  May
- * be Ipv4Address:GetAny for open groups.
- * @param group The Ipv4Address of the multicast group or this route.
- * @param inputInterface The input network interface index over which to 
- * expect packets destined for this route.  May be
- * Ipv4RoutingProtocol::IF_INDEX_ANY for packets of local origin.
- * @param outputInterfaces A vector of network interface indices used to specify
- * how to send packets to the destination(s).
- *
- * @see Ipv4Address
- */
-  void AddMulticastRoute (Ipv4Address origin,
-                          Ipv4Address group,
-                          uint32_t inputInterface,
-                          std::vector<uint32_t> outputInterfaces);
-
-/**
- * @brief Add a default multicast route to the static routing table.
- *
- * This is the multicast equivalent of the unicast version SetDefaultRoute.
- * We tell the routing system what to do in the case where a specific route
- * to a destination multicast group is not found.  The system forwards 
- * packets out the specified interface in the hope that "something out there"
- * knows better how to route the packet.  This method is only used in 
- * initially sending packets off of a host.  The default multicast route is
- * not consulted during forwarding -- exact routes must be specified using
- * AddMulticastRoute for that case.
- *
- * Since we're basically sending packets to some entity we think may know
- * better what to do, we don't pay attention to "subtleties" like origin
- * address, nor do we worry about forwarding out multiple  interfaces.  If the
- * default multicast route is set, it is returned as the selected route from 
- * LookupStatic irrespective of origin or multicast group if another specific
- * route is not found.
- *
- * @param outputInterface The network interface index used to specify where
- * to send packets in the case of unknown routes.
- *
- * @see Ipv4Address
- */
-  void SetDefaultMulticastRoute (uint32_t outputInterface);
-
-/**
- * @brief Get the number of individual multicast routes that have been added
- * to the routing table.
- *
- * @warning The default multicast route counts as one of the routes.
- */
-  uint32_t GetNMulticastRoutes (void) const;
-
-/**
- * @brief Get a route from the static multicast routing table.
- *
- * Externally, the multicast static routing table appears simply as a table 
- * with n entries.  The one sublety of note is that if a default route has 
- * been set it will appear as the zeroth entry in the table.  This means that 
- * if you add only a default route, the table will have one entry that can be
- * accessed either by explicity calling GetDefaultMulticastRoute () or by
- * calling GetMulticastRoute (0).
- * 
- * Similarly, if the default route has been set, calling 
- * RemoveMulticastRoute (0) will remove the default route.
- *
- * @param i The index (into the routing table) of the multicast route to
- * retrieve.  If the default route has been set, it will occupy index zero.
- * @return If route \e i is set, a pointer to that Ipv4MulticastRoute is
- * returned, otherwise a zero pointer is returned.
- *
- * @see Ipv4MulticastRoute
- * @see Ipv4StaticRouting::RemoveRoute
- */
-  Ipv4MulticastRoute *GetMulticastRoute (uint32_t i) const;
-
-/**
- * @brief Get the default multicast route from the static routing table.
- *
- * @return If the default route is set, a pointer to that Ipv4MulticastRoute is
- * returned, otherwise a zero pointer is returned.
- *
- * @see Ipv4Route
- */
-  Ipv4MulticastRoute *GetDefaultMulticastRoute (void) const;
-
-/**
- * @brief Remove a route from the static multicast routing table.
- *
- * Externally, the multicast static routing table appears simply as a table 
- * with n entries.  The one sublety of note is that if a default multicast
- * route has been set it will appear as the zeroth entry in the table.  This
- * means that the default route may be removed by calling this method with
- * appropriate wildcard parameters.
- *
- * This method causes the multicast routing table to be searched for the first
- * route that matches the parameters and removes it.
- *
- * Wildcards may be provided to this function, but the wildcards are used to
- * exacly match wildcards in the routes (see AddMulticastRoute).  That is,
- * calling RemoveMulticastRoute with the origin set to "0.0.0.0" will not
- * remove routes with any address in the origin, but will only remove routes
- * with "0.0.0.0" set as the the origin.
- *
- * @param origin The IP address specified as the origin of packets for the
- * route.
- * @param group The IP address specified as the multicast group addres of
- * the route.
- * @param inputInterface The network interface index specified as the expected
- * input interface for the route.
- * @returns true if a route was found and removed, false otherwise.
- *
- * @see Ipv4MulticastRoute
- * @see Ipv4StaticRouting::AddMulticastRoute
- */
-  bool RemoveMulticastRoute (Ipv4Address origin,
-                             Ipv4Address group,
-                             uint32_t inputInterface);
-
-/**
- * @brief Remove a route from the static multicast routing table.
- *
- * Externally, the multicast static routing table appears simply as a table 
- * with n entries.  The one sublety of note is that if a default multicast
- * route has been set it will appear as the zeroth entry in the table.  This 
- * means that if the default route has been set, calling 
- * RemoveMulticastRoute (0) will remove the default route.
- *
- * @param index The index (into the multicast routing table) of the route to
- * remove.  If the default route has been set, it will occupy index zero.
- *
- * @see Ipv4Route
- * @see Ipv4StaticRouting::GetRoute
- * @see Ipv4StaticRouting::AddRoute
- */
-  void RemoveMulticastRoute (uint32_t index);
-
-protected:
-  void DoDispose (void);
-
-private:
-  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;
-
-  typedef std::list<Ipv4MulticastRoute *> MulticastRoutes;
-  typedef std::list<Ipv4MulticastRoute *>::const_iterator MulticastRoutesCI;
-  typedef std::list<Ipv4MulticastRoute *>::iterator MulticastRoutesI;
-
-  Ipv4Route *LookupStatic (Ipv4Address dest);
-  Ipv4MulticastRoute *LookupStatic (Ipv4Address origin, Ipv4Address group,
-                                    uint32_t ifIndex);
-
-  HostRoutes m_hostRoutes;
-  NetworkRoutes m_networkRoutes;
-  Ipv4Route *m_defaultRoute;
-  Ipv4MulticastRoute *m_defaultMulticastRoute;
-  MulticastRoutes m_multicastRoutes;
-};
-
-} // Namespace ns3
-
-#endif /* IPV4_STATIC_ROUTING_H */
--- a/src/internet-node/pending-data.cc	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,211 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//
-// Author: Rajib Bhattacharjea<raj.b@gatech.edu>
-//
-
-
-// This is a port of Data PDU Headers from:
-// Georgia Tech Network Simulator
-// George F. Riley.  Georgia Tech, Spring 2002
-
-#include <iostream>
-#include <algorithm>
-
-#include <string.h>
-
-#include "pending-data.h"
-#include "ns3/packet.h"
-#include "ns3/fatal-error.h"
-namespace ns3
-{
-
-namespace Serializable
-{
-  uint8_t* GetSize (uint8_t* b, uint32_t& r, uint32_t& s)
-  { // Get the size of the next size field
-    if (sizeof(s) > r)
-    {
-      NS_FATAL_ERROR ("Serialization error; remaining " << r
-           << " thissize " << sizeof(s) << std::endl);
-    }
-    r -= sizeof (s); // Reduce remaining for next time
-    memcpy (&s, b, sizeof(s));
-    return b + sizeof (s);
-  }
-}
-
-PendingData::PendingData () : size (0), data (0),
-               msgSize (0), responseSize (0)
-{
-}
-
-PendingData::PendingData (uint32_t s, uint8_t* d, uint32_t msg, uint32_t resp)
-  : size (s), data (0), msgSize (msg), responseSize (resp)
-{ // Make a copy of the data
-  if (d)
-    {
-      data = new uint8_t[s];
-      memcpy (data, d, s);
-    }
-}
-
-PendingData::PendingData(const std::string& s) 
-  : size (s.length () + 1), data ((uint8_t*)strdup(s.c_str ())),
-    msgSize (0), responseSize (0)
-{
-}
-
-PendingData::PendingData(const PendingData& c)
-  : size (c.Size ()), data (0),
-    msgSize (c.msgSize), responseSize (c.responseSize)
-{ // Copy constructor
-  if (c.Contents())
-    { // Has data
-      data = new uint8_t[Size ()];
-      memcpy(data, c.Contents (), Size ());
-    }
-}
-
-PendingData::~PendingData()
-{ // destructor
-  if (data)
-    {
-	  delete [] data;
-    }
-}
-
-PendingData* PendingData::Copy () const
-{
-  return new PendingData (*this);
-};
-
-PendingData* PendingData::CopyS (uint32_t s)
-{ // Copy, but with new size (assumes no associated data);
-  return new PendingData (s, 0, msgSize, responseSize);
-}
-
-PendingData* PendingData::CopySD (uint32_t s, uint8_t* d)
-{ // Copy, but with new size (assumes no associated data);
-  return new PendingData (s, d, msgSize, responseSize);
-}
-
-void PendingData::Clear ()
-{ // Remove all pending data
-  if (data)
-    {
-      delete [] data; // Free memory if used
-    }
-  data = 0;
-  size = 0;
-}
-
-void PendingData::Add (uint32_t s, const uint8_t* d)
-{
-  if (data)
-    { // PendingData exists, realloc and copy
-      uint8_t* n = new uint8_t[Size () + s];
-      memcpy(n, data, Size ());
-      if (d)
-        { // New data specified
-          memcpy(n + Size (), d, s); // Append the new data
-        }
-      else
-        {
-          memset(n + Size (), 0, s); // Apend zeros
-        }
-      delete [] data;           // Delete the old data
-      data = n;                 // Points to new one
-    }
-  else
-    { // No existing data, see if new data
-      if (d)
-        {
-          data = new uint8_t[s];
-          memcpy (data, d, s);
-        }
-    }
-  size += s;
-}
-
-void PendingData::Remove(uint32_t s)
-{
-  uint32_t r = s > Size () ? Size () : s;
-
-  size -= r;          // Reduce size from current
-  if (data)
-    { // data actually exists, realloc and copy
-      if (size)
-        {
-          uint8_t* d = new uint8_t[Size ()];
-          memcpy(d, data, Size ());
-          delete [] data;
-          data = d;
-        }
-      else
-        { // Zero size, so don't need the data anymore
-          delete [] data;
-          data = NULL;
-        }
-    }
-}
-
-uint32_t PendingData::SizeFromSeq (const SequenceNumber& f, const SequenceNumber& o)
-{
-  uint32_t o1 = OffsetFromSeq (f,o); // Offset to start of unused data
-  return SizeFromOffset (o1);      // Amount of data after offset
-}
-
-uint32_t PendingData::SizeFromOffset (uint32_t o)
-{ // Find out how much data is available from offset
-  if (o > size) return 0;     // No data at requested offset
-  return size - o;            // Available data after offset
-}
-
-uint32_t PendingData::OffsetFromSeq (const SequenceNumber& f, const SequenceNumber& o)
-{ // f is the first sequence number in this data, o is offset sequence
-  if (o < f) 
-    {
-      return 0; // HuH?  Shouldn't happen
-    }
-  return o - f;
-}
-
-Ptr<Packet> PendingData::CopyFromOffset (uint32_t s, uint32_t o)
-{ // Make a copy of data from starting position "o" for "s" bytes
-  // Return NULL if results in zero length data
-  uint32_t s1 = std::min (s, SizeFromOffset (o)); // Insure not beyond end of data
-  if (s1 == 0)
-    {
-      return 0;   // No data requested
-    }
-  if (data)
-    { // Actual data exists, make copy and return it
-      return Create<Packet> (data+o, s1);
-    }
-  else
-    { // No actual data, just return non-data pdu of correct size
-      return Create<Packet> (s1);
-    }
-}
-
-Ptr<Packet> PendingData::CopyFromSeq (uint32_t s, const SequenceNumber& f, const SequenceNumber& o)
-{
-  return CopyFromOffset (s, OffsetFromSeq(f,o));
-}
-
-}//namepsace ns3
--- a/src/internet-node/pending-data.h	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//
-// Author: Rajib Bhattacharjea<raj.b@gatech.edu>
-//
-
-// Georgia Tech Network Simulator - Data Descriptors
-// George F. Riley.  Georgia Tech, Spring 2002
-
-#ifndef __datapdu_h__
-#define __datapdu_h__
-
-#include "pending-data.h"
-#include "sequence-number.h"
-
-#include "ns3/ptr.h"
-namespace ns3
-{
-class Packet;
-//Doc:ClassXRef
-class PendingData {
-public:
-  PendingData ();
-  PendingData (uint32_t s, uint8_t* d = NULL, uint32_t msg = 0, uint32_t resp = 0);
-  PendingData (const std::string&); // Construct from string
-  PendingData (uint8_t*, uint32_t&, Packet*); // Construct from serialized buffer
-  PendingData (const PendingData&);   // Copy constructor
-  virtual ~PendingData ();     // Destructor
-  uint32_t Size () const { return size;}
-  // Serialization
-  uint32_t SSize ();                   // Size needed for serialization
-  uint8_t*  Serialize (uint8_t*, uint32_t&); // Serialize to a buffer
-  uint8_t*  Construct (uint8_t*, uint32_t&); // Construct from buffer
-  virtual void Clear ();// Remove all associated data
-  virtual void Add (uint32_t s, const uint8_t* d = 0);// Add some data to end
-  virtual void Remove (uint32_t);      // Remove data from head
-  // Inquire available data from (f,o) sequence pair
-  virtual uint32_t SizeFromSeq (const SequenceNumber&, const SequenceNumber&);
-  // Inquire available data from offset
-  virtual uint32_t SizeFromOffset (uint32_t);
-  // Available size from sequence difference 
-  virtual uint32_t OffsetFromSeq (const SequenceNumber&, const SequenceNumber&);
-  virtual Ptr<Packet> CopyFromOffset (uint32_t, uint32_t);  // Size, offset, ret packet
-  // Copy data, size, offset specified by sequence difference
-  virtual Ptr<Packet> CopyFromSeq (uint32_t, const SequenceNumber&, const SequenceNumber&);
-  PendingData*   Copy () const;          // Create a copy of this header
-  PendingData*   CopyS (uint32_t);         // Copy with new size
-  PendingData*   CopySD (uint32_t, uint8_t*); // Copy with new size, new data
-  virtual uint8_t* Contents() const { return data;}
-public:
-  uint32_t size;        // Number of data bytes
-  uint8_t* data;         // Corresponding data (may be null)
-  // The next two fields allow simulated applications to exchange some info
-  uint32_t msgSize;     // Total size of message
-  uint32_t responseSize;// Size of response requested
-};
-
-}//namepsace ns3
-#endif
-
--- a/src/internet-node/rtt-estimator.cc	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,235 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//
-// Author: Rajib Bhattacharjea<raj.b@gatech.edu>
-//
-
-
-// Ported from:
-// Georgia Tech Network Simulator - Round Trip Time Estimation Class
-// George F. Riley.  Georgia Tech, Spring 2002
-
-// Implements several variations of round trip time estimators
-
-#include <iostream>
-
-#include "rtt-estimator.h"
-#include "ns3/simulator.h"
-#include "ns3/double.h"
-
-namespace ns3{
-
-NS_OBJECT_ENSURE_REGISTERED (RttEstimator);
-
-//RttEstimator iid
-TypeId 
-RttEstimator::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::RttEstimator")
-    .SetParent<Object> ()
-    .AddAttribute ("MaxMultiplier", 
-                   "XXX",
-                   DoubleValue (64.0),
-                   MakeDoubleAccessor (&RttEstimator::m_maxMultiplier),
-                   MakeDoubleChecker<double> ())
-    .AddAttribute ("InitialEstimation", 
-                   "XXX",
-                   TimeValue (Seconds (1.0)),
-                   MakeTimeAccessor (&RttEstimator::est),
-                   MakeTimeChecker ())
-    ;
-  return tid;
-}
-
-//RttHistory methods
-RttHistory::RttHistory (SequenceNumber s, uint32_t c, Time t)
-  : seq (s), count (c), time (t), retx (false)
-  {
-  }
-
-RttHistory::RttHistory (const RttHistory& h)
-  : seq (h.seq), count (h.count), time (h.time), retx (h.retx)
-  {
-  }
-
-// Base class methods
-
-RttEstimator::RttEstimator () : next (1), history (),
-    nSamples (0), multiplier (1.0) 
-{ 
-  //note next=1 everywhere since first segment will have sequence 1
-}
-
-RttEstimator::RttEstimator(const RttEstimator& c)
-  : Object (c), next(c.next), history(c.history), 
-    m_maxMultiplier (c.m_maxMultiplier), est(c.est), nSamples(c.nSamples),
-    multiplier(c.multiplier)
-{}
-
-RttEstimator::~RttEstimator ()
-{
-}
-
-void RttEstimator::SentSeq (SequenceNumber s, uint32_t c)
-{ // Note that a particular sequence has been sent
-  if (s == next)
-    { // This is the next expected one, just log at end
-      history.push_back (RttHistory (s, c, Simulator::Now () ));
-      next = s + SequenceNumber (c); // Update next expected
-    }
-  else
-    { // This is a retransmit, find in list and mark as re-tx
-      for (RttHistory_t::iterator i = history.begin (); i != history.end (); ++i)
-        {
-          if ((s >= i->seq) && (s < (i->seq + SequenceNumber (i->count))))
-            { // Found it
-              i->retx = true;
-              // One final test..be sure this re-tx does not extend "next"
-              if ((s + SequenceNumber (c)) > next)
-                {
-                  next = s + SequenceNumber (c);
-                  i->count = ((s + SequenceNumber (c)) - i->seq); // And update count in hist
-                }
-              break;
-            }
-        }
-    }
-}
-
-Time RttEstimator::AckSeq (SequenceNumber a)
-{ // An ack has been received, calculate rtt and log this measurement
-  // Note we use a linear search (O(n)) for this since for the common
-  // case the ack'ed packet will be at the head of the list
-  Time m = Seconds (0.0);
-  if (history.size () == 0) return (m);    // No pending history, just exit
-  RttHistory& h = history.front ();
-  if (!h.retx && a >= (h.seq + SequenceNumber (h.count)))
-    { // Ok to use this sample
-      m = Simulator::Now () - h.time; // Elapsed time
-      Measurement(m);                // Log the measurement
-      ResetMultiplier();             // Reset multiplier on valid measurement
-    }
-  // Now delete all ack history with seq <= ack
-  while(history.size() > 0)
-    {
-      RttHistory& h = history.front ();
-      if ((h.seq + SequenceNumber(h.count)) > a) break;                // Done removing
-      history.pop_front (); // Remove
-    }
-  return m;
-}
-
-void RttEstimator::ClearSent ()
-{ // Clear all history entries
-  next = 1;
-  history.clear ();
-}
-
-void RttEstimator::IncreaseMultiplier ()
-{
-  double a;
-  a = multiplier * 2.0;
-  double b;
-  b = m_maxMultiplier * 2.0;
-  multiplier = std::min (multiplier * 2.0, m_maxMultiplier);
-}
-
-void RttEstimator::ResetMultiplier ()
-{
-  multiplier = 1.0;
-}
-
-void RttEstimator::Reset ()
-{ // Reset to initial state
-  next = 1;
-  est = Seconds (1.0); // XXX: we should go back to the 'initial value' here. Need to add support in Object for this.
-  history.clear ();         // Remove all info from the history
-  nSamples = 0;
-  ResetMultiplier ();
-}
-
-
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-// Mean-Deviation Estimator
-
-NS_OBJECT_ENSURE_REGISTERED (RttMeanDeviation);
-
-TypeId 
-RttMeanDeviation::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::RttMeanDeviation")
-    .SetParent<RttEstimator> ()
-    .AddConstructor<RttMeanDeviation> ()
-    .AddAttribute ("Gain",
-                   "XXX",
-                   DoubleValue (0.1),
-                   MakeDoubleAccessor (&RttMeanDeviation::gain),
-                   MakeDoubleChecker<double> ())
-    ;
-  return tid;
-}
-
-RttMeanDeviation::RttMeanDeviation() :
-  variance (ns3::Seconds(0)) 
-{ 
-}
-
-RttMeanDeviation::RttMeanDeviation (const RttMeanDeviation& c)
-  : RttEstimator (c), gain (c.gain), variance (c.variance)
-{
-}
-
-void RttMeanDeviation::Measurement (Time m)
-{
-  if (nSamples)
-    { // Not first
-      Time err = m - est;
-      est = est + Scalar (gain) * err;         // estimated rtt
-      err = Abs (err);        // absolute value of error
-      variance = variance + Scalar (gain) * (err - variance); // variance of rtt
-    }
-  else
-    { // First sample
-      est = m;                        // Set estimate to current
-      //variance = m / 2;               // And variance to current / 2
-      variance = m; // try this
-    }
-  nSamples++;
-}
-
-Time RttMeanDeviation::RetransmitTimeout ()
-{
-  // If not enough samples, justjust return 2 times estimate   
-  //if (nSamples < 2) return est * 2;
-  if (variance < est / Scalar (4.0))
-    return est * Scalar (2 * multiplier);            // At least twice current est
-  return (est + Scalar (4) * variance) * Scalar (multiplier); // As suggested by Jacobson
-}
-
-Ptr<RttEstimator> RttMeanDeviation::Copy () const
-{
-  return CopyObject<RttMeanDeviation> (this);
-}
-
-void RttMeanDeviation::Reset ()
-{ // Reset to initial state
-  variance = Seconds (0.0);
-  RttEstimator::Reset ();
-}
-}//namepsace ns3
--- a/src/internet-node/rtt-estimator.h	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//
-// Author: Rajib Bhattacharjea<raj.b@gatech.edu>
-//
-
-// Georgia Tech Network Simulator - Round Trip Time Estimation Class
-// George F. Riley.  Georgia Tech, Spring 2002
-
-// Implements several variations of round trip time estimators
-
-#ifndef __rtt_estimator_h__
-#define __rtt_estimator_h__
-
-#include <deque>
-#include "sequence-number.h"
-#include "ns3/nstime.h"
-#include "ns3/object.h"
-
-namespace ns3 {
-
-class RttHistory {
-public:
-  RttHistory (SequenceNumber s, uint32_t c, Time t);
-  RttHistory (const RttHistory& h); // Copy constructor
-public:
-  SequenceNumber  seq;    // First sequence number in packet sent
-  uint32_t        count;  // Number of bytes sent
-  Time            time;   // Time this one was sent
-  bool            retx;   // True if this has been retransmitted
-};
-
-typedef std::deque<RttHistory> RttHistory_t;
-
-class RttEstimator : public Object {  //  Base class for all RTT Estimators
-public:
-  static TypeId GetTypeId (void);
-
-  RttEstimator();
-  RttEstimator(const RttEstimator&); // Copy constructor
-  virtual ~RttEstimator();
-
-  virtual void SentSeq(SequenceNumber, uint32_t);
-  virtual Time AckSeq(SequenceNumber);
-  virtual void ClearSent();
-  virtual void   Measurement(Time t) = 0;
-  virtual Time Estimate() = 0;
-  virtual Time RetransmitTimeout() = 0;
-  void Init(SequenceNumber s) { next = s;}
-  virtual Ptr<RttEstimator> Copy() const = 0;
-  virtual void IncreaseMultiplier();
-  virtual void ResetMultiplier();
-  virtual void Reset();
-
-private:
-  SequenceNumber        next;    // Next expected sequence to be sent
-  RttHistory_t history; // List of sent packet
-  double m_maxMultiplier;
-public:
-  Time       est;     // Current estimate
-  uint32_t      nSamples;// Number of samples
-  double       multiplier;   // RTO Multiplier
-};
-
-// The "Mean-Deviation" estimator, as discussed by Van Jacobson
-// "Congestion Avoidance and Control", SIGCOMM 88, Appendix A
-
-  //Doc:Class Class {\tt RttMeanDeviation} implements the "Mean--Deviation" estimator
-  //Doc:Class as described by Van Jacobson 
-  //Doc:Class "Congestion Avoidance and Control", SIGCOMM 88, Appendix A
-class RttMeanDeviation : public RttEstimator {
-public :
-  static TypeId GetTypeId (void);
-
-  RttMeanDeviation ();
-
-
-  //Doc:Method
-  RttMeanDeviation (const RttMeanDeviation&); // Copy constructor
-    //Doc:Desc Copy constructor.
-    //Doc:Arg1 {\tt RttMeanDeviation} object to copy.
-
-  void Measurement (Time);
-  Time Estimate () { return est;}
-  Time Variance () { return variance;}
-  Time RetransmitTimeout ();
-  Ptr<RttEstimator> Copy () const;
-  void Reset ();
-  void Gain (double g) { gain = g;}
-
-public:
-  double       gain;       // Filter gain
-  Time       variance;   // Current variance
-};
-}//namespace ns3
-#endif
-
-
-
--- a/src/internet-node/sequence-number.cc	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//
-// Author: Rajib Bhattacharjea<raj.b@gatech.edu>
-//
-
-
-// Ported from:
-// Georgia Tech Network Simulator - Manage 32 bit unsigned sequence numbers
-// George F. Riley.  Georgia Tech, Spring 2002
-
-// Class to manage arithmetic operations on sequence numbers (mod 2^32)
-
-#include "sequence-number.h"
-
-bool operator< (const SequenceNumber l, const SequenceNumber r) 
-{ // Account for 32 bit rollover
-  if (l.seq > 0xc0000000 && r.seq < 0x40000000) return true; // Rollover
-  return l.seq < r.seq;
-}
-
-bool operator<= (const SequenceNumber l, const SequenceNumber r) 
-{ // Account for 32 bit rollover
-  if (l.seq > 0xc0000000 && r.seq < 0x40000000) return true; // Rollover
-  return l.seq <= r.seq;
-}
-
-bool operator> (const SequenceNumber l, const SequenceNumber r) 
-{ // Account for 32 bit rollover
-  if (l.seq > 0xc0000000 && r.seq < 0x40000000) return false; // Rollover
-  return l.seq > r.seq;
-}
-
-bool operator>= (const SequenceNumber l, const SequenceNumber r) 
-{ // Account for 32 bit rollover
-  if (l.seq > 0xc0000000 && r.seq < 0x40000000) return false; // Rollover
-  return l.seq >= r.seq;
-}
-
-// Non-Member Arithmetic operators
-SequenceNumber  operator+ (const SequenceNumber l, const SequenceNumber r)
-{
-  return SequenceNumber (l.seq + r.seq);
-}
-
-SequenceNumber operator- (const SequenceNumber l, const SequenceNumber r)
-{ // This assumes l is always bigger than r (allows for rollover)
-  if (l.seq >= r.seq) return SequenceNumber (l.seq-r.seq);
-  return SequenceNumber ((MAX_SEQ - r.seq) + l.seq + 1);  // Adjust for rollover
-}
-
--- a/src/internet-node/sequence-number.h	Wed Jun 11 16:19:28 2008 -0700
+++ /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) 2006 Georgia Tech Research Corporation
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as
-// published by the Free Software Foundation;
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//
-// Author: Rajib Bhattacharjea<raj.b@gatech.edu>
-//
-
-// Ported from:
-// Georgia Tech Network Simulator - Manage 32 bit unsigned sequence numbers
-// George F. Riley.  Georgia Tech, Spring 2002
-
-// Class to manage arithmetic operations on sequence numbers (mod 2^32)
-
-#ifndef __seq_h__
-#define __seq_h__
-
-#include <stdint.h>
-
-#define MAX_SEQ ((uint32_t)0xffffffff)
-
-class SequenceNumber {
-public:
-  SequenceNumber () : seq(0) { }
-  SequenceNumber (const uint32_t s) : seq (s) { }
-
-  operator uint32_t () const { return seq;}
-
-  SequenceNumber& operator= (const uint32_t s) { seq = s; return *this;}
-
-  SequenceNumber& operator+= (const uint32_t s) { seq += s; return *this;}
-  SequenceNumber  operator++ ()              { seq++; return *this;}
-  SequenceNumber  operator++ (int)           { SequenceNumber ss (seq); seq++; return ss;}
-  SequenceNumber& operator-= (const uint32_t s) { seq -= s; return *this;}
-  SequenceNumber  operator-- ()              { seq--; return *this;}
-  SequenceNumber  operator-- (int)           { SequenceNumber ss (seq); seq--; return ss;}
-public:
-  uint32_t seq;
-};
-
-// Comparison operators
-
-bool operator< (const SequenceNumber l, const SequenceNumber r);
-bool operator<= (const SequenceNumber l, const SequenceNumber r); 
-bool operator> (const SequenceNumber l, const SequenceNumber r);
-bool operator>= (const SequenceNumber l, const SequenceNumber r);
-
-// Non-member arithmetic operators
-SequenceNumber  operator+ (const SequenceNumber l, const SequenceNumber r);
-SequenceNumber  operator- (const SequenceNumber l, const SequenceNumber r);
-
-#endif
-
-
--- a/src/internet-node/sgi-hashmap.h	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/* This code snippet was ripped out of the gcc 
- * documentation and slightly modified to work
- * with gcc 4.x
- */
-#ifndef SGI_HASHMAP_H
-#define SGI_HASHMAP_H
-
-/* To use gcc extensions.
- */
-#ifdef __GNUC__
-  #if __GNUC__ < 3
-     #include <hash_map.h>
-namespace sgi { using ::hash_map; }; // inherit globals
-  #else 
-     #if __GNUC__ < 4
-       #include <ext/hash_map>
-       #if __GNUC_MINOR__ == 0
-namespace sgi = std;         // GCC 3.0
-       #else
-namespace sgi = ::__gnu_cxx;       // GCC 3.1 and later
-       #endif
-     #else  // gcc 4.x and later
-       #include <ext/hash_map>
-       namespace sgi = ::__gnu_cxx;
-     #endif
-  #endif
-#else      // ...  there are other compilers, right?
-namespace sgi = std;
-#endif
-
-
-#endif /* SGI_HASHMAP_H */
--- a/src/internet-node/tcp-header.cc	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,217 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 Georgia Tech Research Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Raj Bhattacharjea <raj.b@gatech.edu>
- */
-
-#include <stdint.h>
-#include <iostream>
-#include "tcp-socket-impl.h"
-#include "tcp-header.h"
-#include "ns3/buffer.h"
-
-namespace ns3 {
-
-NS_OBJECT_ENSURE_REGISTERED (TcpHeader);
-
-bool TcpHeader::m_calcChecksum = false;
-
-TcpHeader::TcpHeader ()
-  : m_sourcePort (0),
-    m_destinationPort (0),
-    m_sequenceNumber (0),
-    m_ackNumber (0),
-    m_length (5),
-    m_flags (0),
-    m_windowSize (0xffff),
-    m_checksum (0),
-    m_urgentPointer (0)
-{}
-
-TcpHeader::~TcpHeader ()
-{}
-
-void
-TcpHeader::EnableChecksums (void)
-{
-  m_calcChecksum = true;
-}
-
-void TcpHeader::SetSourcePort (uint16_t port)
-{
-  m_sourcePort = port;
-}
-void TcpHeader::SetDestinationPort (uint16_t port)
-{
-  m_destinationPort = port;
-}
-void TcpHeader::SetSequenceNumber (SequenceNumber sequenceNumber)
-{
-  m_sequenceNumber = sequenceNumber;
-}
-void TcpHeader::SetAckNumber (SequenceNumber ackNumber)
-{
-  m_ackNumber = ackNumber;
-}
-void TcpHeader::SetLength (uint8_t length)
-{
-  m_length = length;
-}
-void TcpHeader::SetFlags (uint8_t flags)
-{
-  m_flags = flags;
-}
-void TcpHeader::SetWindowSize (uint16_t windowSize)
-{
-  m_windowSize = windowSize;
-}
-void TcpHeader::SetChecksum (uint16_t checksum)
-{
-  m_checksum = checksum;
-}
-void TcpHeader::SetUrgentPointer (uint16_t urgentPointer)
-{
-  m_urgentPointer = urgentPointer;
-}
-
-uint16_t TcpHeader::GetSourcePort () const
-{
-  return m_sourcePort;
-}
-uint16_t TcpHeader::GetDestinationPort () const
-{
-  return m_destinationPort;
-}
-SequenceNumber TcpHeader::GetSequenceNumber () const
-{
-  return m_sequenceNumber;
-}
-SequenceNumber TcpHeader::GetAckNumber () const
-{
-  return m_ackNumber;
-}
-uint8_t  TcpHeader::GetLength () const
-{
-  return m_length;
-}
-uint8_t  TcpHeader::GetFlags () const
-{
-  return m_flags;
-}
-uint16_t TcpHeader::GetWindowSize () const
-{
-  return m_windowSize;
-}
-uint16_t TcpHeader::GetChecksum () const
-{
-  return m_checksum;
-}
-uint16_t TcpHeader::GetUrgentPointer () const
-{
-  return m_urgentPointer;
-}
-
-void 
-TcpHeader::InitializeChecksum (Ipv4Address source, 
-                                   Ipv4Address destination,
-                                   uint8_t protocol)
-{
-  m_checksum = 0;
-//XXX requires peeking into IP to get length of the TCP segment
-}
-
-TypeId 
-TcpHeader::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::TcpHeader")
-    .SetParent<Header> ()
-    .AddConstructor<TcpHeader> ()
-    ;
-  return tid;
-}
-TypeId 
-TcpHeader::GetInstanceTypeId (void) const
-{
-  return GetTypeId ();
-}
-void TcpHeader::Print (std::ostream &os)  const
-{
-  os << m_sourcePort << " > " << m_destinationPort;
-  if(m_flags!=0)
-  {
-    os<<" [";
-    if((m_flags & FIN) != 0)
-    {
-      os<<" FIN ";
-    }
-    if((m_flags & SYN) != 0)
-    {
-      os<<" SYN ";
-    }
-    if((m_flags & RST) != 0)
-    {
-      os<<" RST ";
-    }
-    if((m_flags & PSH) != 0)
-    {
-      os<<" PSH ";
-    }
-    if((m_flags & ACK) != 0)
-    {
-      os<<" ACK ";
-    }
-    if((m_flags & URG) != 0)
-    {
-      os<<" URG ";
-    }
-    os<<"]";
-  }
-  os<<" Seq="<<m_sequenceNumber<<" Ack="<<m_ackNumber<<" Win="<<m_windowSize;
-}
-uint32_t TcpHeader::GetSerializedSize (void)  const
-{
-  return 4*m_length;
-}
-void TcpHeader::Serialize (Buffer::Iterator start)  const
-{
-  start.WriteHtonU16 (m_sourcePort);
-  start.WriteHtonU16 (m_destinationPort);
-  start.WriteHtonU32 (m_sequenceNumber);
-  start.WriteHtonU32 (m_ackNumber);
-  start.WriteHtonU16 (m_length << 12 | m_flags); //reserved bits are all zero
-  start.WriteHtonU16 (m_windowSize);
-  //XXX calculate checksum here
-  start.WriteHtonU16 (m_checksum);
-  start.WriteHtonU16 (m_urgentPointer);
-}
-uint32_t TcpHeader::Deserialize (Buffer::Iterator start)
-{
-  m_sourcePort = start.ReadNtohU16 ();
-  m_destinationPort = start.ReadNtohU16 ();
-  m_sequenceNumber = start.ReadNtohU32 ();
-  m_ackNumber = start.ReadNtohU32 ();
-  uint16_t field = start.ReadNtohU16 ();
-  m_flags = field & 0x3F;
-  m_length = field>>12;
-  m_windowSize = start.ReadNtohU16 ();
-  m_checksum = start.ReadNtohU16 ();
-  m_urgentPointer = start.ReadNtohU16 ();
-  return GetSerializedSize ();
-}
-
-
-}; // namespace ns3
--- a/src/internet-node/tcp-header.h	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,161 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 Georgia Tech Research Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Raj Bhattacharjea <raj.b@gatech.edu>
- */
-
-#ifndef TCP_HEADER_H
-#define TCP_HEADER_H
-
-#include <stdint.h>
-#include "ns3/header.h"
-#include "ns3/buffer.h"
-#include "ns3/tcp-socket-factory.h"
-#include "ns3/ipv4-address.h"
-#include "ns3/sequence-number.h"
-
-namespace ns3 {
-
-class TcpHeader : public Header 
-{
-public:
-  TcpHeader ();
-  virtual ~TcpHeader ();
-
-  /**
-   * \brief Enable checksum calculation for TCP (XXX currently has no effect)
-   */
-  static void EnableChecksums (void);
-//Setters
-  /**
-   * \param port The source port for this TcpHeader
-   */
-  void SetSourcePort (uint16_t port);
-  /**
-   * \param port the destination port for this TcpHeader
-   */
-  void SetDestinationPort (uint16_t port);
-  /**
-   * \param sequenceNumber the sequence number for this TcpHeader
-   */
-  void SetSequenceNumber (SequenceNumber sequenceNumber);
-  /**
-   * \param ackNumber the ACK number for this TcpHeader
-   */
-  void SetAckNumber (SequenceNumber ackNumber);
-  /**
-   * \param length the length of this TcpHeader
-   */
-  void SetLength (uint8_t length);
-  /**
-   * \param flags the flags for this TcpHeader
-   */
-  void SetFlags (uint8_t flags);
-  /**
-   * \param windowSize the window size for this TcpHeader
-   */
-  void SetWindowSize (uint16_t windowSize);
-  /**
-   * \param checksum the checksum for this TcpHeader
-   */
-  void SetChecksum (uint16_t checksum);
-  /**
-   * \param urgentPointer the urgent pointer for this TcpHeader
-   */
-  void SetUrgentPointer (uint16_t urgentPointer);
-
-
-//Getters
-  /**
-   * \return The source port for this TcpHeader
-   */
-  uint16_t GetSourcePort () const;
-  /**
-   * \return the destination port for this TcpHeader
-   */
-  uint16_t GetDestinationPort () const;
-  /**
-   * \return the sequence number for this TcpHeader
-   */
-  SequenceNumber GetSequenceNumber () const;
-  /**
-   * \return the ACK number for this TcpHeader
-   */
-  SequenceNumber GetAckNumber () const;
-  /**
-   * \return the length of this TcpHeader
-   */
-  uint8_t  GetLength () const;
-  /**
-   * \return the flags for this TcpHeader
-   */
-  uint8_t  GetFlags () const;
-  /**
-   * \return the window size for this TcpHeader
-   */
-  uint16_t GetWindowSize () const;
-  /**
-   * \return the checksum for this TcpHeader
-   */
-  uint16_t GetChecksum () const;
-  /**
-   * \return the urgent pointer for this TcpHeader
-   */
-  uint16_t GetUrgentPointer () const;
-
-  /**
-   * \param source the ip source to use in the underlying
-   *        ip packet.
-   * \param destination the ip destination to use in the
-   *        underlying ip packet.
-   * \param protocol the protocol number to use in the underlying
-   *        ip packet.
-   *
-   * If you want to use tcp checksums, you should call this
-   * method prior to adding the header to a packet.
-   */
-  void InitializeChecksum (Ipv4Address source, 
-                           Ipv4Address destination,
-                           uint8_t protocol);
-
-  typedef enum { NONE = 0, FIN = 1, SYN = 2, RST = 4, PSH = 8, ACK = 16, 
-    URG = 32} Flags_t;
-
-  static TypeId GetTypeId (void);
-  virtual TypeId GetInstanceTypeId (void) const;
-  virtual void Print (std::ostream &os) const;
-  virtual uint32_t GetSerializedSize (void) const;
-  virtual void Serialize (Buffer::Iterator start) const;
-  virtual uint32_t Deserialize (Buffer::Iterator start);
-
-private:
-  uint16_t m_sourcePort;
-  uint16_t m_destinationPort;
-  uint32_t m_sequenceNumber;
-  uint32_t m_ackNumber;
-  uint8_t m_length; // really a uint4_t
-  uint8_t m_flags;      // really a uint6_t
-  uint16_t m_windowSize;
-  uint16_t m_checksum;
-  uint16_t m_urgentPointer;
-
-  static bool m_calcChecksum;
-};
-
-}; // namespace ns3
-
-#endif /* TCP_HEADER */
--- a/src/internet-node/tcp-l4-protocol.cc	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,526 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 Georgia Tech Research Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Raj Bhattacharjea <raj.b@gatech.edu>
- */
-
-#include "ns3/assert.h"
-#include "ns3/log.h"
-#include "ns3/nstime.h"
-
-#include "ns3/packet.h"
-#include "ns3/node.h"
-
-#include "tcp-l4-protocol.h"
-#include "tcp-header.h"
-#include "ipv4-end-point-demux.h"
-#include "ipv4-end-point.h"
-#include "ipv4-l3-protocol.h"
-#include "tcp-socket-impl.h"
-
-#include "tcp-typedefs.h"
-
-#include <vector>
-#include <sstream>
-#include <iomanip>
-
-NS_LOG_COMPONENT_DEFINE ("TcpL4Protocol");
-
-namespace ns3 {
-
-NS_OBJECT_ENSURE_REGISTERED (TcpL4Protocol);
-
-//State Machine things --------------------------------------------------------
-TcpStateMachine::TcpStateMachine() 
-  : aT (LAST_STATE, StateActionVec_t(LAST_EVENT)),
-       eV (MAX_FLAGS)
-{ 
-  NS_LOG_FUNCTION_NOARGS ();
-
-  // Create the state table
-  // Closed state
-  aT[CLOSED][APP_LISTEN]  = SA (LISTEN,   NO_ACT);
-  aT[CLOSED][APP_CONNECT] = SA (SYN_SENT, SYN_TX);
-  aT[CLOSED][APP_SEND]    = SA (CLOSED,   RST_TX);
-  aT[CLOSED][SEQ_RECV]    = SA (CLOSED,   NO_ACT);
-  aT[CLOSED][APP_CLOSE]   = SA (CLOSED,   NO_ACT);
-  aT[CLOSED][TIMEOUT]     = SA (CLOSED,   RST_TX);
-  aT[CLOSED][ACK_RX]      = SA (CLOSED,   RST_TX);
-  aT[CLOSED][SYN_RX]      = SA (CLOSED,   RST_TX);
-  aT[CLOSED][SYN_ACK_RX]  = SA (CLOSED,   RST_TX);
-  aT[CLOSED][FIN_RX]      = SA (CLOSED,   RST_TX);
-  aT[CLOSED][FIN_ACK_RX]  = SA (CLOSED,   RST_TX);
-  aT[CLOSED][RST_RX]      = SA (CLOSED,   CANCEL_TM);
-  aT[CLOSED][BAD_FLAGS]   = SA (CLOSED,   RST_TX);
-
-  // Listen State
-  // For the listen state, anything other than CONNECT or SEND
-  // is simply ignored....this likely indicates the child TCP
-  // has finished and issued unbind call, but the remote end
-  // has not yet  closed.
-  aT[LISTEN][APP_LISTEN]  = SA (LISTEN,   NO_ACT);
-  aT[LISTEN][APP_CONNECT] = SA (SYN_SENT, SYN_TX);
-  aT[LISTEN][APP_SEND]    = SA (SYN_SENT, SYN_TX);
-  aT[LISTEN][SEQ_RECV]    = SA (LISTEN,   NO_ACT);
-  aT[LISTEN][APP_CLOSE]   = SA (CLOSED,   NO_ACT);
-  aT[LISTEN][TIMEOUT]     = SA (LISTEN,   NO_ACT);
-  aT[LISTEN][ACK_RX]      = SA (LISTEN,   NO_ACT);
-  aT[LISTEN][SYN_RX]      = SA (LISTEN,   SYN_ACK_TX);//stay in listen and fork
-  aT[LISTEN][SYN_ACK_RX]  = SA (LISTEN,   NO_ACT);
-  aT[LISTEN][FIN_RX]      = SA (LISTEN,   NO_ACT);
-  aT[LISTEN][FIN_ACK_RX]  = SA (LISTEN,   NO_ACT);
-  aT[LISTEN][RST_RX]      = SA (LISTEN,   NO_ACT);
-  aT[LISTEN][BAD_FLAGS]   = SA (LISTEN,   NO_ACT);
-
-  // Syn Sent State
-  aT[SYN_SENT][APP_LISTEN]  = SA (CLOSED,      RST_TX);
-  aT[SYN_SENT][APP_CONNECT] = SA (SYN_SENT,    SYN_TX);
-  aT[SYN_SENT][APP_SEND]    = SA (SYN_SENT,    NO_ACT);
-  aT[SYN_SENT][SEQ_RECV]    = SA (ESTABLISHED, NEW_SEQ_RX);
-  aT[SYN_SENT][APP_CLOSE]   = SA (CLOSED,      RST_TX);
-  aT[SYN_SENT][TIMEOUT]     = SA (CLOSED,      NO_ACT);
-  aT[SYN_SENT][ACK_RX]      = SA (SYN_SENT,    NO_ACT);
-  aT[SYN_SENT][SYN_RX]      = SA (SYN_RCVD,    SYN_ACK_TX);
-  aT[SYN_SENT][SYN_ACK_RX]  = SA (ESTABLISHED, ACK_TX_1);
-  aT[SYN_SENT][FIN_RX]      = SA (CLOSED,      RST_TX);
-  aT[SYN_SENT][FIN_ACK_RX]  = SA (CLOSED,      RST_TX);
-  aT[SYN_SENT][RST_RX]      = SA (CLOSED,      APP_NOTIFY);
-  aT[SYN_SENT][BAD_FLAGS]   = SA (CLOSED,      RST_TX);
-
-  // Syn Recvd State
-  aT[SYN_RCVD][APP_LISTEN]  = SA (CLOSED,      RST_TX);
-  aT[SYN_RCVD][APP_CONNECT] = SA (CLOSED,      RST_TX);
-  aT[SYN_RCVD][APP_SEND]    = SA (CLOSED,      RST_TX);
-  aT[SYN_RCVD][SEQ_RECV]    = SA (ESTABLISHED, NEW_SEQ_RX);
-  aT[SYN_RCVD][APP_CLOSE]   = SA (FIN_WAIT_1,  FIN_TX);
-  aT[SYN_RCVD][TIMEOUT]     = SA (CLOSED,      RST_TX);
-  aT[SYN_RCVD][ACK_RX]      = SA (ESTABLISHED, SERV_NOTIFY);
-  aT[SYN_RCVD][SYN_RX]      = SA (SYN_RCVD,    SYN_ACK_TX);
-  aT[SYN_RCVD][SYN_ACK_RX]  = SA (CLOSED,      RST_TX);
-  aT[SYN_RCVD][FIN_RX]      = SA (CLOSED,      RST_TX);
-  aT[SYN_RCVD][FIN_ACK_RX]  = SA (CLOSE_WAIT,  PEER_CLOSE);
-  aT[SYN_RCVD][RST_RX]      = SA (CLOSED,      CANCEL_TM);
-  aT[SYN_RCVD][BAD_FLAGS]   = SA (CLOSED,      RST_TX);
-
-  // Established State
-  aT[ESTABLISHED][APP_LISTEN] = SA (CLOSED,     RST_TX);
-  aT[ESTABLISHED][APP_CONNECT]= SA (CLOSED,     RST_TX);
-  aT[ESTABLISHED][APP_SEND]   = SA (ESTABLISHED,TX_DATA);
-  aT[ESTABLISHED][SEQ_RECV]   = SA (ESTABLISHED,NEW_SEQ_RX);
-  aT[ESTABLISHED][APP_CLOSE]  = SA (FIN_WAIT_1, FIN_TX);
-  aT[ESTABLISHED][TIMEOUT]    = SA (ESTABLISHED,RETX);
-  aT[ESTABLISHED][ACK_RX]     = SA (ESTABLISHED,NEW_ACK);
-  aT[ESTABLISHED][SYN_RX]     = SA (SYN_RCVD,   SYN_ACK_TX);
-  aT[ESTABLISHED][SYN_ACK_RX] = SA (ESTABLISHED,NO_ACT);
-  aT[ESTABLISHED][FIN_RX]     = SA (CLOSE_WAIT, PEER_CLOSE);
-  aT[ESTABLISHED][FIN_ACK_RX] = SA (CLOSE_WAIT, PEER_CLOSE);
-  aT[ESTABLISHED][RST_RX]     = SA (CLOSED,     CANCEL_TM);
-  aT[ESTABLISHED][BAD_FLAGS]  = SA (CLOSED,     RST_TX);
-
-  // Close Wait State
-  aT[CLOSE_WAIT][APP_LISTEN]  = SA (CLOSED,     RST_TX);
-  aT[CLOSE_WAIT][APP_CONNECT] = SA (SYN_SENT,   SYN_TX);
-  aT[CLOSE_WAIT][APP_SEND]    = SA (CLOSE_WAIT, TX_DATA);
-  aT[CLOSE_WAIT][SEQ_RECV]    = SA (CLOSE_WAIT, NEW_SEQ_RX);
-  aT[CLOSE_WAIT][APP_CLOSE]   = SA (LAST_ACK,   FIN_ACK_TX);
-  aT[CLOSE_WAIT][TIMEOUT]     = SA (CLOSE_WAIT, NO_ACT);
-  aT[CLOSE_WAIT][ACK_RX]      = SA (CLOSE_WAIT, NO_ACT);
-  aT[CLOSE_WAIT][SYN_RX]      = SA (CLOSED,     RST_TX);
-  aT[CLOSE_WAIT][SYN_ACK_RX]  = SA (CLOSED,     RST_TX);
-  aT[CLOSE_WAIT][FIN_RX]      = SA (CLOSE_WAIT, ACK_TX);
-  aT[CLOSE_WAIT][FIN_ACK_RX]  = SA (CLOSE_WAIT, ACK_TX);
-  aT[CLOSE_WAIT][RST_RX]      = SA (CLOSED,     CANCEL_TM);
-  aT[CLOSE_WAIT][BAD_FLAGS]   = SA (CLOSED,     RST_TX);
-
-  // Close Last Ack State
-  aT[LAST_ACK][APP_LISTEN]  = SA (CLOSED,      RST_TX);
-  aT[LAST_ACK][APP_CONNECT] = SA (SYN_SENT,    SYN_TX);
-  aT[LAST_ACK][APP_SEND]    = SA (CLOSED,      RST_TX);
-  aT[LAST_ACK][SEQ_RECV]    = SA (LAST_ACK,    NEW_SEQ_RX);
-  aT[LAST_ACK][APP_CLOSE]   = SA (CLOSED,      NO_ACT);
-  aT[LAST_ACK][TIMEOUT]     = SA (CLOSED,      NO_ACT);
-  aT[LAST_ACK][ACK_RX]      = SA (CLOSED,      APP_CLOSED);
-  aT[LAST_ACK][SYN_RX]      = SA (CLOSED,      RST_TX);
-  aT[LAST_ACK][SYN_ACK_RX]  = SA (CLOSED,      RST_TX);
-  aT[LAST_ACK][FIN_RX]      = SA (LAST_ACK,    FIN_ACK_TX);
-  aT[LAST_ACK][FIN_ACK_RX]  = SA (CLOSED,      NO_ACT);
-  aT[LAST_ACK][RST_RX]      = SA (CLOSED,      CANCEL_TM);
-  aT[LAST_ACK][BAD_FLAGS]   = SA (CLOSED,      RST_TX);
-
-  // FIN_WAIT_1 state
-  aT[FIN_WAIT_1][APP_LISTEN]  = SA (CLOSED,     RST_TX);
-  aT[FIN_WAIT_1][APP_CONNECT] = SA (CLOSED,     RST_TX);
-  aT[FIN_WAIT_1][APP_SEND]    = SA (CLOSED,     RST_TX);
-  aT[FIN_WAIT_1][SEQ_RECV]    = SA (FIN_WAIT_1, NEW_SEQ_RX);
-  aT[FIN_WAIT_1][APP_CLOSE]   = SA (FIN_WAIT_1, NO_ACT);
-  aT[FIN_WAIT_1][TIMEOUT]     = SA (FIN_WAIT_1, NO_ACT);
-  aT[FIN_WAIT_1][ACK_RX]      = SA (FIN_WAIT_2, NEW_ACK);
-  aT[FIN_WAIT_1][SYN_RX]      = SA (CLOSED,     RST_TX);
-  aT[FIN_WAIT_1][SYN_ACK_RX]  = SA (CLOSED,     RST_TX);
-  aT[FIN_WAIT_1][FIN_RX]      = SA (CLOSING,    ACK_TX);
-  aT[FIN_WAIT_1][FIN_ACK_RX]  = SA (TIMED_WAIT, ACK_TX);
-  aT[FIN_WAIT_1][RST_RX]      = SA (CLOSED,     CANCEL_TM);
-  aT[FIN_WAIT_1][BAD_FLAGS]   = SA (CLOSED,     RST_TX);
-
-  // FIN_WAIT_2 state
-  aT[FIN_WAIT_2][APP_LISTEN]  = SA (CLOSED,      RST_TX);
-  aT[FIN_WAIT_2][APP_CONNECT] = SA (CLOSED,      RST_TX);
-  aT[FIN_WAIT_2][APP_SEND]    = SA (CLOSED,      RST_TX);
-  aT[FIN_WAIT_2][SEQ_RECV]    = SA (FIN_WAIT_2,  NEW_SEQ_RX);
-  aT[FIN_WAIT_2][APP_CLOSE]   = SA (FIN_WAIT_2,  NO_ACT);
-  aT[FIN_WAIT_2][TIMEOUT]     = SA (FIN_WAIT_2,  NO_ACT);
-  aT[FIN_WAIT_2][ACK_RX]      = SA (FIN_WAIT_2,  NEW_ACK);
-  aT[FIN_WAIT_2][SYN_RX]      = SA (CLOSED,      RST_TX);
-  aT[FIN_WAIT_2][SYN_ACK_RX]  = SA (CLOSED,      RST_TX);
-  aT[FIN_WAIT_2][FIN_RX]      = SA (TIMED_WAIT,  ACK_TX);
-  aT[FIN_WAIT_2][FIN_ACK_RX]  = SA (TIMED_WAIT,  ACK_TX);
-  aT[FIN_WAIT_2][RST_RX]      = SA (CLOSED,      CANCEL_TM);
-  aT[FIN_WAIT_2][BAD_FLAGS]   = SA (CLOSED,      RST_TX);
-
-  // CLOSING state
-  aT[CLOSING][APP_LISTEN]  = SA (CLOSED,      RST_TX);
-  aT[CLOSING][APP_CONNECT] = SA (CLOSED,      RST_TX);
-  aT[CLOSING][APP_SEND]    = SA (CLOSED,      RST_TX);
-  aT[CLOSING][SEQ_RECV]    = SA (CLOSED,      RST_TX);
-  aT[CLOSING][APP_CLOSE]   = SA (CLOSED,      RST_TX);
-  aT[CLOSING][TIMEOUT]     = SA (CLOSING,     NO_ACT);
-  aT[CLOSING][ACK_RX]      = SA (TIMED_WAIT,  NO_ACT);
-  aT[CLOSING][SYN_RX]      = SA (CLOSED,      RST_TX);
-  aT[CLOSING][SYN_ACK_RX]  = SA (CLOSED,      RST_TX);
-  aT[CLOSING][FIN_RX]      = SA (CLOSED,      ACK_TX);
-  aT[CLOSING][FIN_ACK_RX]  = SA (CLOSED,      ACK_TX);
-  aT[CLOSING][RST_RX]      = SA (CLOSED,      CANCEL_TM);
-  aT[CLOSING][BAD_FLAGS]   = SA (CLOSED,      RST_TX);
-
-  // TIMED_WAIT state
-  aT[TIMED_WAIT][APP_LISTEN]  = SA (TIMED_WAIT, NO_ACT);
-  aT[TIMED_WAIT][APP_CONNECT] = SA (TIMED_WAIT, NO_ACT);
-  aT[TIMED_WAIT][APP_SEND]    = SA (TIMED_WAIT, NO_ACT);
-  aT[TIMED_WAIT][SEQ_RECV]    = SA (TIMED_WAIT, NO_ACT);
-  aT[TIMED_WAIT][APP_CLOSE]   = SA (TIMED_WAIT, NO_ACT);
-  aT[TIMED_WAIT][TIMEOUT]     = SA (TIMED_WAIT, NO_ACT);
-  aT[TIMED_WAIT][ACK_RX]      = SA (TIMED_WAIT, NO_ACT);
-  aT[TIMED_WAIT][SYN_RX]      = SA (TIMED_WAIT, NO_ACT);
-  aT[TIMED_WAIT][SYN_ACK_RX]  = SA (TIMED_WAIT, NO_ACT);
-  aT[TIMED_WAIT][FIN_RX]      = SA (TIMED_WAIT, NO_ACT);
-  aT[TIMED_WAIT][FIN_ACK_RX]  = SA (TIMED_WAIT, NO_ACT);
-  aT[TIMED_WAIT][RST_RX]      = SA (TIMED_WAIT, NO_ACT);
-  aT[TIMED_WAIT][BAD_FLAGS]   = SA (TIMED_WAIT, NO_ACT);
-
-  // Create the flags lookup table
-  eV[ 0x00] = SEQ_RECV;  // No flags
-  eV[ 0x01] = FIN_RX;    // Fin
-  eV[ 0x02] = SYN_RX;    // Syn
-  eV[ 0x03] = BAD_FLAGS; // Illegal
-  eV[ 0x04] = RST_RX;    // Rst
-  eV[ 0x05] = BAD_FLAGS; // Illegal
-  eV[ 0x06] = BAD_FLAGS; // Illegal
-  eV[ 0x07] = BAD_FLAGS; // Illegal
-  eV[ 0x08] = SEQ_RECV;  // Psh flag is not used
-  eV[ 0x09] = FIN_RX;    // Fin
-  eV[ 0x0a] = SYN_RX;    // Syn
-  eV[ 0x0b] = BAD_FLAGS; // Illegal
-  eV[ 0x0c] = RST_RX;    // Rst
-  eV[ 0x0d] = BAD_FLAGS; // Illegal
-  eV[ 0x0e] = BAD_FLAGS; // Illegal
-  eV[ 0x0f] = BAD_FLAGS; // Illegal
-  eV[ 0x10] = ACK_RX;    // Ack
-  eV[ 0x11] = FIN_ACK_RX;// Fin/Ack
-  eV[ 0x12] = SYN_ACK_RX;// Syn/Ack
-  eV[ 0x13] = BAD_FLAGS; // Illegal
-  eV[ 0x14] = RST_RX;    // Rst
-  eV[ 0x15] = BAD_FLAGS; // Illegal
-  eV[ 0x16] = BAD_FLAGS; // Illegal
-  eV[ 0x17] = BAD_FLAGS; // Illegal
-  eV[ 0x18] = ACK_RX;    // Ack
-  eV[ 0x19] = FIN_ACK_RX;// Fin/Ack
-  eV[ 0x1a] = SYN_ACK_RX;// Syn/Ack
-  eV[ 0x1b] = BAD_FLAGS; // Illegal
-  eV[ 0x1c] = RST_RX;    // Rst
-  eV[ 0x1d] = BAD_FLAGS; // Illegal
-  eV[ 0x1e] = BAD_FLAGS; // Illegal
-  eV[ 0x1f] = BAD_FLAGS; // Illegal
-  eV[ 0x20] = SEQ_RECV;  // No flags (Urgent not presently used)
-  eV[ 0x21] = FIN_RX;    // Fin
-  eV[ 0x22] = SYN_RX;    // Syn
-  eV[ 0x23] = BAD_FLAGS; // Illegal
-  eV[ 0x24] = RST_RX;    // Rst
-  eV[ 0x25] = BAD_FLAGS; // Illegal
-  eV[ 0x26] = BAD_FLAGS; // Illegal
-  eV[ 0x27] = BAD_FLAGS; // Illegal
-  eV[ 0x28] = SEQ_RECV;  // Psh flag is not used
-  eV[ 0x29] = FIN_RX;    // Fin
-  eV[ 0x2a] = SYN_RX;    // Syn
-  eV[ 0x2b] = BAD_FLAGS; // Illegal
-  eV[ 0x2c] = RST_RX;    // Rst
-  eV[ 0x2d] = BAD_FLAGS; // Illegal
-  eV[ 0x2e] = BAD_FLAGS; // Illegal
-  eV[ 0x2f] = BAD_FLAGS; // Illegal
-  eV[ 0x30] = ACK_RX;    // Ack (Urgent not used)
-  eV[ 0x31] = FIN_ACK_RX;// Fin/Ack
-  eV[ 0x32] = SYN_ACK_RX;// Syn/Ack
-  eV[ 0x33] = BAD_FLAGS; // Illegal
-  eV[ 0x34] = RST_RX;    // Rst
-  eV[ 0x35] = BAD_FLAGS; // Illegal
-  eV[ 0x36] = BAD_FLAGS; // Illegal
-  eV[ 0x37] = BAD_FLAGS; // Illegal
-  eV[ 0x38] = ACK_RX;    // Ack
-  eV[ 0x39] = FIN_ACK_RX;// Fin/Ack
-  eV[ 0x3a] = SYN_ACK_RX;// Syn/Ack
-  eV[ 0x3b] = BAD_FLAGS; // Illegal
-  eV[ 0x3c] = RST_RX;    // Rst
-  eV[ 0x3d] = BAD_FLAGS; // Illegal
-  eV[ 0x3e] = BAD_FLAGS; // Illegal
-  eV[ 0x3f] = BAD_FLAGS; // Illegal
-}
-
-SA TcpStateMachine::Lookup (States_t s, Events_t e)
-{
-  NS_LOG_FUNCTION (this << s << e);
-  return aT[s][e];
-}
-
-Events_t TcpStateMachine::FlagsEvent (uint8_t f)
-{ 
-  NS_LOG_FUNCTION (this << f);
-  // Lookup event from flags
-  if (f >= MAX_FLAGS) return BAD_FLAGS;
-  return eV[f]; // Look up flags event
-}
-
-static TcpStateMachine tcpStateMachine; //only instance of a TcpStateMachine
-
-//TcpL4Protocol stuff----------------------------------------------------------
-
-
-/* see http://www.iana.org/assignments/protocol-numbers */
-const uint8_t TcpL4Protocol::PROT_NUMBER = 6;
-
-ObjectFactory
-TcpL4Protocol::GetDefaultRttEstimatorFactory (void)
-{
-  ObjectFactory factory;
-  factory.SetTypeId (RttMeanDeviation::GetTypeId ());
-  return factory;
-}
-
-TypeId 
-TcpL4Protocol::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::TcpL4Protocol")
-    .SetParent<Ipv4L4Protocol> ()
-    .AddAttribute ("RttEstimatorFactory",
-                   "How RttEstimator objects are created.",
-                   ObjectFactoryValue (GetDefaultRttEstimatorFactory ()),
-                   MakeObjectFactoryAccessor (&TcpL4Protocol::m_rttFactory),
-                   MakeObjectFactoryChecker ())
-    ;
-  return tid;
-}
-
-TcpL4Protocol::TcpL4Protocol ()
-  : m_endPoints (new Ipv4EndPointDemux ())
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  NS_LOG_LOGIC("Made a TcpL4Protocol "<<this);
-}
-
-TcpL4Protocol::~TcpL4Protocol ()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-}
-
-void 
-TcpL4Protocol::SetNode (Ptr<Node> node)
-{
-  m_node = node;
-}
-
-int 
-TcpL4Protocol::GetProtocolNumber (void) const
-{
-  return PROT_NUMBER;
-}
-int 
-TcpL4Protocol::GetVersion (void) const
-{
-  return 2;
-}
-
-void
-TcpL4Protocol::DoDispose (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  if (m_endPoints != 0)
-    {
-      delete m_endPoints;
-      m_endPoints = 0;
-    }
-  m_node = 0;
-  Ipv4L4Protocol::DoDispose ();
-}
-
-Ptr<Socket>
-TcpL4Protocol::CreateSocket (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  Ptr<RttEstimator> rtt = m_rttFactory.Create<RttEstimator> ();
-  Ptr<TcpSocketImpl> socket = CreateObject<TcpSocketImpl> ();
-  socket->SetNode (m_node);
-  socket->SetTcp (this);
-  socket->SetRtt (rtt);
-  return socket;
-}
-
-Ipv4EndPoint *
-TcpL4Protocol::Allocate (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_endPoints->Allocate ();
-}
-
-Ipv4EndPoint *
-TcpL4Protocol::Allocate (Ipv4Address address)
-{
-  NS_LOG_FUNCTION (this << address);
-  return m_endPoints->Allocate (address);
-}
-
-Ipv4EndPoint *
-TcpL4Protocol::Allocate (uint16_t port)
-{
-  NS_LOG_FUNCTION (this << port);
-  return m_endPoints->Allocate (port);
-}
-
-Ipv4EndPoint *
-TcpL4Protocol::Allocate (Ipv4Address address, uint16_t port)
-{
-  NS_LOG_FUNCTION (this << address << port);
-  return m_endPoints->Allocate (address, port);
-}
-
-Ipv4EndPoint *
-TcpL4Protocol::Allocate (Ipv4Address localAddress, uint16_t localPort,
-                         Ipv4Address peerAddress, uint16_t peerPort)
-{
-  NS_LOG_FUNCTION (this << localAddress << localPort << peerAddress << peerPort);
-  return m_endPoints->Allocate (localAddress, localPort,
-                                peerAddress, peerPort);
-}
-
-void 
-TcpL4Protocol::DeAllocate (Ipv4EndPoint *endPoint)
-{
-  NS_LOG_FUNCTION (this << endPoint);
-  m_endPoints->DeAllocate (endPoint);
-}
-
-void 
-TcpL4Protocol::Receive (Ptr<Packet> packet,
-             Ipv4Address const &source,
-             Ipv4Address const &destination,
-             Ptr<Ipv4Interface> incomingInterface)
-{
-  NS_LOG_FUNCTION (this << packet << source << destination << incomingInterface);
-
-  TcpHeader tcpHeader;
-  //these two do a peek, so that the packet can be forwarded up
-  packet->RemoveHeader (tcpHeader);
-  NS_LOG_LOGIC("TcpL4Protocol " << this
-               << " receiving seq " << tcpHeader.GetSequenceNumber()
-               << " ack " << tcpHeader.GetAckNumber()
-               << " flags "<< std::hex << (int)tcpHeader.GetFlags() << std::dec
-               << " data size " << packet->GetSize());
-  packet->AddHeader (tcpHeader); 
-  NS_LOG_LOGIC ("TcpL4Protocol "<<this<<" received a packet");
-  Ipv4EndPointDemux::EndPoints endPoints =
-    m_endPoints->Lookup (destination, tcpHeader.GetDestinationPort (),
-                         source, tcpHeader.GetSourcePort (),incomingInterface);
-  if (endPoints.empty ())
-  {
-    NS_LOG_LOGIC ("  No endpoints matched on TcpL4Protocol "<<this);
-    std::ostringstream oss;
-    oss<<"  destination IP: ";
-    destination.Print (oss);
-    oss<<" destination port: "<< tcpHeader.GetDestinationPort ()<<" source IP: ";
-    source.Print (oss);
-    oss<<" source port: "<<tcpHeader.GetSourcePort ();
-    NS_LOG_LOGIC (oss.str ());
-    return;
-  }
-  NS_ASSERT_MSG (endPoints.size() == 1 , "Demux returned more than one endpoint");
-  NS_LOG_LOGIC ("TcpL4Protocol "<<this<<" forwarding up to endpoint/socket");
-  (*endPoints.begin ())->ForwardUp (packet, source, tcpHeader.GetSourcePort ());
-}
-
-void
-TcpL4Protocol::Send (Ptr<Packet> packet, 
-           Ipv4Address saddr, Ipv4Address daddr, 
-           uint16_t sport, uint16_t dport)
-{
-  NS_LOG_FUNCTION (this << packet << saddr << daddr << sport << dport);
-
-  TcpHeader tcpHeader;
-  tcpHeader.SetDestinationPort (dport);
-  tcpHeader.SetSourcePort (sport);
-  tcpHeader.InitializeChecksum (saddr,
-                               daddr,
-                               PROT_NUMBER);
-  tcpHeader.SetFlags (TcpHeader::ACK);
-  tcpHeader.SetAckNumber (0);
-
-  packet->AddHeader (tcpHeader);
-
-  Ptr<Ipv4L3Protocol> ipv4 = 
-    m_node->GetObject<Ipv4L3Protocol> ();
-  if (ipv4 != 0)
-    {
-      ipv4->Send (packet, saddr, daddr, PROT_NUMBER);
-    }
-}
-
-void
-TcpL4Protocol::SendPacket (Ptr<Packet> packet, TcpHeader outgoingHeader,
-                               Ipv4Address saddr, Ipv4Address daddr)
-{
-  NS_LOG_LOGIC("TcpL4Protocol " << this
-              << " sending seq " << outgoingHeader.GetSequenceNumber()
-              << " ack " << outgoingHeader.GetAckNumber()
-              << " flags " << std::hex << (int)outgoingHeader.GetFlags() << std::dec
-              << " data size " << packet->GetSize());
-  NS_LOG_FUNCTION (this << packet << saddr << daddr);
-  // XXX outgoingHeader cannot be logged
-
-  outgoingHeader.SetLength (5); //header length in units of 32bit words
-  outgoingHeader.SetChecksum (0);  //XXX
-  outgoingHeader.SetUrgentPointer (0); //XXX
-
-  packet->AddHeader (outgoingHeader);
-
-  Ptr<Ipv4L3Protocol> ipv4 = 
-    m_node->GetObject<Ipv4L3Protocol> ();
-  if (ipv4 != 0)
-    {
-      ipv4->Send (packet, saddr, daddr, PROT_NUMBER);
-    }
-  else
-    NS_FATAL_ERROR("Trying to use Tcp on a node without an Ipv4 interface");
-}
-
-}; // namespace ns3
-
--- a/src/internet-node/tcp-l4-protocol.h	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,117 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 Georgia Tech Research Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Raj Bhattacharjea <raj.b@gatech.edu>
- */
-
-#ifndef TCP_L4_PROTOCOL_H
-#define TCP_L4_PROTOCOL_H
-
-#include <stdint.h>
-
-#include "ns3/packet.h"
-#include "ns3/ipv4-address.h"
-#include "ns3/ptr.h"
-#include "ns3/object-factory.h"
-#include "ipv4-end-point-demux.h"
-#include "ipv4-l4-protocol.h"
-#include "ipv4-interface.h"
-
-#include "tcp-header.h"
-#include "tcp-typedefs.h"
-
-namespace ns3 {
-
-class Node;
-class Socket;
-class TcpHeader;
-/**
- * \brief Implementation of the TCP protocol
- */
-class TcpL4Protocol : public Ipv4L4Protocol {
-public:
-  static TypeId GetTypeId (void);
-  static const uint8_t PROT_NUMBER;
-  /**
-   * \brief Constructor
-   */
-  TcpL4Protocol ();
-  virtual ~TcpL4Protocol ();
-
-  void SetNode (Ptr<Node> node);
-
-  virtual int GetProtocolNumber (void) const;
-  virtual int GetVersion (void) const;
-
-  /**
-   * \return A smart Socket pointer to a TcpSocketImpl, allocated by this instance
-   * of the TCP 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 TcpSocketImpl.
-//   bool Connect (const Ipv4Address& saddr, const Ipv4Address& daddr,
-//                 uint16_t sport, uint16_t dport);
-
-  /**
-   * \brief Send a packet via TCP
-   * \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 (Ptr<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
-   * \param incomingInterface The Ipv4Interface it was received on
-   */
-  virtual void Receive (Ptr<Packet> p,
-                       Ipv4Address const &source,
-                       Ipv4Address const &destination,
-                       Ptr<Ipv4Interface> incomingInterface);
-
-protected:
-  virtual void DoDispose (void);
-private:
-  Ptr<Node> m_node;
-  Ipv4EndPointDemux *m_endPoints;
-  ObjectFactory m_rttFactory;
-private:
-  friend class TcpSocketImpl;
-  void SendPacket (Ptr<Packet>, TcpHeader,
-                  Ipv4Address, Ipv4Address);
-  static ObjectFactory GetDefaultRttEstimatorFactory (void);
-};
-
-}; // namespace ns3
-
-#endif /* TCP_L4_PROTOCOL_H */
--- a/src/internet-node/tcp-socket-factory-impl.cc	Wed Jun 11 16:19:28 2008 -0700
+++ /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) 2007 Georgia Tech Research Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Raj Bhattacharjea <raj.b@gatech.edu>
- */
-#include "tcp-socket-factory-impl.h"
-#include "tcp-l4-protocol.h"
-#include "ns3/socket.h"
-#include "ns3/assert.h"
-
-namespace ns3 {
-
-TcpSocketFactoryImpl::TcpSocketFactoryImpl ()
-  : m_tcp (0)
-{}
-TcpSocketFactoryImpl::~TcpSocketFactoryImpl ()
-{
-  NS_ASSERT (m_tcp == 0);
-}
-
-void 
-TcpSocketFactoryImpl::SetTcp (Ptr<TcpL4Protocol> tcp)
-{
-  m_tcp = tcp;
-}
-
-Ptr<Socket>
-TcpSocketFactoryImpl::CreateSocket (void)
-{
-  return m_tcp->CreateSocket ();
-}
-
-void 
-TcpSocketFactoryImpl::DoDispose (void)
-{
-  m_tcp = 0;
-  TcpSocketFactory::DoDispose ();
-}
-
-} // namespace ns3
--- a/src/internet-node/tcp-socket-factory-impl.h	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 Georgia Tech Research Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Raj Bhattacharjea <raj.b@gatech.edu>
- */
-#ifndef TCP_SOCKET_FACTORY_IMPL_H
-#define TCP_SOCKET_FACTORY_IMPL_H
-
-#include "ns3/tcp-socket-factory.h"
-#include "ns3/ptr.h"
-
-namespace ns3 {
-
-class TcpL4Protocol;
-
-/**
- * \ingroup internetNode
- * \defgroup Tcp Tcp
- */
-/**
- * \ingroup Tcp
- * \section Tcp Overview
- *
- * The TCP code in ns3::InternetNode is ported from the  
- * <a href="http://www.ece.gatech.edu/research/labs/MANIACS/GTNetS/">
- * Georgia Tech Network Simulator (GTNetS)</a>.
- * 
- * Most of the logic is in class ns3::TcpSocketImpl.
- */
-class TcpSocketFactoryImpl : public TcpSocketFactory
-{
-public:
-  TcpSocketFactoryImpl ();
-  virtual ~TcpSocketFactoryImpl ();
-
-  void SetTcp (Ptr<TcpL4Protocol> tcp);
-
-  virtual Ptr<Socket> CreateSocket (void);
-
-protected:
-  virtual void DoDispose (void);
-private:
-  Ptr<TcpL4Protocol> m_tcp;
-};
-
-} // namespace ns3
-
-#endif /* TCP_SOCKET_FACTORY_IMPL_H */
--- a/src/internet-node/tcp-socket-impl.cc	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1435 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 Georgia Tech Research Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Raj Bhattacharjea <raj.b@gatech.edu>
- */
-
-
-#include "ns3/node.h"
-#include "ns3/inet-socket-address.h"
-#include "ns3/log.h"
-#include "ns3/ipv4.h"
-#include "tcp-socket-impl.h"
-#include "tcp-l4-protocol.h"
-#include "ipv4-end-point.h"
-#include "ipv4-l4-demux.h"
-#include "ns3/simulation-singleton.h"
-#include "tcp-typedefs.h"
-#include "ns3/simulator.h"
-#include "ns3/packet.h"
-#include "ns3/uinteger.h"
-#include "ns3/trace-source-accessor.h"
-
-#include <algorithm>
-
-NS_LOG_COMPONENT_DEFINE ("TcpSocketImpl");
-
-using namespace std;
-
-namespace ns3 {
-
-NS_OBJECT_ENSURE_REGISTERED (TcpSocketImpl);
-
-TypeId
-TcpSocketImpl::GetTypeId ()
-{
-  static TypeId tid = TypeId("ns3::TcpSocketImpl")
-    .SetParent<TcpSocket> ()
-    .AddTraceSource ("CongestionWindow",
-                     "The TCP connection's congestion window",
-                     MakeTraceSourceAccessor (&TcpSocketImpl::m_cWnd))
-    ;
-  return tid;
-}
-
-  TcpSocketImpl::TcpSocketImpl ()
-  : m_skipRetxResched (false),
-    m_dupAckCount (0),
-    m_delAckCount (0),
-    m_endPoint (0),
-    m_node (0),
-    m_tcp (0),
-    m_errno (ERROR_NOTERROR),
-    m_shutdownSend (false),
-    m_shutdownRecv (false),
-    m_connected (false),
-    m_state (CLOSED),
-    m_closeNotified (false),
-    m_closeRequestNotified (false),
-    m_closeOnEmpty (false),
-    m_pendingClose (false),
-    m_nextTxSequence (0),
-    m_highTxMark (0),
-    m_highestRxAck (0),
-    m_lastRxAck (0),
-    m_nextRxSequence (0),
-    m_pendingData (0),
-    m_rtt (0),
-    m_lastMeasuredRtt (Seconds(0.0)),
-    m_rxAvailable (0), 
-    m_wouldBlock (false) 
-{
-  NS_LOG_FUNCTION (this);
-}
-
-TcpSocketImpl::TcpSocketImpl(const TcpSocketImpl& sock)
-  : TcpSocket(sock), //copy the base class callbacks
-    m_skipRetxResched (sock.m_skipRetxResched),
-    m_dupAckCount (sock.m_dupAckCount),
-    m_delAckCount (0),
-    m_delAckMaxCount (sock.m_delAckMaxCount),
-    m_delAckTimeout (sock.m_delAckTimeout),
-    m_endPoint (0),
-    m_node (sock.m_node),
-    m_tcp (sock.m_tcp),
-    m_remoteAddress (sock.m_remoteAddress),
-    m_remotePort (sock.m_remotePort),
-    m_localAddress (sock.m_localAddress),
-    m_localPort (sock.m_localPort),
-    m_errno (sock.m_errno),
-    m_shutdownSend (sock.m_shutdownSend),
-    m_shutdownRecv (sock.m_shutdownRecv),
-    m_connected (sock.m_connected),
-    m_state (sock.m_state),
-    m_closeNotified (sock.m_closeNotified),
-    m_closeRequestNotified (sock.m_closeRequestNotified),
-    m_closeOnEmpty (sock.m_closeOnEmpty),
-    m_pendingClose (sock.m_pendingClose),
-    m_nextTxSequence (sock.m_nextTxSequence),
-    m_highTxMark (sock.m_highTxMark),
-    m_highestRxAck (sock.m_highestRxAck),
-    m_lastRxAck (sock.m_lastRxAck),
-    m_nextRxSequence (sock.m_nextRxSequence),
-    m_pendingData (0),
-    m_segmentSize (sock.m_segmentSize),
-    m_rxWindowSize (sock.m_rxWindowSize),
-    m_advertisedWindowSize (sock.m_advertisedWindowSize),
-    m_cWnd (sock.m_cWnd),
-    m_ssThresh (sock.m_ssThresh),
-    m_initialCWnd (sock.m_initialCWnd),
-    m_rtt (0),
-    m_lastMeasuredRtt (Seconds(0.0)),
-    m_cnTimeout (sock.m_cnTimeout),
-    m_cnCount (sock.m_cnCount),
-    m_rxAvailable (0),
-    m_wouldBlock (false),
-    m_sndBufSize (sock.m_sndBufSize)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  NS_LOG_LOGIC("Invoked the copy constructor");
-  //copy the pending data if necessary
-  if(sock.m_pendingData)
-    {
-      m_pendingData = sock.m_pendingData->Copy();
-    }
-  //copy the rtt if necessary
-  if (sock.m_rtt)
-    {
-      m_rtt = sock.m_rtt->Copy();
-    }
-  //can't "copy" the endpoint just yes, must do this when we know the peer info
-  //too; this is in SYN_ACK_TX
-}
-
-TcpSocketImpl::~TcpSocketImpl ()
-{
-  NS_LOG_FUNCTION(this);
-  m_node = 0;
-  if (m_endPoint != 0)
-    {
-      NS_ASSERT (m_tcp != 0);
-      /**
-       * Note that this piece of code is a bit tricky:
-       * when DeAllocate is called, it will call into
-       * Ipv4EndPointDemux::Deallocate which triggers
-       * a delete of the associated endPoint which triggers
-       * in turn a call to the method ::Destroy below
-       * will will zero the m_endPoint field.
-       */
-      NS_ASSERT (m_endPoint != 0);
-      m_tcp->DeAllocate (m_endPoint);
-      NS_ASSERT (m_endPoint == 0);
-    }
-  m_tcp = 0;
-  delete m_pendingData; //prevents leak
-  m_pendingData = 0;
-}
-
-void
-TcpSocketImpl::SetNode (Ptr<Node> node)
-{
-  m_node = node;
-  // Initialize some variables 
-  m_cWnd = m_initialCWnd * m_segmentSize;
-  m_rxWindowSize = m_advertisedWindowSize;
-}
-
-void 
-TcpSocketImpl::SetTcp (Ptr<TcpL4Protocol> tcp)
-{
-  m_tcp = tcp;
-}
-void 
-TcpSocketImpl::SetRtt (Ptr<RttEstimator> rtt)
-{
-  m_rtt = rtt;
-}
-
-
-enum Socket::SocketErrno
-TcpSocketImpl::GetErrno (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_errno;
-}
-
-Ptr<Node>
-TcpSocketImpl::GetNode (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_node;
-}
-
-void 
-TcpSocketImpl::Destroy (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_node = 0;
-  m_endPoint = 0;
-  m_tcp = 0;
-  m_retxEvent.Cancel ();
-}
-int
-TcpSocketImpl::FinishBind (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  if (m_endPoint == 0)
-    {
-      return -1;
-    }
-  m_endPoint->SetRxCallback (MakeCallback (&TcpSocketImpl::ForwardUp, Ptr<TcpSocketImpl>(this)));
-  m_endPoint->SetDestroyCallback (MakeCallback (&TcpSocketImpl::Destroy, Ptr<TcpSocketImpl>(this)));
-  m_localAddress = m_endPoint->GetLocalAddress ();
-  m_localPort = m_endPoint->GetLocalPort ();
-  return 0;
-}
-
-int
-TcpSocketImpl::Bind (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_endPoint = m_tcp->Allocate ();
-  return FinishBind ();
-}
-int 
-TcpSocketImpl::Bind (const Address &address)
-{
-  NS_LOG_FUNCTION (this<<address);
-  if (!InetSocketAddress::IsMatchingType (address))
-    {
-      return ERROR_INVAL;
-    }
-  InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
-  Ipv4Address ipv4 = transport.GetIpv4 ();
-  uint16_t port = transport.GetPort ();
-  if (ipv4 == Ipv4Address::GetAny () && port == 0)
-    {
-      m_endPoint = m_tcp->Allocate ();
-      NS_LOG_LOGIC ("TcpSocketImpl "<<this<<" got an endpoint: "<<m_endPoint);
-    }
-  else if (ipv4 == Ipv4Address::GetAny () && port != 0)
-    {
-      m_endPoint = m_tcp->Allocate (port);
-      NS_LOG_LOGIC ("TcpSocketImpl "<<this<<" got an endpoint: "<<m_endPoint);
-    }
-  else if (ipv4 != Ipv4Address::GetAny () && port == 0)
-    {
-      m_endPoint = m_tcp->Allocate (ipv4);
-      NS_LOG_LOGIC ("TcpSocketImpl "<<this<<" got an endpoint: "<<m_endPoint);
-    }
-  else if (ipv4 != Ipv4Address::GetAny () && port != 0)
-    {
-      m_endPoint = m_tcp->Allocate (ipv4, port);
-      NS_LOG_LOGIC ("TcpSocketImpl "<<this<<" got an endpoint: "<<m_endPoint);
-    }
-
-  return FinishBind ();
-}
-
-int 
-TcpSocketImpl::ShutdownSend (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_shutdownSend = true;
-  return 0;
-}
-int 
-TcpSocketImpl::ShutdownRecv (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_shutdownRecv = false;
-  return 0;
-}
-
-int
-TcpSocketImpl::Close (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  if (m_state == CLOSED) 
-    {
-      return -1;
-    }
-  if (m_pendingData && m_pendingData->Size() != 0)
-    { // App close with pending data must wait until all data transmitted
-      m_closeOnEmpty = true;
-      NS_LOG_LOGIC("Socket " << this << 
-                   " deferring close, state " << m_state);
-      return 0;
-    }
-
-  Actions_t action  = ProcessEvent (APP_CLOSE);
-  ProcessAction (action);
-  ShutdownSend ();
-  return 0;
-}
-
-int
-TcpSocketImpl::Connect (const Address & address)
-{
-  NS_LOG_FUNCTION (this << address);
-  if (m_endPoint == 0)
-    {
-      if (Bind () == -1)
-        {
-          NS_ASSERT (m_endPoint == 0);
-          return -1;
-        }
-      NS_ASSERT (m_endPoint != 0);
-    }
-  InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
-  m_remoteAddress = transport.GetIpv4 ();
-  m_remotePort = transport.GetPort ();
-  
-  uint32_t localIfIndex;
-  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
-
-  if (ipv4->GetIfIndexForDestination (m_remoteAddress, localIfIndex))
-    {
-      m_endPoint->SetLocalAddress (ipv4->GetAddress (localIfIndex));
-    }
-  else
-    {
-      m_errno = ERROR_NOROUTETOHOST;
-      return -1;
-    }
-
-  Actions_t action = ProcessEvent (APP_CONNECT);
-  bool success = ProcessAction (action);
-  if (success) 
-    {
-      return 0;
-    }
-  return -1;
-}
-int 
-TcpSocketImpl::Send (const Ptr<Packet> p) //p here is just data, no headers
-{ // TCP Does not deal with packets from app, just data
-  return Send(p->PeekData(), p->GetSize());
-}
-
-int TcpSocketImpl::Send (const uint8_t* buf, uint32_t size)
-{
-  NS_LOG_FUNCTION (this << buf << size);
-  if (m_state == ESTABLISHED || m_state == SYN_SENT || m_state == CLOSE_WAIT)
-    { 
-      if (size > GetTxAvailable ())
-        {
-          m_wouldBlock = true;
-          m_errno = ERROR_MSGSIZE;
-          return -1;
-        }
-      if (!m_pendingData)
-        {
-          m_pendingData = new PendingData ();   // Create if non-existent
-          m_firstPendingSequence = m_nextTxSequence; // Note seq of first
-        }
-      //PendingData::Add always copies the data buffer, never modifies
-      m_pendingData->Add (size,buf);
-      NS_LOG_DEBUG("TcpSock::Send, pdsize " << m_pendingData->Size() << 
-                   " state " << m_state);
-      Actions_t action = ProcessEvent (APP_SEND);
-      NS_LOG_DEBUG(" action " << action);
-      if (!ProcessAction (action)) 
-        {
-          return -1; // Failed, return zero
-        }
-      return size;
-    }
-  else
-  {
-    m_errno = ERROR_NOTCONN;
-    return -1;
-  }
-}
-
-int TcpSocketImpl::DoSendTo (Ptr<Packet> p, const Address &address)
-{
-  NS_LOG_FUNCTION (this << p << address);
-  InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
-  Ipv4Address ipv4 = transport.GetIpv4 ();
-  uint16_t port = transport.GetPort ();
-  return DoSendTo (p, ipv4, port);
-}
-
-int TcpSocketImpl::DoSendTo (Ptr<Packet> p, Ipv4Address ipv4, uint16_t port)
-{
-  NS_LOG_FUNCTION (this << p << ipv4 << port);
-  if (m_endPoint == 0)
-    {
-      if (Bind () == -1)
-	{
-          NS_ASSERT (m_endPoint == 0);
-	  return -1;
-	}
-      NS_ASSERT (m_endPoint != 0);
-    }
-  if (m_shutdownSend)
-    {
-      m_errno = ERROR_SHUTDOWN;
-      return -1;
-    }
-  m_tcp->Send (p, m_endPoint->GetLocalAddress (), ipv4,
-                  m_endPoint->GetLocalPort (), port);
-  NotifyDataSent (p->GetSize ());
-  return 0;
-}
-
-int 
-TcpSocketImpl::SendTo (Ptr<Packet> p, const Address &address)
-{
-  NS_LOG_FUNCTION (this << address << p);
-  if (!m_connected)
-    {
-      m_errno = ERROR_NOTCONN;
-      return -1;
-    }
-  else
-    {
-      return Send (p); //drop the address according to BSD manpages
-    }
-}
-
-uint32_t
-TcpSocketImpl::GetTxAvailable (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  if (m_pendingData != 0)
-    {
-      uint32_t unAckedDataSize = 
-        m_pendingData->SizeFromSeq (m_firstPendingSequence, m_highestRxAck);
-      NS_ASSERT (m_sndBufSize >= unAckedDataSize); //else a logical error
-      return m_sndBufSize-unAckedDataSize;
-    }
-  else
-    {
-      return m_sndBufSize;
-    }
-}
-
-int
-TcpSocketImpl::Listen (uint32_t q)
-{
-  NS_LOG_FUNCTION (this << q);
-  Actions_t action = ProcessEvent (APP_LISTEN);
-  ProcessAction (action);
-  return 0;
-}
-
-Ptr<Packet>
-TcpSocketImpl::Recv (uint32_t maxSize, uint32_t flags)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  if (m_deliveryQueue.empty() )
-    {
-      return 0;
-    }
-  Ptr<Packet> p = m_deliveryQueue.front ();
-  if (p->GetSize () <= maxSize)
-    {
-      m_deliveryQueue.pop ();
-      m_rxAvailable -= p->GetSize ();
-    }
-  else
-    {
-      p = 0;
-    }
-  return p;
-}
-
-uint32_t
-TcpSocketImpl::GetRxAvailable (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  // We separately maintain this state to avoid walking the queue 
-  // every time this might be called
-  return m_rxAvailable;
-}
-
-void
-TcpSocketImpl::ForwardUp (Ptr<Packet> packet, Ipv4Address ipv4, uint16_t port)
-{
-  NS_LOG_DEBUG("Socket " << this << " got forward up" <<
-               " dport " << m_endPoint->GetLocalPort() <<
-               " daddr " << m_endPoint->GetLocalAddress() <<
-               " sport " << m_endPoint->GetPeerPort() <<
-               " saddr " << m_endPoint->GetPeerAddress());
-
-  NS_LOG_FUNCTION (this << packet << ipv4 << port);
-  if (m_shutdownRecv)
-    {
-      return;
-    }
-  TcpHeader tcpHeader;
-  packet->RemoveHeader (tcpHeader);
-
-  if (tcpHeader.GetFlags () & TcpHeader::ACK)
-    {
-      Time m = m_rtt->AckSeq (tcpHeader.GetAckNumber () );
-      if (m != Seconds (0.0))
-        {
-          m_lastMeasuredRtt = m;
-        }
-    }
-
-  Events_t event = SimulationSingleton<TcpStateMachine>::Get ()->FlagsEvent (tcpHeader.GetFlags () );
-  Actions_t action = ProcessEvent (event); //updates the state
-  Address address = InetSocketAddress (ipv4, port);
-  NS_LOG_DEBUG("Socket " << this << 
-               " processing pkt action, " << action <<
-               " current state " << m_state);
-  ProcessPacketAction (action, packet, tcpHeader, address);
-}
-
-Actions_t TcpSocketImpl::ProcessEvent (Events_t e)
-{
-  NS_LOG_FUNCTION (this << e);
-  States_t saveState = m_state;
-  NS_LOG_LOGIC ("TcpSocketImpl " << this << " processing event " << e);
-  // simulation singleton is a way to get a single global static instance of a
-  // class intended to be a singleton; see simulation-singleton.h
-  SA stateAction = SimulationSingleton<TcpStateMachine>::Get ()->Lookup (m_state,e);
-  // debug
-  if (stateAction.action == RST_TX)
-    {
-      NS_LOG_LOGIC ("TcpSocketImpl " << this << " sending RST from state "
-              << saveState << " event " << e);
-    }
-  bool needCloseNotify = (stateAction.state == CLOSED && m_state != CLOSED 
-    && e != TIMEOUT);
-  m_state = stateAction.state;
-  NS_LOG_LOGIC ("TcpSocketImpl " << this << " moved from state " << saveState 
-    << " to state " <<m_state);
-  NS_LOG_LOGIC ("TcpSocketImpl " << this << " pendingData " << m_pendingData);
-
-  //extra event logic is here for RX events
-  //e = SYN_ACK_RX
-  if (saveState == SYN_SENT && m_state == ESTABLISHED)
-    // this means the application side has completed its portion of 
-    // the handshaking
-    {
-      Simulator::ScheduleNow(&TcpSocketImpl::ConnectionSucceeded, this);
-      //NotifyConnectionSucceeded ();
-      m_connected = true;
-      m_endPoint->SetPeer (m_remoteAddress, m_remotePort);
-      NS_LOG_LOGIC ("TcpSocketImpl " << this << " Connected!");
-    }
-
-  if (needCloseNotify && !m_closeNotified)
-    {
-      NS_LOG_LOGIC ("TcpSocketImpl " << this << " transition to CLOSED from " 
-               << m_state << " event " << e << " closeNot " << m_closeNotified
-               << " action " << stateAction.action);
-      NotifyCloseCompleted ();
-      m_closeNotified = true;
-      NS_LOG_LOGIC ("TcpSocketImpl " << this << " calling Closed from PE"
-              << " origState " << saveState
-              << " event " << e);
-      NS_LOG_LOGIC ("TcpSocketImpl " << this << " transition to CLOSED from "
-          << m_state << " event " << e
-          << " set CloseNotif ");
-    }
-  return stateAction.action;
-}
-
-void TcpSocketImpl::SendEmptyPacket (uint8_t flags)
-{
-  NS_LOG_FUNCTION (this << flags);
-  Ptr<Packet> p = Create<Packet> ();
-  TcpHeader header;
-
-  header.SetFlags (flags);
-  header.SetSequenceNumber (m_nextTxSequence);
-  header.SetAckNumber (m_nextRxSequence);
-  header.SetSourcePort (m_endPoint->GetLocalPort ());
-  header.SetDestinationPort (m_remotePort);
-  header.SetWindowSize (m_advertisedWindowSize);
-  m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (), 
-    m_remoteAddress);
-  Time rto = m_rtt->RetransmitTimeout ();
-  if (flags & TcpHeader::SYN)
-    {
-      rto = m_cnTimeout;
-      m_cnTimeout = m_cnTimeout + m_cnTimeout;
-      m_cnCount--;
-    }
-  if (m_retxEvent.IsExpired () ) //no outstanding timer
-  {
-    NS_LOG_LOGIC ("Schedule retransmission timeout at time " 
-          << Simulator::Now ().GetSeconds () << " to expire at time " 
-          << (Simulator::Now () + rto).GetSeconds ());
-    m_retxEvent = Simulator::Schedule (rto, &TcpSocketImpl::ReTxTimeout, this);
-  }
-}
-
-bool TcpSocketImpl::ProcessAction (Actions_t a)
-{ // These actions do not require a packet or any TCP Headers
-  NS_LOG_FUNCTION (this << a);
-  switch (a)
-  {
-    case NO_ACT:
-      NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action: NO_ACT");
-      break;
-    case ACK_TX:
-      SendEmptyPacket (TcpHeader::ACK);
-      break;
-    case ACK_TX_1:
-      NS_ASSERT (false); // This should be processed in ProcessPacketAction
-      break;
-    case RST_TX:
-      NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action RST_TX");
-      SendEmptyPacket (TcpHeader::RST);
-      break;
-    case SYN_TX:
-      NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action SYN_TX");
-      // TCP SYN Flag consumes one byte
-      // is the above correct? we're SENDING a syn, not acking back -- Raj
-      // commented out for now
-      // m_nextTxSequence+= 1;
-      SendEmptyPacket (TcpHeader::SYN);
-      break;
-    case SYN_ACK_TX:
-      NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action SYN_ACK_TX");
-      // TCP SYN Flag consumes one byte
-      ++m_nextRxSequence;
-      SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK);
-      break;
-    case FIN_TX:
-      NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action FIN_TX");
-      SendEmptyPacket (TcpHeader::FIN);
-      break;
-    case FIN_ACK_TX:
-      NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action FIN_ACK_TX");
-      SendEmptyPacket (TcpHeader::FIN | TcpHeader::ACK);
-      break;
-    case NEW_ACK:
-      NS_ASSERT (false); // This should be processed in ProcessPacketAction
-      break;
-    case NEW_SEQ_RX:
-      NS_ASSERT (false); // This should be processed in ProcessPacketAction
-      break;
-    case RETX:
-      NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action RETX");
-      break;
-    case TX_DATA:
-      NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action TX_DATA");
-      SendPendingData ();
-      break;
-    case PEER_CLOSE:
-      NS_ASSERT (false); // This should be processed in ProcessPacketAction
-      NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action PEER_CLOSE");
-      break;
-    case APP_CLOSED:
-      NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action APP_CLOSED");
-      break;
-    case CANCEL_TM:
-      NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action CANCEL_TM");
-      break;
-    case APP_NOTIFY:
-      NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action APP_NOTIFY");
-      break;
-    case SERV_NOTIFY:
-      NS_ASSERT (false); // This should be processed in ProcessPacketAction
-      break;
-    case LAST_ACTION:
-      NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action LAST_ACTION");
-      break;
-  }
-  return true;
-}
-
-bool TcpSocketImpl::ProcessPacketAction (Actions_t a, Ptr<Packet> p,
-                                     const TcpHeader& tcpHeader,
-                                     const Address& fromAddress)
-{
-  NS_LOG_FUNCTION (this << a << p  << fromAddress);
-  uint32_t localIfIndex;
-  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
-  switch (a)
-  {
-    case SYN_ACK_TX:
-      NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action SYN_ACK_TX");
-//      m_remotePort = InetSocketAddress::ConvertFrom (fromAddress).GetPort ();
-//      m_remoteAddress = InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 ();
-//       if (ipv4->GetIfIndexForDestination (m_remoteAddress, localIfIndex))
-//         {
-//           m_localAddress = ipv4->GetAddress (localIfIndex);
-//         }
-      if (m_state == LISTEN) //this means we should fork a new TcpSocketImpl
-        {
-          NS_LOG_DEBUG("In SYN_ACK_TX, m_state is LISTEN, this " << this);
-          //notify the server that we got a SYN
-          // If server refuses connection do nothing
-          if (!NotifyConnectionRequest(fromAddress)) return true;
-          // Clone the socket
-          Ptr<TcpSocketImpl> newSock = Copy ();
-          NS_LOG_LOGIC ("Cloned a TcpSocketImpl " << newSock);
-          //this listening socket should do nothing more
-          Simulator::ScheduleNow (&TcpSocketImpl::CompleteFork, newSock,
-                                  p, tcpHeader,fromAddress);
-          return true;
-        }
-        // This is the cloned endpoint
-        m_endPoint->SetPeer (m_remoteAddress, m_remotePort);
-        if (ipv4->GetIfIndexForDestination (m_remoteAddress, localIfIndex))
-          {
-            m_localAddress = ipv4->GetAddress (localIfIndex);
-            m_endPoint->SetLocalAddress (m_localAddress);
-            // Leave local addr in the portmap to any, as the path from
-            // remote can change and packets can arrive on different interfaces
-            //m_endPoint->SetLocalAddress (Ipv4Address::GetAny());
-          }
-        // TCP SYN consumes one byte
-        m_nextRxSequence = tcpHeader.GetSequenceNumber() + SequenceNumber(1);
-        SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK);
-      break;
-    case ACK_TX_1:
-      NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action ACK_TX_1");
-      // TCP SYN consumes one byte
-      m_nextRxSequence = tcpHeader.GetSequenceNumber() + SequenceNumber(1);
-      m_nextTxSequence = tcpHeader.GetAckNumber ();
-      m_firstPendingSequence = m_nextTxSequence;  //bug 166
-      NS_LOG_DEBUG ("TcpSocketImpl " << this << " ACK_TX_1" <<
-                    " nextRxSeq " << m_nextRxSequence);
-      SendEmptyPacket (TcpHeader::ACK);
-      m_rxWindowSize = tcpHeader.GetWindowSize ();
-      if (tcpHeader.GetAckNumber () > m_highestRxAck)
-      {
-        m_highestRxAck = tcpHeader.GetAckNumber ();
-        // Data freed from the send buffer; notify any blocked sender
-        if (m_wouldBlock)
-          {
-            NotifySend (GetTxAvailable ());
-            m_wouldBlock = false;
-          }
-      }
-      SendPendingData ();
-      break;
-    case NEW_ACK:
-      NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action NEW_ACK_TX");
-      if (tcpHeader.GetAckNumber () < m_highestRxAck) //old ack, do nothing
-      {
-        break;
-      }
-      if (tcpHeader.GetAckNumber () == m_highestRxAck && 
-         tcpHeader.GetAckNumber ()  < m_nextTxSequence)
-      {
-        DupAck (tcpHeader, ++m_dupAckCount);
-        break;
-      }
-      if (tcpHeader.GetAckNumber () > m_highestRxAck)  
-        {
-          m_dupAckCount = 0;
-        }
-      NewAck (tcpHeader.GetAckNumber ());
-      break;
-    case NEW_SEQ_RX:
-      NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action NEW_SEQ_RX");
-      NewRx (p, tcpHeader, fromAddress); // Process new data received
-      break;
-    case PEER_CLOSE:
-    {
-      // First we have to be sure the FIN packet was not received
-      // out of sequence.  If so, note pending close and process
-      // new sequence rx
-      if (tcpHeader.GetSequenceNumber () != m_nextRxSequence)
-        { // process close later
-          m_pendingClose = true;
-          NS_LOG_LOGIC ("TcpSocketImpl " << this << " setting pendingClose" 
-            << " rxseq " << tcpHeader.GetSequenceNumber () 
-            << " nextRxSeq " << m_nextRxSequence);
-          NewRx (p, tcpHeader, fromAddress);
-          return true;
-        }
-      // Now we need to see if any data came with the FIN
-      // if so, call NewRx
-      if (p->GetSize () != 0)
-        {
-          NewRx (p, tcpHeader, fromAddress);
-        }
-      States_t saveState = m_state; // Used to see if app responds
-      NS_LOG_LOGIC ("TcpSocketImpl " << this 
-          << " peer close, state " << m_state);
-      if (!m_closeRequestNotified)
-        {
-          NS_LOG_LOGIC ("TCP " << this 
-              << " calling AppCloseRequest");
-          NotifyCloseRequested(); 
-          m_closeRequestNotified = true;
-        }
-      NS_LOG_LOGIC ("TcpSocketImpl " << this 
-          << " peer close, state after " << m_state);
-      if (m_state == saveState)
-        { // Need to ack, the application will close later
-          SendEmptyPacket (TcpHeader::ACK);
-//               // Also need to re-tx the ack if we
-        }
-      if (m_state == LAST_ACK)
-        {
-          NS_LOG_LOGIC ("TcpSocketImpl " << this << " scheduling LATO1");
-          m_lastAckEvent = Simulator::Schedule (m_rtt->RetransmitTimeout (),
-                                                &TcpSocketImpl::LastAckTimeout,this);
-        }
-      break;
-    }
-    case SERV_NOTIFY:
-      NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action SERV_NOTIFY");
-      NS_LOG_LOGIC ("TcpSocketImpl " << this << " Connected!");
-      NotifyNewConnectionCreated (this, fromAddress);
-      m_connected = true; // ! This is bogus; fix when we clone the tcp
-      m_endPoint->SetPeer (m_remoteAddress, m_remotePort);
-      //treat the connection orientation final ack as a newack
-      CommonNewAck (tcpHeader.GetAckNumber (), true);
-      break;
-    default:
-      break;
-  }
-  return true;
-}
-
-void TcpSocketImpl::CompleteFork(Ptr<Packet> p, const TcpHeader& h, const Address& fromAddress)
-{
-  // Get port and address from peer (connecting host)
-  m_remotePort = InetSocketAddress::ConvertFrom (fromAddress).GetPort ();
-  m_remoteAddress = InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 ();
-  m_endPoint = m_tcp->Allocate (m_localAddress,
-                                m_localPort,
-                                m_remoteAddress,
-                                m_remotePort);
-  //the cloned socket with be in listen state, so manually change state
-  m_state = SYN_RCVD;
-  //equivalent to FinishBind
-  m_endPoint->SetRxCallback (MakeCallback (&TcpSocketImpl::ForwardUp, Ptr<TcpSocketImpl>(this)));
-  m_endPoint->SetDestroyCallback (MakeCallback (&TcpSocketImpl::Destroy, Ptr<TcpSocketImpl>(this)));
-  ProcessPacketAction(SYN_ACK_TX, p, h, fromAddress);
- }
-
-void TcpSocketImpl::ConnectionSucceeded()
-{ // We would preferred to have scheduled an event directly to
-  // NotifyConnectionSucceeded, but (sigh) these are protected
-  // and we can get the address of it :(
-  NotifyConnectionSucceeded();
-}
-
-bool TcpSocketImpl::SendPendingData (bool withAck)
-{
-  NS_LOG_FUNCTION (this << withAck);
-  NS_LOG_LOGIC ("ENTERING SendPendingData");
-  if (!m_pendingData)
-    {
-      return false; // No data exists
-    }
-  uint32_t nPacketsSent = 0;
-  while (m_pendingData->SizeFromSeq (m_firstPendingSequence, m_nextTxSequence))
-    {
-      uint32_t w = AvailableWindow ();// Get available window size
-      NS_LOG_LOGIC ("TcpSocketImpl " << this << " SendPendingData"
-           << " w " << w 
-           << " rxwin " << m_rxWindowSize
-           << " cWnd " << m_cWnd
-           << " segsize " << m_segmentSize
-           << " nextTxSeq " << m_nextTxSequence
-           << " highestRxAck " << m_highestRxAck 
-           << " pd->Size " << m_pendingData->Size ()
-           << " pd->SFS " << m_pendingData->SizeFromSeq (m_firstPendingSequence, m_nextTxSequence));
-
-      if (w < m_segmentSize && m_pendingData->Size () > w)
-        {
-          break; // No more
-        }
-      uint32_t s = std::min (w, m_segmentSize);  // Send no more than window
-      Ptr<Packet> p = m_pendingData->CopyFromSeq (s, m_firstPendingSequence, 
-        m_nextTxSequence);
-      NS_LOG_LOGIC("TcpSocketImpl " << this << " sendPendingData"
-                   << " txseq " << m_nextTxSequence
-                   << " s " << s 
-                   << " datasize " << p->GetSize() );
-      uint8_t flags = 0;
-      if (withAck)
-        {
-          flags |= TcpHeader::ACK;
-        }
-      uint32_t sz = p->GetSize (); // Size of packet
-      uint32_t remainingData = m_pendingData->SizeFromSeq(
-          m_firstPendingSequence,
-          m_nextTxSequence + SequenceNumber (sz));
-      if (m_closeOnEmpty && (remainingData == 0))
-        {
-          flags = TcpHeader::FIN;
-          m_state = FIN_WAIT_1;
-        }
-
-      TcpHeader header;
-      header.SetFlags (flags);
-      header.SetSequenceNumber (m_nextTxSequence);
-      header.SetAckNumber (m_nextRxSequence);
-      header.SetSourcePort (m_endPoint->GetLocalPort());
-      header.SetDestinationPort (m_remotePort);
-      if (m_shutdownSend)
-        {
-          m_errno = ERROR_SHUTDOWN;
-          return -1;
-        }
-
-      
-      if (m_retxEvent.IsExpired () ) //go ahead and schedule the retransmit
-        {
-            Time rto = m_rtt->RetransmitTimeout (); 
-            NS_LOG_LOGIC ("Schedule retransmission timeout at time " << 
-              Simulator::Now ().GetSeconds () << " to expire at time " <<
-              (Simulator::Now () + rto).GetSeconds () );
-          m_retxEvent = Simulator::Schedule (rto,&TcpSocketImpl::ReTxTimeout,this);
-        }
-      NS_LOG_LOGIC ("About to send a packet with flags: " << flags);
-      m_tcp->SendPacket (p, header,
-                         m_endPoint->GetLocalAddress (),
-                         m_remoteAddress);
-      m_rtt->SentSeq(m_nextTxSequence, sz);       // notify the RTT
-      // Notify the application
-      Simulator::ScheduleNow(&TcpSocketImpl::NotifyDataSent, this, p->GetSize ());
-      nPacketsSent++;                             // Count sent this loop
-      m_nextTxSequence += sz;                     // Advance next tx sequence
-      // Note the high water mark
-      m_highTxMark = std::max (m_nextTxSequence, m_highTxMark);
-    }
-  NS_LOG_LOGIC ("Sent "<<nPacketsSent<<" packets");
-  NS_LOG_LOGIC("RETURN SendPendingData");
-  return (nPacketsSent>0);
-}
-
-uint32_t  TcpSocketImpl::UnAckDataCount ()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_nextTxSequence - m_highestRxAck;
-}
-
-uint32_t  TcpSocketImpl::BytesInFlight ()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_highTxMark - m_highestRxAck;
-}
-
-uint32_t  TcpSocketImpl::Window ()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  NS_LOG_LOGIC ("TcpSocketImpl::Window() "<<this);
-  return std::min (m_rxWindowSize, m_cWnd.Get());
-}
-
-uint32_t  TcpSocketImpl::AvailableWindow ()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  uint32_t unack = UnAckDataCount (); // Number of outstanding bytes
-  uint32_t win = Window ();
-  if (win < unack) 
-    {
-      return 0;  // No space available
-    }
-  return (win - unack);       // Amount of window space available
-}
-
-void TcpSocketImpl::NewRx (Ptr<Packet> p,
-                        const TcpHeader& tcpHeader, 
-                        const Address& fromAddress)
-{
-  NS_LOG_FUNCTION (this << p << "tcpHeader " << fromAddress);
-  NS_LOG_LOGIC ("TcpSocketImpl " << this << " NewRx,"
-                << " seq " << tcpHeader.GetSequenceNumber()
-                << " ack " << tcpHeader.GetAckNumber()
-                << " p.size is " << p->GetSize () );
-  NS_LOG_DEBUG ("TcpSocketImpl " << this <<
-                " NewRx," <<
-                " seq " << tcpHeader.GetSequenceNumber() <<
-                " ack " << tcpHeader.GetAckNumber() <<
-                " p.size is " << p->GetSize());
-  States_t origState = m_state;
-  uint32_t s = p->GetSize ();  // Size of associated data
-  if (s == 0)
-    {// Nothing to do if no associated data
-      return;
-    }
-  // Log sequence received if enabled
-  // NoteTimeSeq(LOG_SEQ_RX, h->sequenceNumber);
-  // Three possibilities
-  // 1) Received seq is expected, deliver this and any buffered data
-  // 2) Received seq is < expected, just re-ack previous
-  // 3) Received seq is > expected, just re-ack previous and buffer data
-  if (tcpHeader.GetSequenceNumber () == m_nextRxSequence)
-    { // If seq is expected seq
-      // 1) Update nextRxSeq
-      // 2) Deliver to application this packet
-      // 3) See if any buffered can be delivered
-      // 4) Send the ack
-      m_nextRxSequence += s;           // Advance next expected sequence
-      //bytesReceived += s;       // Statistics
-      NS_LOG_LOGIC("Case 1, advanced nrxs to " << m_nextRxSequence );
-      SocketRxAddressTag tag;
-      tag.SetAddress (fromAddress);
-      p->AddTag (tag);
-      m_deliveryQueue.push (p);
-      m_rxAvailable += p->GetSize ();
-      NotifyDataRecv ();
-      if (m_closeNotified)
-        {
-          NS_LOG_LOGIC ("Tcp " << this << " HuH?  Got data after closeNotif");
-        }
-      NS_LOG_LOGIC ("TcpSocketImpl " << this << " adv rxseq by " << s);
-      // Look for buffered data
-      UnAckData_t::iterator i;
-      // Note that the bufferedData list DOES contain the tcp header
-      while (!m_bufferedData.empty ())
-        { // Check the buffered data for delivery
-          NS_LOG_LOGIC("TCP " << this << " bufferedData.size() " 
-              << m_bufferedData.size () 
-              << " time " << Simulator::Now ());
-          i = m_bufferedData.begin ();
-          Ptr<Packet> p1 = i->second;
-          SequenceNumber s1 = 0;
-          if (i->first > m_nextRxSequence) 
-            {
-              break;  // Not next expected
-            }
-          // already have the header as a param
-          //TCPHeader* h = dynamic_cast<TCPHeader*>(p1->PopPDU());
-          // Check non-null here...
-          uint8_t flags = tcpHeader.GetFlags ();           // Flags (used below)
-          if (i->first < m_nextRxSequence)
-            { // remove already delivered data
-              // Two cases here.
-              // 1) seq + length <= nextRxSeq, just discard
-              // 2) seq + length > nextRxSeq, can deliver partial
-              s1 = p->GetSize ();
-              if (i->first + s1 < m_nextRxSequence)
-                { // Just remove from list
-                  //bufferedData.erase(i);
-                  p1 = 0; // Nothing to deliver
-                }
-              else
-                { // Remove partial data to prepare for delivery
-                  uint32_t dup = m_nextRxSequence - i->first;
-                  i->second = p1->CreateFragment (0, p1->GetSize () - dup);
-                  p1 = i->second;
-                }
-            }
-          else
-            { // At this point i->first must equal nextRxSeq
-              if (i->first != m_nextRxSequence)
-                {
-                  NS_FATAL_ERROR ("HuH?  NexRx failure, first " 
-                      << i->first << " nextRxSeq " << m_nextRxSequence);
-                }
-              s1 = p1->GetSize ();
-            }
-          SocketRxAddressTag tag;
-          tag.SetAddress (fromAddress);
-          p1->AddTag (tag);
-          m_deliveryQueue.push (p1);
-          m_rxAvailable += p->GetSize ();
-          NotifyDataRecv ();
-
-          NS_LOG_LOGIC ("TcpSocketImpl " << this << " adv rxseq1 by " << s1 );
-          m_nextRxSequence += s1;           // Note data received
-          m_bufferedData.erase (i);     // Remove from list
-          if (flags & TcpHeader::FIN)
-            NS_LOG_LOGIC("TcpSocketImpl " << this 
-                    << " found FIN in buffered");
-        }
-
-      if (m_pendingClose || (origState > ESTABLISHED))
-        { // See if we can close now
-          if (m_bufferedData.empty())
-            {
-              ProcessPacketAction (PEER_CLOSE, p, tcpHeader, fromAddress);
-            }
-        }
-    }
-  else if (SequenceNumber (tcpHeader.GetSequenceNumber ()) >= m_nextRxSequence)
-    { // Need to buffer this one
-      NS_LOG_LOGIC ("Case 2, buffering " << tcpHeader.GetSequenceNumber () );
-      UnAckData_t::iterator i = 
-        m_bufferedData.find (tcpHeader.GetSequenceNumber () );
-      if (i != m_bufferedData.end () )
-        {
-          i->second = 0; // relase reference to already buffered
-        }
-      // Save for later delivery
-      m_bufferedData[tcpHeader.GetSequenceNumber () ] = p;  
-    }
-  else
-    { // debug
-      NS_LOG_LOGIC("TCP " << this 
-               << " got seq " << tcpHeader.GetSequenceNumber ()
-               << " expected " << m_nextRxSequence
-               << "       flags " << tcpHeader.GetFlags ());
-    }
-  // Now send a new ack packet acknowledging all received and delivered data
-  if(++m_delAckCount >= m_delAckMaxCount)
-  {
-    m_delAckEvent.Cancel();
-    m_delAckCount = 0;
-    SendEmptyPacket (TcpHeader::ACK);
-  }
-  else
-  {
-    m_delAckEvent = Simulator::Schedule (m_delAckTimeout, &TcpSocketImpl::DelAckTimeout, this);
-  }
-}
-
-void TcpSocketImpl::DelAckTimeout ()
-{
-  m_delAckCount = 0;
-  SendEmptyPacket (TcpHeader::ACK);
-}
-
-void TcpSocketImpl::CommonNewAck (SequenceNumber ack, bool skipTimer)
-{ // CommonNewAck is called only for "New" (non-duplicate) acks
-  // and MUST be called by any subclass, from the NewAck function
-  // Always cancel any pending re-tx timer on new acknowledgement
-  NS_LOG_FUNCTION (this << ack << skipTimer); 
-  //DEBUG(1,(cout << "TCP " << this << "Cancelling retx timer " << endl));
-  if (!skipTimer)
-    {
-      m_retxEvent.Cancel ();  
-      //On recieving a "New" ack we restart retransmission timer .. RFC 2988
-      Time rto = m_rtt->RetransmitTimeout ();
-      NS_LOG_LOGIC ("Schedule retransmission timeout at time " 
-          << Simulator::Now ().GetSeconds () << " to expire at time " 
-          << (Simulator::Now () + rto).GetSeconds ());
-    m_retxEvent = Simulator::Schedule (rto, &TcpSocketImpl::ReTxTimeout, this);
-    }
-  NS_LOG_LOGIC ("TCP " << this << " NewAck " << ack 
-           << " numberAck " << (ack - m_highestRxAck)); // Number bytes ack'ed
-  m_highestRxAck = ack;         // Note the highest recieved Ack
-  if (m_wouldBlock)
-    {
-      // m_highestRxAck advancing means some data was acked, and the size 
-      // of free space in the buffer has increased
-      NotifySend (GetTxAvailable ());
-      m_wouldBlock = false;
-    }
-  if (ack > m_nextTxSequence) 
-    {
-      m_nextTxSequence = ack; // If advanced
-    }
-  // See if all pending ack'ed; if so we can delete the data
-  if (m_pendingData)
-    { // Data exists, see if can be deleted
-      if (m_pendingData->SizeFromSeq (m_firstPendingSequence, m_highestRxAck) == 0)
-        { // All pending acked, can be deleted
-          m_pendingData->Clear ();
-          delete m_pendingData;
-          m_pendingData = 0;
-          // Insure no re-tx timer
-          m_retxEvent.Cancel ();
-        }
-    }
-  // Try to send more data
-  SendPendingData();
-}
-
-Ptr<TcpSocketImpl> TcpSocketImpl::Copy ()
-{
-  return CopyObject<TcpSocketImpl> (this);
-}
-
-void TcpSocketImpl::NewAck (SequenceNumber seq)
-{ // New acknowledgement up to sequence number "seq"
-  // Adjust congestion window in response to new ack's received
-  NS_LOG_FUNCTION (this << seq);
-  NS_LOG_LOGIC ("TcpSocketImpl " << this << " NewAck "
-           << " seq " << seq
-           << " cWnd " << m_cWnd
-           << " ssThresh " << m_ssThresh);
-  if (m_cWnd < m_ssThresh)
-    { // Slow start mode, add one segSize to cWnd
-      m_cWnd += m_segmentSize;
-      NS_LOG_LOGIC ("TcpSocketImpl " << this << " NewCWnd SlowStart, cWnd " << m_cWnd 
-          << " sst " << m_ssThresh);
-    }
-  else
-    { // Congestion avoidance mode, adjust by (ackBytes*segSize) / cWnd
-      double adder =  ((double) m_segmentSize * m_segmentSize) / m_cWnd.Get();
-      if (adder < 1.0) 
-        {
-          adder = 1.0;
-        }
-      m_cWnd += (uint32_t) adder;
-      NS_LOG_LOGIC ("NewCWnd CongAvoid, cWnd " << m_cWnd 
-           << " sst " << m_ssThresh);
-    }
-  CommonNewAck (seq, false);           // Complete newAck processing
-}
-
-void TcpSocketImpl::DupAck (const TcpHeader& t, uint32_t count)
-{
-  NS_LOG_FUNCTION (this << "t " << count);
-  NS_LOG_LOGIC ("TcpSocketImpl " << this << " DupAck " <<  t.GetAckNumber ()
-      << ", count " << count
-      << ", time " << Simulator::Now ());
-  if (count == 3)
-  { // Count of three indicates triple duplicate ack
-    m_ssThresh = Window () / 2; // Per RFC2581
-    m_ssThresh = std::max (m_ssThresh, 2 * m_segmentSize);
-    NS_LOG_LOGIC("TcpSocketImpl " << this << "Tahoe TDA, time " << Simulator::Now ()
-        << " seq " << t.GetAckNumber ()
-        << " in flight " << BytesInFlight ()
-        << " new ssthresh " << m_ssThresh);
-
-    m_cWnd = m_segmentSize; // Collapse cwnd (re-enter slowstart)
-    // For Tahoe, we also reset nextTxSeq
-    m_nextTxSequence = m_highestRxAck;
-    SendPendingData ();
-  }
-}
-
-void TcpSocketImpl::ReTxTimeout ()
-{ // Retransmit timeout
-  NS_LOG_FUNCTION (this);
-  m_ssThresh = Window () / 2; // Per RFC2581
-  m_ssThresh = std::max (m_ssThresh, 2 * m_segmentSize);
-  // Set cWnd to segSize on timeout,  per rfc2581
-  // Collapse congestion window (re-enter slowstart)
-  m_cWnd = m_segmentSize;           
-  m_nextTxSequence = m_highestRxAck; // Start from highest Ack
-  m_rtt->IncreaseMultiplier (); // DoubleValue timeout value for next retx timer
-  Retransmit ();             // Retransmit the packet
-}
-
-void TcpSocketImpl::LastAckTimeout ()
-{
-  m_lastAckEvent.Cancel ();
-  if (m_state == LAST_ACK)
-    {
-      Actions_t action = ProcessEvent (TIMEOUT);
-      ProcessAction (action);
-    }
-  if (!m_closeNotified)
-    {
-      m_closeNotified = true;
-    }
-}
-
-void TcpSocketImpl::Retransmit ()
-{
-  NS_LOG_FUNCTION (this);
-  uint8_t flags = TcpHeader::NONE;
-  if (m_state == SYN_SENT) 
-    {
-      if (m_cnCount > 0) 
-        {
-          SendEmptyPacket (TcpHeader::SYN);
-          return;
-        }
-      else
-        {
-          NotifyConnectionFailed ();
-          return;
-        }
-    } 
-  if (!m_pendingData)
-    {
-      if (m_state == FIN_WAIT_1 || m_state == FIN_WAIT_2)
-        { // Must have lost FIN, re-send
-          SendEmptyPacket (TcpHeader::FIN);
-        }
-      return;
-    }
-  Ptr<Packet> p = m_pendingData->CopyFromSeq (m_segmentSize,
-                                            m_firstPendingSequence,
-                                            m_highestRxAck);
-  // Calculate remaining data for COE check
-  uint32_t remainingData = m_pendingData->SizeFromSeq (
-      m_firstPendingSequence,
-      m_nextTxSequence + SequenceNumber(p->GetSize ()));
-  if (m_closeOnEmpty && remainingData == 0)
-    { // Add the FIN flag
-      flags = flags | TcpHeader::FIN;
-    }
-
-  NS_LOG_LOGIC ("TcpSocketImpl " << this << " retxing seq " << m_highestRxAck);
-  if (m_retxEvent.IsExpired () )
-    {
-      Time rto = m_rtt->RetransmitTimeout ();
-      NS_LOG_LOGIC ("Schedule retransmission timeout at time "
-          << Simulator::Now ().GetSeconds () << " to expire at time "
-          << (Simulator::Now () + rto).GetSeconds ());
-      m_retxEvent = Simulator::Schedule (rto,&TcpSocketImpl::ReTxTimeout,this);
-    }
-  m_rtt->SentSeq (m_highestRxAck,p->GetSize ());
-  // And send the packet
-  TcpHeader tcpHeader;
-  tcpHeader.SetSequenceNumber (m_nextTxSequence);
-  tcpHeader.SetAckNumber (m_nextRxSequence);
-  tcpHeader.SetSourcePort (m_endPoint->GetLocalPort());
-  tcpHeader.SetDestinationPort (m_remotePort);
-  tcpHeader.SetFlags (flags);
-  tcpHeader.SetWindowSize (m_advertisedWindowSize);
-
-  m_tcp->SendPacket (p, tcpHeader, m_endPoint->GetLocalAddress (),
-    m_remoteAddress);
-}
-
-void
-TcpSocketImpl::SetSndBufSize (uint32_t size)
-{
-  m_sndBufSize = size;
-}
-
-uint32_t
-TcpSocketImpl::GetSndBufSize (void) const
-{
-  return m_sndBufSize;
-}
-
-void
-TcpSocketImpl::SetRcvBufSize (uint32_t size)
-{
-  m_rcvBufSize = size;
-}
-
-uint32_t
-TcpSocketImpl::GetRcvBufSize (void) const
-{
-  return m_rcvBufSize;
-}
-
-void
-TcpSocketImpl::SetSegSize (uint32_t size)
-{
-  m_segmentSize = size;
-}
-
-uint32_t
-TcpSocketImpl::GetSegSize (void) const
-{
-  return m_segmentSize;
-}
-
-void
-TcpSocketImpl::SetAdvWin (uint32_t window)
-{
-  m_advertisedWindowSize = window;
-}
-
-uint32_t
-TcpSocketImpl::GetAdvWin (void) const
-{
-  return m_advertisedWindowSize;
-}
-
-void
-TcpSocketImpl::SetSSThresh (uint32_t threshold)
-{
-  m_ssThresh = threshold;
-}
-
-uint32_t
-TcpSocketImpl::GetSSThresh (void) const
-{
-  return m_ssThresh;
-}
-
-void
-TcpSocketImpl::SetInitialCwnd (uint32_t cwnd)
-{
-  m_initialCWnd = cwnd;
-}
-
-uint32_t
-TcpSocketImpl::GetInitialCwnd (void) const
-{
-  return m_initialCWnd;
-}
-
-void 
-TcpSocketImpl::SetConnTimeout (Time timeout)
-{
-  m_cnTimeout = timeout;
-}
-
-Time
-TcpSocketImpl::GetConnTimeout (void) const
-{
-  return m_cnTimeout;
-}
-
-void 
-TcpSocketImpl::SetConnCount (uint32_t count)
-{
-  m_cnCount = count;
-}
-
-uint32_t 
-TcpSocketImpl::GetConnCount (void) const
-{
-  return m_cnCount;
-}
-
-void 
-TcpSocketImpl::SetDelAckTimeout (Time timeout)
-{
-  m_delAckTimeout = timeout;
-}
-
-Time
-TcpSocketImpl::GetDelAckTimeout (void) const
-{
-  return m_delAckTimeout;
-}
-
-void
-TcpSocketImpl::SetDelAckMaxCount (uint32_t count)
-{
-  m_delAckMaxCount = count;
-}
-
-uint32_t
-TcpSocketImpl::GetDelAckMaxCount (void) const
-{
-  return m_delAckMaxCount;
-}
-
-}//namespace ns3
--- a/src/internet-node/tcp-socket-impl.h	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,215 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 Georgia Tech Research Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Raj Bhattacharjea <raj.b@gatech.edu>
- */
-#ifndef TCP_SOCKET_IMPL_H
-#define TCP_SOCKET_IMPL_H
-
-#include <stdint.h>
-#include <queue>
-#include "ns3/callback.h"
-#include "ns3/traced-value.h"
-#include "ns3/tcp-socket.h"
-#include "ns3/ptr.h"
-#include "ns3/ipv4-address.h"
-#include "ns3/event-id.h"
-#include "tcp-typedefs.h"
-#include "pending-data.h"
-#include "sequence-number.h"
-#include "rtt-estimator.h"
-
-
-namespace ns3 {
-
-class Ipv4EndPoint;
-class Node;
-class Packet;
-class TcpL4Protocol;
-class TcpHeader;
-
-class TcpSocketImpl : public TcpSocket
-{
-public:
-  static TypeId GetTypeId (void);
-  /**
-   * Create an unbound tcp socket.
-   */
-  TcpSocketImpl ();
-  TcpSocketImpl (const TcpSocketImpl& sock);
-  virtual ~TcpSocketImpl ();
-
-  void SetNode (Ptr<Node> node);
-  void SetTcp (Ptr<TcpL4Protocol> tcp);
-  void SetRtt (Ptr<RttEstimator> rtt);
-
-  virtual enum SocketErrno GetErrno (void) const;
-  virtual Ptr<Node> GetNode (void) const;
-  virtual int Bind (void);
-  virtual int Bind (const Address &address);
-  virtual int Close (void);
-  virtual int ShutdownSend (void);
-  virtual int ShutdownRecv (void);
-  virtual int Connect(const Address &address);
-  virtual int Send (Ptr<Packet> p);
-  virtual int Send (const uint8_t* buf, uint32_t size);
-  virtual int SendTo(Ptr<Packet> p, const Address &address);
-  virtual uint32_t GetTxAvailable (void) const;
-  virtual int Listen(uint32_t queueLimit);
-
-  virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags);
-  virtual uint32_t GetRxAvailable (void) const;
-
-private:
-  friend class Tcp;
-  // invoked by Tcp class
-  int FinishBind (void);
-  void ForwardUp (Ptr<Packet> p, Ipv4Address ipv4, uint16_t port);
-  void Destroy (void);
-  int DoSendTo (Ptr<Packet> p, const Address &daddr);
-  int DoSendTo (Ptr<Packet> p, Ipv4Address daddr, uint16_t dport);
-  void SendEmptyPacket(uint8_t flags);
-  //methods for state
-  bool ProcessAction (Actions_t a);
-  bool ProcessAction (Actions_t a, const TcpHeader& tcpHeader,
-                      Ipv4Address saddr, Ipv4Address daddr);
-  bool ProcessPacketAction (Actions_t a, Ptr<Packet> p,
-                                       const TcpHeader& tcpHeader,
-                                       const Address& fromAddress);
-  Actions_t ProcessEvent (Events_t e);
-  bool SendPendingData(bool withAck = false);
-  void CompleteFork(Ptr<Packet>, const TcpHeader&, const Address& fromAddress);
-  void ConnectionSucceeded();
-  
-  //methods for window management
-  virtual uint32_t  UnAckDataCount(); // Return count of number of unacked bytes
-  virtual uint32_t  BytesInFlight();  // Return total bytes in flight
-  virtual uint32_t  Window();         // Return window size (integer)
-  virtual uint32_t  AvailableWindow();// Return unfilled portion of window
-
-  // Manage data tx/rx
-  void NewRx (Ptr<Packet>, const TcpHeader&, const Address&);
-  // XXX This should be virtual and overridden
-  Ptr<TcpSocketImpl> Copy ();
-  void NewAck (SequenceNumber seq); 
-  // XXX This should be virtual and overridden
-  void DupAck (const TcpHeader& t, uint32_t count); 
-  void ReTxTimeout ();
-  void DelAckTimeout ();
-  void LastAckTimeout ();
-  void Retransmit ();
-  void CommonNewAck (SequenceNumber seq, bool skipTimer = false);
-
-  // attribute related
-  virtual void SetSndBufSize (uint32_t size);
-  virtual uint32_t GetSndBufSize (void) const;
-  virtual void SetRcvBufSize (uint32_t size);
-  virtual uint32_t GetRcvBufSize (void) const;
-  virtual void SetSegSize (uint32_t size);
-  virtual uint32_t GetSegSize (void) const;
-  virtual void SetAdvWin (uint32_t window);
-  virtual uint32_t GetAdvWin (void) const;
-  virtual void SetSSThresh (uint32_t threshold);
-  virtual uint32_t GetSSThresh (void) const;
-  virtual void SetInitialCwnd (uint32_t cwnd);
-  virtual uint32_t GetInitialCwnd (void) const;
-  virtual void SetConnTimeout (Time timeout);
-  virtual Time GetConnTimeout (void) const;
-  virtual void SetConnCount (uint32_t count);
-  virtual uint32_t GetConnCount (void) const;
-  virtual void SetDelAckTimeout (Time timeout);
-  virtual Time GetDelAckTimeout (void) const;
-  virtual void SetDelAckMaxCount (uint32_t count);
-  virtual uint32_t GetDelAckMaxCount (void) const;
-
-  bool m_skipRetxResched;
-  uint32_t m_dupAckCount;
-  EventId m_retxEvent;
-  EventId m_lastAckEvent;
-
-  EventId m_delAckEvent;
-  uint32_t m_delAckCount;
-  uint32_t m_delAckMaxCount;
-  Time m_delAckTimeout;
-
-  Ipv4EndPoint *m_endPoint;
-  Ptr<Node> m_node;
-  Ptr<TcpL4Protocol> m_tcp;
-  Ipv4Address m_remoteAddress;
-  uint16_t m_remotePort;
-  //these two are so that the socket/endpoint cloning works
-  Ipv4Address m_localAddress;
-  uint16_t m_localPort;
-  enum SocketErrno m_errno;
-  bool m_shutdownSend;
-  bool m_shutdownRecv;
-  bool m_connected;
-  
-  //manage the state infomation
-  States_t m_state;
-  bool m_closeNotified;
-  bool m_closeRequestNotified;
-  bool m_closeOnEmpty;
-  bool m_pendingClose;
-
-  
-  //sequence info, sender side
-  SequenceNumber m_nextTxSequence;
-  SequenceNumber m_highTxMark;
-  SequenceNumber m_highestRxAck;
-  SequenceNumber m_lastRxAck;
-  
-  //sequence info, reciever side
-  SequenceNumber m_nextRxSequence;
-
-  //history data
-  //this is the incoming data buffer which sorts out of sequence data
-  UnAckData_t m_bufferedData;
-  //this is kind of the tx buffer
-  PendingData* m_pendingData;
-  SequenceNumber m_firstPendingSequence;
-
-  // Window management
-  uint32_t                       m_segmentSize;          //SegmentSize
-  uint32_t                       m_rxWindowSize;
-  uint32_t                       m_advertisedWindowSize; //Window to advertise
-  TracedValue<uint32_t>          m_cWnd;                 //Congestion window
-  uint32_t                       m_ssThresh;             //Slow Start Threshold
-  uint32_t                       m_initialCWnd;          //Initial cWnd value
-
-  // Round trip time estimation
-  Ptr<RttEstimator> m_rtt;
-  Time m_lastMeasuredRtt;
-
-  // Timer-related members
-  Time              m_cnTimeout; 
-  uint32_t          m_cnCount;
-  
-  // Temporary queue for delivering data to application
-  std::queue<Ptr<Packet> > m_deliveryQueue;
-  uint32_t m_rxAvailable;
-  
-  bool m_wouldBlock;  // set to true whenever socket would block on send()
-
-  // Attributes
-  uint32_t m_rcvBufSize;   // maximum receive socket buffer size
-  uint32_t m_sndBufSize;   // buffer limit for the outgoing queue
-};
-
-}//namespace ns3
-
-#endif /* TCP_SOCKET_IMPL_H */
--- a/src/internet-node/tcp-typedefs.h	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 Georgia Tech Research Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Raj Bhattacharjea <raj.b@gatech.edu>
- * typedefs for tcp state machine
- */ 
-
-#include <vector>
-#include <map>
-#include "sequence-number.h"
-
-#ifndef TCP_TYPEDEFS_H
-#define TCP_TYPEDEFS_H
-
-namespace ns3 {
-
-typedef enum { MAX_FLAGS = 0x40 } TCPMaxFlags_t;  // Flags are 6 bits
-
-typedef enum {
-  CLOSED,       // 0
-  LISTEN,       // 1
-  SYN_SENT,     // 2
-  SYN_RCVD,     // 3
-  ESTABLISHED,  // 4
-  CLOSE_WAIT,   // 5
-  LAST_ACK,     // 6
-  FIN_WAIT_1,   // 7
-  FIN_WAIT_2,   // 8
-  CLOSING,      // 9
-  TIMED_WAIT,   // 10
-  LAST_STATE } States_t;
-
-typedef enum {
-  APP_LISTEN,   // 0
-  APP_CONNECT,  // 1
-  APP_SEND,     // 2
-  SEQ_RECV,     // 3
-  APP_CLOSE,    // 4
-  TIMEOUT,      // 5
-  ACK_RX,       // 6
-  SYN_RX,       // 7
-  SYN_ACK_RX,   // 8
-  FIN_RX,       // 9
-  FIN_ACK_RX,   // 10
-  RST_RX,       // 11
-  BAD_FLAGS,    // 12
-  LAST_EVENT } Events_t;
-
-typedef enum {
-  NO_ACT,       // 0
-  ACK_TX,       // 1
-  ACK_TX_1,     // ACK response to syn
-  RST_TX,       // 2
-  SYN_TX,       // 3
-  SYN_ACK_TX,   // 4
-  FIN_TX,       // 5
-  FIN_ACK_TX,   // 6
-  NEW_ACK,      // 7
-  NEW_SEQ_RX,   // 8
-  RETX,         // 9
-  TX_DATA,      // 10
-  PEER_CLOSE,   // 11
-  APP_CLOSED,   // 12
-  CANCEL_TM,    // 13
-  APP_NOTIFY,   // 14 - Notify app that connection failed
-  SERV_NOTIFY,  // 15 - Notify server tcp that connection completed
-  LAST_ACTION } Actions_t;
-
-class SA  // State/Action pair
-{
-public:
-  SA () : state (LAST_STATE), action (LAST_ACTION) { }
-  SA (States_t s, Actions_t a) : state (s), action (a) { }
-public:
-  States_t  state;
-  Actions_t action;
-};
-typedef std::vector<SA>  StateActionVec_t;
-typedef std::vector<StateActionVec_t> StateActions_t;  // One per current state
-typedef std::vector<Events_t> EventVec_t;      // For flag events lookup
-
-//type for managing buffered out of sequence data
-typedef std::map<SequenceNumber, Ptr<Packet> > UnAckData_t;
-
-class TcpStateMachine {
-  public:
-    TcpStateMachine ();
-    SA Lookup (States_t, Events_t);
-    Events_t FlagsEvent (uint8_t); // Lookup event from flags
-
-  public:
-    StateActions_t aT; // Action table
-    EventVec_t     eV; // Flags event lookup  
-};
-
-}//namespace ns3
-#endif //TCP_TYPEDEFS_H
--- a/src/internet-node/udp-header.cc	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,162 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005 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
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#include "udp-header.h"
-#include "ipv4-checksum.h"
-
-namespace ns3 {
-
-NS_OBJECT_ENSURE_REGISTERED (UdpHeader);
-
-bool UdpHeader::m_calcChecksum = false;
-
-/* The magic values below are used only for debugging.
- * They can be used to easily detect memory corruption
- * problems so you can see the patterns in memory.
- */
-UdpHeader::UdpHeader ()
-  : m_sourcePort (0xfffd),
-    m_destinationPort (0xfffd),
-    m_payloadSize (0xfffd),
-    m_initialChecksum (0)
-{}
-UdpHeader::~UdpHeader ()
-{
-  m_sourcePort = 0xfffe;
-  m_destinationPort = 0xfffe;
-  m_payloadSize = 0xfffe;
-}
-
-void 
-UdpHeader::EnableChecksums (void)
-{
-  m_calcChecksum = true;
-}
-
-void 
-UdpHeader::SetDestinationPort (uint16_t port)
-{
-  m_destinationPort = port;
-}
-void 
-UdpHeader::SetSourcePort (uint16_t port)
-{
-  m_sourcePort = port;
-}
-uint16_t 
-UdpHeader::GetSourcePort (void) const
-{
-  return m_sourcePort;
-}
-uint16_t 
-UdpHeader::GetDestinationPort (void) const
-{
-  return m_destinationPort;
-}
-void 
-UdpHeader::SetPayloadSize (uint16_t size)
-{
-  m_payloadSize = size;
-}
-void 
-UdpHeader::InitializeChecksum (Ipv4Address source, 
-                              Ipv4Address destination,
-                              uint8_t protocol)
-{
-  uint8_t buf[12];
-  source.Serialize (buf);
-  destination.Serialize (buf+4);
-  buf[8] = 0;
-  buf[9] = protocol;
-  uint16_t udpLength = m_payloadSize + GetSerializedSize ();
-  buf[10] = udpLength >> 8;
-  buf[11] = udpLength & 0xff;
-
-  m_initialChecksum = Ipv4ChecksumCalculate (0, buf, 12);
-}
-
-TypeId 
-UdpHeader::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::UdpHeader")
-    .SetParent<Header> ()
-    .AddConstructor<UdpHeader> ()
-    ;
-  return tid;
-}
-TypeId 
-UdpHeader::GetInstanceTypeId (void) const
-{
-  return GetTypeId ();
-}
-void 
-UdpHeader::Print (std::ostream &os) const
-{
-  os << "length: " << m_payloadSize + GetSerializedSize ()
-     << " " 
-     << m_sourcePort << " > " << m_destinationPort
-    ;
-}
-
-uint32_t 
-UdpHeader::GetSerializedSize (void) const
-{
-  return 8;
-}
-
-void
-UdpHeader::Serialize (Buffer::Iterator start) const
-{
-  Buffer::Iterator i = start;
-  i.WriteHtonU16 (m_sourcePort);
-  i.WriteHtonU16 (m_destinationPort);
-  i.WriteHtonU16 (m_payloadSize + GetSerializedSize ());
-  i.WriteU16 (0);
-
-  if (m_calcChecksum) 
-    {
-#if 0
-      //XXXX
-      uint16_t checksum = Ipv4ChecksumCalculate (m_initialChecksum, 
-                                                  buffer->PeekData (), 
-                                                  GetSerializedSize () + m_payloadSize);
-      checksum = Ipv4ChecksumComplete (checksum);
-      i = buffer->Begin ();
-      i.Next (6);
-      i.WriteU16 (checksum);
-#endif
-    }
-}
-uint32_t
-UdpHeader::Deserialize (Buffer::Iterator start)
-{
-  Buffer::Iterator i = start;
-  m_sourcePort = i.ReadNtohU16 ();
-  m_destinationPort = i.ReadNtohU16 ();
-  m_payloadSize = i.ReadNtohU16 () - GetSerializedSize ();
-  if (m_calcChecksum) 
-    {
-      // XXX verify checksum.
-    }
-  return GetSerializedSize ();
-}
-
-
-}; // namespace ns3
--- a/src/internet-node/udp-header.h	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005 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
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#ifndef UDP_HEADER_H
-#define UDP_HEADER_H
-
-#include <stdint.h>
-#include <string>
-#include "ns3/header.h"
-#include "ns3/ipv4-address.h"
-
-namespace ns3 {
-/**
- * \brief Packet header for UDP packets
- */
-class UdpHeader : public Header 
-{
-public:
-
-  /**
-   * \brief Constructor
-   *
-   * Creates a null header
-   */
-  UdpHeader ();
-  ~UdpHeader ();
-
-  /**
-   * \brief Enable checksum calculation for UDP (XXX currently has no effect)
-   */
-  static void EnableChecksums (void);
-  /**
-   * \param port the destination port for this UdpHeader
-   */
-  void SetDestinationPort (uint16_t port);
-  /**
-   * \param port The source port for this UdpHeader
-   */
-  void SetSourcePort (uint16_t port);
-  /**
-   * \return The source port for this UdpHeader
-   */
-  uint16_t GetSourcePort (void) const;
-  /**
-   * \return the destination port for this UdpHeader
-   */
-  uint16_t GetDestinationPort (void) const;
-  /**
-   * \param size The payload size in bytes
-   */
-  void SetPayloadSize (uint16_t size);
-
-  /**
-   * \param source the ip source to use in the underlying
-   *        ip packet.
-   * \param destination the ip destination to use in the
-   *        underlying ip packet.
-   * \param protocol the protocol number to use in the underlying
-   *        ip packet.
-   *
-   * If you want to use udp checksums, you should call this
-   * method prior to adding the header to a packet.
-   */
-  void InitializeChecksum (Ipv4Address source, 
-                           Ipv4Address destination,
-                           uint8_t protocol);
-
-  static TypeId GetTypeId (void);
-  virtual TypeId GetInstanceTypeId (void) const;
-  virtual void Print (std::ostream &os) const;
-  virtual uint32_t GetSerializedSize (void) const;
-  virtual void Serialize (Buffer::Iterator start) const;
-  virtual uint32_t Deserialize (Buffer::Iterator start);
-
-private:
-  uint16_t m_sourcePort;
-  uint16_t m_destinationPort;
-  uint16_t m_payloadSize;
-  uint16_t m_initialChecksum;
-
-  static bool m_calcChecksum;
-};
-
-} // namespace ns3
-
-#endif /* UDP_HEADER */
--- a/src/internet-node/udp-l4-protocol.cc	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,194 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005 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
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#include "ns3/log.h"
-#include "ns3/assert.h"
-#include "ns3/packet.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 "udp-socket-impl.h"
-
-NS_LOG_COMPONENT_DEFINE ("UdpL4Protocol");
-
-namespace ns3 {
-
-NS_OBJECT_ENSURE_REGISTERED (UdpL4Protocol);
-
-/* see http://www.iana.org/assignments/protocol-numbers */
-const uint8_t UdpL4Protocol::PROT_NUMBER = 17;
-
-TypeId 
-UdpL4Protocol::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::UdpL4Protocol")
-    .SetParent<Ipv4L4Protocol> ()
-    .AddConstructor<UdpL4Protocol> ()
-    ;
-  return tid;
-}
-
-UdpL4Protocol::UdpL4Protocol ()
-  : m_endPoints (new Ipv4EndPointDemux ())
-{
-  NS_LOG_FUNCTION_NOARGS ();
-}
-
-UdpL4Protocol::~UdpL4Protocol ()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-}
-
-void 
-UdpL4Protocol::SetNode (Ptr<Node> node)
-{
-  m_node = node;
-}
-
-int 
-UdpL4Protocol::GetProtocolNumber (void) const
-{
-  return PROT_NUMBER;
-}
-int 
-UdpL4Protocol::GetVersion (void) const
-{
-  return 2;
-}
-
-
-void
-UdpL4Protocol::DoDispose (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  if (m_endPoints != 0)
-    {
-      delete m_endPoints;
-      m_endPoints = 0;
-    }
-  m_node = 0;
-  Ipv4L4Protocol::DoDispose ();
-}
-
-Ptr<Socket>
-UdpL4Protocol::CreateSocket (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  Ptr<UdpSocketImpl> socket = CreateObject<UdpSocketImpl> ();
-  socket->SetNode (m_node);
-  socket->SetUdp (this);
-  return socket;
-}
-
-Ipv4EndPoint *
-UdpL4Protocol::Allocate (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_endPoints->Allocate ();
-}
-
-Ipv4EndPoint *
-UdpL4Protocol::Allocate (Ipv4Address address)
-{
-  NS_LOG_FUNCTION (this << address);
-  return m_endPoints->Allocate (address);
-}
-
-Ipv4EndPoint *
-UdpL4Protocol::Allocate (uint16_t port)
-{
-  NS_LOG_FUNCTION (this << port);
-  return m_endPoints->Allocate (port);
-}
-
-Ipv4EndPoint *
-UdpL4Protocol::Allocate (Ipv4Address address, uint16_t port)
-{
-  NS_LOG_FUNCTION (this << address << port);
-  return m_endPoints->Allocate (address, port);
-}
-Ipv4EndPoint *
-UdpL4Protocol::Allocate (Ipv4Address localAddress, uint16_t localPort,
-                         Ipv4Address peerAddress, uint16_t peerPort)
-{
-  NS_LOG_FUNCTION (this << localAddress << localPort << peerAddress << peerPort);
-  return m_endPoints->Allocate (localAddress, localPort,
-                                peerAddress, peerPort);
-}
-
-void 
-UdpL4Protocol::DeAllocate (Ipv4EndPoint *endPoint)
-{
-  NS_LOG_FUNCTION (this << endPoint);
-  m_endPoints->DeAllocate (endPoint);
-}
-
-void 
-UdpL4Protocol::Receive(Ptr<Packet> packet, 
-                       Ipv4Address const &source,
-                       Ipv4Address const &destination,
-                       Ptr<Ipv4Interface> interface)
-{
-  NS_LOG_FUNCTION (this << packet << source << destination);
-
-  UdpHeader udpHeader;
-  packet->RemoveHeader (udpHeader);
-  Ipv4EndPointDemux::EndPoints endPoints =
-    m_endPoints->Lookup (destination, udpHeader.GetDestinationPort (),
-                         source, udpHeader.GetSourcePort (), interface);
-  for (Ipv4EndPointDemux::EndPointsI endPoint = endPoints.begin ();
-       endPoint != endPoints.end (); endPoint++)
-    {
-      (*endPoint)->ForwardUp (packet->Copy (), source, udpHeader.GetSourcePort ());
-    }
-}
-
-void
-UdpL4Protocol::Send (Ptr<Packet> packet, 
-                     Ipv4Address saddr, Ipv4Address daddr, 
-                     uint16_t sport, uint16_t dport)
-{
-  NS_LOG_FUNCTION (this << packet << saddr << daddr << sport << dport);
-
-  UdpHeader udpHeader;
-  udpHeader.SetDestinationPort (dport);
-  udpHeader.SetSourcePort (sport);
-  udpHeader.SetPayloadSize (packet->GetSize ());
-  udpHeader.InitializeChecksum (saddr,
-                                daddr,
-                                PROT_NUMBER);
-
-  packet->AddHeader (udpHeader);
-
-  Ptr<Ipv4L3Protocol> ipv4 = m_node->GetObject<Ipv4L3Protocol> ();
-  if (ipv4 != 0)
-    {
-      NS_LOG_LOGIC ("Sending to IP");
-      ipv4->Send (packet, saddr, daddr, PROT_NUMBER);
-    }
-}
-
-
-}; // namespace ns3
-
--- a/src/internet-node/udp-l4-protocol.h	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005,2006,2007 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
- *
- * 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 Socket;
-/**
- * \brief Implementation of the UDP protocol
- */
-class UdpL4Protocol : public Ipv4L4Protocol {
-public:
-  static TypeId GetTypeId (void);
-  static const uint8_t PROT_NUMBER;
-
-  UdpL4Protocol ();
-  virtual ~UdpL4Protocol ();
-
-  void SetNode (Ptr<Node> node);
-
-  virtual int GetProtocolNumber (void) const;
-  virtual int GetVersion (void) const;
-
-  /**
-   * \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 (Ptr<Packet> packet,
-             Ipv4Address saddr, Ipv4Address daddr, 
-             uint16_t sport, uint16_t dport);
-  /**
-   * \brief Receive 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
-   * \param interface the interface from which the packet is coming.
-   */
-  // inherited from Ipv4L4Protocol
-  virtual void Receive(Ptr<Packet> p, 
-                       Ipv4Address const &source,
-                       Ipv4Address const &destination,
-                       Ptr<Ipv4Interface> interface);
-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-factory-impl.cc	Wed Jun 11 16:19:28 2008 -0700
+++ /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) 2007 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
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#include "udp-socket-factory-impl.h"
-#include "udp-l4-protocol.h"
-#include "ns3/socket.h"
-#include "ns3/assert.h"
-
-namespace ns3 {
-
-UdpSocketFactoryImpl::UdpSocketFactoryImpl ()
-  : m_udp (0)
-{}
-UdpSocketFactoryImpl::~UdpSocketFactoryImpl ()
-{
-  NS_ASSERT (m_udp == 0);
-}
-
-void 
-UdpSocketFactoryImpl::SetUdp (Ptr<UdpL4Protocol> udp)
-{
-  m_udp = udp;
-}
-
-Ptr<Socket>
-UdpSocketFactoryImpl::CreateSocket (void)
-{
-  return m_udp->CreateSocket ();
-}
-
-void 
-UdpSocketFactoryImpl::DoDispose (void)
-{
-  m_udp = 0;
-  UdpSocketFactory::DoDispose ();
-}
-
-} // namespace ns3
--- a/src/internet-node/udp-socket-factory-impl.h	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 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
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef UDP_SOCKET_FACTORY_IMPL_H
-#define UDP_SOCKET_FACTORY_IMPL_H
-
-#include "ns3/udp-socket-factory.h"
-#include "ns3/ptr.h"
-
-namespace ns3 {
-
-class UdpL4Protocol;
-
-/**
- * \brief Object to create UDP socket instances 
- * \internal
- *
- * This class implements the API for creating UDP sockets.
- * It is a socket factory (deriving from class SocketFactory).
- */
-class UdpSocketFactoryImpl : public UdpSocketFactory
-{
-public:
-  UdpSocketFactoryImpl ();
-  virtual ~UdpSocketFactoryImpl ();
-
-  void SetUdp (Ptr<UdpL4Protocol> udp);
-
-  /**
-   * \brief Implements a method to create a Udp-based socket and return
-   * a base class smart pointer to the socket.
-   * \internal
-   *
-   * \return smart pointer to Socket
-   */
-  virtual Ptr<Socket> CreateSocket (void);
-
-protected:
-  virtual void DoDispose (void);
-private:
-  Ptr<UdpL4Protocol> m_udp;
-};
-
-} // namespace ns3
-
-#endif /* UDP_SOCKET_FACTORY_IMPL_H */
--- a/src/internet-node/udp-socket-impl.cc	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,694 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 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
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#include "ns3/log.h"
-#include "ns3/node.h"
-#include "ns3/inet-socket-address.h"
-#include "ns3/ipv4-route.h"
-#include "ns3/ipv4.h"
-#include "ns3/udp-socket-factory.h"
-#include "ns3/trace-source-accessor.h"
-#include "ns3/uinteger.h"
-#include "ns3/boolean.h"
-#include "udp-socket-impl.h"
-#include "udp-l4-protocol.h"
-#include "ipv4-end-point.h"
-#include "ipv4-l4-demux.h"
-
-NS_LOG_COMPONENT_DEFINE ("UdpSocketImpl");
-
-namespace ns3 {
-
-static const uint32_t MAX_IPV4_UDP_DATAGRAM_SIZE = 65507;
-
-// Add attributes generic to all UdpSockets to base class UdpSocket
-TypeId
-UdpSocketImpl::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::UdpSocketImpl")
-    .SetParent<UdpSocket> ()
-    .AddConstructor<UdpSocketImpl> ()
-    .AddTraceSource ("Drop", "Drop UDP packet due to receive buffer overflow",
-                     MakeTraceSourceAccessor (&UdpSocketImpl::m_dropTrace))
-    ;
-  return tid;
-}
-
-UdpSocketImpl::UdpSocketImpl ()
-  : m_endPoint (0),
-    m_node (0),
-    m_udp (0),
-    m_errno (ERROR_NOTERROR),
-    m_shutdownSend (false),
-    m_shutdownRecv (false),
-    m_connected (false),
-    m_rxAvailable (0)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-}
-
-UdpSocketImpl::~UdpSocketImpl ()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-
-  m_node = 0;
-  if (m_endPoint != 0)
-    {
-      NS_ASSERT (m_udp != 0);
-      /**
-       * Note that this piece of code is a bit tricky:
-       * when DeAllocate is called, it will call into
-       * Ipv4EndPointDemux::Deallocate which triggers
-       * a delete of the associated endPoint which triggers
-       * in turn a call to the method ::Destroy below
-       * will will zero the m_endPoint field.
-       */
-      NS_ASSERT (m_endPoint != 0);
-      m_udp->DeAllocate (m_endPoint);
-      NS_ASSERT (m_endPoint == 0);
-    }
-  m_udp = 0;
-}
-
-void 
-UdpSocketImpl::SetNode (Ptr<Node> node)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_node = node;
-
-}
-void 
-UdpSocketImpl::SetUdp (Ptr<UdpL4Protocol> udp)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_udp = udp;
-}
-
-
-enum Socket::SocketErrno
-UdpSocketImpl::GetErrno (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_errno;
-}
-
-Ptr<Node>
-UdpSocketImpl::GetNode (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_node;
-}
-
-void 
-UdpSocketImpl::Destroy (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_node = 0;
-  m_endPoint = 0;
-  m_udp = 0;
-}
-
-int
-UdpSocketImpl::FinishBind (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  if (m_endPoint == 0)
-    {
-      return -1;
-    }
-  m_endPoint->SetRxCallback (MakeCallback (&UdpSocketImpl::ForwardUp, Ptr<UdpSocketImpl> (this)));
-  m_endPoint->SetDestroyCallback (MakeCallback (&UdpSocketImpl::Destroy, Ptr<UdpSocketImpl> (this)));
-  return 0;
-}
-
-int
-UdpSocketImpl::Bind (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_endPoint = m_udp->Allocate ();
-  return FinishBind ();
-}
-
-int 
-UdpSocketImpl::Bind (const Address &address)
-{
-  NS_LOG_FUNCTION (this << address);
-
-  if (!InetSocketAddress::IsMatchingType (address))
-    {
-      NS_LOG_ERROR ("Not IsMatchingType");
-      return ERROR_INVAL;
-    }
-  InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
-  Ipv4Address ipv4 = transport.GetIpv4 ();
-  uint16_t port = transport.GetPort ();
-  if (ipv4 == Ipv4Address::GetAny () && port == 0)
-    {
-      m_endPoint = m_udp->Allocate ();
-    }
-  else if (ipv4 == Ipv4Address::GetAny () && port != 0)
-    {
-      m_endPoint = m_udp->Allocate (port);
-    }
-  else if (ipv4 != Ipv4Address::GetAny () && port == 0)
-    {
-      m_endPoint = m_udp->Allocate (ipv4);
-    }
-  else if (ipv4 != Ipv4Address::GetAny () && port != 0)
-    {
-      m_endPoint = m_udp->Allocate (ipv4, port);
-    }
-
-  return FinishBind ();
-}
-
-int 
-UdpSocketImpl::ShutdownSend (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_shutdownSend = true;
-  return 0;
-}
-
-int 
-UdpSocketImpl::ShutdownRecv (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_shutdownRecv = false;
-  return 0;
-}
-
-int
-UdpSocketImpl::Close(void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  NotifyCloseCompleted ();
-  return 0;
-}
-
-int
-UdpSocketImpl::Connect(const Address & address)
-{
-  NS_LOG_FUNCTION (this << address);
-  InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
-  m_defaultAddress = transport.GetIpv4 ();
-  m_defaultPort = transport.GetPort ();
-  NotifyConnectionSucceeded ();
-  m_connected = true;
-
-  return 0;
-}
-
-int 
-UdpSocketImpl::Listen (uint32_t queueLimit)
-{
-  m_errno = Socket::ERROR_OPNOTSUPP;
-  return -1;
-}
-
-int 
-UdpSocketImpl::Send (Ptr<Packet> p)
-{
-  NS_LOG_FUNCTION (this << p);
-
-  if (!m_connected)
-    {
-      m_errno = ERROR_NOTCONN;
-      return -1;
-    }
-  return DoSend (p);
-}
-
-int 
-UdpSocketImpl::DoSend (Ptr<Packet> p)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  if (m_endPoint == 0)
-    {
-      if (Bind () == -1)
-       {
-          NS_ASSERT (m_endPoint == 0);
-         return -1;
-       }
-      NS_ASSERT (m_endPoint != 0);
-    }
-  if (m_shutdownSend)
-    {
-      m_errno = ERROR_SHUTDOWN;
-      return -1;
-    } 
-  
-  return DoSendTo (p, m_defaultAddress, m_defaultPort);
-}
-
-int
-UdpSocketImpl::DoSendTo (Ptr<Packet> p, const Address &address)
-{
-  NS_LOG_FUNCTION (this << p << address);
-
-  if (!m_connected)
-    {
-      NS_LOG_LOGIC ("Not connected");
-      InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
-      Ipv4Address ipv4 = transport.GetIpv4 ();
-      uint16_t port = transport.GetPort ();
-      return DoSendTo (p, ipv4, port);
-    }
-  else
-    {
-      // connected UDP socket must use default addresses
-      NS_LOG_LOGIC ("Connected");
-      return DoSendTo (p, m_defaultAddress, m_defaultPort);
-    }
-}
-
-int
-UdpSocketImpl::DoSendTo (Ptr<Packet> p, Ipv4Address dest, uint16_t port)
-{
-  NS_LOG_FUNCTION (this << p << dest << port);
-
-  if (m_endPoint == 0)
-    {
-      if (Bind () == -1)
-	{
-          NS_ASSERT (m_endPoint == 0);
-	  return -1;
-	}
-      NS_ASSERT (m_endPoint != 0);
-    }
-  if (m_shutdownSend)
-    {
-      m_errno = ERROR_SHUTDOWN;
-      return -1;
-    }
-
-  if (p->GetSize () > GetTxAvailable () )
-    {
-      m_errno = ERROR_MSGSIZE;
-      return -1;
-    }
-
-  uint32_t localIfIndex;
-  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
-
-  // Locally override the IP TTL for this socket
-  // We cannot directly modify the TTL at this stage, so we set a Packet tag
-  // The destination can be either multicast, unicast/anycast, or
-  // either all-hosts broadcast or limited (subnet-directed) broadcast.
-  // For the latter two broadcast types, the TTL will later be set to one
-  // irrespective of what is set in these socket options.  So, this tagging  
-  // may end up setting the TTL of a limited broadcast packet to be
-  // the same as a unicast, but it will be fixed further down the stack
-  //NS_LOG_UNCOND ("IPttl: " << m_ipTtl);
-  if (m_ipMulticastTtl != 0 && dest.IsMulticast ())
-    {
-      SocketIpTtlTag tag;
-      tag.SetTtl (m_ipMulticastTtl);
-      p->AddTag (tag);
-    }
-  else if (m_ipTtl != 0 && !dest.IsMulticast () && !dest.IsBroadcast ())
-    {
-      SocketIpTtlTag tag;
-      tag.SetTtl (m_ipTtl);
-      p->AddTag (tag);
-    }
-  //
-  // If dest is sent to the limited broadcast address (all ones),
-  // convert it to send a copy of the packet out of every interface
-  //
-  if (dest.IsBroadcast ())
-    {
-      NS_LOG_LOGIC ("Limited broadcast start.");
-      for (uint32_t i = 0; i < ipv4->GetNInterfaces (); i++ )
-        {
-          Ipv4Address addri = ipv4->GetAddress (i);
-          Ipv4Mask maski = ipv4->GetNetworkMask (i);
-          Ipv4Address bcast = addri.GetSubnetDirectedBroadcast (maski);
-          NS_LOG_LOGIC ("Sending one copy from " << addri << " to " << bcast
-                        << " (mask is " << maski << ")");
-          m_udp->Send (p->Copy (), addri, bcast,
-                       m_endPoint->GetLocalPort (), port);
-          NotifyDataSent (p->GetSize ());
-        }
-      NS_LOG_LOGIC ("Limited broadcast end.");
-      return p->GetSize();
-    }
-  else if (ipv4->GetIfIndexForDestination(dest, localIfIndex))
-    {
-      NS_LOG_LOGIC ("Route exists");
-      m_udp->Send (p->Copy (), ipv4->GetAddress (localIfIndex), dest,
-		   m_endPoint->GetLocalPort (), port);
-      NotifyDataSent (p->GetSize ());
-      return p->GetSize();;
-    }
-  else
-   {
-      NS_LOG_ERROR ("ERROR_NOROUTETOHOST");
-      m_errno = ERROR_NOROUTETOHOST;
-      return -1;
-   }
-
-  return 0;
-}
-
-// XXX maximum message size for UDP broadcast is limited by MTU
-// size of underlying link; we are not checking that now.
-uint32_t
-UdpSocketImpl::GetTxAvailable (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  // No finite send buffer is modelled, but we must respect
-  // the maximum size of an IP datagram (65535 bytes - headers).
-  return MAX_IPV4_UDP_DATAGRAM_SIZE;
-}
-
-int 
-UdpSocketImpl::SendTo (Ptr<Packet> p, const Address &address)
-{
-  NS_LOG_FUNCTION (this << address << p);
-  InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
-  Ipv4Address ipv4 = transport.GetIpv4 ();
-  uint16_t port = transport.GetPort ();
-  return DoSendTo (p, ipv4, port);
-}
-
-Ptr<Packet>
-UdpSocketImpl::Recv (uint32_t maxSize, uint32_t flags)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  if (m_deliveryQueue.empty() )
-    {
-      return 0;
-    }
-  Ptr<Packet> p = m_deliveryQueue.front ();
-  if (p->GetSize () <= maxSize) 
-    {
-      m_deliveryQueue.pop ();
-      m_rxAvailable -= p->GetSize ();
-    }
-  else
-    {
-      p = 0; 
-    }
-  return p;
-}
-
-uint32_t
-UdpSocketImpl::GetRxAvailable (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  // We separately maintain this state to avoid walking the queue 
-  // every time this might be called
-  return m_rxAvailable;
-}
-
-void 
-UdpSocketImpl::ForwardUp (Ptr<Packet> packet, Ipv4Address ipv4, uint16_t port)
-{
-  NS_LOG_FUNCTION (this << packet << ipv4 << port);
-
-  if (m_shutdownRecv)
-    {
-      return;
-    }
-  if ((m_rxAvailable + packet->GetSize ()) <= m_rcvBufSize)
-    {
-      Address address = InetSocketAddress (ipv4, port);
-      SocketRxAddressTag tag;
-      tag.SetAddress (address);
-      packet->AddTag (tag);
-      m_deliveryQueue.push (packet);
-      m_rxAvailable += packet->GetSize ();
-      NotifyDataRecv ();
-    }
-  else
-    {
-      // In general, this case should not occur unless the
-      // receiving application reads data from this socket slowly
-      // in comparison to the arrival rate
-      //
-      // drop and trace packet
-      NS_LOG_WARN ("No receive buffer space available.  Drop.");
-      m_dropTrace (packet);
-    }
-}
-
-
-void 
-UdpSocketImpl::SetRcvBufSize (uint32_t size)
-{
-  m_rcvBufSize = size;
-}
-
-uint32_t 
-UdpSocketImpl::GetRcvBufSize (void) const
-{
-  return m_rcvBufSize;
-}
-
-void 
-UdpSocketImpl::SetIpTtl (uint32_t ipTtl)
-{
-  m_ipTtl = ipTtl;
-}
-
-uint32_t 
-UdpSocketImpl::GetIpTtl (void) const
-{
-  return m_ipTtl;
-}
-
-void 
-UdpSocketImpl::SetIpMulticastTtl (uint32_t ipTtl)
-{
-  m_ipMulticastTtl = ipTtl;
-}
-
-uint32_t 
-UdpSocketImpl::GetIpMulticastTtl (void) const
-{
-  return m_ipMulticastTtl;
-}
-
-} //namespace ns3
-
-
-#ifdef RUN_SELF_TESTS
-
-#include "ns3/test.h"
-#include "ns3/socket-factory.h"
-#include "ns3/udp-socket-factory.h"
-#include "ns3/simulator.h"
-#include "ns3/simple-channel.h"
-#include "ns3/simple-net-device.h"
-#include "ns3/drop-tail-queue.h"
-#include "internet-stack.h"
-#include <string>
-
-namespace ns3 {
-
-class UdpSocketImplTest: public Test
-{
-  Ptr<Packet> m_receivedPacket;
-  Ptr<Packet> m_receivedPacket2;
-
-public:
-  virtual bool RunTests (void);
-  UdpSocketImplTest ();
-
-  void ReceivePacket (Ptr<Socket> socket, Ptr<Packet> packet, const Address &from);
-  void ReceivePacket2 (Ptr<Socket> socket, Ptr<Packet> packet, const Address &from);
-  void ReceivePkt (Ptr<Socket> socket);
-  void ReceivePkt2 (Ptr<Socket> socket);
-};
-
-
-UdpSocketImplTest::UdpSocketImplTest ()
-  : Test ("UdpSocketImpl") 
-{
-}
-
-void UdpSocketImplTest::ReceivePacket (Ptr<Socket> socket, Ptr<Packet> packet, const Address &from)
-{
-  m_receivedPacket = packet;
-}
-
-void UdpSocketImplTest::ReceivePacket2 (Ptr<Socket> socket, Ptr<Packet> packet, const Address &from)
-{
-  m_receivedPacket2 = packet;
-}
-
-void UdpSocketImplTest::ReceivePkt (Ptr<Socket> socket)
-{
-  uint32_t availableData;
-  availableData = socket->GetRxAvailable ();
-  m_receivedPacket = socket->Recv (std::numeric_limits<uint32_t>::max(), 0);
-  NS_ASSERT (availableData == m_receivedPacket->GetSize ());
-}
-
-void UdpSocketImplTest::ReceivePkt2 (Ptr<Socket> socket)
-{
-  uint32_t availableData;
-  availableData = socket->GetRxAvailable ();
-  m_receivedPacket2 = socket->Recv (std::numeric_limits<uint32_t>::max(), 0);
-  NS_ASSERT (availableData == m_receivedPacket2->GetSize ());
-}
-
-bool
-UdpSocketImplTest::RunTests (void)
-{
-  bool result = true;
-
-  // Create topology
-  
-  // Receiver Node
-  Ptr<Node> rxNode = CreateObject<Node> ();
-  AddInternetStack (rxNode);
-  Ptr<SimpleNetDevice> rxDev1, rxDev2;
-  { // first interface
-    rxDev1 = CreateObject<SimpleNetDevice> ();
-    rxDev1->SetAddress (Mac48Address::Allocate ());
-    rxNode->AddDevice (rxDev1);
-    Ptr<Ipv4> ipv4 = rxNode->GetObject<Ipv4> ();
-    uint32_t netdev_idx = ipv4->AddInterface (rxDev1);
-    ipv4->SetAddress (netdev_idx, Ipv4Address ("10.0.0.1"));
-    ipv4->SetNetworkMask (netdev_idx, Ipv4Mask (0xffff0000U));
-    ipv4->SetUp (netdev_idx);
-  }
-
-  { // second interface
-    rxDev2 = CreateObject<SimpleNetDevice> ();
-    rxDev2->SetAddress (Mac48Address::Allocate ());
-    rxNode->AddDevice (rxDev2);
-    Ptr<Ipv4> ipv4 = rxNode->GetObject<Ipv4> ();
-    uint32_t netdev_idx = ipv4->AddInterface (rxDev2);
-    ipv4->SetAddress (netdev_idx, Ipv4Address ("10.0.1.1"));
-    ipv4->SetNetworkMask (netdev_idx, Ipv4Mask (0xffff0000U));
-    ipv4->SetUp (netdev_idx);
-  }
-  
-  // Sender Node
-  Ptr<Node> txNode = CreateObject<Node> ();
-  AddInternetStack (txNode);
-  Ptr<SimpleNetDevice> txDev1;
-  {
-    txDev1 = CreateObject<SimpleNetDevice> ();
-    txDev1->SetAddress (Mac48Address::Allocate ());
-    txNode->AddDevice (txDev1);
-    Ptr<Ipv4> ipv4 = txNode->GetObject<Ipv4> ();
-    uint32_t netdev_idx = ipv4->AddInterface (txDev1);
-    ipv4->SetAddress (netdev_idx, Ipv4Address ("10.0.0.2"));
-    ipv4->SetNetworkMask (netdev_idx, Ipv4Mask (0xffff0000U));
-    ipv4->SetUp (netdev_idx);
-  }
-  Ptr<SimpleNetDevice> txDev2;
-  {
-    txDev2 = CreateObject<SimpleNetDevice> ();
-    txDev2->SetAddress (Mac48Address::Allocate ());
-    txNode->AddDevice (txDev2);
-    Ptr<Ipv4> ipv4 = txNode->GetObject<Ipv4> ();
-    uint32_t netdev_idx = ipv4->AddInterface (txDev2);
-    ipv4->SetAddress (netdev_idx, Ipv4Address ("10.0.1.2"));
-    ipv4->SetNetworkMask (netdev_idx, Ipv4Mask (0xffff0000U));
-    ipv4->SetUp (netdev_idx);
-  }
-
-  // link the two nodes
-  Ptr<SimpleChannel> channel1 = CreateObject<SimpleChannel> ();
-  rxDev1->SetChannel (channel1);
-  txDev1->SetChannel (channel1);
-
-  Ptr<SimpleChannel> channel2 = CreateObject<SimpleChannel> ();
-  rxDev2->SetChannel (channel2);
-  txDev2->SetChannel (channel2);
-
-
-  // Create the UDP sockets
-  Ptr<SocketFactory> rxSocketFactory = rxNode->GetObject<UdpSocketFactory> ();
-  Ptr<Socket> rxSocket = rxSocketFactory->CreateSocket ();
-  NS_TEST_ASSERT_EQUAL (rxSocket->Bind (InetSocketAddress (Ipv4Address ("10.0.0.1"), 1234)), 0);
-  rxSocket->SetRecvCallback (MakeCallback (&UdpSocketImplTest::ReceivePkt, this));
-
-  Ptr<Socket> rxSocket2 = rxSocketFactory->CreateSocket ();
-  rxSocket2->SetRecvCallback (MakeCallback (&UdpSocketImplTest::ReceivePkt2, this));
-  NS_TEST_ASSERT_EQUAL (rxSocket2->Bind (InetSocketAddress (Ipv4Address ("10.0.1.1"), 1234)), 0);
-
-  Ptr<SocketFactory> txSocketFactory = txNode->GetObject<UdpSocketFactory> ();
-  Ptr<Socket> txSocket = txSocketFactory->CreateSocket ();
-
-  // ------ Now the tests ------------
-
-  // Unicast test
-  m_receivedPacket = Create<Packet> ();
-  m_receivedPacket2 = Create<Packet> ();
-  NS_TEST_ASSERT_EQUAL (txSocket->SendTo ( Create<Packet> (123), 
-    InetSocketAddress (Ipv4Address("10.0.0.1"), 1234)), 123);
-  Simulator::Run ();
-  NS_TEST_ASSERT_EQUAL (m_receivedPacket->GetSize (), 123);
-  NS_TEST_ASSERT_EQUAL (m_receivedPacket2->GetSize (), 0); // second interface should receive it
-
-  m_receivedPacket->RemoveAllTags ();
-  m_receivedPacket2->RemoveAllTags ();
-
-  // Simple broadcast test
-
-  m_receivedPacket = Create<Packet> ();
-  m_receivedPacket2 = Create<Packet> ();
-  NS_TEST_ASSERT_EQUAL (txSocket->SendTo ( Create<Packet> (123), 
-    InetSocketAddress (Ipv4Address("255.255.255.255"), 1234)), 123);
-  Simulator::Run ();
-  NS_TEST_ASSERT_EQUAL (m_receivedPacket->GetSize (), 123);
-  // second socket should not receive it (it is bound specifically to the second interface's address
-  NS_TEST_ASSERT_EQUAL (m_receivedPacket2->GetSize (), 0);
-
-  m_receivedPacket->RemoveAllTags ();
-  m_receivedPacket2->RemoveAllTags ();
-
-  // Broadcast test with multiple receiving sockets
-
-  // When receiving broadcast packets, all sockets sockets bound to
-  // the address/port should receive a copy of the same packet -- if
-  // the socket address matches.
-  rxSocket2->Dispose ();
-  rxSocket2 = rxSocketFactory->CreateSocket ();
-  rxSocket2->SetRecvCallback (MakeCallback (&UdpSocketImplTest::ReceivePkt2, this));
-  NS_TEST_ASSERT_EQUAL (rxSocket2->Bind (InetSocketAddress (Ipv4Address ("0.0.0.0"), 1234)), 0);
-
-  m_receivedPacket = Create<Packet> ();
-  m_receivedPacket2 = Create<Packet> ();
-  NS_TEST_ASSERT_EQUAL (txSocket->SendTo (Create<Packet> (123),
-InetSocketAddress (Ipv4Address("255.255.255.255"), 1234)), 123);
-  Simulator::Run ();
-  NS_TEST_ASSERT_EQUAL (m_receivedPacket->GetSize (), 123);
-  NS_TEST_ASSERT_EQUAL (m_receivedPacket2->GetSize (), 123);
-
-  m_receivedPacket->RemoveAllTags ();
-  m_receivedPacket2->RemoveAllTags ();
-
-  Simulator::Destroy ();
-
-  return result;
-}
-
-static UdpSocketImplTest gUdpSocketImplTest;
-
-}; // namespace ns3
-
-#endif /* RUN_SELF_TESTS */
--- a/src/internet-node/udp-socket-impl.h	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,112 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 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
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef UDP_SOCKET_IMPL_H
-#define UDP_SOCKET_IMPL_H
-
-#include <stdint.h>
-#include <queue>
-#include "ns3/callback.h"
-#include "ns3/traced-callback.h"
-#include "ns3/socket.h"
-#include "ns3/ptr.h"
-#include "ns3/ipv4-address.h"
-#include "ns3/udp-socket.h"
-
-namespace ns3 {
-
-class Ipv4EndPoint;
-class Node;
-class Packet;
-class UdpL4Protocol;
-
-class UdpSocketImpl : public UdpSocket
-{
-public:
-  static TypeId GetTypeId (void);
-  /**
-   * Create an unbound udp socket.
-   */
-  UdpSocketImpl ();
-  virtual ~UdpSocketImpl ();
-
-  void SetNode (Ptr<Node> node);
-  void SetUdp (Ptr<UdpL4Protocol> udp);
-
-  virtual enum SocketErrno GetErrno (void) const;
-  virtual Ptr<Node> GetNode (void) const;
-  virtual int Bind (void);
-  virtual int Bind (const Address &address);
-  virtual int Close (void);
-  virtual int ShutdownSend (void);
-  virtual int ShutdownRecv (void);
-  virtual int Connect(const Address &address);
-  virtual int Listen (uint32_t queueLimit);
-  virtual int Send (Ptr<Packet> p);
-  virtual int SendTo (Ptr<Packet> p, const Address &address);
-  virtual uint32_t GetTxAvailable (void) const;
-
-  virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags);
-  virtual uint32_t GetRxAvailable (void) const;
-
-private:
-  // Attributes set through UdpSocket base class 
-  virtual void SetRcvBufSize (uint32_t size);
-  virtual uint32_t GetRcvBufSize (void) const;
-  virtual void SetIpTtl (uint32_t ipTtl);
-  virtual uint32_t GetIpTtl (void) const;
-  virtual void SetIpMulticastTtl (uint32_t ipTtl);
-  virtual uint32_t GetIpMulticastTtl (void) const;
-
-  friend class UdpSocketFactory;
-  // invoked by Udp class
-  int FinishBind (void);
-  void ForwardUp (Ptr<Packet> p, Ipv4Address ipv4, uint16_t port);
-  void Destroy (void);
-  int DoSend (Ptr<Packet> p);
-  int DoSendTo (Ptr<Packet> p, const Address &daddr);
-  int DoSendTo (Ptr<Packet> p, Ipv4Address daddr, uint16_t dport);
-
-  Ipv4EndPoint *m_endPoint;
-  Ptr<Node> m_node;
-  Ptr<UdpL4Protocol> m_udp;
-  Ipv4Address m_defaultAddress;
-  uint16_t m_defaultPort;
-  Callback<void,Ptr<Socket>,uint32_t,const Address &> m_dummyRxCallback;
-  Callback<void,Ptr<Socket>,uint8_t const*,uint32_t,const Address &> m_rxCallback;
-  TracedCallback<Ptr<const Packet> > m_dropTrace;
-
-  enum SocketErrno m_errno;
-  bool m_shutdownSend;
-  bool m_shutdownRecv;
-  bool m_connected;
-
-  std::queue<Ptr<Packet> > m_deliveryQueue;
-  uint32_t m_rxAvailable;
-  
-  // Socket attributes
-  uint32_t m_rcvBufSize;
-  uint32_t m_ipTtl;
-  uint32_t m_ipMulticastTtl;
-
-};
-
-}//namespace ns3
-
-#endif /* UDP_SOCKET_IMPL_H */
--- a/src/internet-node/waf	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-exec "`dirname "$0"`"/../../waf "$@"
\ No newline at end of file
--- a/src/internet-node/wscript	Wed Jun 11 16:19:28 2008 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
-
-
-def build(bld):
-    obj = bld.create_ns3_module('internet-node', ['node'])
-    obj.source = [
-        'internet-stack.cc',
-        'ipv4-l4-demux.cc',
-        'ipv4-l4-protocol.cc',
-        'udp-header.cc',
-        'tcp-header.cc',
-        'ipv4-checksum.cc',
-        'ipv4-interface.cc',
-        'ipv4-l3-protocol.cc',
-        'ipv4-static-routing.cc',
-        'ipv4-end-point.cc',
-        'udp-l4-protocol.cc',
-        'tcp-l4-protocol.cc',
-        'arp-header.cc',
-        'arp-cache.cc',
-        'arp-ipv4-interface.cc',
-        'arp-l3-protocol.cc',
-        'ipv4-loopback-interface.cc',
-        'udp-socket-impl.cc',
-        'tcp-socket-impl.cc',
-        'ipv4-end-point-demux.cc',
-        'ipv4-impl.cc',
-        'udp-socket-factory-impl.cc',
-        'tcp-socket-factory-impl.cc',
-        'pending-data.cc',
-        'sequence-number.cc',
-        'rtt-estimator.cc',
-        ]
-
-    headers = bld.create_obj('ns3header')
-    headers.module = 'internet-node'
-    headers.source = [
-        'internet-stack.h',
-        'udp-header.h',
-        'tcp-header.h',
-        'sequence-number.h',
-        ]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/arp-cache.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,287 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "ns3/assert.h"
+#include "ns3/packet.h"
+#include "ns3/simulator.h"
+#include "ns3/uinteger.h"
+#include "ns3/log.h"
+
+#include "arp-cache.h"
+#include "arp-header.h"
+#include "ipv4-interface.h"
+
+NS_LOG_COMPONENT_DEFINE ("ArpCache");
+
+namespace ns3 {
+
+TypeId 
+ArpCache::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::ArpCache")
+    .SetParent<Object> ()
+    .AddAttribute ("AliveTimeout",
+                   "When this timeout expires, the matching cache entry needs refreshing",
+                   TimeValue (Seconds (120)),
+                   MakeTimeAccessor (&ArpCache::m_aliveTimeout),
+                   MakeTimeChecker ())
+    .AddAttribute ("DeadTimeout",
+                   "When this timeout expires, a new attempt to resolve the matching entry is made",
+                   TimeValue (Seconds (100)),
+                   MakeTimeAccessor (&ArpCache::m_deadTimeout),
+                   MakeTimeChecker ())
+    .AddAttribute ("WaitReplyTimeout",
+                   "When this timeout expires, the matching cache entry is marked dead",
+                   TimeValue (Seconds (1)),
+                   MakeTimeAccessor (&ArpCache::m_waitReplyTimeout),
+                   MakeTimeChecker ())
+    .AddAttribute ("PendingQueueSize",
+                   "The size of the queue for packets pending an arp reply.",
+                   UintegerValue (3),
+                   MakeUintegerAccessor (&ArpCache::m_pendingQueueSize),
+                   MakeUintegerChecker<uint32_t> ())
+    ;
+  return tid;
+}
+
+ArpCache::ArpCache ()
+  : m_device (0), 
+    m_interface (0)
+{
+  NS_LOG_FUNCTION (this);
+}
+
+ArpCache::~ArpCache ()
+{
+  NS_LOG_FUNCTION (this);
+}
+
+void 
+ArpCache::DoDispose (void)
+{
+  NS_LOG_FUNCTION (this);
+  Flush ();
+  m_device = 0;
+  m_interface = 0;
+  Object::DoDispose ();
+}
+
+void
+ArpCache::SetDevice (Ptr<NetDevice> device, Ptr<Ipv4Interface> interface)
+{
+  m_device = device;
+  m_interface = interface;
+}
+
+Ptr<NetDevice>
+ArpCache::GetDevice (void) const
+{
+  return m_device;
+}
+
+Ptr<Ipv4Interface>
+ArpCache::GetInterface (void) const
+{
+  return m_interface;
+}
+
+void 
+ArpCache::SetAliveTimeout (Time aliveTimeout)
+{
+  m_aliveTimeout = aliveTimeout;
+}
+void 
+ArpCache::SetDeadTimeout (Time deadTimeout)
+{
+  m_deadTimeout = deadTimeout;
+}
+void 
+ArpCache::SetWaitReplyTimeout (Time waitReplyTimeout)
+{
+  m_waitReplyTimeout = waitReplyTimeout;
+}
+
+Time
+ArpCache::GetAliveTimeout (void) const
+{
+  return m_aliveTimeout;
+}
+Time
+ArpCache::GetDeadTimeout (void) const
+{
+  return m_deadTimeout;
+}
+Time
+ArpCache::GetWaitReplyTimeout (void) const
+{
+  return m_waitReplyTimeout;
+}
+
+void 
+ArpCache::Flush (void)
+{
+  for (CacheI i = m_arpCache.begin (); i != m_arpCache.end (); i++) 
+    {
+      delete (*i).second;
+    }
+  m_arpCache.erase (m_arpCache.begin (), m_arpCache.end ());
+}
+
+ArpCache::Entry *
+ArpCache::Lookup (Ipv4Address to)
+{
+  if (m_arpCache.find (to) != m_arpCache.end ()) 
+    {
+      ArpCache::Entry *entry = m_arpCache[to];
+      return entry;
+    }
+  return 0;
+}
+
+ArpCache::Entry *
+ArpCache::Add (Ipv4Address to)
+{
+  NS_ASSERT (m_arpCache.find (to) == m_arpCache.end ());
+
+  ArpCache::Entry *entry = new ArpCache::Entry (this);
+  m_arpCache[to] = entry;  
+  return entry;
+}
+
+ArpCache::Entry::Entry (ArpCache *arp)
+  : m_arp (arp),
+    m_state (ALIVE)
+{}
+
+
+bool 
+ArpCache::Entry::IsDead (void)
+{
+  return (m_state == DEAD)?true:false;
+}
+bool 
+ArpCache::Entry::IsAlive (void)
+{
+  return (m_state == ALIVE)?true:false;
+}
+bool
+ArpCache::Entry::IsWaitReply (void)
+{
+  return (m_state == WAIT_REPLY)?true:false;
+}
+
+
+void 
+ArpCache::Entry::MarkDead (void) 
+{
+  m_state = DEAD;
+  UpdateSeen ();
+}
+void
+ArpCache::Entry::MarkAlive (Address macAddress) 
+{
+  NS_ASSERT (m_state == WAIT_REPLY);
+  m_macAddress = macAddress;
+  m_state = ALIVE;
+  UpdateSeen ();
+}
+
+bool
+ArpCache::Entry::UpdateWaitReply (Ptr<Packet> waiting)
+{
+  NS_ASSERT (m_state == WAIT_REPLY);
+  /* We are already waiting for an answer so
+   * we dump the previously waiting packet and
+   * replace it with this one.
+   */
+  if (m_pending.size () >= m_arp->m_pendingQueueSize)
+    {
+      return false;
+    }
+  m_pending.push_back (waiting);
+  return true;
+}
+void 
+ArpCache::Entry::MarkWaitReply (Ptr<Packet> waiting)
+{
+  NS_ASSERT (m_state == ALIVE || m_state == DEAD);
+  NS_ASSERT (m_pending.empty ());
+  m_state = WAIT_REPLY;
+  m_pending.push_back (waiting);
+  UpdateSeen ();
+}
+
+Address
+ArpCache::Entry::GetMacAddress (void)
+{
+  NS_ASSERT (m_state == ALIVE);
+  return m_macAddress;
+}
+bool 
+ArpCache::Entry::IsExpired (void)
+{
+  Time timeout;
+  switch (m_state) {
+  case ArpCache::Entry::WAIT_REPLY:
+    timeout = m_arp->GetWaitReplyTimeout ();
+    break;
+  case ArpCache::Entry::DEAD:
+    timeout = m_arp->GetDeadTimeout ();
+    break;
+  case ArpCache::Entry::ALIVE:
+    timeout = m_arp->GetAliveTimeout ();
+    break;
+  default:
+    NS_ASSERT (false);
+    timeout = Seconds (0);
+    /* NOTREACHED */
+    break;
+  }
+  Time delta = Simulator::Now () - m_lastSeen;
+  if (delta >= timeout) 
+    {
+      return true;
+    } 
+  else 
+    {
+      return false;
+    }
+}
+Ptr<Packet> 
+ArpCache::Entry::DequeuePending (void)
+{
+  if (m_pending.empty ())
+    {
+      return 0;
+    }
+  else
+    {
+      Ptr<Packet> p = m_pending.front ();
+      m_pending.pop_front ();
+      return p;
+    }
+}
+void 
+ArpCache::Entry::UpdateSeen (void)
+{
+  m_lastSeen = Simulator::Now ();
+}
+
+} // namespace ns3
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/arp-cache.h	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,178 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef ARP_CACHE_H
+#define ARP_CACHE_H
+
+#include <stdint.h>
+#include <list>
+#include "ns3/packet.h"
+#include "ns3/nstime.h"
+#include "ns3/net-device.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/address.h"
+#include "ns3/ptr.h"
+#include "ns3/object.h"
+#include "sgi-hashmap.h"
+
+namespace ns3 {
+
+class NetDevice;
+class Ipv4Interface;
+
+/**
+ * \brief An ARP cache
+ *
+ * A cached lookup table for translating layer 3 addresses to layer 2.
+ * This implementation does lookups from IPv4 to a MAC address
+ */
+class ArpCache : public Object
+{
+public:
+  static TypeId GetTypeId (void);
+  class Entry;
+  ArpCache ();
+  ~ArpCache ();
+
+  /**
+   * \param device The hardware NetDevice associated with this ARP chache
+   * \param interface the Ipv4Interface associated with this ARP chache
+   */
+  void SetDevice (Ptr<NetDevice> device, Ptr<Ipv4Interface> interface);
+  /**
+   * \return The NetDevice that this ARP cache is associated with
+   */
+  Ptr<NetDevice> GetDevice (void) const;
+  /**
+   * \return the Ipv4Interface that this ARP cache is associated with
+   */
+  Ptr<Ipv4Interface> GetInterface (void) const;
+  
+  void SetAliveTimeout (Time aliveTimeout);
+  void SetDeadTimeout (Time deadTimeout);
+  void SetWaitReplyTimeout (Time waitReplyTimeout);
+  Time GetAliveTimeout (void) const;
+  Time GetDeadTimeout (void) const;
+  Time GetWaitReplyTimeout (void) const;
+
+  /**
+   * \brief Do lookup in the ARP chache against an IP address
+   * \param destination The destination IPv4 address to lookup the MAC address
+   * of
+   * \return An ArpCache::Entry with info about layer 2
+   */
+  ArpCache::Entry *Lookup (Ipv4Address destination);
+  /**
+   * \brief Add an Ipv4Address to this ARP cache
+   */
+  ArpCache::Entry *Add (Ipv4Address to);
+  /**
+   * \brief Clear the ArpCache of all entries
+   */
+  void Flush (void);
+
+  /**
+   * \brief A record that that holds information about an ArpCache entry
+   */
+  class Entry {
+  public:
+    /**
+     * \brief Constructor
+     * \param arp The ArpCache this entry belongs to
+     */
+    Entry (ArpCache *arp);
+    
+    /**
+     * \brief Changes the state of this entry to dead
+     */
+    void MarkDead (void);
+    /**
+     * \param macAddress
+     */
+    void MarkAlive (Address macAddress);
+    /**
+     * \param waiting
+     */
+    void MarkWaitReply (Ptr<Packet> waiting);
+    /**
+     * \param waiting
+     * \return 
+     */
+    bool UpdateWaitReply (Ptr<Packet> waiting);
+    /**
+     * \return True if the state of this entry is dead; false otherwise.
+     */
+    bool IsDead (void);
+    /**
+     * \return True if the state of this entry is alive; false otherwise.
+     */
+    bool IsAlive (void);
+    /**
+     * \return True if the state of this entry is wait_reply; false otherwise.
+     */
+    bool IsWaitReply (void);
+    
+    /**
+     * \return The MacAddress of this entry
+     */
+    Address GetMacAddress (void);
+    /**
+     * \return True if this entry has timedout; false otherwise.
+     */
+    bool IsExpired (void);
+
+    /**
+     * \returns 0 is no packet is pending, the next packet to send if 
+     *            packets are pending.
+     */
+    Ptr<Packet> DequeuePending (void);
+  private:
+    enum ArpCacheEntryState_e {
+      ALIVE,
+      WAIT_REPLY,
+      DEAD
+    };
+
+    void UpdateSeen (void);
+    ArpCache *m_arp;
+    ArpCacheEntryState_e m_state;
+    Time m_lastSeen;
+    Address m_macAddress;
+    std::list<Ptr<Packet> > m_pending;
+  };
+
+private:
+  typedef sgi::hash_map<Ipv4Address, ArpCache::Entry *, Ipv4AddressHash> Cache;
+  typedef sgi::hash_map<Ipv4Address, ArpCache::Entry *, Ipv4AddressHash>::iterator CacheI;
+
+  virtual void DoDispose (void);
+
+  Ptr<NetDevice> m_device;
+  Ptr<Ipv4Interface> m_interface;
+  Time m_aliveTimeout;
+  Time m_deadTimeout;
+  Time m_waitReplyTimeout;
+  uint32_t m_pendingQueueSize;
+  Cache m_arpCache;
+};
+
+
+}; // namespace ns3
+
+#endif /* ARP_CACHE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/arp-header.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,161 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#include "ns3/assert.h"
+#include "ns3/address-utils.h"
+#include "arp-header.h"
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (ArpHeader);
+
+void 
+ArpHeader::SetRequest (Address sourceHardwareAddress,
+                       Ipv4Address sourceProtocolAddress,
+                       Address destinationHardwareAddress,
+                       Ipv4Address destinationProtocolAddress)
+{
+  m_type = ARP_TYPE_REQUEST;
+  m_macSource = sourceHardwareAddress;
+  m_macDest = destinationHardwareAddress;
+  m_ipv4Source = sourceProtocolAddress;
+  m_ipv4Dest = destinationProtocolAddress;
+}
+void 
+ArpHeader::SetReply (Address sourceHardwareAddress,
+                     Ipv4Address sourceProtocolAddress,
+                     Address destinationHardwareAddress,
+                     Ipv4Address destinationProtocolAddress)
+{
+  m_type = ARP_TYPE_REPLY;
+  m_macSource = sourceHardwareAddress;
+  m_macDest = destinationHardwareAddress;
+  m_ipv4Source = sourceProtocolAddress;
+  m_ipv4Dest = destinationProtocolAddress;
+}
+bool 
+ArpHeader::IsRequest (void) const
+{
+  return (m_type == ARP_TYPE_REQUEST)?true:false;
+}
+bool 
+ArpHeader::IsReply (void) const
+{
+  return (m_type == ARP_TYPE_REPLY)?true:false;
+}
+Address 
+ArpHeader::GetSourceHardwareAddress (void)
+{
+  return m_macSource;
+}
+Address 
+ArpHeader::GetDestinationHardwareAddress (void)
+{
+  return m_macDest;
+}
+Ipv4Address 
+ArpHeader::GetSourceIpv4Address (void)
+{
+  return m_ipv4Source;
+}
+Ipv4Address 
+ArpHeader::GetDestinationIpv4Address (void)
+{
+  return m_ipv4Dest;
+}
+
+
+TypeId 
+ArpHeader::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::ArpHeader")
+    .SetParent<Header> ()
+    .AddConstructor<ArpHeader> ()
+    ;
+  return tid;
+}
+TypeId 
+ArpHeader::GetInstanceTypeId (void) const
+{
+  return GetTypeId ();
+}
+void 
+ArpHeader::Print (std::ostream &os) const
+{
+  if (IsRequest ()) 
+    {
+      os << "request "
+         << "source mac: " << m_macSource << " "
+         << "source ipv4: " << m_ipv4Source << " "
+         << "dest ipv4: " << m_ipv4Dest
+        ;
+    } 
+  else 
+    {
+      NS_ASSERT (IsReply ());
+      os << "reply " 
+         << "source mac: " << m_macSource << " "
+         << "source ipv4: " << m_ipv4Source << " "
+         << "dest mac: " << m_macDest << " "
+         << "dest ipv4: " <<m_ipv4Dest
+        ;
+    }
+}
+uint32_t 
+ArpHeader::GetSerializedSize (void) const
+{
+  /* this is the size of an ARP payload. */
+  return 28;
+}
+
+void
+ArpHeader::Serialize (Buffer::Iterator start) const
+{
+  Buffer::Iterator i = start;
+  NS_ASSERT (m_macSource.GetLength () == m_macDest.GetLength ());
+
+  /* ethernet */
+  i.WriteHtonU16 (0x0001);
+  /* ipv4 */
+  i.WriteHtonU16 (0x0800);
+  i.WriteU8 (m_macSource.GetLength ());
+  i.WriteU8 (4);
+  i.WriteHtonU16 (m_type);
+  WriteTo (i, m_macSource);
+  WriteTo (i, m_ipv4Source);
+  WriteTo (i, m_macDest);
+  WriteTo (i, m_ipv4Dest);
+}
+uint32_t
+ArpHeader::Deserialize (Buffer::Iterator start)
+{
+  Buffer::Iterator i = start;
+  i.Next (2+2);
+  uint32_t hardwareAddressLen = i.ReadU8 ();
+  i.Next (1);
+  m_type = i.ReadNtohU16 ();
+  ReadFrom (i, m_macSource, hardwareAddressLen);
+  ReadFrom (i, m_ipv4Source);
+  ReadFrom (i, m_macDest, hardwareAddressLen);
+  ReadFrom (i, m_ipv4Dest);
+  return GetSerializedSize ();
+}
+
+}; // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/arp-header.h	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,71 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#ifndef ARP_HEADER_H
+#define ARP_HEADER_H
+
+#include "ns3/header.h"
+#include "ns3/address.h"
+#include "ns3/ipv4-address.h"
+#include <string>
+
+namespace ns3 {
+/**
+ * \brief The packet header for an ARP packet
+ */
+class ArpHeader : public Header 
+{
+public:
+  void SetRequest (Address sourceHardwareAddress,
+                   Ipv4Address sourceProtocolAddress,
+                   Address destinationHardwareAddress,
+                   Ipv4Address destinationProtocolAddress);
+  void SetReply (Address sourceHardwareAddress,
+                 Ipv4Address sourceProtocolAddress,
+                 Address destinationHardwareAddress,
+                 Ipv4Address destinationProtocolAddress);
+  bool IsRequest (void) const;
+  bool IsReply (void) const;
+  Address GetSourceHardwareAddress (void);
+  Address GetDestinationHardwareAddress (void);
+  Ipv4Address GetSourceIpv4Address (void);
+  Ipv4Address GetDestinationIpv4Address (void);
+
+  static TypeId GetTypeId (void);
+  virtual TypeId GetInstanceTypeId (void) const;
+  virtual void Print (std::ostream &os) const;
+  virtual uint32_t GetSerializedSize (void) const;
+  virtual void Serialize (Buffer::Iterator start) const;
+  virtual uint32_t Deserialize (Buffer::Iterator start);
+
+  enum ArpType_e {
+    ARP_TYPE_REQUEST = 1,
+    ARP_TYPE_REPLY   = 2
+  };
+  uint16_t m_type;
+  Address m_macSource;
+  Address m_macDest;
+  Ipv4Address m_ipv4Source;
+  Ipv4Address m_ipv4Dest;
+};
+
+}; // namespace ns3
+
+#endif /* ARP_HEADER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/arp-ipv4-interface.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,156 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 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: 
+ *  Mathieu Lacage <mathieu.lacage@sophia.inria.fr>,
+ */
+
+#include "ns3/packet.h"
+#include "ns3/log.h"
+#include "ns3/node.h"
+#include "ns3/net-device.h"
+#include "ns3/address.h"
+#include "ns3/pointer.h"
+
+#include "arp-ipv4-interface.h"
+#include "ipv4-l3-protocol.h"
+#include "arp-l3-protocol.h"
+#include "arp-cache.h"
+
+NS_LOG_COMPONENT_DEFINE ("ArpIpv4Interface");
+
+namespace ns3 {
+
+TypeId 
+ArpIpv4Interface::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::ArpIpv4Interface")
+    .SetParent<Ipv4Interface> ()
+    .AddAttribute ("ArpCache",
+                   "The arp cache for this ipv4 interface",
+                   PointerValue (0),
+                   MakePointerAccessor (&ArpIpv4Interface::m_cache),
+                   MakePointerChecker<ArpIpv4Interface> ())
+    ;
+  return tid;
+}
+
+ArpIpv4Interface::ArpIpv4Interface ()
+  : m_node (0),
+    m_device (0)
+{
+  NS_LOG_FUNCTION (this);
+}
+
+ArpIpv4Interface::~ArpIpv4Interface ()
+{
+  NS_LOG_FUNCTION (this);
+}
+
+void 
+ArpIpv4Interface::DoDispose (void)
+{
+  NS_LOG_FUNCTION (this);
+  m_node = 0;
+  m_device = 0;
+  m_cache = 0;
+  Ipv4Interface::DoDispose ();
+}
+
+void 
+ArpIpv4Interface::SetNode (Ptr<Node> node)
+{
+  m_node = node;
+  DoSetup ();
+}
+void 
+ArpIpv4Interface::SetDevice (Ptr<NetDevice> device)
+{
+  m_device = device;
+  DoSetup ();
+}
+
+Ptr<NetDevice> 
+ArpIpv4Interface::GetDevice (void) const
+{
+  return m_device;
+}
+
+void
+ArpIpv4Interface::DoSetup (void)
+{
+  if (m_node == 0 || m_device == 0)
+    {
+      return;
+    }
+  Ptr<ArpL3Protocol> arp = m_node->GetObject<ArpL3Protocol> ();
+  m_cache = arp->CreateCache (m_device, this);
+}
+
+void 
+ArpIpv4Interface::SendTo (Ptr<Packet> p, Ipv4Address dest)
+{
+  NS_LOG_FUNCTION (this << p << dest);
+
+  NS_ASSERT (GetDevice () != 0);
+  if (m_device->NeedsArp ())
+    {
+      NS_LOG_LOGIC ("Needs ARP");
+      Ptr<ArpL3Protocol> arp = 
+        m_node->GetObject<ArpL3Protocol> ();
+      Address hardwareDestination;
+      bool found;
+      
+      if (dest.IsBroadcast () || 
+          dest.IsSubnetDirectedBroadcast (GetNetworkMask ()) )
+        {
+          NS_LOG_LOGIC ("IsBroadcast");
+          hardwareDestination = GetDevice ()->GetBroadcast ();
+          found = true;
+        }
+      else if (dest.IsMulticast ())
+        {
+          NS_LOG_LOGIC ("IsMulticast");
+          NS_ASSERT_MSG(GetDevice ()->IsMulticast (),
+            "ArpIpv4Interface::SendTo (): Sending multicast packet over "
+            "non-multicast device");
+
+          hardwareDestination = GetDevice ()->MakeMulticastAddress(dest);
+          found = true;
+        }
+      else
+        {
+          NS_LOG_LOGIC ("ARP Lookup");
+          found = arp->Lookup (p, dest, GetDevice (), m_cache, &hardwareDestination);
+        }
+
+      if (found)
+        {
+          NS_LOG_LOGIC ("Address Resolved.  Send.");
+          GetDevice ()->Send (p, hardwareDestination, 
+            Ipv4L3Protocol::PROT_NUMBER);
+        }
+    }
+  else
+    {
+      NS_LOG_LOGIC ("Doesn't need ARP");
+      GetDevice ()->Send (p, GetDevice ()->GetBroadcast (), 
+        Ipv4L3Protocol::PROT_NUMBER);
+    }
+}
+
+}//namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/arp-ipv4-interface.h	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,64 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 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: 
+ *  Mathieu Lacage <mathieu.lacage@sophia.inria.fr>,
+ */
+#ifndef ARP_IPV4_INTERFACE_H
+#define ARP_IPV4_INTERFACE_H
+
+#include "ipv4-interface.h"
+#include "ns3/ptr.h"
+
+namespace ns3 {
+
+class Node;
+class ArpCache;
+
+/**
+ * \brief an Ipv4 Interface which uses ARP
+ *
+ * If you need to use ARP on top of a specific NetDevice, you
+ * can use this Ipv4Interface subclass to wrap it for the Ipv4 class
+ * when calling Ipv4::AggregateObject.
+ */
+class ArpIpv4Interface : public Ipv4Interface
+{
+public:
+  static TypeId GetTypeId (void);
+
+  ArpIpv4Interface ();
+  virtual ~ArpIpv4Interface ();
+
+  void SetNode (Ptr<Node> node);
+  void SetDevice (Ptr<NetDevice> device);
+
+  virtual Ptr<NetDevice> GetDevice (void) const;
+
+private:
+  virtual void SendTo (Ptr<Packet> p, Ipv4Address dest);
+  virtual void DoDispose (void);
+  void DoSetup (void);
+  Ptr<Node> m_node;
+  Ptr<NetDevice> m_device;
+  Ptr<ArpCache> m_cache;
+};
+
+}//namespace ns3
+
+
+#endif /* ARP_IPV4_INTERFACE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/arp-l3-protocol.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,303 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "ns3/packet.h"
+#include "ns3/log.h"
+#include "ns3/node.h"
+#include "ns3/net-device.h"
+#include "ns3/object-vector.h"
+#include "ns3/trace-source-accessor.h"
+
+#include "ipv4-l3-protocol.h"
+#include "arp-l3-protocol.h"
+#include "arp-header.h"
+#include "arp-cache.h"
+#include "ipv4-interface.h"
+
+NS_LOG_COMPONENT_DEFINE ("ArpL3Protocol");
+
+namespace ns3 {
+
+const uint16_t ArpL3Protocol::PROT_NUMBER = 0x0806;
+
+NS_OBJECT_ENSURE_REGISTERED (ArpL3Protocol);
+
+TypeId 
+ArpL3Protocol::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::ArpL3Protocol")
+    .SetParent<Object> ()
+    .AddAttribute ("CacheList",
+                   "The list of ARP caches",
+                   ObjectVectorValue (),
+                   MakeObjectVectorAccessor (&ArpL3Protocol::m_cacheList),
+                   MakeObjectVectorChecker<ArpCache> ())
+    .AddTraceSource ("Drop",
+                     "Packet dropped because not enough room in pending queue for a specific cache entry.",
+                     MakeTraceSourceAccessor (&ArpL3Protocol::m_dropTrace))
+    ;
+  return tid;
+}
+
+ArpL3Protocol::ArpL3Protocol ()
+{
+  NS_LOG_FUNCTION (this);
+}
+
+ArpL3Protocol::~ArpL3Protocol ()
+{
+  NS_LOG_FUNCTION (this);
+}
+
+void 
+ArpL3Protocol::SetNode (Ptr<Node> node)
+{
+  m_node = node;
+}
+
+void 
+ArpL3Protocol::DoDispose (void)
+{
+  NS_LOG_FUNCTION (this);
+  for (CacheList::iterator i = m_cacheList.begin (); i != m_cacheList.end (); ++i)
+    {
+      Ptr<ArpCache> cache = *i;
+      cache->Dispose ();
+    }
+  m_cacheList.clear ();
+  m_node = 0;
+  Object::DoDispose ();
+}
+
+Ptr<ArpCache> 
+ArpL3Protocol::CreateCache (Ptr<NetDevice> device, Ptr<Ipv4Interface> interface)
+{
+  Ptr<Ipv4L3Protocol> ipv4 = m_node->GetObject<Ipv4L3Protocol> ();
+  Ptr<ArpCache> cache = CreateObject<ArpCache> ();
+  cache->SetDevice (device, interface);
+  NS_ASSERT (device->IsBroadcast ());
+  device->SetLinkChangeCallback (MakeCallback (&ArpCache::Flush, cache));
+  m_cacheList.push_back (cache);
+  return cache;
+}
+
+Ptr<ArpCache>
+ArpL3Protocol::FindCache (Ptr<NetDevice> device)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  for (CacheList::const_iterator i = m_cacheList.begin (); i != m_cacheList.end (); i++)
+    {
+      if ((*i)->GetDevice () == device)
+	{
+	  return *i;
+	}
+    }
+  NS_ASSERT (false);
+  // quiet compiler
+  return 0;
+}
+
+void 
+ArpL3Protocol::Receive(Ptr<NetDevice> device, Ptr<Packet> packet, uint16_t protocol, const Address &from)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  Ptr<ArpCache> cache = FindCache (device);
+  ArpHeader arp;
+  packet->RemoveHeader (arp);
+  
+  NS_LOG_LOGIC ("ARP: received "<< (arp.IsRequest ()? "request" : "reply") <<
+            " node="<<m_node->GetId ()<<", got request from " <<
+            arp.GetSourceIpv4Address () << " for address " <<
+            arp.GetDestinationIpv4Address () << "; we have address " <<
+            cache->GetInterface ()->GetAddress ());
+
+  /**
+   * Note: we do not update the ARP cache when we receive an ARP request
+   * from an unknown node. See bug #107
+   */
+
+  if (arp.IsRequest () && 
+      arp.GetDestinationIpv4Address () == cache->GetInterface ()->GetAddress ()) 
+    {
+      NS_LOG_LOGIC ("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 () == device->GetAddress ()) 
+    {
+      Ipv4Address from = arp.GetSourceIpv4Address ();
+      ArpCache::Entry *entry = cache->Lookup (from);
+      if (entry != 0)
+        {
+          if (entry->IsWaitReply ()) 
+            {
+              NS_LOG_LOGIC ("node="<<m_node->GetId ()<<", got reply from " << 
+                        arp.GetSourceIpv4Address ()
+                     << " for waiting entry -- flush");
+              Address from_mac = arp.GetSourceHardwareAddress ();
+              entry->MarkAlive (from_mac);
+              Ptr<Packet> pending = entry->DequeuePending();
+              while (pending != 0)
+                {
+                  cache->GetInterface ()->Send (pending,
+                                                arp.GetSourceIpv4Address ());
+                  pending = entry->DequeuePending();
+                }
+            } 
+          else 
+            {
+              // ignore this reply which might well be an attempt 
+              // at poisening my arp cache.
+              NS_LOG_LOGIC("node="<<m_node->GetId ()<<", got reply from " << 
+                        arp.GetSourceIpv4Address () << 
+                        " for non-waiting entry -- drop");
+              m_dropTrace (packet);
+            }
+        } 
+      else 
+        {
+          NS_LOG_LOGIC ("node="<<m_node->GetId ()<<", got reply for unknown entry -- drop");
+          m_dropTrace (packet);
+        }
+    }
+  else
+    {
+      NS_LOG_LOGIC ("node="<<m_node->GetId ()<<", got request from " <<
+                arp.GetSourceIpv4Address () << " for unknown address " <<
+                arp.GetDestinationIpv4Address () << " -- drop");
+    }
+}
+bool 
+ArpL3Protocol::Lookup (Ptr<Packet> packet, Ipv4Address destination, 
+                       Ptr<NetDevice> device,
+                       Ptr<ArpCache> cache,
+                       Address *hardwareDestination)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  ArpCache::Entry *entry = cache->Lookup (destination);
+  if (entry != 0)
+    {
+      if (entry->IsExpired ()) 
+        {
+          if (entry->IsDead ()) 
+            {
+              NS_LOG_LOGIC ("node="<<m_node->GetId ()<<
+                        ", dead entry for " << destination << " expired -- send arp request");
+              entry->MarkWaitReply (packet);
+              SendArpRequest (cache, destination);
+            } 
+          else if (entry->IsAlive ()) 
+            {
+              NS_LOG_LOGIC ("node="<<m_node->GetId ()<<
+                        ", alive entry for " << destination << " expired -- send arp request");
+              entry->MarkWaitReply (packet);
+              SendArpRequest (cache, destination);
+            } 
+          else if (entry->IsWaitReply ()) 
+            {
+              NS_LOG_LOGIC ("node="<<m_node->GetId ()<<
+                        ", wait reply for " << destination << " expired -- drop");
+              entry->MarkDead ();
+              Ptr<Packet> pending = entry->DequeuePending();
+              while (pending != 0)
+                {
+                  m_dropTrace (pending);
+                  pending = entry->DequeuePending();
+                }
+              m_dropTrace (packet);
+            }
+        } 
+      else 
+        {
+          if (entry->IsDead ()) 
+            {
+              NS_LOG_LOGIC ("node="<<m_node->GetId ()<<
+                            ", dead entry for " << destination << " valid -- drop");
+              m_dropTrace (packet);
+            } 
+          else if (entry->IsAlive ()) 
+            {
+              NS_LOG_LOGIC ("node="<<m_node->GetId ()<<
+                            ", alive entry for " << destination << " valid -- send");
+	      *hardwareDestination = entry->GetMacAddress ();
+              return true;
+            } 
+          else if (entry->IsWaitReply ()) 
+            {
+              NS_LOG_LOGIC ("node="<<m_node->GetId ()<<
+                            ", wait reply for " << destination << " valid -- drop previous");
+              if (!entry->UpdateWaitReply (packet))
+                {
+                  m_dropTrace (packet);
+                }
+            }
+        }
+    }
+  else
+    {
+      // This is our first attempt to transmit data to this destination.
+      NS_LOG_LOGIC ("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 (Ptr<const ArpCache> cache, Ipv4Address to)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  ArpHeader arp;
+  NS_LOG_LOGIC ("ARP: sending request from node "<<m_node->GetId ()<<
+            " || src: " << cache->GetDevice ()->GetAddress () <<
+            " / " << cache->GetInterface ()->GetAddress () <<
+            " || dst: " << cache->GetDevice ()->GetBroadcast () <<
+            " / " << to);
+  arp.SetRequest (cache->GetDevice ()->GetAddress (),
+		  cache->GetInterface ()->GetAddress (), 
+                  cache->GetDevice ()->GetBroadcast (),
+                  to);
+  Ptr<Packet> packet = Create<Packet> ();
+  packet->AddHeader (arp);
+  cache->GetDevice ()->Send (packet, cache->GetDevice ()->GetBroadcast (), PROT_NUMBER);
+}
+
+void
+ArpL3Protocol::SendArpReply (Ptr<const ArpCache> cache, Ipv4Address toIp, Address toMac)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  ArpHeader arp;
+  NS_LOG_LOGIC ("ARP: sending reply from node "<<m_node->GetId ()<<
+            "|| src: " << cache->GetDevice ()->GetAddress () << 
+            " / " << cache->GetInterface ()->GetAddress () <<
+            " || dst: " << toMac << " / " << toIp);
+  arp.SetReply (cache->GetDevice ()->GetAddress (),
+                cache->GetInterface ()->GetAddress (),
+                toMac, toIp);
+  Ptr<Packet> packet = Create<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-stack/arp-l3-protocol.h	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,86 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 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
+ *
+ * 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/address.h"
+#include "ns3/ptr.h"
+#include "ns3/traced-callback.h"
+
+#include "ipv4-interface.h"
+
+namespace ns3 {
+
+class ArpCache;
+class NetDevice;
+class Node;
+class Packet;
+
+/**
+ * \brief An implementation of the ARP protocol
+ */
+class ArpL3Protocol : public Object
+{
+public:
+  static TypeId GetTypeId (void);
+  static const uint16_t PROT_NUMBER;
+
+  ArpL3Protocol ();
+  virtual ~ArpL3Protocol ();
+
+  void SetNode (Ptr<Node> node);
+
+  Ptr<ArpCache> CreateCache (Ptr<NetDevice> device, Ptr<Ipv4Interface> interface);
+
+  /**
+   * \brief Recieve a packet
+   */
+  void Receive(Ptr<NetDevice> device, Ptr<Packet> p, uint16_t protocol, const Address &from);
+  /**
+   * \brief Perform an ARP lookup
+   * \param p
+   * \param destination
+   * \param device
+   * \param cache
+   * \param hardwareDestination
+   * \return 
+   */
+  bool Lookup (Ptr<Packet> p, Ipv4Address destination, 
+	       Ptr<NetDevice> device,
+               Ptr<ArpCache> cache,
+	       Address *hardwareDestination);
+protected:
+  virtual void DoDispose (void);
+private:
+  typedef std::list<Ptr<ArpCache> > CacheList;
+  Ptr<ArpCache> FindCache (Ptr<NetDevice> device);
+  void SendArpRequest (Ptr<const ArpCache>cache, Ipv4Address to);
+  void SendArpReply (Ptr<const ArpCache> cache, Ipv4Address toIp, Address toMac);
+  CacheList m_cacheList;
+  Ptr<Node> m_node;
+  TracedCallback<Ptr<const Packet> > m_dropTrace;
+};
+
+}//namespace ns3
+
+
+#endif /* ARP_L3_PROTOCOL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/internet-stack.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,71 @@
+// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation;
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+// Author: George F. Riley<riley@ece.gatech.edu>
+//
+
+#include "ns3/net-device.h"
+#include "ns3/callback.h"
+#include "ns3/node.h"
+
+#include "ipv4-l4-demux.h"
+#include "udp-l4-protocol.h"
+#include "tcp-l4-protocol.h"
+#include "ipv4-l3-protocol.h"
+#include "arp-l3-protocol.h"
+#include "udp-socket-factory-impl.h"
+#include "tcp-socket-factory-impl.h"
+#include "ipv4-impl.h"
+
+namespace ns3 {
+
+void 
+AddInternetStack (Ptr<Node> node)
+{
+  Ptr<Ipv4L3Protocol> ipv4 = CreateObject<Ipv4L3Protocol> ();
+  Ptr<ArpL3Protocol> arp = CreateObject<ArpL3Protocol> ();
+  ipv4->SetNode (node);
+  arp->SetNode (node);
+
+  Ptr<Ipv4L4Demux> ipv4L4Demux = CreateObject<Ipv4L4Demux> ();
+  Ptr<UdpL4Protocol> udp = CreateObject<UdpL4Protocol> ();
+  Ptr<TcpL4Protocol> tcp = CreateObject<TcpL4Protocol> ();
+
+  ipv4L4Demux->SetNode (node);
+  udp->SetNode (node);
+  tcp->SetNode (node);
+
+  ipv4L4Demux->Insert (udp);
+  ipv4L4Demux->Insert (tcp);
+
+  Ptr<UdpSocketFactoryImpl> udpFactory = CreateObject<UdpSocketFactoryImpl> ();
+  Ptr<TcpSocketFactoryImpl> tcpFactory = CreateObject<TcpSocketFactoryImpl> ();
+  Ptr<Ipv4Impl> ipv4Impl = CreateObject<Ipv4Impl> ();
+
+  udpFactory->SetUdp (udp);
+  tcpFactory->SetTcp (tcp);
+  ipv4Impl->SetIpv4 (ipv4);
+
+  node->AggregateObject (ipv4);
+  node->AggregateObject (arp);
+  node->AggregateObject (ipv4Impl);
+  node->AggregateObject (udpFactory);
+  node->AggregateObject (tcpFactory);
+  node->AggregateObject (ipv4L4Demux);
+}
+
+}//namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/internet-stack.h	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,33 @@
+// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation;
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+// Author: George F. Riley<riley@ece.gatech.edu>
+
+#ifndef INTERNET_STACK_H
+#define INTERNET_STACK_H
+
+#include "ns3/ptr.h"
+
+namespace ns3 {
+
+class Node;
+
+void AddInternetStack (Ptr<Node> node);
+
+}//namespace ns3
+
+#endif /* INTERNET_STACK_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv4-checksum.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,52 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005,2006,2007 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "ipv4-checksum.h"
+
+namespace ns3 {
+
+uint16_t 
+Ipv4ChecksumCalculate (uint16_t checksum, uint8_t *buffer, uint16_t size)
+{
+  /* see RFC 1071 to understand this code. */
+  uint32_t sum = checksum;
+  uint16_t *data = (uint16_t *) buffer;
+  for (uint16_t i = 0; i < (size/2); i++) {
+    sum += data[i];
+  }
+  if ((size % 2) != 0) {
+    uint8_t tmpBuf[2];
+    tmpBuf[0] = buffer[size-1];
+    tmpBuf[1] = 0;
+    data = (uint16_t *)tmpBuf;
+    sum += *data;
+  }
+  while (sum >> 16) {
+    sum = (sum & 0xffff) + (sum >> 16);
+  }
+  return sum;
+}
+
+uint16_t 
+Ipv4ChecksumComplete (uint16_t checksum)
+{
+  return ~checksum;
+}
+
+}; //namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv4-checksum.h	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,33 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005,2006,2007 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef IPV4_CHECKSUM_H
+#define IPV4_CHECKSUM_H
+
+#include <stdint.h>
+
+namespace ns3 {
+
+uint16_t Ipv4ChecksumCalculate (uint16_t checksum, uint8_t *buffer, uint16_t size);
+
+uint16_t Ipv4ChecksumComplete (uint16_t checksum);
+
+}; //namespace ns3
+
+#endif /* IPV4_CHECKSUM_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv4-end-point-demux.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,293 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#include "ipv4-end-point-demux.h"
+#include "ipv4-end-point.h"
+#include "ns3/log.h"
+
+namespace ns3{
+
+NS_LOG_COMPONENT_DEFINE ("Ipv4EndPointDemux");
+
+Ipv4EndPointDemux::Ipv4EndPointDemux ()
+  : m_ephemeral (49152)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+Ipv4EndPointDemux::~Ipv4EndPointDemux ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++) 
+    {
+      Ipv4EndPoint *endPoint = *i;
+      delete endPoint;
+    }
+  m_endPoints.clear ();
+}
+
+bool
+Ipv4EndPointDemux::LookupPortLocal (uint16_t port)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++) 
+    {
+      if ((*i)->GetLocalPort  () == port) 
+        {
+          return true;
+        }
+    }
+  return false;
+}
+
+bool
+Ipv4EndPointDemux::LookupLocal (Ipv4Address addr, uint16_t port)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++) 
+    {
+      if ((*i)->GetLocalPort () == port &&
+          (*i)->GetLocalAddress () == addr) 
+        {
+          return true;
+        }
+    }
+  return false;
+}
+
+Ipv4EndPoint *
+Ipv4EndPointDemux::Allocate (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  uint16_t port = AllocateEphemeralPort ();
+  if (port == 0) 
+    {
+      NS_LOG_WARN ("Ephemeral port allocation failed.");
+      return 0;
+    }
+  Ipv4EndPoint *endPoint = new Ipv4EndPoint (Ipv4Address::GetAny (), port);
+  m_endPoints.push_back (endPoint);
+  NS_LOG_DEBUG ("Now have >>" << m_endPoints.size () << "<< endpoints.");
+  return endPoint;
+}
+
+Ipv4EndPoint *
+Ipv4EndPointDemux::Allocate (Ipv4Address address)
+{
+  NS_LOG_FUNCTION (this << address);
+  uint16_t port = AllocateEphemeralPort ();
+  if (port == 0) 
+    {
+      NS_LOG_WARN ("Ephemeral port allocation failed.");
+      return 0;
+    }
+  Ipv4EndPoint *endPoint = new Ipv4EndPoint (address, port);
+  m_endPoints.push_back (endPoint);
+  NS_LOG_DEBUG ("Now have >>" << m_endPoints.size () << "<< endpoints.");
+  return endPoint;
+}
+
+Ipv4EndPoint *
+Ipv4EndPointDemux::Allocate (uint16_t port)
+{
+  NS_LOG_FUNCTION (this <<  port);
+
+  return Allocate (Ipv4Address::GetAny (), port);
+}
+
+Ipv4EndPoint *
+Ipv4EndPointDemux::Allocate (Ipv4Address address, uint16_t port)
+{
+  NS_LOG_FUNCTION (this << address << port);
+  if (LookupLocal (address, port)) 
+    {
+      NS_LOG_WARN ("Duplicate address/port; failing.");
+      return 0;
+    }
+  Ipv4EndPoint *endPoint = new Ipv4EndPoint (address, port);
+  m_endPoints.push_back (endPoint);
+  NS_LOG_DEBUG ("Now have >>" << m_endPoints.size () << "<< endpoints.");
+  return endPoint;
+}
+
+Ipv4EndPoint *
+Ipv4EndPointDemux::Allocate (Ipv4Address localAddress, uint16_t localPort,
+			     Ipv4Address peerAddress, uint16_t peerPort)
+{
+  NS_LOG_FUNCTION (this << localAddress << localPort << peerAddress << peerPort);
+  for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++) 
+    {
+      if ((*i)->GetLocalPort () == localPort &&
+          (*i)->GetLocalAddress () == localAddress &&
+          (*i)->GetPeerPort () == peerPort &&
+          (*i)->GetPeerAddress () == peerAddress) 
+        {
+          NS_LOG_WARN ("No way we can allocate this end-point.");
+          /* no way we can allocate this end-point. */
+          return 0;
+        }
+    }
+  Ipv4EndPoint *endPoint = new Ipv4EndPoint (localAddress, localPort);
+  endPoint->SetPeer (peerAddress, peerPort);
+  m_endPoints.push_back (endPoint);
+
+  NS_LOG_DEBUG ("Now have >>" << m_endPoints.size () << "<< endpoints.");
+
+  return endPoint;
+}
+
+void 
+Ipv4EndPointDemux::DeAllocate (Ipv4EndPoint *endPoint)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++) 
+    {
+      if (*i == endPoint)
+        {
+          delete endPoint;
+          m_endPoints.erase (i);
+          break;
+        }
+    }
+}
+
+/*
+ * If we have an exact match, we return it.
+ * Otherwise, if we find a generic match, we return it.
+ * Otherwise, we return 0.
+ */
+Ipv4EndPointDemux::EndPoints
+Ipv4EndPointDemux::Lookup (Ipv4Address daddr, uint16_t dport, 
+                           Ipv4Address saddr, uint16_t sport,
+                           Ptr<Ipv4Interface> incomingInterface)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  EndPoints retval1; // Matches exact on local port, wildcards on others
+  EndPoints retval2; // Matches exact on local port/adder, wildcards on others
+  EndPoints retval3; // Matches all but local address
+  EndPoints retval4; // Exact match on all 4
+  
+  NS_LOG_FUNCTION (this << daddr << dport << saddr << sport << incomingInterface);
+  NS_LOG_DEBUG ("Looking up endpoint for destination address " << daddr);
+  for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++) 
+    {
+      Ipv4EndPoint* endP = *i;
+      NS_LOG_DEBUG ("Looking at endpoint dport=" << endP->GetLocalPort ()
+                    << " daddr=" << endP->GetLocalAddress ()
+                    << " sport=" << endP->GetPeerPort ()
+                    << " saddr=" << endP->GetPeerAddress ());
+      if (endP->GetLocalPort () != dport) 
+        {
+          NS_LOG_LOGIC ("Skipping endpoint " << &endP
+                        << " because endpoint dport "
+                        << endP->GetLocalPort ()
+                        << " does not match packet dport " << dport);
+          continue;
+        }
+      bool isBroadcast = (daddr.IsBroadcast () ||
+         daddr.IsSubnetDirectedBroadcast (
+             incomingInterface->GetNetworkMask ()));
+      Ipv4Address incomingInterfaceAddr = incomingInterface->GetAddress ();
+      NS_LOG_DEBUG ("dest addr " << daddr << " broadcast? " << isBroadcast);
+      bool localAddressMatchesWildCard = 
+        endP->GetLocalAddress() == Ipv4Address::GetAny();
+      bool localAddressMatchesExact = endP->GetLocalAddress () == daddr;
+
+      if (isBroadcast)
+        {
+          NS_LOG_DEBUG("Found bcast, localaddr " << endP->GetLocalAddress());
+        }
+
+      if (isBroadcast && (endP->GetLocalAddress() != Ipv4Address::GetAny()))
+        {
+          localAddressMatchesExact = (endP->GetLocalAddress () ==
+                                      incomingInterfaceAddr);
+        }
+      // if no match here, keep looking
+      if (!(localAddressMatchesExact || localAddressMatchesWildCard))
+        continue; 
+      bool remotePeerMatchesExact = endP->GetPeerPort () == sport;
+      bool remotePeerMatchesWildCard = endP->GetPeerPort() == 0;
+      bool remoteAddressMatchesExact = endP->GetPeerAddress () == saddr;
+      bool remoteAddressMatchesWildCard = endP->GetPeerAddress () ==
+        Ipv4Address::GetAny();
+      // If remote does not match either with exact or wildcard,
+      // skip this one
+      if (!(remotePeerMatchesExact || remotePeerMatchesWildCard))
+        continue;
+      if (!(remoteAddressMatchesExact || remoteAddressMatchesWildCard))
+        continue;
+      
+      // Now figure out which return list to add this one to
+      if (localAddressMatchesWildCard &&
+          remotePeerMatchesWildCard &&
+          remoteAddressMatchesWildCard)
+        { // Only local port matches exactly
+          retval1.push_back(endP);
+        }
+      if ((localAddressMatchesExact || (isBroadcast && localAddressMatchesWildCard))&&
+          remotePeerMatchesWildCard &&
+           remoteAddressMatchesWildCard)
+        { // Only local port and local address matches exactly
+          retval2.push_back(endP);
+        }
+      if (localAddressMatchesWildCard &&
+          remotePeerMatchesExact &&
+          remoteAddressMatchesExact)
+        { // All but local address
+          retval3.push_back(endP);
+        }
+      if (localAddressMatchesExact &&
+          remotePeerMatchesExact &&
+          remoteAddressMatchesExact)
+        { // All 4 match
+          retval4.push_back(endP);
+        }
+    }
+
+  // Here we find the most exact match
+  if (!retval4.empty()) return retval4;
+  if (!retval3.empty()) return retval3;
+  if (!retval2.empty()) return retval2;
+  return retval1;  // might be empty if no matches
+}
+
+uint16_t
+Ipv4EndPointDemux::AllocateEphemeralPort (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  uint16_t port = m_ephemeral;
+  do 
+    {
+      port++;
+      if (port == 65535) 
+        {
+          port = 49152;
+        }
+      if (!LookupPortLocal (port)) 
+        {
+          return port;
+        }
+  } while (port != m_ephemeral);
+  return 0;
+}
+
+} //namespace ns3
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv4-end-point-demux.h	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,69 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#ifndef IPV4_END_POINT_DEMUX_H
+#define IPV4_END_POINT_DEMUX_H
+
+#include <stdint.h>
+#include <list>
+#include "ns3/ipv4-address.h"
+#include "ipv4-interface.h"
+
+namespace ns3 {
+
+class Ipv4EndPoint;
+
+class Ipv4EndPointDemux {
+public:
+  typedef std::list<Ipv4EndPoint *> EndPoints;
+  typedef std::list<Ipv4EndPoint *>::iterator EndPointsI;
+
+  Ipv4EndPointDemux ();
+  ~Ipv4EndPointDemux ();
+
+  bool LookupPortLocal (uint16_t port);
+  bool LookupLocal (Ipv4Address addr, uint16_t port);
+  EndPoints Lookup (Ipv4Address daddr, 
+                    uint16_t dport, 
+                    Ipv4Address saddr, 
+                    uint16_t sport,
+                    Ptr<Ipv4Interface> incomingInterface);
+
+  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);
+
+ private:
+  uint16_t AllocateEphemeralPort (void);
+
+  uint16_t m_ephemeral;
+  EndPoints m_endPoints;
+};
+
+} // namespace ns3
+
+#endif /* IPV4_END_POINTS_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv4-end-point.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,97 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#include "ipv4-end-point.h"
+#include "ns3/packet.h"
+
+namespace ns3 {
+
+Ipv4EndPoint::Ipv4EndPoint (Ipv4Address address, uint16_t port)
+  : m_localAddr (address), 
+    m_localPort (port),
+    m_peerAddr (Ipv4Address::GetAny ()),
+    m_peerPort (0)
+{}
+Ipv4EndPoint::~Ipv4EndPoint ()
+{
+  if (!m_destroyCallback.IsNull ())
+    {
+      m_destroyCallback ();
+    }
+}
+
+Ipv4Address 
+Ipv4EndPoint::GetLocalAddress (void)
+{
+  return m_localAddr;
+}
+
+void 
+Ipv4EndPoint::SetLocalAddress (Ipv4Address address)
+{
+  m_localAddr = address;
+}
+
+uint16_t 
+Ipv4EndPoint::GetLocalPort (void)
+{
+  return m_localPort;
+}
+Ipv4Address 
+Ipv4EndPoint::GetPeerAddress (void)
+{
+  return m_peerAddr;
+}
+uint16_t 
+Ipv4EndPoint::GetPeerPort (void)
+{
+  return m_peerPort;
+}
+void 
+Ipv4EndPoint::SetPeer (Ipv4Address address, uint16_t port)
+{
+  m_peerAddr = address;
+  m_peerPort = port;
+}
+
+void 
+Ipv4EndPoint::SetRxCallback (Callback<void,Ptr<Packet>, Ipv4Address, uint16_t> callback)
+{
+  m_rxCallback = callback;
+}
+
+void 
+Ipv4EndPoint::SetDestroyCallback (Callback<void> callback)
+{
+  m_destroyCallback = callback;
+}
+
+void 
+Ipv4EndPoint::ForwardUp (Ptr<Packet> p, Ipv4Address saddr, uint16_t sport)
+{
+  if (!m_rxCallback.IsNull ())
+  {
+    m_rxCallback (p, saddr, sport);
+  }
+}
+
+
+
+}; // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv4-end-point.h	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,63 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#ifndef IPV4_END_POINT_H
+#define IPV4_END_POINT_H
+
+#include <stdint.h>
+#include "ns3/ipv4-address.h"
+#include "ns3/callback.h"
+
+namespace ns3 {
+
+class Header;
+class Packet;
+
+class Ipv4EndPoint {
+public:
+  Ipv4EndPoint (Ipv4Address address, uint16_t port);
+  ~Ipv4EndPoint ();
+
+  Ipv4Address GetLocalAddress (void);
+  void SetLocalAddress (Ipv4Address address);
+  uint16_t GetLocalPort (void);
+  Ipv4Address GetPeerAddress (void);
+  uint16_t GetPeerPort (void);
+
+  void SetPeer (Ipv4Address address, uint16_t port);
+
+  void SetRxCallback (Callback<void,Ptr<Packet>, Ipv4Address, uint16_t> callback);
+  void SetDestroyCallback (Callback<void> callback);
+
+  void ForwardUp (Ptr<Packet> p, Ipv4Address saddr, uint16_t sport);
+
+private:
+  Ipv4Address m_localAddr;
+  uint16_t m_localPort;
+  Ipv4Address m_peerAddr;
+  uint16_t m_peerPort;
+  Callback<void,Ptr<Packet>, Ipv4Address, uint16_t> m_rxCallback;
+  Callback<void> m_destroyCallback;
+};
+
+}; // namespace ns3
+
+
+#endif /* IPV4_END_POINT_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv4-impl.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,273 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 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
+ *
+ * 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 ()
+  : m_ipv4 (0)
+{}
+Ipv4Impl::~Ipv4Impl ()
+{
+  NS_ASSERT (m_ipv4 == 0);
+}
+void 
+Ipv4Impl::SetIpv4 (Ptr<Ipv4L3Protocol> ipv4)
+{
+  m_ipv4 = ipv4;
+}
+void 
+Ipv4Impl::DoDispose (void)
+{
+  m_ipv4 = 0;
+}
+
+void
+Ipv4Impl::AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
+                              int16_t priority)
+{
+  m_ipv4->AddRoutingProtocol (routingProtocol, priority);
+}
+
+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);
+}
+
+void
+Ipv4Impl::AddMulticastRoute (Ipv4Address origin,
+                             Ipv4Address group,
+                             uint32_t inputInterface,
+                             std::vector<uint32_t> outputInterfaces)
+{
+  m_ipv4->AddMulticastRoute (origin, group, inputInterface, outputInterfaces);
+}
+
+void
+Ipv4Impl::SetDefaultMulticastRoute (uint32_t outputInterface)
+{
+  m_ipv4->SetDefaultMulticastRoute (outputInterface);
+}
+
+uint32_t 
+Ipv4Impl::GetNMulticastRoutes (void) const
+{
+  return m_ipv4->GetNMulticastRoutes ();
+}
+
+Ipv4MulticastRoute 
+Ipv4Impl::GetMulticastRoute (uint32_t i) const
+{
+  return *m_ipv4->GetMulticastRoute (i);
+}
+
+void
+Ipv4Impl::RemoveMulticastRoute (Ipv4Address origin,
+                                Ipv4Address group,
+                                uint32_t inputInterface)
+{
+  m_ipv4->RemoveMulticastRoute (origin, group, inputInterface);
+}
+
+void 
+Ipv4Impl::RemoveMulticastRoute (uint32_t i)
+{
+  return m_ipv4->RemoveMulticastRoute (i);
+}
+
+uint32_t 
+Ipv4Impl::AddInterface (Ptr<NetDevice> device)
+{
+  return m_ipv4->AddInterface (device);
+}
+
+uint32_t 
+Ipv4Impl::GetNInterfaces (void)
+{
+  return m_ipv4->GetNInterfaces ();
+}
+
+uint32_t 
+Ipv4Impl::FindInterfaceForAddr (Ipv4Address addr) const
+{
+  return m_ipv4->FindInterfaceForAddr (addr);
+}
+
+uint32_t 
+Ipv4Impl::FindInterfaceForAddr (Ipv4Address addr, Ipv4Mask mask) const
+{
+  return m_ipv4->FindInterfaceForAddr (addr, mask);
+}
+
+int32_t 
+Ipv4Impl::FindInterfaceForDevice (Ptr<NetDevice> device) const
+{
+  return m_ipv4->FindInterfaceIndexForDevice (device);
+}
+
+Ptr<NetDevice>
+Ipv4Impl::GetNetDevice (uint32_t i)
+{
+  return m_ipv4->GetInterface (i)-> GetDevice ();
+}
+
+void 
+Ipv4Impl::JoinMulticastGroup (Ipv4Address origin, Ipv4Address group)
+{
+  m_ipv4->JoinMulticastGroup(origin, group);
+}
+
+void
+Ipv4Impl::LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group)
+{
+  m_ipv4->LeaveMulticastGroup(origin, group);
+}
+
+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);
+}
+
+void
+Ipv4Impl::SetMetric (uint32_t i, uint16_t metric) 
+{
+  m_ipv4->SetMetric (i, metric);
+}
+
+uint16_t
+Ipv4Impl::GetMetric (uint32_t i) const
+{
+  return m_ipv4->GetMetric (i);
+}
+
+bool
+Ipv4Impl::GetIfIndexForDestination (Ipv4Address dest, uint32_t &ifIndex) const
+{
+  return m_ipv4->GetIfIndexForDestination (dest, ifIndex);
+}
+
+Ipv4Address 
+Ipv4Impl::GetSourceAddress (Ipv4Address destination) const
+{
+  uint32_t ifIndex = 0xffffffff;
+
+  bool result = m_ipv4->GetIfIndexForDestination (destination, ifIndex);
+
+  if (result)
+    {
+      return m_ipv4->GetAddress (ifIndex);
+    }
+  else
+    {
+//
+// If we can't find any address, just leave it 0.0.0.0
+//
+      return Ipv4Address::GetAny ();
+    }
+}
+
+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-stack/ipv4-impl.h	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,112 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 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
+ *
+ * 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 ();
+
+  virtual ~Ipv4Impl ();
+
+  void SetIpv4 (Ptr<Ipv4L3Protocol> ipv4);
+
+  virtual void AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
+                                   int16_t priority);
+
+  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 void AddMulticastRoute (Ipv4Address origin,
+                                  Ipv4Address group,
+                                  uint32_t inputInterface,
+                                  std::vector<uint32_t> outputInterfaces);
+
+  virtual void SetDefaultMulticastRoute (uint32_t outputInterface);
+
+  virtual uint32_t GetNMulticastRoutes (void) const;
+  virtual Ipv4MulticastRoute GetMulticastRoute (uint32_t i) const;
+
+  virtual void RemoveMulticastRoute (Ipv4Address origin,
+                                     Ipv4Address group,
+                                     uint32_t inputInterface);
+  virtual void RemoveMulticastRoute (uint32_t i);
+
+  virtual uint32_t AddInterface (Ptr<NetDevice> device);
+  virtual uint32_t GetNInterfaces (void);  
+
+  virtual uint32_t FindInterfaceForAddr (Ipv4Address addr) const;
+  virtual uint32_t FindInterfaceForAddr (Ipv4Address addr, 
+    Ipv4Mask mask) const;
+
+  virtual int32_t FindInterfaceForDevice (Ptr<NetDevice> device) const;
+
+  virtual Ptr<NetDevice> GetNetDevice(uint32_t i);
+
+  virtual void JoinMulticastGroup (Ipv4Address origin, Ipv4Address group);
+  virtual void LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group);
+
+  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 void SetMetric (uint32_t i, uint16_t metric);
+  virtual uint16_t GetMetric (uint32_t i) const;
+  virtual Ipv4Address GetSourceAddress (Ipv4Address destination) const;
+  virtual bool GetIfIndexForDestination (Ipv4Address dest, 
+    uint32_t &ifIndex) 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-stack/ipv4-interface.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,174 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005,2006,2007 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#include "ipv4-interface.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/net-device.h"
+#include "ns3/log.h"
+#include "ns3/packet.h"
+
+NS_LOG_COMPONENT_DEFINE ("Ipv4Interface");
+
+namespace ns3 {
+
+TypeId 
+Ipv4Interface::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::Ipv4Interface")
+    .SetParent<Object> ()
+    ;
+  return tid;
+}
+
+  /**
+   * By default, Ipv4 interface are created in the "down" state
+   * with ip address 192.168.0.1 and a matching mask. Before
+   * becoming useable, the user must invoke SetUp on them
+   * once the final Ipv4 address and mask has been set.
+   */
+Ipv4Interface::Ipv4Interface () 
+  : m_ifup(false),
+    m_metric(1)
+{
+  NS_LOG_FUNCTION (this);
+}
+
+Ipv4Interface::~Ipv4Interface ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+void
+Ipv4Interface::DoDispose (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  Object::DoDispose ();
+}
+
+void 
+Ipv4Interface::SetAddress (Ipv4Address a)
+{
+  NS_LOG_FUNCTION (this << a);
+  m_address = a;
+}
+
+void 
+Ipv4Interface::SetNetworkMask (Ipv4Mask mask)
+{
+  NS_LOG_FUNCTION (this << mask);
+  m_netmask = mask;
+}
+
+Ipv4Address
+Ipv4Interface::GetBroadcast (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  uint32_t mask = m_netmask.Get ();
+  uint32_t address = m_address.Get ();
+  Ipv4Address broadcast = Ipv4Address (address | (~mask));
+  return broadcast;
+}
+
+Ipv4Mask 
+Ipv4Interface::GetNetworkMask (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_netmask;
+}
+
+void
+Ipv4Interface::SetMetric (uint16_t metric)
+{
+  NS_LOG_FUNCTION (metric);
+  m_metric = metric;
+}
+
+uint16_t
+Ipv4Interface::GetMetric (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_metric;
+}
+
+Ipv4Address 
+Ipv4Interface::GetAddress (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_address;
+}
+
+uint16_t 
+Ipv4Interface::GetMtu (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  if (GetDevice () == 0)
+    {
+      uint32_t mtu = (1<<16) - 1;
+      return mtu;
+    }
+  return GetDevice ()->GetMtu ();
+}
+
+/**
+ * These are IP interface states and may be distinct from 
+ * NetDevice states, such as found in real implementations
+ * (where the device may be down but IP interface state is still up).
+ */
+bool 
+Ipv4Interface::IsUp (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_ifup;
+}
+
+bool 
+Ipv4Interface::IsDown (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return !m_ifup;
+}
+
+void 
+Ipv4Interface::SetUp (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_ifup = true;
+}
+
+void 
+Ipv4Interface::SetDown (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_ifup = false;
+}
+
+// public wrapper on private virtual function
+void 
+Ipv4Interface::Send(Ptr<Packet> p, Ipv4Address dest)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  if (IsUp()) {
+    NS_LOG_LOGIC ("SendTo");
+    SendTo(p, dest);
+  }
+}
+
+}; // namespace ns3
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv4-interface.h	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,156 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005,2006,2007 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: 
+ *  Mathieu Lacage <mathieu.lacage@sophia.inria.fr>,
+ *  Tom Henderson <tomh@tomh.org>
+ */
+#ifndef IPV4_INTERFACE_H
+#define IPV4_INTERFACE_H
+
+#include <list>
+#include "ns3/ipv4-address.h"
+#include "ns3/ptr.h"
+#include "ns3/object.h"
+
+namespace ns3 {
+
+class NetDevice;
+class Packet;
+
+/**
+ * \brief The IPv4 representation of a network interface
+ *
+ * This class roughly corresponds to the struct in_device
+ * of Linux; the main purpose is to provide address-family
+ * specific information (addresses) about an interface.
+ *
+ * This class defines two APIs:
+ *  - the public API which is expected to be used by both 
+ *    the IPv4 layer and the user during forwarding and 
+ *    configuration.
+ *  - the private API which is expected to be implemented
+ *    by subclasses of this base class. One such subclass 
+ *    will be a Loopback interface which loops every
+ *    packet sent back to the ipv4 layer. Another such 
+ *    subclass typically contains the Ipv4 <-> MAC address
+ *    translation logic which will use most of the time the
+ *    ARP/RARP protocols.
+ *
+ * By default, Ipv4 interface are created in the "down" state
+ * with ip address 192.168.0.1 and a matching mask. Before
+ * becoming useable, the user must invoke SetUp on them
+ * once the final Ipv4 address and mask has been set.
+ *
+ * Subclasses must implement the two methods:
+ *   - Ipv4Interface::SendTo
+ */
+class Ipv4Interface  : public Object
+{
+public:
+  static TypeId GetTypeId (void);
+
+  Ipv4Interface ();
+  virtual ~Ipv4Interface();
+
+  /**
+   * \returns the underlying NetDevice. This method can return
+   *          zero if this interface has no associated NetDevice.
+   */
+  virtual Ptr<NetDevice> GetDevice (void) const = 0;
+
+  /**
+   * \param a set the ipv4 address of this interface.
+   */
+  void SetAddress (Ipv4Address a);
+  /**
+   * \param mask set the ipv4 netmask of this interface.
+   */
+  void SetNetworkMask (Ipv4Mask mask);
+
+  /**
+   * \returns the broadcast ipv4 address associated to this interface
+   */
+  Ipv4Address GetBroadcast (void) const;
+  /**
+   * \returns the ipv4 netmask of this interface
+   */
+  Ipv4Mask GetNetworkMask (void) const;
+  /**
+   * \param metric configured routing metric (cost) of this interface
+   */
+  void SetMetric (uint16_t metric);
+  /**
+   * \returns configured routing metric (cost) of this interface
+   */
+  uint16_t GetMetric (void) const;
+  /**
+   * \returns the ipv4 address of this interface
+   */
+  Ipv4Address GetAddress (void) const;
+
+  /**
+   * This function a pass-through to NetDevice GetMtu, modulo
+   * the  LLC/SNAP header i.e., ipv4MTU = NetDeviceMtu - LLCSNAPSIZE
+   * \returns the Maximum Transmission Unit associated to this interface.
+   */
+  uint16_t GetMtu (void) const;
+
+  /**
+   * These are IP interface states and may be distinct from 
+   * NetDevice states, such as found in real implementations
+   * (where the device may be down but IP interface state is still up).
+   */
+  /**
+   * \returns true if this interface is enabled, false otherwise.
+   */
+  bool IsUp (void) const;
+  /**
+   * \returns true if this interface is disabled, false otherwise.
+   */
+  bool IsDown (void) const;
+  /**
+   * Enable this interface
+   */
+  void SetUp (void);
+  /**
+   * Disable this interface
+   */
+  void SetDown (void);
+
+  /**
+   * \param p packet to send
+   * \param dest next hop address of packet.
+   *
+   * This method will eventually call the private
+   * SendTo method which must be implemented by subclasses.
+   */ 
+  void Send(Ptr<Packet> p, Ipv4Address dest);
+
+protected:
+  virtual void DoDispose (void);
+private:
+  virtual void SendTo (Ptr<Packet> p, Ipv4Address dest) = 0;
+  bool m_ifup;
+  Ipv4Address m_address;
+  Ipv4Mask m_netmask;
+  uint16_t m_metric;
+};
+
+}; // namespace ns3
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv4-l3-protocol.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,906 @@
+// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation;
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+// Author: George F. Riley<riley@ece.gatech.edu>
+//
+
+#include "ns3/packet.h"
+#include "ns3/log.h"
+#include "ns3/callback.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/ipv4-route.h"
+#include "ns3/node.h"
+#include "ns3/socket.h"
+#include "ns3/net-device.h"
+#include "ns3/uinteger.h"
+#include "ns3/trace-source-accessor.h"
+#include "ns3/object-vector.h"
+#include "ns3/ipv4-header.h"
+#include "ns3/boolean.h"
+#include "arp-l3-protocol.h"
+
+#include "ipv4-l3-protocol.h"
+#include "ipv4-l4-protocol.h"
+#include "ipv4-interface.h"
+#include "ipv4-loopback-interface.h"
+#include "arp-ipv4-interface.h"
+#include "ipv4-l4-demux.h"
+
+NS_LOG_COMPONENT_DEFINE ("Ipv4L3Protocol");
+
+namespace ns3 {
+
+const uint16_t Ipv4L3Protocol::PROT_NUMBER = 0x0800;
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv4L3Protocol);
+
+TypeId 
+Ipv4L3Protocol::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::Ipv4L3Protocol")
+    .SetParent<Object> ()
+    .AddConstructor<Ipv4L3Protocol> ()
+    .AddAttribute ("DefaultTtl", "The TTL value set by default on all outgoing packets generated on this node.",
+                   UintegerValue (64),
+                   MakeUintegerAccessor (&Ipv4L3Protocol::m_defaultTtl),
+                   MakeUintegerChecker<uint8_t> ())
+    .AddAttribute ("CalcChecksum", "If true, we calculate the checksum of outgoing packets"
+                   " and verify the checksum of incoming packets.",
+                   BooleanValue (false),
+                   MakeBooleanAccessor (&Ipv4L3Protocol::m_calcChecksum),
+                   MakeBooleanChecker ())
+    .AddTraceSource ("Tx", "Send ipv4 packet to outgoing interface.",
+                   MakeTraceSourceAccessor (&Ipv4L3Protocol::m_txTrace))
+    .AddTraceSource ("Rx", "Receive ipv4 packet from incoming interface.",
+                     MakeTraceSourceAccessor (&Ipv4L3Protocol::m_rxTrace))
+    .AddTraceSource ("Drop", "Drop ipv4 packet",
+                     MakeTraceSourceAccessor (&Ipv4L3Protocol::m_dropTrace))
+    .AddAttribute ("InterfaceList", "The set of Ipv4 interfaces associated to this Ipv4 stack.",
+                   ObjectVectorValue (),
+                   MakeObjectVectorAccessor (&Ipv4L3Protocol::m_interfaces),
+                   MakeObjectVectorChecker<Ipv4Interface> ())
+    ;
+  return tid;
+}
+
+Ipv4L3Protocol::Ipv4L3Protocol()
+  : m_nInterfaces (0),
+    m_identification (0)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_staticRouting = CreateObject<Ipv4StaticRouting> ();
+  AddRoutingProtocol (m_staticRouting, 0);
+}
+
+Ipv4L3Protocol::~Ipv4L3Protocol ()
+{
+  NS_LOG_FUNCTION (this);
+}
+
+void
+Ipv4L3Protocol::SetNode (Ptr<Node> node)
+{
+  m_node = node;
+  SetupLoopback ();
+}
+
+void 
+Ipv4L3Protocol::DoDispose (void)
+{
+  NS_LOG_FUNCTION (this);
+  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); ++i)
+    {
+      Ptr<Ipv4Interface> interface = *i;
+      interface->Dispose ();
+    }
+  m_interfaces.clear ();
+  m_node = 0;
+  m_staticRouting->Dispose ();
+  m_staticRouting = 0;
+  Object::DoDispose ();
+}
+
+void
+Ipv4L3Protocol::SetupLoopback (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  Ptr<Ipv4LoopbackInterface> interface = CreateObject<Ipv4LoopbackInterface> ();
+  interface->SetNode (m_node);
+  interface->SetAddress (Ipv4Address::GetLoopback ());
+  interface->SetNetworkMask (Ipv4Mask::GetLoopback ());
+  uint32_t index = AddIpv4Interface (interface);
+  AddHostRouteTo (Ipv4Address::GetLoopback (), index);
+  interface->SetUp ();
+}
+
+void 
+Ipv4L3Protocol::SetDefaultTtl (uint8_t ttl)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_defaultTtl = ttl;
+}
+    
+
+void 
+Ipv4L3Protocol::AddHostRouteTo (Ipv4Address dest, 
+                      Ipv4Address nextHop, 
+                      uint32_t interface)
+{
+  NS_LOG_FUNCTION (this << dest << nextHop << interface);
+  m_staticRouting->AddHostRouteTo (dest, nextHop, interface);
+}
+
+void 
+Ipv4L3Protocol::AddHostRouteTo (Ipv4Address dest, 
+				uint32_t interface)
+{
+  NS_LOG_FUNCTION (this << dest << interface);
+  m_staticRouting->AddHostRouteTo (dest, interface);
+}
+
+void 
+Ipv4L3Protocol::AddNetworkRouteTo (Ipv4Address network, 
+				   Ipv4Mask networkMask, 
+				   Ipv4Address nextHop, 
+				   uint32_t interface)
+{
+  NS_LOG_FUNCTION (this << network << networkMask << nextHop << interface);
+  m_staticRouting->AddNetworkRouteTo (network, networkMask, nextHop, interface);
+}
+
+void 
+Ipv4L3Protocol::AddNetworkRouteTo (Ipv4Address network, 
+				   Ipv4Mask networkMask, 
+				   uint32_t interface)
+{
+  NS_LOG_FUNCTION (this << network << networkMask << interface);
+  m_staticRouting->AddNetworkRouteTo (network, networkMask, interface);
+}
+
+void 
+Ipv4L3Protocol::SetDefaultRoute (Ipv4Address nextHop, 
+				 uint32_t interface)
+{
+  NS_LOG_FUNCTION (this << nextHop << interface);
+  m_staticRouting->SetDefaultRoute (nextHop, interface);
+}
+
+void
+Ipv4L3Protocol::Lookup (
+  Ipv4Header const &ipHeader,
+  Ptr<Packet> packet,
+  Ipv4RoutingProtocol::RouteReplyCallback routeReply)
+{
+  NS_LOG_FUNCTION (this << &ipHeader << packet << &routeReply);
+
+  Lookup (Ipv4RoutingProtocol::IF_INDEX_ANY, ipHeader, packet, routeReply);
+}
+
+void
+Ipv4L3Protocol::Lookup (
+  uint32_t ifIndex,
+  Ipv4Header const &ipHeader,
+  Ptr<Packet> packet,
+  Ipv4RoutingProtocol::RouteReplyCallback routeReply)
+{
+  NS_LOG_FUNCTION (this << ifIndex << &ipHeader << packet << &routeReply);
+
+  for (Ipv4RoutingProtocolList::const_iterator rprotoIter = 
+         m_routingProtocols.begin ();
+       rprotoIter != m_routingProtocols.end (); 
+       rprotoIter++)
+    {
+      NS_LOG_LOGIC ("Requesting route");
+      if ((*rprotoIter).second->RequestRoute (ifIndex, ipHeader, packet, 
+                                              routeReply))
+        return;
+    }
+
+  if (ipHeader.GetDestination ().IsMulticast () && 
+      ifIndex == Ipv4RoutingProtocol::IF_INDEX_ANY)
+    {
+      NS_LOG_LOGIC ("Multicast destination with local source");
+//
+// We have a multicast packet originating from the current node and were not
+// able to send it using the usual RequestRoute process.  Since the usual
+// process includes trying to use a default multicast route, this means that
+// there was no specific route out of the node found, and there was no default
+// multicast route set.
+//
+// The fallback position is to look for a default unicast route and use that
+// to get the packet off the node if we have one.
+//
+      Ipv4Route *route = m_staticRouting->GetDefaultRoute ();
+
+      if (route)
+        {
+          NS_LOG_LOGIC ("Local source. Using unicast default route for "
+            "multicast packet");
+
+          routeReply (true, *route, packet, ipHeader);
+          return;
+        }
+    }
+//
+// No route found
+//
+  routeReply (false, Ipv4Route (), packet, ipHeader);
+}
+
+void
+Ipv4L3Protocol::AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
+                                    int priority)
+{
+  NS_LOG_FUNCTION (this << &routingProtocol << priority);
+  m_routingProtocols.push_back
+    (std::pair<int, Ptr<Ipv4RoutingProtocol> > (-priority, routingProtocol));
+  m_routingProtocols.sort ();
+}
+
+uint32_t 
+Ipv4L3Protocol::GetNRoutes (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_staticRouting->GetNRoutes ();
+}
+
+Ipv4Route *
+Ipv4L3Protocol::GetRoute (uint32_t index)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_staticRouting->GetRoute (index);
+}
+
+void 
+Ipv4L3Protocol::RemoveRoute (uint32_t index)
+{
+  NS_LOG_FUNCTION (this << index);
+  m_staticRouting->RemoveRoute (index);
+}
+
+void 
+Ipv4L3Protocol::AddMulticastRoute (Ipv4Address origin,
+                                   Ipv4Address group,
+                                   uint32_t inputInterface,
+                                   std::vector<uint32_t> outputInterfaces)
+{
+  NS_LOG_FUNCTION (this << origin << group << inputInterface << &outputInterfaces);
+
+  m_staticRouting->AddMulticastRoute (origin, group, inputInterface,
+    outputInterfaces);
+}
+
+void 
+Ipv4L3Protocol::SetDefaultMulticastRoute (uint32_t outputInterface)
+{
+  NS_LOG_FUNCTION (this << outputInterface);
+
+  m_staticRouting->SetDefaultMulticastRoute (outputInterface);
+}
+
+uint32_t 
+Ipv4L3Protocol::GetNMulticastRoutes (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_staticRouting->GetNMulticastRoutes ();
+}
+
+Ipv4MulticastRoute *
+Ipv4L3Protocol::GetMulticastRoute (uint32_t index) const
+{
+  NS_LOG_FUNCTION (this << index);
+  return m_staticRouting->GetMulticastRoute (index);
+}
+
+void 
+Ipv4L3Protocol::RemoveMulticastRoute (Ipv4Address origin,
+                                       Ipv4Address group,
+                                       uint32_t inputInterface)
+{
+  NS_LOG_FUNCTION (this << origin << group << inputInterface);
+  m_staticRouting->RemoveMulticastRoute (origin, group, inputInterface);
+}
+
+void 
+Ipv4L3Protocol::RemoveMulticastRoute (uint32_t index)
+{
+  NS_LOG_FUNCTION (this << index);
+  m_staticRouting->RemoveMulticastRoute (index);
+}
+
+uint32_t 
+Ipv4L3Protocol::AddInterface (Ptr<NetDevice> device)
+{
+  NS_LOG_FUNCTION (this << &device);
+
+  Ptr<Node> node = GetObject<Node> ();
+  node->RegisterProtocolHandler (MakeCallback (&Ipv4L3Protocol::Receive, this), 
+                                 Ipv4L3Protocol::PROT_NUMBER, device);
+  node->RegisterProtocolHandler (MakeCallback (&ArpL3Protocol::Receive, PeekPointer (GetObject<ArpL3Protocol> ())),
+                                 ArpL3Protocol::PROT_NUMBER, device);
+
+  Ptr<ArpIpv4Interface> interface = CreateObject<ArpIpv4Interface> ();
+  interface->SetNode (m_node);
+  interface->SetDevice (device);
+  return AddIpv4Interface (interface);
+}
+
+uint32_t 
+Ipv4L3Protocol::AddIpv4Interface (Ptr<Ipv4Interface>interface)
+{
+  NS_LOG_FUNCTION (this << interface);
+  uint32_t index = m_nInterfaces;
+  m_interfaces.push_back (interface);
+  m_nInterfaces++;
+  return index;
+}
+
+Ptr<Ipv4Interface>
+Ipv4L3Protocol::GetInterface (uint32_t index) const
+{
+  NS_LOG_FUNCTION (this << index);
+  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
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_nInterfaces;
+}
+
+uint32_t 
+Ipv4L3Protocol::FindInterfaceForAddr (Ipv4Address addr) const
+{
+  NS_LOG_FUNCTION (this << addr);
+
+  uint32_t ifIndex = 0;
+  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); 
+       i != m_interfaces.end (); 
+       i++, ifIndex++)
+    {
+      if ((*i)->GetAddress () == addr)
+        {
+          return ifIndex;
+        }
+    }
+
+  NS_FATAL_ERROR ("Ipv4L3Protocol::FindInterfaceForAddr (): "
+                  "Interface not found for IP address " << addr);
+  return 0;
+}
+
+uint32_t 
+Ipv4L3Protocol::FindInterfaceForAddr (Ipv4Address addr, Ipv4Mask mask) const
+{
+  NS_LOG_FUNCTION (this << addr << mask);
+
+  uint32_t ifIndex = 0;
+  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); 
+       i != m_interfaces.end (); 
+       i++, ifIndex++)
+    {
+      if ((*i)->GetAddress ().CombineMask (mask) == addr.CombineMask (mask))
+        {
+          return ifIndex;
+        }
+    }
+
+  NS_ASSERT_MSG(false, "Ipv4L3Protocol::FindInterfaceForAddr (): "
+    "Interface not found for masked IP address");
+  return 0;
+}
+
+int32_t 
+Ipv4L3Protocol::FindInterfaceIndexForDevice (Ptr<NetDevice> device) const
+{
+  NS_LOG_FUNCTION (this << device);
+
+  uint32_t ifIndex = 0;
+  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); 
+       i != m_interfaces.end (); 
+       i++, ifIndex++)
+    {
+      if ((*i)->GetDevice () == device)
+        {
+          return ifIndex;
+        }
+    }
+
+  return -1;
+}
+
+Ptr<Ipv4Interface>
+Ipv4L3Protocol::FindInterfaceForDevice (Ptr<const NetDevice> device)
+{
+  NS_LOG_FUNCTION (this << &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( Ptr<NetDevice> device, Ptr<Packet> packet, uint16_t protocol, const Address &from)
+{
+  NS_LOG_FUNCTION (this << &device << packet << protocol <<  from);
+
+  NS_LOG_LOGIC ("Packet from " << from << " received on node " << m_node->GetId ());
+
+  uint32_t index = 0;
+  Ptr<Ipv4Interface> ipv4Interface;
+  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); 
+       i != m_interfaces.end (); 
+       i++)
+    {
+      ipv4Interface = *i;
+      if (ipv4Interface->GetDevice () == device)
+        {
+          m_rxTrace (packet, index);
+          break;
+        }
+      index++;
+    }
+  Ipv4Header ipHeader;
+  if (m_calcChecksum)
+    {
+      ipHeader.EnableChecksum ();
+    }
+  packet->RemoveHeader (ipHeader);
+
+  if (!ipHeader.IsChecksumOk ()) 
+    {
+      m_dropTrace (packet);
+      return;
+    }
+
+  if (Forwarding (index, packet, ipHeader, device)) 
+    {
+      return;
+    }
+
+  ForwardUp (packet, ipHeader, ipv4Interface);
+}
+
+
+void 
+Ipv4L3Protocol::Send (Ptr<Packet> packet, 
+            Ipv4Address source, 
+            Ipv4Address destination,
+            uint8_t protocol)
+{
+  NS_LOG_FUNCTION (this << packet << source << destination << protocol);
+
+  Ipv4Header ipHeader;
+
+  if (m_calcChecksum)
+    {
+      ipHeader.EnableChecksum ();
+    }
+
+  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 ++;
+
+  // Set TTL to 1 if it is a broadcast packet of any type.  Otherwise,
+  // possibly override the default TTL if the packet is tagged
+  SocketIpTtlTag tag;
+  bool found = packet->FindFirstMatchingTag (tag);
+
+  if (destination.IsBroadcast ()) 
+    {
+      ipHeader.SetTtl (1);
+    }
+  else if (found)
+    {
+      ipHeader.SetTtl (tag.GetTtl ());
+      // XXX remove tag here?  
+    }
+  else
+    {
+      uint32_t ifaceIndex = 0;
+      for (Ipv4InterfaceList::iterator ifaceIter = m_interfaces.begin ();
+           ifaceIter != m_interfaces.end (); ifaceIter++, ifaceIndex++)
+        {
+          Ptr<Ipv4Interface> outInterface = *ifaceIter;
+          if (destination.IsSubnetDirectedBroadcast (
+                outInterface->GetNetworkMask ()))
+          {
+            ipHeader.SetTtl (1);
+          }
+        }
+    }
+  if (destination.IsBroadcast ())
+    {
+      uint32_t ifaceIndex = 0;
+      for (Ipv4InterfaceList::iterator ifaceIter = m_interfaces.begin ();
+           ifaceIter != m_interfaces.end (); ifaceIter++, ifaceIndex++)
+        {
+          Ptr<Ipv4Interface> outInterface = *ifaceIter;
+          Ptr<Packet> packetCopy = packet->Copy ();
+
+          NS_ASSERT (packetCopy->GetSize () <= outInterface->GetMtu ());
+          packetCopy->AddHeader (ipHeader);
+          m_txTrace (packetCopy, ifaceIndex);
+          outInterface->Send (packetCopy, destination);
+        }
+    }
+  else
+    {
+      // 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.
+      Lookup (ipHeader, packet,
+              MakeCallback (&Ipv4L3Protocol::SendRealOut, this));
+    }
+}
+
+void
+Ipv4L3Protocol::SendRealOut (bool found,
+                             Ipv4Route const &route,
+                             Ptr<Packet> packet,
+                             Ipv4Header const &ipHeader)
+{
+  NS_LOG_FUNCTION (this << found << &route << packet << &ipHeader);
+
+  packet->AddHeader (ipHeader);
+  if (!found)
+    {
+      NS_LOG_WARN ("No route to host.  Drop.");
+      m_dropTrace (packet);
+      return;
+    }
+
+  NS_LOG_LOGIC ("Send via interface " << route.GetInterface ());
+
+  Ptr<Ipv4Interface> outInterface = GetInterface (route.GetInterface ());
+  NS_ASSERT (packet->GetSize () <= outInterface->GetMtu ());
+  m_txTrace (packet, route.GetInterface ());
+  if (route.IsGateway ()) 
+    {
+      NS_LOG_LOGIC ("Send to gateway " << route.GetGateway ());
+      outInterface->Send (packet, route.GetGateway ());
+    } 
+  else 
+    {
+      NS_LOG_LOGIC ("Send to destination " << ipHeader.GetDestination ());
+      outInterface->Send (packet, ipHeader.GetDestination ());
+    }
+}
+
+bool
+Ipv4L3Protocol::Forwarding (
+  uint32_t ifIndex, 
+  Ptr<Packet> packet, 
+  Ipv4Header &ipHeader, 
+  Ptr<NetDevice> device)
+{
+  NS_LOG_FUNCTION (ifIndex << packet << &ipHeader<< device);
+  NS_LOG_LOGIC ("Forwarding logic for node: " << m_node->GetId ());
+
+  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
+       i != m_interfaces.end (); i++) 
+    {
+      if ((*i)->GetAddress ().IsEqual (ipHeader.GetDestination ())) 
+        {
+          NS_LOG_LOGIC ("For me (destination match)");
+          return false;
+        }
+    }
+  
+  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
+       i != m_interfaces.end (); i++) 
+    {
+      Ptr<Ipv4Interface> interface = *i;
+      if (interface->GetDevice () == device)
+	{
+	  if (ipHeader.GetDestination ().IsEqual (interface->GetBroadcast ())) 
+	    {
+              NS_LOG_LOGIC ("For me (interface broadcast address)");
+	      return false;
+	    }
+	  break;
+	}
+    }
+      
+  if (ipHeader.GetDestination ().IsBroadcast ()) 
+    {
+      NS_LOG_LOGIC ("For me (Ipv4Addr broadcast address)");
+      return false;
+    }
+
+  if (ipHeader.GetDestination ().IsEqual (Ipv4Address::GetAny ())) 
+    {
+      NS_LOG_LOGIC ("For me (Ipv4Addr any address)");
+      return false;
+    }
+
+  if (ipHeader.GetTtl () == 1) 
+    {
+      // Should send ttl expired here
+      // XXX
+      NS_LOG_LOGIC ("Not for me (TTL expired).  Drop");
+      m_dropTrace (packet);
+      return true;
+    }
+  ipHeader.SetTtl (ipHeader.GetTtl () - 1);
+
+//  
+// If this is a to a multicast address and this node is a member of the 
+// indicated group we need to return false so the multicast is forwarded up.
+//        
+  for (Ipv4MulticastGroupList::const_iterator i = m_multicastGroups.begin ();
+       i != m_multicastGroups.end (); i++)
+    {
+      if ((*i).first.IsEqual (ipHeader.GetSource ()) &&
+          (*i).second.IsEqual (ipHeader.GetDestination ()))
+        {
+          NS_LOG_LOGIC ("For me (Joined multicast group)");
+          // We forward with a packet copy, since forwarding may change
+          // the packet, affecting our local delivery
+          NS_LOG_LOGIC ("Forwarding (multicast).");
+          Lookup (ifIndex, ipHeader, packet->Copy (),
+          MakeCallback (&Ipv4L3Protocol::SendRealOut, this));
+          return false;
+        }   
+    }     
+  NS_LOG_LOGIC ("Not for me, forwarding.");
+  Lookup (ifIndex, ipHeader, packet,
+  MakeCallback (&Ipv4L3Protocol::SendRealOut, this));
+  
+  return true;
+}
+
+void
+Ipv4L3Protocol::ForwardUp (Ptr<Packet> p, Ipv4Header const&ip,
+                           Ptr<Ipv4Interface> incomingInterface)
+{
+  NS_LOG_FUNCTION (this << p << &ip);
+
+  Ptr<Ipv4L4Demux> demux = m_node->GetObject<Ipv4L4Demux> ();
+  Ptr<Ipv4L4Protocol> protocol = demux->GetProtocol (ip.GetProtocol ());
+  protocol->Receive (p, ip.GetSource (), ip.GetDestination (), incomingInterface);
+}
+
+void 
+Ipv4L3Protocol::JoinMulticastGroup (Ipv4Address origin, Ipv4Address group)
+{
+  NS_LOG_FUNCTION (this << origin << group);
+  m_multicastGroups.push_back(
+    std::pair<Ipv4Address, Ipv4Address> (origin, group));
+}
+
+void
+Ipv4L3Protocol::LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group)
+{
+  NS_LOG_FUNCTION (this << origin << group);
+
+  for (Ipv4MulticastGroupList::iterator i = m_multicastGroups.begin ();
+       i != m_multicastGroups.end (); 
+       i++)
+    {
+      if ((*i).first.IsEqual(origin) && (*i).second.IsEqual(group))
+        {
+          m_multicastGroups.erase (i);
+          return;
+        }
+    }
+}
+
+void 
+Ipv4L3Protocol::SetAddress (uint32_t i, Ipv4Address address)
+{
+  NS_LOG_FUNCTION (this << i << address);
+  Ptr<Ipv4Interface> interface = GetInterface (i);
+  interface->SetAddress (address);
+}
+
+void 
+Ipv4L3Protocol::SetNetworkMask (uint32_t i, Ipv4Mask mask)
+{
+  NS_LOG_FUNCTION (this << i << mask);
+  Ptr<Ipv4Interface> interface = GetInterface (i);
+  interface->SetNetworkMask (mask);
+}
+
+Ipv4Mask 
+Ipv4L3Protocol::GetNetworkMask (uint32_t i) const
+{
+  NS_LOG_FUNCTION (this << i);
+  Ptr<Ipv4Interface> interface = GetInterface (i);
+  return interface->GetNetworkMask ();
+}
+
+Ipv4Address 
+Ipv4L3Protocol::GetAddress (uint32_t i) const
+{
+  NS_LOG_FUNCTION (this << i);
+  Ptr<Ipv4Interface> interface = GetInterface (i);
+  return interface->GetAddress ();
+}
+
+void 
+Ipv4L3Protocol::SetMetric (uint32_t i, uint16_t metric)
+{
+  NS_LOG_FUNCTION (i << metric);
+  Ptr<Ipv4Interface> interface = GetInterface (i);
+  interface->SetMetric (metric);
+}
+
+uint16_t
+Ipv4L3Protocol::GetMetric (uint32_t i) const
+{
+  NS_LOG_FUNCTION (i);
+  Ptr<Ipv4Interface> interface = GetInterface (i);
+  return interface->GetMetric ();
+}
+
+bool
+Ipv4L3Protocol::GetIfIndexForDestination (
+  Ipv4Address destination, uint32_t& ifIndex) const
+{
+  NS_LOG_FUNCTION (this << destination << &ifIndex);
+//
+// The first thing we do in trying to determine a source address is to 
+// consult the routing protocols.  These will also check for a default route
+// if one has been set.
+//
+  for (Ipv4RoutingProtocolList::const_iterator i = m_routingProtocols.begin ();
+       i != m_routingProtocols.end (); 
+       i++)
+    {
+      NS_LOG_LOGIC ("Requesting Source Address");
+      uint32_t ifIndexTmp;
+
+      if ((*i).second->RequestIfIndex (destination, ifIndexTmp))
+        {
+          NS_LOG_LOGIC ("Found ifIndex " << ifIndexTmp);
+          ifIndex = ifIndexTmp;
+          return true;
+        }
+    }
+//
+// If there's no routing table entry telling us what *single* interface will 
+// be used to send a packet to this destination, we'll have to just pick one.  
+// If there's only one interface on this node, a good answer isn't very hard
+// to come up with.  Before jumping to any conclusions, remember that the 
+// zeroth interface is the loopback interface, so what we actually want is
+// a situation where there are exactly two interfaces on the node, in which
+// case interface one is the "single" interface connected to the outside world.
+//
+  if (GetNInterfaces () == 2)
+    {
+      NS_LOG_LOGIC ("One Interface.  Using interface 1.");
+      ifIndex = 1;
+      return true;
+    }
+//
+// If we fall through to here, we have a node with multiple interfaces and
+// no routes to guide us in determining what interface to choose.  Either
+// no default route was found (for unicast or multicast), or in the case of a
+// multicast, the default route contained multiple outbound interfaces.
+//
+// The fallback position is to just get the unicast default route and use 
+// the outgoing interface specified there.  We don't want to leave the source
+// address unset, so we just assert here.
+//
+// N.B. that in the case of a multicast with a route containing multiple
+// outgoing interfaces, the source address of packets from that node will be
+// set to the IP address of the interface set in the default unicast route.
+// Also, in the case of a broadcast, the same will be true.
+//
+  NS_LOG_LOGIC ("Using default unicast route");
+  Ipv4Route *route = m_staticRouting->GetDefaultRoute ();
+
+  if (route == NULL)
+    {
+      NS_LOG_LOGIC ("Ipv4L3Protocol::GetIfIndexForDestination (): "
+                    "Unable to determine outbound interface.  No default route set");
+      return false;
+    }
+
+  ifIndex = route->GetInterface ();
+
+  NS_LOG_LOGIC ("Default route specifies interface " << ifIndex);
+  return true;
+}
+
+uint16_t 
+Ipv4L3Protocol::GetMtu (uint32_t i) const
+{
+  NS_LOG_FUNCTION (this << i);
+  Ptr<Ipv4Interface> interface = GetInterface (i);
+  return interface->GetMtu ();
+}
+
+bool 
+Ipv4L3Protocol::IsUp (uint32_t i) const
+{
+  NS_LOG_FUNCTION (this << i);
+  Ptr<Ipv4Interface> interface = GetInterface (i);
+  return interface->IsUp ();
+}
+
+void 
+Ipv4L3Protocol::SetUp (uint32_t i)
+{
+  NS_LOG_FUNCTION (this << i);
+  Ptr<Ipv4Interface> interface = GetInterface (i);
+  interface->SetUp ();
+
+  // If interface address and network mask have been set, add a route
+  // to the network of the interface (like e.g. ifconfig does on a
+  // Linux box)
+  if ((interface->GetAddress ()) != (Ipv4Address ())
+      && (interface->GetNetworkMask ()) != (Ipv4Mask ()))
+    {
+      AddNetworkRouteTo (interface->GetAddress ().CombineMask (interface->GetNetworkMask ()),
+                         interface->GetNetworkMask (), i);
+    }
+}
+
+void 
+Ipv4L3Protocol::SetDown (uint32_t ifaceIndex)
+{
+  NS_LOG_FUNCTION (this << ifaceIndex);
+  Ptr<Ipv4Interface> interface = GetInterface (ifaceIndex);
+  interface->SetDown ();
+
+  // Remove all routes that are going through this interface
+  bool modified = true;
+  while (modified)
+    {
+      modified = false;
+      for (uint32_t i = 0; i < GetNRoutes (); i++)
+        {
+          Ipv4Route *route = GetRoute (i);
+          if (route->GetInterface () == ifaceIndex)
+            {
+              RemoveRoute (i);
+              modified = true;
+              break;
+            }
+        }
+    }
+}
+
+}//namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv4-l3-protocol.h	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,209 @@
+// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation;
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+// Author: George F. Riley<riley@ece.gatech.edu>
+//
+
+#ifndef IPV4_L3_PROTOCOL_H
+#define IPV4_L3_PROTOCOL_H
+
+#include <list>
+#include <stdint.h>
+#include "ns3/ipv4-address.h"
+#include "ns3/ptr.h"
+#include "ns3/ipv4.h"
+#include "ns3/traced-callback.h"
+#include "ns3/ipv4-header.h"
+#include "ipv4-static-routing.h"
+
+namespace ns3 {
+
+class Packet;
+class NetDevice;
+class Ipv4Interface;
+class Ipv4Address;
+class Ipv4Header;
+class Ipv4Route;
+class Node;
+
+
+/**
+ * \brief Implement the Ipv4 layer.
+ */
+class Ipv4L3Protocol : public Object
+{
+public:
+  static TypeId GetTypeId (void);
+  static const uint16_t PROT_NUMBER;
+
+  Ipv4L3Protocol();
+  virtual ~Ipv4L3Protocol ();
+
+  void SetNode (Ptr<Node> node);
+
+  /**
+   * \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.
+   */
+  Ptr<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
+   */
+  void Receive( Ptr<NetDevice> device, Ptr<Packet> p, uint16_t protocol, const Address &from);
+
+  /**
+   * \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 (Ptr<Packet> 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);
+
+  void Lookup (Ipv4Header const &ipHeader,
+               Ptr<Packet> packet,
+               Ipv4RoutingProtocol::RouteReplyCallback routeReply);
+
+  uint32_t GetNRoutes (void);
+  Ipv4Route *GetRoute (uint32_t i);
+  void RemoveRoute (uint32_t i);
+
+  void AddMulticastRoute (Ipv4Address origin,
+                          Ipv4Address group,
+                          uint32_t inputInterface,
+                          std::vector<uint32_t> outputInterfaces);
+
+  void SetDefaultMulticastRoute (uint32_t onputInterface);
+
+  uint32_t GetNMulticastRoutes (void) const;
+  Ipv4MulticastRoute *GetMulticastRoute (uint32_t i) const;
+
+  void RemoveMulticastRoute (Ipv4Address origin,
+                             Ipv4Address group,
+                             uint32_t inputInterface);
+  void RemoveMulticastRoute (uint32_t i);
+
+  uint32_t AddInterface (Ptr<NetDevice> device);
+  Ptr<Ipv4Interface> GetInterface (uint32_t i) const;
+  uint32_t GetNInterfaces (void) const;
+
+  uint32_t FindInterfaceForAddr (Ipv4Address addr) const;
+  uint32_t FindInterfaceForAddr (Ipv4Address addr, Ipv4Mask mask) const;
+  int32_t FindInterfaceIndexForDevice (Ptr<NetDevice> device) const;
+  
+  void JoinMulticastGroup (Ipv4Address origin, Ipv4Address group);
+  void LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group);
+
+  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;
+  void SetMetric (uint32_t i, uint16_t metric);
+  uint16_t GetMetric (uint32_t i) const;
+  bool GetIfIndexForDestination (Ipv4Address destination, 
+                                 uint32_t& ifIndex) const;
+  uint16_t GetMtu (uint32_t i) const;
+  bool IsUp (uint32_t i) const;
+  void SetUp (uint32_t i);
+  void SetDown (uint32_t i);
+
+  void AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
+                           int priority);
+
+protected:
+
+  virtual void DoDispose (void);
+
+private:
+  void Lookup (uint32_t ifIndex,
+               Ipv4Header const &ipHeader,
+               Ptr<Packet> packet,
+               Ipv4RoutingProtocol::RouteReplyCallback routeReply);
+
+  void SendRealOut (bool found,
+                    Ipv4Route const &route,
+                    Ptr<Packet> packet,
+                    Ipv4Header const &ipHeader);
+  bool Forwarding (uint32_t ifIndex, 
+                   Ptr<Packet> packet, 
+                   Ipv4Header &ipHeader, 
+                   Ptr<NetDevice> device);
+  void ForwardUp (Ptr<Packet> p, Ipv4Header const&ip, Ptr<Ipv4Interface> incomingInterface);
+  uint32_t AddIpv4Interface (Ptr<Ipv4Interface> interface);
+  void SetupLoopback (void);
+
+  typedef std::list<Ptr<Ipv4Interface> > Ipv4InterfaceList;
+  typedef std::list<std::pair<Ipv4Address, Ipv4Address> > 
+    Ipv4MulticastGroupList;
+  typedef std::list< std::pair< int, Ptr<Ipv4RoutingProtocol> > > Ipv4RoutingProtocolList;
+
+  Ipv4InterfaceList m_interfaces;
+  uint32_t m_nInterfaces;
+  uint8_t m_defaultTtl;
+  bool m_calcChecksum;
+  uint16_t m_identification;
+  Ptr<Node> m_node;
+  TracedCallback<Ptr<const Packet>, uint32_t> m_txTrace;
+  TracedCallback<Ptr<const Packet>, uint32_t> m_rxTrace;
+  TracedCallback<Ptr<const Packet> > m_dropTrace;
+
+  Ipv4RoutingProtocolList m_routingProtocols;
+
+  Ptr<Ipv4StaticRouting> m_staticRouting;
+  Ipv4MulticastGroupList m_multicastGroups;
+};
+
+} // Namespace ns3
+
+#endif /* IPV4_L3_PROTOCOL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv4-l4-demux.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,97 @@
+// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation;
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+// Author: George F. Riley<riley@ece.gatech.edu>
+//
+
+// Define the layer 4 demultiplexer object for ns3.
+// George F. Riley, Georgia Tech, Fall 2006
+
+#include <sstream>
+#include "ns3/node.h"
+#include "ns3/object-vector.h"
+#include "ipv4-l4-demux.h"
+#include "ipv4-l4-protocol.h"
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv4L4Demux);
+
+TypeId 
+Ipv4L4Demux::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::Ipv4L4Demux")
+    .SetParent<Object> ()
+    .AddAttribute ("Protocols", "The set of protocols registered with this demux.",
+                   ObjectVectorValue (),
+                   MakeObjectVectorAccessor (&Ipv4L4Demux::m_protocols),
+                   MakeObjectVectorChecker<Ipv4L4Protocol> ())
+    ;
+  return tid;
+}
+
+Ipv4L4Demux::Ipv4L4Demux ()
+{}
+
+Ipv4L4Demux::~Ipv4L4Demux()
+{}
+
+void 
+Ipv4L4Demux::SetNode (Ptr<Node> node)
+{
+  m_node = node;
+}
+
+void
+Ipv4L4Demux::DoDispose (void)
+{
+  for (L4List_t::iterator i = m_protocols.begin(); i != m_protocols.end(); ++i)
+    {
+      (*i)->Dispose ();
+      *i = 0;
+    }
+  m_protocols.clear ();
+  m_node = 0;
+  Object::DoDispose ();
+}
+
+void
+Ipv4L4Demux::Insert(Ptr<Ipv4L4Protocol> protocol)
+{
+  m_protocols.push_back (protocol);
+}
+Ptr<Ipv4L4Protocol>
+Ipv4L4Demux::GetProtocol(int protocolNumber)
+{
+  for (L4List_t::iterator i = m_protocols.begin(); i != m_protocols.end(); ++i)
+    {
+      if ((*i)->GetProtocolNumber () == protocolNumber)
+	{
+	  return *i;
+	}
+    }
+  return 0;
+}
+void
+Ipv4L4Demux::Remove (Ptr<Ipv4L4Protocol> protocol)
+{
+  m_protocols.remove (protocol);
+}
+
+
+
+}//namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv4-l4-demux.h	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,85 @@
+// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation;
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+// Author: George F. Riley<riley@ece.gatech.edu>
+//
+
+// Define the layer 4 demultiplexer object for ns3.
+// George F. Riley, Georgia Tech, Fall 2006
+
+#ifndef IPV4_L4_DEMUX_H
+#define IPV4_L4_DEMUX_H
+
+#include <list>
+#include "ns3/object.h"
+#include "ns3/ptr.h"
+
+namespace ns3 {
+
+class Ipv4L4Protocol;
+class Node;
+
+/**
+ * \brief L4 Ipv4 Demux
+ */
+class Ipv4L4Demux : public Object
+{
+public:
+  static TypeId GetTypeId (void);
+  Ipv4L4Demux ();
+  virtual ~Ipv4L4Demux();
+
+  void SetNode (Ptr<Node> node);
+
+  /**
+   * \param protocol a template for the protocol to add to this L4 Demux.
+   * \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 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.
+   */
+  void Insert(Ptr<Ipv4L4Protocol> protocol);
+  /**
+   * \param protocolNumber number of protocol to lookup
+   *        in this L4 Demux
+   * \returns a matching L4 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::GetUdp for example.
+   */
+  Ptr<Ipv4L4Protocol> GetProtocol(int protocolNumber);
+  /**
+   * \param protocol protocol to remove from this demux.
+   *
+   * The input value to this method should be the value
+   * returned from the Ipv4L4Protocol::Insert method.
+   */
+  void Remove (Ptr<Ipv4L4Protocol> protocol);
+protected:
+  virtual void DoDispose (void);
+private:
+  typedef std::list<Ptr<Ipv4L4Protocol> > L4List_t;
+  L4List_t m_protocols;
+  Ptr<Node> m_node;
+};
+
+} //namespace ns3
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv4-l4-protocol.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,51 @@
+// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation;
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+// Author: George F. Riley<riley@ece.gatech.edu>
+//
+
+// NS3 - Layer 4 Protocol base class
+// George F. Riley, Georgia Tech, Spring 2007
+
+#include "ipv4-l4-protocol.h"
+#include "ns3/uinteger.h"
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv4L4Protocol);
+
+TypeId 
+Ipv4L4Protocol::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::Ipv4L4Protocol")
+    .SetParent<Object> ()
+    .AddAttribute ("ProtocolNumber", "The Ipv4 protocol number.",
+                   UintegerValue (0),
+                   MakeUintegerAccessor (&Ipv4L4Protocol::GetProtocolNumber),
+                   MakeUintegerChecker<int> ())
+    .AddAttribute ("Version", "The version of the protocol.",
+                   UintegerValue (0),
+                   MakeUintegerAccessor (&Ipv4L4Protocol::GetVersion),
+                   MakeUintegerChecker<int> ())
+    ;
+  return tid;
+}
+
+Ipv4L4Protocol::~Ipv4L4Protocol ()
+{}
+
+}//namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv4-l4-protocol.h	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,74 @@
+// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation;
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+// Author: George F. Riley<riley@ece.gatech.edu>
+//
+
+// NS3 - Layer 4 Protocol base class
+// George F. Riley, Georgia Tech, Spring 2007
+
+#ifndef IPV4_L4_PROTOCOL_H
+#define IPV4_L4_PROTOCOL_H
+
+#include "ns3/object.h"
+#include "ipv4-interface.h"
+
+namespace ns3 {
+
+class Packet;
+class Ipv4Address;
+
+/**
+ * \brief L4 Protocol base class 
+ *
+ * If you want to implement a new L4 protocol, all you have to do is
+ * implement a subclass of this base class and add it to an L4Demux.
+ */  
+class Ipv4L4Protocol : public Object
+{
+public:
+  static TypeId GetTypeId (void);
+
+  virtual ~Ipv4L4Protocol ();
+
+  /**
+   * \returns the protocol number of this protocol.
+   */
+  virtual int GetProtocolNumber (void) const = 0;
+  /**
+   * \returns the version number of this protocol.
+   */
+  virtual int GetVersion (void) const = 0;
+
+  /**
+   * \param p packet to forward up
+   * \param source source address of packet received
+   * \param destination address of packet received
+   * \param incomingInterface the Ipv4Interface on which the packet arrived
+   * 
+   * Called from lower-level layers to send the packet up
+   * in the stack. 
+   */
+  virtual void Receive(Ptr<Packet> p, 
+                       Ipv4Address const &source,
+                       Ipv4Address const &destination,
+                       Ptr<Ipv4Interface> incomingInterface) = 0;
+};
+
+} // Namespace ns3
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv4-loopback-interface.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,79 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 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: 
+ *  Mathieu Lacage <mathieu.lacage@sophia.inria.fr>,
+ */
+
+#include "ns3/log.h"
+#include "ns3/net-device.h"
+#include "ns3/node.h"
+#include "ns3/mac48-address.h"
+#include "ns3/packet.h"
+#include "ipv4-loopback-interface.h"
+#include "ipv4-l3-protocol.h"
+
+NS_LOG_COMPONENT_DEFINE ("Ipv4LoopbackInterface");
+
+namespace ns3 {
+
+TypeId 
+Ipv4LoopbackInterface::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::Ipv4LoopbackInterface")
+    .SetParent<Ipv4Interface> ()
+    ;
+  return tid;
+}
+
+Ipv4LoopbackInterface::Ipv4LoopbackInterface ()
+  : m_node (0)
+{
+  NS_LOG_FUNCTION (this);
+}
+
+Ipv4LoopbackInterface::~Ipv4LoopbackInterface ()
+{
+  NS_LOG_FUNCTION (this);
+  NS_ASSERT (m_node != 0);
+}
+
+Ptr<NetDevice> 
+Ipv4LoopbackInterface::GetDevice (void) const
+{
+  return 0;
+}
+
+void 
+Ipv4LoopbackInterface::SetNode (Ptr<Node> node)
+{
+  m_node = node;
+}
+
+void 
+Ipv4LoopbackInterface::SendTo (Ptr<Packet> packet, Ipv4Address dest)
+{
+  NS_LOG_FUNCTION (this << packet << dest);
+
+  Ptr<Ipv4L3Protocol> ipv4 = 
+    m_node->GetObject<Ipv4L3Protocol> ();
+
+  ipv4->Receive (0, packet, Ipv4L3Protocol::PROT_NUMBER, 
+                 Mac48Address ("ff:ff:ff:ff:ff:ff"));
+}
+
+}//namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv4-loopback-interface.h	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,53 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 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: 
+ *  Mathieu Lacage <mathieu.lacage@sophia.inria.fr>,
+ */
+#ifndef IPV4_LOOPBACK_INTERFACE_H
+#define IPV4_LOOPBACK_INTERFACE_H
+
+#include "ipv4-interface.h"
+#include "ns3/ptr.h"
+
+namespace ns3 {
+
+class Node;
+/**
+ * \brief An IPv4 loopback interface
+ */
+class Ipv4LoopbackInterface : public Ipv4Interface 
+{
+public:
+  static TypeId GetTypeId (void);
+  Ipv4LoopbackInterface ();
+  virtual ~Ipv4LoopbackInterface ();
+
+  virtual Ptr<NetDevice> GetDevice (void) const;
+
+  void SetNode (Ptr<Node> node);
+
+ private:
+  virtual void SendTo (Ptr<Packet> p, Ipv4Address dest);
+
+  Ptr<Node> m_node;
+};
+
+}//namespace ns3
+
+
+#endif /* IPV4_LOOPBACK_INTERFACE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv4-static-routing.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,654 @@
+// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation;
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+// Author: George F. Riley<riley@ece.gatech.edu>
+//         Gustavo Carneiro <gjc@inescporto.pt>
+
+#include "ns3/log.h"
+#include "ipv4-static-routing.h"
+#include "ns3/packet.h"
+
+NS_LOG_COMPONENT_DEFINE ("Ipv4StaticRouting");
+
+namespace ns3 {
+
+Ipv4StaticRouting::Ipv4StaticRouting () 
+: m_defaultRoute (0), m_defaultMulticastRoute (0)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+void 
+Ipv4StaticRouting::AddHostRouteTo (Ipv4Address dest, 
+                                   Ipv4Address nextHop, 
+                                   uint32_t interface)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  Ipv4Route *route = new Ipv4Route ();
+  *route = Ipv4Route::CreateHostRouteTo (dest, nextHop, interface);
+  m_hostRoutes.push_back (route);
+}
+
+void 
+Ipv4StaticRouting::AddHostRouteTo (Ipv4Address dest, 
+                                   uint32_t interface)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  Ipv4Route *route = new Ipv4Route ();
+  *route = Ipv4Route::CreateHostRouteTo (dest, interface);
+  m_hostRoutes.push_back (route);
+}
+
+void 
+Ipv4StaticRouting::AddNetworkRouteTo (Ipv4Address network, 
+                                      Ipv4Mask networkMask, 
+                                      Ipv4Address nextHop, 
+                                      uint32_t interface)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  Ipv4Route *route = new Ipv4Route ();
+  *route = Ipv4Route::CreateNetworkRouteTo (network,
+                                            networkMask,
+                                            nextHop,
+                                            interface);
+  m_networkRoutes.push_back (route);
+}
+
+void 
+Ipv4StaticRouting::AddNetworkRouteTo (Ipv4Address network, 
+                                      Ipv4Mask networkMask, 
+                                      uint32_t interface)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  Ipv4Route *route = new Ipv4Route ();
+  *route = Ipv4Route::CreateNetworkRouteTo (network,
+                                            networkMask,
+                                            interface);
+  m_networkRoutes.push_back (route);
+}
+
+void 
+Ipv4StaticRouting::SetDefaultRoute (Ipv4Address nextHop, 
+                                    uint32_t interface)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  Ipv4Route *route = new Ipv4Route ();
+  *route = Ipv4Route::CreateDefaultRoute (nextHop, interface);
+  delete m_defaultRoute;
+  m_defaultRoute = route;
+}
+
+void 
+Ipv4StaticRouting::AddMulticastRoute(Ipv4Address origin,
+                                     Ipv4Address group,
+                                     uint32_t inputInterface,
+                                     std::vector<uint32_t> outputInterfaces)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  Ipv4MulticastRoute *route = new Ipv4MulticastRoute ();
+  *route = Ipv4MulticastRoute::CreateMulticastRoute (origin, group, 
+    inputInterface, outputInterfaces);
+  m_multicastRoutes.push_back (route);
+}
+
+void 
+Ipv4StaticRouting::SetDefaultMulticastRoute(uint32_t outputInterface)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  Ipv4Address origin = Ipv4Address::GetAny ();
+  Ipv4Address group = Ipv4Address::GetAny ();
+  uint32_t inputInterface = Ipv4RoutingProtocol::IF_INDEX_ANY;
+
+  std::vector<uint32_t> outputInterfaces (1);
+  outputInterfaces[0] = outputInterface;
+  
+  Ipv4MulticastRoute *route = new Ipv4MulticastRoute ();
+  *route = Ipv4MulticastRoute::CreateMulticastRoute (origin, group, 
+    inputInterface, outputInterfaces);
+
+  delete m_defaultMulticastRoute;
+  m_defaultMulticastRoute = route;
+}
+
+uint32_t 
+Ipv4StaticRouting::GetNMulticastRoutes (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_multicastRoutes.size () + m_defaultMulticastRoute ? 1 : 0;
+}
+
+Ipv4MulticastRoute *
+Ipv4StaticRouting::GetMulticastRoute (uint32_t index) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  NS_ASSERT_MSG(index < m_multicastRoutes.size (),
+    "Ipv4StaticRouting::GetMulticastRoute ():  Index out of range");
+//
+// From an external point of view the default route appears to be in slot 0
+// of the routing table.  The implementation, however, puts it in a separate 
+// place.  So, if a client asks for index 0 and we have a default multicast
+// route, we have to return it from that different place 
+// (m_defaultMulticastRoute).
+//
+  if (index == 0 && m_defaultMulticastRoute != 0)
+    {
+      return m_defaultMulticastRoute;
+    }
+//
+// If there is a default multicast route present, a client will just assume
+// that it is in slot zero and there is one "extra" zeroth route in the table.
+// To return the correct indexed entry in our list, we have to decrement the
+// index to take into account the default route not being in the actual list.
+// Since we fell through to here, we've taken care of the case where the
+// index was zero.
+//
+  if (m_defaultMulticastRoute != 0)
+    {
+      NS_ASSERT(index > 0);
+      index--;
+    }
+
+  if (index < m_multicastRoutes.size ())
+    {
+      uint32_t tmp = 0;
+      for (MulticastRoutesCI i = m_multicastRoutes.begin (); 
+           i != m_multicastRoutes.end (); 
+           i++) 
+        {
+          if (tmp  == index)
+            {
+              return *i;
+            }
+          tmp++;
+        }
+    }
+  return 0;
+}
+
+Ipv4MulticastRoute *
+Ipv4StaticRouting::GetDefaultMulticastRoute () const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  if (m_defaultMulticastRoute != 0)
+    {
+      return m_defaultMulticastRoute;
+    }
+  return 0;
+}
+
+bool
+Ipv4StaticRouting::RemoveMulticastRoute(Ipv4Address origin,
+                                        Ipv4Address group,
+                                        uint32_t inputInterface)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  for (MulticastRoutesI i = m_multicastRoutes.begin (); 
+       i != m_multicastRoutes.end (); 
+       i++) 
+    {
+      Ipv4MulticastRoute *route = *i;
+      if (origin == route->GetOrigin () &&
+          group == route->GetGroup () &&
+          inputInterface == route->GetInputInterface ())
+        {
+          delete *i;
+          m_multicastRoutes.erase (i);
+          return true;
+        }
+    }
+  return false;
+}
+
+void 
+Ipv4StaticRouting::RemoveMulticastRoute(uint32_t index)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+//
+// From an external point of view the default route appears to be in slot 0
+// of the routing table.  The implementation, however, puts it in a separate 
+// place.  So, if a client asks to delete index 0 and we have a default
+// multicast route set, we have to delete it from that different place 
+// (m_defaultMulticastRoute).
+//
+  if (index == 0 && m_defaultMulticastRoute != 0)
+    {
+      delete m_defaultMulticastRoute;
+      m_defaultMulticastRoute = 0;
+    }
+//
+// If there is a default multicast route present, a client will just assume
+// that it is in slot zero and there is one "extra" zeroth route in the table.
+// To return the correct indexed entry in our list, we have to decrement the
+// index to take into account the default route not being in the actual list.
+// Since we fell through to here, we've taken care of the case where the
+// index was zero.
+//
+  if (m_defaultMulticastRoute != 0)
+    {
+      NS_ASSERT(index > 0);
+      index--;
+    }
+
+  uint32_t tmp = 0;
+  for (MulticastRoutesI i = m_multicastRoutes.begin (); 
+       i != m_multicastRoutes.end (); 
+       i++) 
+    {
+      if (tmp  == index)
+        {
+          delete *i;
+          m_multicastRoutes.erase (i);
+          return;
+        }
+      tmp++;
+    }
+}
+
+Ipv4Route *
+Ipv4StaticRouting::LookupStatic (Ipv4Address dest)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  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;
+}
+
+Ipv4MulticastRoute *
+Ipv4StaticRouting::LookupStatic (
+  Ipv4Address origin, 
+  Ipv4Address group,
+  uint32_t    ifIndex)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+//
+// We treat the "any" address (typically 0.0.0.0) as a wildcard in our matching
+// scheme.
+//
+  Ipv4Address wildcard = Ipv4Address::GetAny ();
+
+  for (MulticastRoutesI i = m_multicastRoutes.begin (); 
+       i != m_multicastRoutes.end (); 
+       i++) 
+    {
+      Ipv4MulticastRoute *route = *i;
+//
+// We've been passed an origin address, a multicast group address and an 
+// interface index.  We have to decide if the current route in the list is
+// a match.
+//
+// The first case is the restrictive case where the origin, group and index
+// matches.  This picks up exact routes during forwarded and exact routes from
+// the local node (in which case the ifIndex is a wildcard).
+//
+      if (origin == route->GetOrigin () && group == route->GetGroup ())
+        {
+          if (ifIndex == Ipv4RoutingProtocol::IF_INDEX_ANY || 
+              ifIndex == route->GetInputInterface ())
+            {
+              return *i;
+            }
+        }
+    }
+//
+// If the input interface index is not a wildcard (that means that the packet 
+// did not originally come from this node), we're done.  We don't
+// just happily forward packets we don't really know what to do with.  
+// Multicast storms are not generally considered a good thing.
+//
+  if (ifIndex != Ipv4RoutingProtocol::IF_INDEX_ANY)
+    {
+      return 0;
+    }
+//
+// Now, we're going to get a litle less restricive.  This only applies in the
+// case where the packet in question is coming from the local node.  In order
+// to avoid dependencies on the order in which routes were added, we will 
+// actually walk the list two more times, the first time looking for routes
+// with a single wildcard, and the last time looking for the first route
+// with two wildcards.
+//
+  for (MulticastRoutesI i = m_multicastRoutes.begin (); 
+       i != m_multicastRoutes.end (); 
+       i++) 
+    {
+      Ipv4MulticastRoute *route = *i;
+//
+// Here we will ignore the origin.  We know that a single source address must
+// be picked for a packet, but we may want to send multicast packets out
+// multiple interfaces.  To support this case, a user would need to add
+// a Multicast route with the route's origin set to wildcard.  N.B As a
+// result, packets sourced from a node with multiple interface may have a
+// source IP address different from that of the interface actually used to
+// send the packet.
+//
+      if (route->GetOrigin () == wildcard && group == route->GetGroup ())
+        {
+          return *i;
+        }
+    }
+//
+// Finally we want to allow users to specify a default route that specifies
+// sending all multicast packets out multiple interfaces.  The standard
+// default multicast route is patterned after other systems and limits the 
+// number of outputs to one.  If, however a client manually adds a multicast
+// route with the origin, the multicast group and the input interface index
+// all set to wildcard, she has created a default route with multiple output
+// interfaces.
+//
+  for (MulticastRoutesI i = m_multicastRoutes.begin (); 
+       i != m_multicastRoutes.end (); 
+       i++) 
+    {
+      Ipv4MulticastRoute *route = *i;
+
+      if (route->GetOrigin () == wildcard && route->GetGroup () == wildcard)
+        {
+          return *i;
+        }
+    }
+//
+// We also allow users to specify a typical default multicast route.  This
+// default route is limited to specifying a single output interface.
+//
+  if (m_defaultMulticastRoute != 0) 
+    {
+      return m_defaultMulticastRoute;
+    }
+
+  return 0;
+}
+
+uint32_t 
+Ipv4StaticRouting::GetNRoutes (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  uint32_t n = 0;
+  if (m_defaultRoute != 0)
+    {
+      n++;
+    }
+  n += m_hostRoutes.size ();
+  n += m_networkRoutes.size ();
+  return n;
+}
+
+Ipv4Route *
+Ipv4StaticRouting::GetDefaultRoute ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  if (m_defaultRoute != 0)
+    {
+      return m_defaultRoute;
+    }
+  else
+    {
+      return 0;
+    }
+}
+
+Ipv4Route *
+Ipv4StaticRouting::GetRoute (uint32_t index)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  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 
+Ipv4StaticRouting::RemoveRoute (uint32_t index)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  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);
+}
+
+bool
+Ipv4StaticRouting::RequestRoute (
+  uint32_t ifIndex,
+  Ipv4Header const &ipHeader,
+  Ptr<Packet> packet,
+  RouteReplyCallback routeReply)
+{
+  NS_LOG_FUNCTION (this << ifIndex << &ipHeader << packet << &routeReply);
+
+  NS_LOG_LOGIC ("source = " << ipHeader.GetSource ());
+
+  NS_LOG_LOGIC ("destination = " << ipHeader.GetDestination ());
+
+  if (ipHeader.GetDestination ().IsMulticast ())
+    {
+      NS_LOG_LOGIC ("Multicast destination");
+
+      Ipv4MulticastRoute *mRoute = LookupStatic(ipHeader.GetSource (),
+        ipHeader.GetDestination (), ifIndex);
+
+      if (mRoute)
+        {
+          NS_LOG_LOGIC ("Multicast route found");
+
+          for (uint32_t i = 0; i < mRoute->GetNOutputInterfaces (); ++i)
+            {
+              Ptr<Packet> p = packet->Copy ();
+              Ipv4Header h = ipHeader;
+              Ipv4Route route = 
+                Ipv4Route::CreateHostRouteTo(h.GetDestination (), 
+                  mRoute->GetOutputInterface(i));
+              NS_LOG_LOGIC ( "Send via interface " << 
+                mRoute->GetOutputInterface(i));
+              routeReply (true, route, p, h);
+            }
+          return true;
+        }
+      return false; // Let other routing protocols try to handle this
+    }
+//
+// This is a unicast packet.  Check to see if we have a route for it.
+//
+  NS_LOG_LOGIC ("Unicast destination");
+  Ipv4Route *route = LookupStatic (ipHeader.GetDestination ());
+  if (route != 0)
+    {
+      routeReply (true, *route, packet, ipHeader);
+      return true;
+    }
+  else
+    {
+      return false; // Let other routing protocols try to handle this
+                    // route request.
+    }
+}
+
+bool
+Ipv4StaticRouting::RequestIfIndex (Ipv4Address destination, uint32_t& ifIndex)
+{
+  NS_LOG_FUNCTION (this << destination << &ifIndex);
+//
+// First, see if this is a multicast packet we have a route for.  If we
+// have a route, then send the packet down each of the specified interfaces.
+//
+  if (destination.IsMulticast ())
+    {
+      NS_LOG_LOGIC ("Multicast destination");
+
+      Ipv4MulticastRoute *mRoute = LookupStatic(Ipv4Address::GetAny (),
+        destination, Ipv4RoutingProtocol::IF_INDEX_ANY);
+
+      if (mRoute)
+        {
+          NS_LOG_LOGIC ("Multicast route found");
+
+          if (mRoute->GetNOutputInterfaces () != 1)
+            {
+              NS_LOG_LOGIC ("Route is to multiple interfaces.  Ignoring.");
+              return false;
+            }
+
+          ifIndex = mRoute->GetOutputInterface(0);
+          NS_LOG_LOGIC ("Found ifIndex " << ifIndex);
+          return true;
+        }
+      return false; // Let other routing protocols try to handle this
+    }
+//
+// See if this is a unicast packet we have a route for.
+//
+  NS_LOG_LOGIC ("Unicast destination");
+  Ipv4Route *route = LookupStatic (destination);
+  if (route)
+    {
+      ifIndex = route->GetInterface ();
+      return true;
+    }
+  else
+    {
+      return false;
+    }
+}
+
+void
+Ipv4StaticRouting::DoDispose (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  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;
+    }
+  for (MulticastRoutesI i = m_multicastRoutes.begin (); 
+       i != m_multicastRoutes.end (); 
+       i = m_multicastRoutes.erase (i)) 
+    {
+      delete (*i);
+    }
+  if (m_defaultMulticastRoute != 0)
+    {
+      delete m_defaultMulticastRoute;
+      m_defaultMulticastRoute = 0;
+    }
+  Ipv4RoutingProtocol::DoDispose ();
+}
+
+}//namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv4-static-routing.h	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,506 @@
+// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation;
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+// Author: George F. Riley<riley@ece.gatech.edu>
+//         Gustavo Carneiro <gjc@inescporto.pt>
+//
+
+#ifndef IPV4_STATIC_ROUTING_H
+#define IPV4_STATIC_ROUTING_H
+
+#include <list>
+#include <stdint.h>
+#include "ns3/ipv4-address.h"
+#include "ns3/ipv4-header.h"
+#include "ns3/ptr.h"
+#include "ns3/ipv4.h"
+
+namespace ns3 {
+
+class Packet;
+class NetDevice;
+class Ipv4Interface;
+class Ipv4Address;
+class Ipv4Header;
+class Ipv4Route;
+class Node;
+
+
+/**
+ * @brief Static routing protocol for IP version 4 stacks.
+ *
+ * In ns-3 we have the concept of a pluggable routing protocol.  Routing
+ * protocols are added to a list maintained by the Ipv4L3Protocol.  Every 
+ * stack gets one routing protocol for free -- the Ipv4StaticRouting routing
+ * protocol is added in the constructor of the Ipv4L3Protocol (this is the 
+ * piece of code that implements the functionality of the IP layer).
+ *
+ * The Ipv4StaticRouting class inherits from the abstract base class 
+ * Ipv4RoutingProtocol that defines the interface methods that a routing 
+ * protocol must support.
+ *
+ * When a packet arrives in the Ipv4L3Protocol for transmission, it comes
+ * either from a local source via Ipv4L3Protocol::Send or from a remote 
+ * source via Ipv4L3Protocol::Forwarding.  In both cases, a function is called
+ * (Ipv4L3Protocol::Lookup) to look up the routing information for the packet.
+ *
+ * The lookup function iterates through the list of routing protocols asking
+ * each to see if it can find a route and send the packet.  A callback is 
+ * provided during each of these calls that should be considered a pre-
+ * packaged send call.  This is done to allow asynchronous calls into 
+ * routing subsystems in order to support on-demand routing, for example.  The
+ * method for requesting this operation is Ipv4StaticRouting::RequestRoute for
+ * the static routing protocol.
+ *
+ * Each routing protocol is also free to implement its own methods for managing
+ * routes which you will find below.  This class manages a set of "static" or
+ * manually configured routes for host, network and multicast routes.
+ *
+ * @see Ipv4RoutingProtocol
+ * @see Ipv4L3Protocol::AddRoutingProtocol
+ * @see Ipv4L3Protocol::Ipv4L3Protocol
+ */
+class Ipv4StaticRouting : public Ipv4RoutingProtocol
+{
+public:
+/**
+ * @brief Construct an empty Ipv4StaticRouting routing protocol,
+ * @internal
+ *
+ * The Ipv4StaticRouting class supports host, network and multicast routes.
+ * This method initializes the lists containing these routes to empty.
+ *
+ * @see Ipv4StaticRouting
+ */
+  Ipv4StaticRouting ();
+
+/**
+ * @brief Request that a check for a route bw performed and if a route is found
+ * that the packet be sent on its way using the pre-packaged send callback.
+ *
+ * The source and destination IP addresses for the packet in question are found
+ * in the provided Ipv4Header.  There are two major processing forks depending
+ * on the type of destination address.  
+ *
+ * If the destination address is unicast then the routing table is consulted 
+ * for a route to the destination and if it is found, the routeReply callback
+ * is executed to send the packet (with the found route).
+ * 
+ * If the destination address is a multicast, then the exact processing steps
+ * depend on whether or not the packet has been sourced locally.  This is 
+ * determined by the parameter ifIndex.  This is the interface index over which
+ * this packet was received.  If the packet has not been received over a
+ * network interface, this index will be set to 
+ * Ipv4RoutingProtocol::IF_INDEX_ANY (a very large number).  In that case, 
+ * we want to avoid the requirement that an explicit route out of each node 
+ * must be set, so we don't do anything here.
+ * 
+ * If the packet is a multicast destination and has been received over a 
+ * network interface, a call to this method implies that the packet is being
+ * forwarded.  In that case, there must be an explicit route out of the node.
+ * A multicast route references the source address, the destination address
+ * (the multicast group) and the input interface in order to find a route.
+ * We consult the multicast routing table and, if a route is found, send the
+ * packet out of as many interfaces as required using the provided callback
+ * (think of it as a pre-packaged send call).
+ *
+ * @param ifIndex The network interface index over which the packed was 
+ * received.  If the packet is from a local source, ifIndex will be set to
+ * Ipv4RoutingProtocol::IF_INDEX_ANY.
+ * @param ipHeader the Ipv4Header containing the source and destination IP
+ * addresses for the packet.
+ * @param packet The packet to be sent if a route is found.
+ * @param routeReply A callback that packaged up the call to actually send the
+ * packet.
+ * @return Returns true if a route is found and the packet has been sent,
+ * otherwise returns false indicating that the next routing protocol should
+ * be consulted.  In practice, the static routing protocol is the last chance
+ * protocol.
+ *
+ * @see Ipv4StaticRouting
+ * @see Ipv4RoutingProtocol
+ */
+  virtual bool RequestRoute (uint32_t ifIndex,
+                             Ipv4Header const &ipHeader,
+                             Ptr<Packet> packet,
+                             RouteReplyCallback routeReply);
+
+/**
+ * @brief Check to see if we can determine the interface index that will be
+ * used if a packet is sent to this destination.
+ *
+ * This method addresses a problem in the IP stack where a destination address
+ * must be present and checksummed into the IP header before the actual 
+ * interface over which the packet is sent can be determined.  The answer is
+ * to implement a known and intentional cross-layer violation.  This is the
+ * endpoint of a call chain that started up quite high in the stack (sockets)
+ * and has found its way down to the Ipv4L3Protocol which is consulting the
+ * routing protocols for what they would do if presented with a packet of the
+ * given destination.
+ *
+ * Note that the a single interface index is returned.  This means that if
+ * the destination address is a multicast, and an explicit route is present
+ * that includeds multiple output interfaces, that route cannot be used.
+ * 
+ * If there are multiple paths out of the node, the resolution is performed
+ * by Ipv4L3Protocol::GetIfIndexforDestination which has access to more 
+ * contextual information that is useful for making a determination.
+ *
+ * @param destination The Ipv4Address if the destination of a hypothetical 
+ * packet.  This may be a multicast group address.
+ * @param ifIndex A reference to the interface index over which a packet
+ * sent to this destination would be sent.
+ * @return Returns true if a route is found to the destination that involves
+ * a single output interface index, otherwise returns false indicating that
+ * the next routing protocol should be consulted.  In practice, the static 
+ * routing protocol is the last chance protocol.
+ *
+ * @see Ipv4StaticRouting
+ * @see Ipv4RoutingProtocol
+ * @see Ipv4L3Protocol
+ */
+  virtual bool RequestIfIndex (Ipv4Address destination, uint32_t& ifIndex);
+
+/**
+ * @brief Add a host route to the static routing table.
+ *
+ * @param dest The Ipv4Address destination for this route.
+ * @param nextHop The Ipv4Address of the next hop in the route.
+ * @param interface The network interface index used to send packets to the
+ * destination.
+ *
+ * @see Ipv4Address
+ */
+  void AddHostRouteTo (Ipv4Address dest, 
+                       Ipv4Address nextHop, 
+                       uint32_t interface);
+/**
+ * @brief Add a host route to the static routing table.
+ *
+ * @param dest The Ipv4Address destination for this route.
+ * @param interface The network interface index used to send packets to the
+ * destination.
+ *
+ * @see Ipv4Address
+ */
+  void AddHostRouteTo (Ipv4Address dest, 
+                       uint32_t interface);
+
+/**
+ * @brief Add a network route to the static routing table.
+ *
+ * @param network The Ipv4Address network for this route.
+ * @param networkMask The Ipv4Mask to extract the network.
+ * @param nextHop The next hop in the route to the destination network.
+ * @param interface The network interface index used to send packets to the
+ * destination.
+ *
+ * @see Ipv4Address
+ */
+  void AddNetworkRouteTo (Ipv4Address network, 
+                          Ipv4Mask networkMask, 
+                          Ipv4Address nextHop, 
+                          uint32_t interface);
+
+/**
+ * @brief Add a network route to the static routing table.
+ *
+ * @param network The Ipv4Address network for this route.
+ * @param networkMask The Ipv4Mask to extract the network.
+ * @param interface The network interface index used to send packets to the
+ * destination.
+ *
+ * @see Ipv4Address
+ */
+  void AddNetworkRouteTo (Ipv4Address network, 
+                          Ipv4Mask networkMask, 
+                          uint32_t interface);
+
+/**
+ * @brief Add a default route to the static routing table.
+ *
+ * This method tells the routing system what to do in the case where a specific
+ * route to a destination is not found.  The system forwards packets to the
+ * specified node in the hope that it knows better how to route the packet.
+ * 
+ * If the default route is set, it is returned as the selected route from 
+ * LookupStatic irrespective of destination address if no specific route is
+ * found.
+ *
+ * @param nextHop The Ipv4Address to send packets to in the hope that they
+ * will be forwarded correctly.
+ * @param interface The network interface index used to send packets.
+ *
+ * @see Ipv4Address
+ * @see Ipv4StaticRouting::Lookup
+ */
+  void SetDefaultRoute (Ipv4Address nextHop, 
+                        uint32_t interface);
+
+/**
+ * @brief Get the number of individual unicast routes that have been added
+ * to the routing table.
+ *
+ * @warning The default route counts as one of the routes.
+ */
+  uint32_t GetNRoutes (void);
+
+/**
+ * @brief Get the default route from the static routing table.
+ *
+ * @return If the default route is set, a pointer to that Ipv4Route is
+ * returned, otherwise a zero pointer is returned.
+ *
+ * @see Ipv4Route
+ */
+  Ipv4Route *GetDefaultRoute (void);
+
+/**
+ * @brief Get a route from the static unicast routing table.
+ *
+ * Externally, the unicast static routing table appears simply as a table with
+ * n entries.  The one sublety of note is that if a default route has been set
+ * it will appear as the zeroth entry in the table.  This means that if you
+ * add only a default route, the table will have one entry that can be accessed
+ * either by explicity calling GetDefaultRoute () or by calling GetRoute (0).
+ * 
+ * Similarly, if the default route has been set, calling RemoveRoute (0) will
+ * remove the default route.
+ *
+ * @param i The index (into the routing table) of the route to retrieve.  If
+ * the default route has been set, it will occupy index zero.
+ * @return If route is set, a pointer to that Ipv4Route is returned, otherwise
+ * a zero pointer is returned.
+ *
+ * @see Ipv4Route
+ * @see Ipv4StaticRouting::RemoveRoute
+ */
+  Ipv4Route *GetRoute (uint32_t i);
+
+/**
+ * @brief Remove a route from the static unicast routing table.
+ *
+ * Externally, the unicast static routing table appears simply as a table with
+ * n entries.  The one sublety of note is that if a default route has been set
+ * it will appear as the zeroth entry in the table.  This means that if the
+ * default route has been set, calling RemoveRoute (0) will remove the
+ * default route.
+ *
+ * @param i The index (into the routing table) of the route to remove.  If
+ * the default route has been set, it will occupy index zero.
+ *
+ * @see Ipv4Route
+ * @see Ipv4StaticRouting::GetRoute
+ * @see Ipv4StaticRouting::AddRoute
+ */
+  void RemoveRoute (uint32_t i);
+
+/**
+ * @brief Add a multicast route to the static routing table.
+ *
+ * A multicast route must specify an origin IP address, a multicast group and
+ * an input network interface index as conditions and provide a vector of
+ * output network interface indices over which packets matching the conditions
+ * are sent.
+ *
+ * Typically there are two main types of multicast routes:  routes of the 
+ * first kind are used during forwarding.  All of the conditions must be
+ * exlicitly provided.  The second kind of routes are used to get packets off
+ * of a local node.  The difference is in the input interface.  Routes for
+ * forwarding will always have an explicit input interface specified.  Routes
+ * off of a node will always set the input interface to a wildcard specified
+ * by the index Ipv4RoutingProtocol::IF_INDEX_ANY.
+ *
+ * For routes off of a local node wildcards may be used in the origin and
+ * multicast group addresses.  The wildcard used for Ipv4Adresses is that 
+ * address returned by Ipv4Address::GetAny () -- typically "0.0.0.0".  Usage
+ * of a wildcard allows one to specify default behavior to varying degrees.
+ *
+ * For example, making the origin address a wildcard, but leaving the 
+ * multicast group specific allows one (in the case of a node with multiple
+ * interfaces) to create different routes using different output interfaces
+ * for each multicast group.
+ *
+ * If the origin and multicast addresses are made wildcards, you have created
+ * essentially a default multicast address that can forward to multiple 
+ * interfaces.  Compare this to the actual default multicast address that is
+ * limited to specifying a single output interface for compatibility with
+ * existing functionality in other systems.
+ * 
+ * @param origin The Ipv4Address of the origin of packets for this route.  May
+ * be Ipv4Address:GetAny for open groups.
+ * @param group The Ipv4Address of the multicast group or this route.
+ * @param inputInterface The input network interface index over which to 
+ * expect packets destined for this route.  May be
+ * Ipv4RoutingProtocol::IF_INDEX_ANY for packets of local origin.
+ * @param outputInterfaces A vector of network interface indices used to specify
+ * how to send packets to the destination(s).
+ *
+ * @see Ipv4Address
+ */
+  void AddMulticastRoute (Ipv4Address origin,
+                          Ipv4Address group,
+                          uint32_t inputInterface,
+                          std::vector<uint32_t> outputInterfaces);
+
+/**
+ * @brief Add a default multicast route to the static routing table.
+ *
+ * This is the multicast equivalent of the unicast version SetDefaultRoute.
+ * We tell the routing system what to do in the case where a specific route
+ * to a destination multicast group is not found.  The system forwards 
+ * packets out the specified interface in the hope that "something out there"
+ * knows better how to route the packet.  This method is only used in 
+ * initially sending packets off of a host.  The default multicast route is
+ * not consulted during forwarding -- exact routes must be specified using
+ * AddMulticastRoute for that case.
+ *
+ * Since we're basically sending packets to some entity we think may know
+ * better what to do, we don't pay attention to "subtleties" like origin
+ * address, nor do we worry about forwarding out multiple  interfaces.  If the
+ * default multicast route is set, it is returned as the selected route from 
+ * LookupStatic irrespective of origin or multicast group if another specific
+ * route is not found.
+ *
+ * @param outputInterface The network interface index used to specify where
+ * to send packets in the case of unknown routes.
+ *
+ * @see Ipv4Address
+ */
+  void SetDefaultMulticastRoute (uint32_t outputInterface);
+
+/**
+ * @brief Get the number of individual multicast routes that have been added
+ * to the routing table.
+ *
+ * @warning The default multicast route counts as one of the routes.
+ */
+  uint32_t GetNMulticastRoutes (void) const;
+
+/**
+ * @brief Get a route from the static multicast routing table.
+ *
+ * Externally, the multicast static routing table appears simply as a table 
+ * with n entries.  The one sublety of note is that if a default route has 
+ * been set it will appear as the zeroth entry in the table.  This means that 
+ * if you add only a default route, the table will have one entry that can be
+ * accessed either by explicity calling GetDefaultMulticastRoute () or by
+ * calling GetMulticastRoute (0).
+ * 
+ * Similarly, if the default route has been set, calling 
+ * RemoveMulticastRoute (0) will remove the default route.
+ *
+ * @param i The index (into the routing table) of the multicast route to
+ * retrieve.  If the default route has been set, it will occupy index zero.
+ * @return If route \e i is set, a pointer to that Ipv4MulticastRoute is
+ * returned, otherwise a zero pointer is returned.
+ *
+ * @see Ipv4MulticastRoute
+ * @see Ipv4StaticRouting::RemoveRoute
+ */
+  Ipv4MulticastRoute *GetMulticastRoute (uint32_t i) const;
+
+/**
+ * @brief Get the default multicast route from the static routing table.
+ *
+ * @return If the default route is set, a pointer to that Ipv4MulticastRoute is
+ * returned, otherwise a zero pointer is returned.
+ *
+ * @see Ipv4Route
+ */
+  Ipv4MulticastRoute *GetDefaultMulticastRoute (void) const;
+
+/**
+ * @brief Remove a route from the static multicast routing table.
+ *
+ * Externally, the multicast static routing table appears simply as a table 
+ * with n entries.  The one sublety of note is that if a default multicast
+ * route has been set it will appear as the zeroth entry in the table.  This
+ * means that the default route may be removed by calling this method with
+ * appropriate wildcard parameters.
+ *
+ * This method causes the multicast routing table to be searched for the first
+ * route that matches the parameters and removes it.
+ *
+ * Wildcards may be provided to this function, but the wildcards are used to
+ * exacly match wildcards in the routes (see AddMulticastRoute).  That is,
+ * calling RemoveMulticastRoute with the origin set to "0.0.0.0" will not
+ * remove routes with any address in the origin, but will only remove routes
+ * with "0.0.0.0" set as the the origin.
+ *
+ * @param origin The IP address specified as the origin of packets for the
+ * route.
+ * @param group The IP address specified as the multicast group addres of
+ * the route.
+ * @param inputInterface The network interface index specified as the expected
+ * input interface for the route.
+ * @returns true if a route was found and removed, false otherwise.
+ *
+ * @see Ipv4MulticastRoute
+ * @see Ipv4StaticRouting::AddMulticastRoute
+ */
+  bool RemoveMulticastRoute (Ipv4Address origin,
+                             Ipv4Address group,
+                             uint32_t inputInterface);
+
+/**
+ * @brief Remove a route from the static multicast routing table.
+ *
+ * Externally, the multicast static routing table appears simply as a table 
+ * with n entries.  The one sublety of note is that if a default multicast
+ * route has been set it will appear as the zeroth entry in the table.  This 
+ * means that if the default route has been set, calling 
+ * RemoveMulticastRoute (0) will remove the default route.
+ *
+ * @param index The index (into the multicast routing table) of the route to
+ * remove.  If the default route has been set, it will occupy index zero.
+ *
+ * @see Ipv4Route
+ * @see Ipv4StaticRouting::GetRoute
+ * @see Ipv4StaticRouting::AddRoute
+ */
+  void RemoveMulticastRoute (uint32_t index);
+
+protected:
+  void DoDispose (void);
+
+private:
+  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;
+
+  typedef std::list<Ipv4MulticastRoute *> MulticastRoutes;
+  typedef std::list<Ipv4MulticastRoute *>::const_iterator MulticastRoutesCI;
+  typedef std::list<Ipv4MulticastRoute *>::iterator MulticastRoutesI;
+
+  Ipv4Route *LookupStatic (Ipv4Address dest);
+  Ipv4MulticastRoute *LookupStatic (Ipv4Address origin, Ipv4Address group,
+                                    uint32_t ifIndex);
+
+  HostRoutes m_hostRoutes;
+  NetworkRoutes m_networkRoutes;
+  Ipv4Route *m_defaultRoute;
+  Ipv4MulticastRoute *m_defaultMulticastRoute;
+  MulticastRoutes m_multicastRoutes;
+};
+
+} // Namespace ns3
+
+#endif /* IPV4_STATIC_ROUTING_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/pending-data.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,200 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation;
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+// Author: Rajib Bhattacharjea<raj.b@gatech.edu>
+//
+
+
+// This is a port of Data PDU Headers from:
+// Georgia Tech Network Simulator
+// George F. Riley.  Georgia Tech, Spring 2002
+
+#include <iostream>
+#include <algorithm>
+
+#include <string.h>
+
+#include "pending-data.h"
+#include "ns3/fatal-error.h"
+namespace ns3
+{
+
+PendingData::PendingData () : size (0), data (0),
+               msgSize (0), responseSize (0)
+{
+}
+
+PendingData::PendingData (uint32_t s, uint8_t* d, uint32_t msg, uint32_t resp)
+  : size (s), data (0), msgSize (msg), responseSize (resp)
+{
+  if (d)
+    {
+      data.push_back (Create<Packet> (d, size));
+    }
+}
+
+PendingData::PendingData(const std::string& s) 
+  : size (s.length () + 1), data (0),
+    msgSize (0), responseSize (0)
+{
+  data.push_back (Create<Packet> ((uint8_t*)s.c_str(), size));
+}
+
+PendingData::PendingData(const PendingData& c)
+  : size (c.Size ()), data (c.data),
+    msgSize (c.msgSize), responseSize (c.responseSize)
+{
+}
+
+PendingData::~PendingData()
+{
+}
+
+PendingData* PendingData::Copy () const
+{
+  return new PendingData (*this);
+};
+
+PendingData* PendingData::CopyS (uint32_t s)
+{ // Copy, but with new size (assumes no associated data);
+  return new PendingData (s, 0, msgSize, responseSize);
+}
+
+PendingData* PendingData::CopySD (uint32_t s, uint8_t* d)
+{ // Copy, but with new size (assumes no associated data);
+  return new PendingData (s, d, msgSize, responseSize);
+}
+
+void PendingData::Clear ()
+{ // Remove all pending data
+  data.clear();
+  size = 0;
+}
+
+void PendingData::Add (uint32_t s, const uint8_t* d)
+{
+  if (d == 0)
+  {
+    data.push_back(Create<Packet> (d,s));
+  }
+  else
+  {
+    data.push_back(Create<Packet> (s));
+  }
+  size += s;
+}
+
+void PendingData::Add (Ptr<Packet> p)
+{
+  data.push_back(p);
+  size += p->GetSize();
+}
+
+uint32_t PendingData::SizeFromSeq (const SequenceNumber& f, const SequenceNumber& o)
+{
+  uint32_t o1 = OffsetFromSeq (f,o); // Offset to start of unused data
+  return SizeFromOffset (o1);      // Amount of data after offset
+}
+
+uint32_t PendingData::SizeFromOffset (uint32_t o)
+{ // Find out how much data is available from offset
+  if (o > size) return 0;     // No data at requested offset
+  return size - o;            // Available data after offset
+}
+
+uint32_t PendingData::OffsetFromSeq (const SequenceNumber& f, const SequenceNumber& o)
+{ // f is the first sequence number in this data, o is offset sequence
+  if (o < f) 
+    {
+      return 0; // HuH?  Shouldn't happen
+    }
+  return o - f;
+}
+
+Ptr<Packet> PendingData::CopyFromOffset (uint32_t s, uint32_t o)
+{ // Make a copy of data from starting position "o" for "s" bytes
+  // Return NULL if results in zero length data
+  uint32_t s1 = std::min (s, SizeFromOffset (o)); // Insure not beyond end of data
+  if (s1 == 0)
+    {
+      return 0;   // No data requested
+    }
+  if (data.size() != 0)
+    { // Actual data exists, make copy and return it
+      uint32_t count = 0;
+      std::vector<Ptr<Packet> >::size_type begin = 0;
+      bool beginFound = false;
+      std::vector<Ptr<Packet> >::size_type end = 0;
+      Ptr<Packet> outPacket;
+      Ptr<Packet> endFragment;
+      for (std::vector<Ptr<Packet> >::size_type i=0;i<data.size();++i)
+        {
+          count+=data[i]->GetSize();
+          if (!beginFound)
+            {
+              if (count > o)
+                {
+                  if (count >= o + s1) //then just copy within this packet
+                  {
+                    Ptr<Packet> toFragment = data[i];
+                    uint32_t packetStart = count - toFragment->GetSize();
+                    uint32_t packetOffset = o - packetStart;
+                    outPacket = toFragment->CreateFragment (packetOffset, s1);
+                    return outPacket;
+                  }
+                  begin = i;
+                  beginFound = true;
+                  Ptr<Packet> toFragment = data[begin];
+                  uint32_t packetStart = count - toFragment->GetSize();
+                  uint32_t packetOffset = o - packetStart;
+                  uint32_t fragmentLength = count - o;
+                  outPacket = toFragment->CreateFragment (packetOffset, fragmentLength);
+                }
+            }
+          else
+            {
+              if (count >= o + s1)
+                {
+                  end = i;
+                  Ptr<Packet> toFragment = data[end];
+                  uint32_t packetStart = count - toFragment->GetSize();
+                  uint32_t fragmentLength = o + s1 - packetStart;
+                  endFragment = toFragment->CreateFragment(0, fragmentLength);
+                  break;
+                }
+            }
+        }
+      for (std::vector<Ptr<Packet> >::size_type i=begin+1;i<end;++i)
+        {
+          outPacket->AddAtEnd (data[i]);
+        }
+      outPacket->AddAtEnd(endFragment);
+      NS_ASSERT(outPacket->GetSize() == s1);
+      return outPacket;
+    }
+  else
+    { // No actual data, just return dummy-data packet of correct size
+      return Create<Packet> (s1);
+    }
+}
+
+Ptr<Packet> PendingData::CopyFromSeq (uint32_t s, const SequenceNumber& f, const SequenceNumber& o)
+{
+  return CopyFromOffset (s, OffsetFromSeq(f,o));
+}
+
+}//namepsace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/pending-data.h	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,74 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation;
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+// Author: Rajib Bhattacharjea<raj.b@gatech.edu>
+//
+
+// Georgia Tech Network Simulator - Data Descriptors
+// George F. Riley.  Georgia Tech, Spring 2002
+
+#ifndef __datapdu_h__
+#define __datapdu_h__
+
+#include "ns3/packet.h"
+#include "pending-data.h"
+#include "sequence-number.h"
+
+#include "ns3/ptr.h"
+namespace ns3
+{
+class Packet;
+//Doc:ClassXRef
+class PendingData {
+public:
+  PendingData ();
+  PendingData (uint32_t s, uint8_t* d = NULL, uint32_t msg = 0, uint32_t resp = 0);
+  PendingData (const std::string&); // Construct from string
+  PendingData (uint8_t*, uint32_t&, Packet*); // Construct from serialized buffer
+  PendingData (const PendingData&);   // Copy constructor
+  virtual ~PendingData ();     // Destructor
+  uint32_t Size () const { return size;}
+  // Serialization
+  uint32_t SSize ();                   // Size needed for serialization
+  uint8_t*  Serialize (uint8_t*, uint32_t&); // Serialize to a buffer
+  uint8_t*  Construct (uint8_t*, uint32_t&); // Construct from buffer
+  virtual void Clear ();// Remove all associated data
+  virtual void Add (uint32_t s, const uint8_t* d = 0);// Add some data to end
+  virtual void Add (Ptr<Packet> p);
+  // Inquire available data from (f,o) sequence pair
+  virtual uint32_t SizeFromSeq (const SequenceNumber&, const SequenceNumber&);
+  // Inquire available data from offset
+  virtual uint32_t SizeFromOffset (uint32_t);
+  // Available size from sequence difference 
+  virtual uint32_t OffsetFromSeq (const SequenceNumber&, const SequenceNumber&);
+  virtual Ptr<Packet> CopyFromOffset (uint32_t, uint32_t);  // Size, offset, ret packet
+  // Copy data, size, offset specified by sequence difference
+  virtual Ptr<Packet> CopyFromSeq (uint32_t, const SequenceNumber&, const SequenceNumber&);
+  PendingData*   Copy () const;          // Create a copy of this header
+  PendingData*   CopyS (uint32_t);         // Copy with new size
+  PendingData*   CopySD (uint32_t, uint8_t*); // Copy with new size, new data
+public:
+  uint32_t size;        // Number of data bytes
+  std::vector<Ptr<Packet> > data;         // Corresponding data (may be null)
+  // The next two fields allow simulated applications to exchange some info
+  uint32_t msgSize;     // Total size of message
+  uint32_t responseSize;// Size of response requested
+};
+
+}//namepsace ns3
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/rtt-estimator.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,235 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation;
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+// Author: Rajib Bhattacharjea<raj.b@gatech.edu>
+//
+
+
+// Ported from:
+// Georgia Tech Network Simulator - Round Trip Time Estimation Class
+// George F. Riley.  Georgia Tech, Spring 2002
+
+// Implements several variations of round trip time estimators
+
+#include <iostream>
+
+#include "rtt-estimator.h"
+#include "ns3/simulator.h"
+#include "ns3/double.h"
+
+namespace ns3{
+
+NS_OBJECT_ENSURE_REGISTERED (RttEstimator);
+
+//RttEstimator iid
+TypeId 
+RttEstimator::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::RttEstimator")
+    .SetParent<Object> ()
+    .AddAttribute ("MaxMultiplier", 
+                   "XXX",
+                   DoubleValue (64.0),
+                   MakeDoubleAccessor (&RttEstimator::m_maxMultiplier),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("InitialEstimation", 
+                   "XXX",
+                   TimeValue (Seconds (1.0)),
+                   MakeTimeAccessor (&RttEstimator::est),
+                   MakeTimeChecker ())
+    ;
+  return tid;
+}
+
+//RttHistory methods
+RttHistory::RttHistory (SequenceNumber s, uint32_t c, Time t)
+  : seq (s), count (c), time (t), retx (false)
+  {
+  }
+
+RttHistory::RttHistory (const RttHistory& h)
+  : seq (h.seq), count (h.count), time (h.time), retx (h.retx)
+  {
+  }
+
+// Base class methods
+
+RttEstimator::RttEstimator () : next (1), history (),
+    nSamples (0), multiplier (1.0) 
+{ 
+  //note next=1 everywhere since first segment will have sequence 1
+}
+
+RttEstimator::RttEstimator(const RttEstimator& c)
+  : Object (c), next(c.next), history(c.history), 
+    m_maxMultiplier (c.m_maxMultiplier), est(c.est), nSamples(c.nSamples),
+    multiplier(c.multiplier)
+{}
+
+RttEstimator::~RttEstimator ()
+{
+}
+
+void RttEstimator::SentSeq (SequenceNumber s, uint32_t c)
+{ // Note that a particular sequence has been sent
+  if (s == next)
+    { // This is the next expected one, just log at end
+      history.push_back (RttHistory (s, c, Simulator::Now () ));
+      next = s + SequenceNumber (c); // Update next expected
+    }
+  else
+    { // This is a retransmit, find in list and mark as re-tx
+      for (RttHistory_t::iterator i = history.begin (); i != history.end (); ++i)
+        {
+          if ((s >= i->seq) && (s < (i->seq + SequenceNumber (i->count))))
+            { // Found it
+              i->retx = true;
+              // One final test..be sure this re-tx does not extend "next"
+              if ((s + SequenceNumber (c)) > next)
+                {
+                  next = s + SequenceNumber (c);
+                  i->count = ((s + SequenceNumber (c)) - i->seq); // And update count in hist
+                }
+              break;
+            }
+        }
+    }
+}
+
+Time RttEstimator::AckSeq (SequenceNumber a)
+{ // An ack has been received, calculate rtt and log this measurement
+  // Note we use a linear search (O(n)) for this since for the common
+  // case the ack'ed packet will be at the head of the list
+  Time m = Seconds (0.0);
+  if (history.size () == 0) return (m);    // No pending history, just exit
+  RttHistory& h = history.front ();
+  if (!h.retx && a >= (h.seq + SequenceNumber (h.count)))
+    { // Ok to use this sample
+      m = Simulator::Now () - h.time; // Elapsed time
+      Measurement(m);                // Log the measurement
+      ResetMultiplier();             // Reset multiplier on valid measurement
+    }
+  // Now delete all ack history with seq <= ack
+  while(history.size() > 0)
+    {
+      RttHistory& h = history.front ();
+      if ((h.seq + SequenceNumber(h.count)) > a) break;                // Done removing
+      history.pop_front (); // Remove
+    }
+  return m;
+}
+
+void RttEstimator::ClearSent ()
+{ // Clear all history entries
+  next = 1;
+  history.clear ();
+}
+
+void RttEstimator::IncreaseMultiplier ()
+{
+  double a;
+  a = multiplier * 2.0;
+  double b;
+  b = m_maxMultiplier * 2.0;
+  multiplier = std::min (multiplier * 2.0, m_maxMultiplier);
+}
+
+void RttEstimator::ResetMultiplier ()
+{
+  multiplier = 1.0;
+}
+
+void RttEstimator::Reset ()
+{ // Reset to initial state
+  next = 1;
+  est = Seconds (1.0); // XXX: we should go back to the 'initial value' here. Need to add support in Object for this.
+  history.clear ();         // Remove all info from the history
+  nSamples = 0;
+  ResetMultiplier ();
+}
+
+
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+// Mean-Deviation Estimator
+
+NS_OBJECT_ENSURE_REGISTERED (RttMeanDeviation);
+
+TypeId 
+RttMeanDeviation::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::RttMeanDeviation")
+    .SetParent<RttEstimator> ()
+    .AddConstructor<RttMeanDeviation> ()
+    .AddAttribute ("Gain",
+                   "XXX",
+                   DoubleValue (0.1),
+                   MakeDoubleAccessor (&RttMeanDeviation::gain),
+                   MakeDoubleChecker<double> ())
+    ;
+  return tid;
+}
+
+RttMeanDeviation::RttMeanDeviation() :
+  variance (ns3::Seconds(0)) 
+{ 
+}
+
+RttMeanDeviation::RttMeanDeviation (const RttMeanDeviation& c)
+  : RttEstimator (c), gain (c.gain), variance (c.variance)
+{
+}
+
+void RttMeanDeviation::Measurement (Time m)
+{
+  if (nSamples)
+    { // Not first
+      Time err = m - est;
+      est = est + Scalar (gain) * err;         // estimated rtt
+      err = Abs (err);        // absolute value of error
+      variance = variance + Scalar (gain) * (err - variance); // variance of rtt
+    }
+  else
+    { // First sample
+      est = m;                        // Set estimate to current
+      //variance = m / 2;               // And variance to current / 2
+      variance = m; // try this
+    }
+  nSamples++;
+}
+
+Time RttMeanDeviation::RetransmitTimeout ()
+{
+  // If not enough samples, justjust return 2 times estimate   
+  //if (nSamples < 2) return est * 2;
+  if (variance < est / Scalar (4.0))
+    return est * Scalar (2 * multiplier);            // At least twice current est
+  return (est + Scalar (4) * variance) * Scalar (multiplier); // As suggested by Jacobson
+}
+
+Ptr<RttEstimator> RttMeanDeviation::Copy () const
+{
+  return CopyObject<RttMeanDeviation> (this);
+}
+
+void RttMeanDeviation::Reset ()
+{ // Reset to initial state
+  variance = Seconds (0.0);
+  RttEstimator::Reset ();
+}
+}//namepsace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/rtt-estimator.h	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,113 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation;
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+// Author: Rajib Bhattacharjea<raj.b@gatech.edu>
+//
+
+// Georgia Tech Network Simulator - Round Trip Time Estimation Class
+// George F. Riley.  Georgia Tech, Spring 2002
+
+// Implements several variations of round trip time estimators
+
+#ifndef __rtt_estimator_h__
+#define __rtt_estimator_h__
+
+#include <deque>
+#include "sequence-number.h"
+#include "ns3/nstime.h"
+#include "ns3/object.h"
+
+namespace ns3 {
+
+class RttHistory {
+public:
+  RttHistory (SequenceNumber s, uint32_t c, Time t);
+  RttHistory (const RttHistory& h); // Copy constructor
+public:
+  SequenceNumber  seq;    // First sequence number in packet sent
+  uint32_t        count;  // Number of bytes sent
+  Time            time;   // Time this one was sent
+  bool            retx;   // True if this has been retransmitted
+};
+
+typedef std::deque<RttHistory> RttHistory_t;
+
+class RttEstimator : public Object {  //  Base class for all RTT Estimators
+public:
+  static TypeId GetTypeId (void);
+
+  RttEstimator();
+  RttEstimator(const RttEstimator&); // Copy constructor
+  virtual ~RttEstimator();
+
+  virtual void SentSeq(SequenceNumber, uint32_t);
+  virtual Time AckSeq(SequenceNumber);
+  virtual void ClearSent();
+  virtual void   Measurement(Time t) = 0;
+  virtual Time Estimate() = 0;
+  virtual Time RetransmitTimeout() = 0;
+  void Init(SequenceNumber s) { next = s;}
+  virtual Ptr<RttEstimator> Copy() const = 0;
+  virtual void IncreaseMultiplier();
+  virtual void ResetMultiplier();
+  virtual void Reset();
+
+private:
+  SequenceNumber        next;    // Next expected sequence to be sent
+  RttHistory_t history; // List of sent packet
+  double m_maxMultiplier;
+public:
+  Time       est;     // Current estimate
+  uint32_t      nSamples;// Number of samples
+  double       multiplier;   // RTO Multiplier
+};
+
+// The "Mean-Deviation" estimator, as discussed by Van Jacobson
+// "Congestion Avoidance and Control", SIGCOMM 88, Appendix A
+
+  //Doc:Class Class {\tt RttMeanDeviation} implements the "Mean--Deviation" estimator
+  //Doc:Class as described by Van Jacobson 
+  //Doc:Class "Congestion Avoidance and Control", SIGCOMM 88, Appendix A
+class RttMeanDeviation : public RttEstimator {
+public :
+  static TypeId GetTypeId (void);
+
+  RttMeanDeviation ();
+
+
+  //Doc:Method
+  RttMeanDeviation (const RttMeanDeviation&); // Copy constructor
+    //Doc:Desc Copy constructor.
+    //Doc:Arg1 {\tt RttMeanDeviation} object to copy.
+
+  void Measurement (Time);
+  Time Estimate () { return est;}
+  Time Variance () { return variance;}
+  Time RetransmitTimeout ();
+  Ptr<RttEstimator> Copy () const;
+  void Reset ();
+  void Gain (double g) { gain = g;}
+
+public:
+  double       gain;       // Filter gain
+  Time       variance;   // Current variance
+};
+}//namespace ns3
+#endif
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/sequence-number.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,65 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation;
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+// Author: Rajib Bhattacharjea<raj.b@gatech.edu>
+//
+
+
+// Ported from:
+// Georgia Tech Network Simulator - Manage 32 bit unsigned sequence numbers
+// George F. Riley.  Georgia Tech, Spring 2002
+
+// Class to manage arithmetic operations on sequence numbers (mod 2^32)
+
+#include "sequence-number.h"
+
+bool operator< (const SequenceNumber l, const SequenceNumber r) 
+{ // Account for 32 bit rollover
+  if (l.seq > 0xc0000000 && r.seq < 0x40000000) return true; // Rollover
+  return l.seq < r.seq;
+}
+
+bool operator<= (const SequenceNumber l, const SequenceNumber r) 
+{ // Account for 32 bit rollover
+  if (l.seq > 0xc0000000 && r.seq < 0x40000000) return true; // Rollover
+  return l.seq <= r.seq;
+}
+
+bool operator> (const SequenceNumber l, const SequenceNumber r) 
+{ // Account for 32 bit rollover
+  if (l.seq > 0xc0000000 && r.seq < 0x40000000) return false; // Rollover
+  return l.seq > r.seq;
+}
+
+bool operator>= (const SequenceNumber l, const SequenceNumber r) 
+{ // Account for 32 bit rollover
+  if (l.seq > 0xc0000000 && r.seq < 0x40000000) return false; // Rollover
+  return l.seq >= r.seq;
+}
+
+// Non-Member Arithmetic operators
+SequenceNumber  operator+ (const SequenceNumber l, const SequenceNumber r)
+{
+  return SequenceNumber (l.seq + r.seq);
+}
+
+SequenceNumber operator- (const SequenceNumber l, const SequenceNumber r)
+{ // This assumes l is always bigger than r (allows for rollover)
+  if (l.seq >= r.seq) return SequenceNumber (l.seq-r.seq);
+  return SequenceNumber ((MAX_SEQ - r.seq) + l.seq + 1);  // Adjust for rollover
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/sequence-number.h	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,66 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation;
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+// Author: Rajib Bhattacharjea<raj.b@gatech.edu>
+//
+
+// Ported from:
+// Georgia Tech Network Simulator - Manage 32 bit unsigned sequence numbers
+// George F. Riley.  Georgia Tech, Spring 2002
+
+// Class to manage arithmetic operations on sequence numbers (mod 2^32)
+
+#ifndef __seq_h__
+#define __seq_h__
+
+#include <stdint.h>
+
+#define MAX_SEQ ((uint32_t)0xffffffff)
+
+class SequenceNumber {
+public:
+  SequenceNumber () : seq(0) { }
+  SequenceNumber (const uint32_t s) : seq (s) { }
+
+  operator uint32_t () const { return seq;}
+
+  SequenceNumber& operator= (const uint32_t s) { seq = s; return *this;}
+
+  SequenceNumber& operator+= (const uint32_t s) { seq += s; return *this;}
+  SequenceNumber  operator++ ()              { seq++; return *this;}
+  SequenceNumber  operator++ (int)           { SequenceNumber ss (seq); seq++; return ss;}
+  SequenceNumber& operator-= (const uint32_t s) { seq -= s; return *this;}
+  SequenceNumber  operator-- ()              { seq--; return *this;}
+  SequenceNumber  operator-- (int)           { SequenceNumber ss (seq); seq--; return ss;}
+public:
+  uint32_t seq;
+};
+
+// Comparison operators
+
+bool operator< (const SequenceNumber l, const SequenceNumber r);
+bool operator<= (const SequenceNumber l, const SequenceNumber r); 
+bool operator> (const SequenceNumber l, const SequenceNumber r);
+bool operator>= (const SequenceNumber l, const SequenceNumber r);
+
+// Non-member arithmetic operators
+SequenceNumber  operator+ (const SequenceNumber l, const SequenceNumber r);
+SequenceNumber  operator- (const SequenceNumber l, const SequenceNumber r);
+
+#endif
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/sgi-hashmap.h	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,32 @@
+/* This code snippet was ripped out of the gcc 
+ * documentation and slightly modified to work
+ * with gcc 4.x
+ */
+#ifndef SGI_HASHMAP_H
+#define SGI_HASHMAP_H
+
+/* To use gcc extensions.
+ */
+#ifdef __GNUC__
+  #if __GNUC__ < 3
+     #include <hash_map.h>
+namespace sgi { using ::hash_map; }; // inherit globals
+  #else 
+     #if __GNUC__ < 4
+       #include <ext/hash_map>
+       #if __GNUC_MINOR__ == 0
+namespace sgi = std;         // GCC 3.0
+       #else
+namespace sgi = ::__gnu_cxx;       // GCC 3.1 and later
+       #endif
+     #else  // gcc 4.x and later
+       #include <ext/hash_map>
+       namespace sgi = ::__gnu_cxx;
+     #endif
+  #endif
+#else      // ...  there are other compilers, right?
+namespace sgi = std;
+#endif
+
+
+#endif /* SGI_HASHMAP_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/tcp-header.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,217 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 Georgia Tech Research Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Raj Bhattacharjea <raj.b@gatech.edu>
+ */
+
+#include <stdint.h>
+#include <iostream>
+#include "tcp-socket-impl.h"
+#include "tcp-header.h"
+#include "ns3/buffer.h"
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (TcpHeader);
+
+bool TcpHeader::m_calcChecksum = false;
+
+TcpHeader::TcpHeader ()
+  : m_sourcePort (0),
+    m_destinationPort (0),
+    m_sequenceNumber (0),
+    m_ackNumber (0),
+    m_length (5),
+    m_flags (0),
+    m_windowSize (0xffff),
+    m_checksum (0),
+    m_urgentPointer (0)
+{}
+
+TcpHeader::~TcpHeader ()
+{}
+
+void
+TcpHeader::EnableChecksums (void)
+{
+  m_calcChecksum = true;
+}
+
+void TcpHeader::SetSourcePort (uint16_t port)
+{
+  m_sourcePort = port;
+}
+void TcpHeader::SetDestinationPort (uint16_t port)
+{
+  m_destinationPort = port;
+}
+void TcpHeader::SetSequenceNumber (SequenceNumber sequenceNumber)
+{
+  m_sequenceNumber = sequenceNumber;
+}
+void TcpHeader::SetAckNumber (SequenceNumber ackNumber)
+{
+  m_ackNumber = ackNumber;
+}
+void TcpHeader::SetLength (uint8_t length)
+{
+  m_length = length;
+}
+void TcpHeader::SetFlags (uint8_t flags)
+{
+  m_flags = flags;
+}
+void TcpHeader::SetWindowSize (uint16_t windowSize)
+{
+  m_windowSize = windowSize;
+}
+void TcpHeader::SetChecksum (uint16_t checksum)
+{
+  m_checksum = checksum;
+}
+void TcpHeader::SetUrgentPointer (uint16_t urgentPointer)
+{
+  m_urgentPointer = urgentPointer;
+}
+
+uint16_t TcpHeader::GetSourcePort () const
+{
+  return m_sourcePort;
+}
+uint16_t TcpHeader::GetDestinationPort () const
+{
+  return m_destinationPort;
+}
+SequenceNumber TcpHeader::GetSequenceNumber () const
+{
+  return m_sequenceNumber;
+}
+SequenceNumber TcpHeader::GetAckNumber () const
+{
+  return m_ackNumber;
+}
+uint8_t  TcpHeader::GetLength () const
+{
+  return m_length;
+}
+uint8_t  TcpHeader::GetFlags () const
+{
+  return m_flags;
+}
+uint16_t TcpHeader::GetWindowSize () const
+{
+  return m_windowSize;
+}
+uint16_t TcpHeader::GetChecksum () const
+{
+  return m_checksum;
+}
+uint16_t TcpHeader::GetUrgentPointer () const
+{
+  return m_urgentPointer;
+}
+
+void 
+TcpHeader::InitializeChecksum (Ipv4Address source, 
+                                   Ipv4Address destination,
+                                   uint8_t protocol)
+{
+  m_checksum = 0;
+//XXX requires peeking into IP to get length of the TCP segment
+}
+
+TypeId 
+TcpHeader::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::TcpHeader")
+    .SetParent<Header> ()
+    .AddConstructor<TcpHeader> ()
+    ;
+  return tid;
+}
+TypeId 
+TcpHeader::GetInstanceTypeId (void) const
+{
+  return GetTypeId ();
+}
+void TcpHeader::Print (std::ostream &os)  const
+{
+  os << m_sourcePort << " > " << m_destinationPort;
+  if(m_flags!=0)
+  {
+    os<<" [";
+    if((m_flags & FIN) != 0)
+    {
+      os<<" FIN ";
+    }
+    if((m_flags & SYN) != 0)
+    {
+      os<<" SYN ";
+    }
+    if((m_flags & RST) != 0)
+    {
+      os<<" RST ";
+    }
+    if((m_flags & PSH) != 0)
+    {
+      os<<" PSH ";
+    }
+    if((m_flags & ACK) != 0)
+    {
+      os<<" ACK ";
+    }
+    if((m_flags & URG) != 0)
+    {
+      os<<" URG ";
+    }
+    os<<"]";
+  }
+  os<<" Seq="<<m_sequenceNumber<<" Ack="<<m_ackNumber<<" Win="<<m_windowSize;
+}
+uint32_t TcpHeader::GetSerializedSize (void)  const
+{
+  return 4*m_length;
+}
+void TcpHeader::Serialize (Buffer::Iterator start)  const
+{
+  start.WriteHtonU16 (m_sourcePort);
+  start.WriteHtonU16 (m_destinationPort);
+  start.WriteHtonU32 (m_sequenceNumber);
+  start.WriteHtonU32 (m_ackNumber);
+  start.WriteHtonU16 (m_length << 12 | m_flags); //reserved bits are all zero
+  start.WriteHtonU16 (m_windowSize);
+  //XXX calculate checksum here
+  start.WriteHtonU16 (m_checksum);
+  start.WriteHtonU16 (m_urgentPointer);
+}
+uint32_t TcpHeader::Deserialize (Buffer::Iterator start)
+{
+  m_sourcePort = start.ReadNtohU16 ();
+  m_destinationPort = start.ReadNtohU16 ();
+  m_sequenceNumber = start.ReadNtohU32 ();
+  m_ackNumber = start.ReadNtohU32 ();
+  uint16_t field = start.ReadNtohU16 ();
+  m_flags = field & 0x3F;
+  m_length = field>>12;
+  m_windowSize = start.ReadNtohU16 ();
+  m_checksum = start.ReadNtohU16 ();
+  m_urgentPointer = start.ReadNtohU16 ();
+  return GetSerializedSize ();
+}
+
+
+}; // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/tcp-header.h	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,161 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 Georgia Tech Research Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Raj Bhattacharjea <raj.b@gatech.edu>
+ */
+
+#ifndef TCP_HEADER_H
+#define TCP_HEADER_H
+
+#include <stdint.h>
+#include "ns3/header.h"
+#include "ns3/buffer.h"
+#include "ns3/tcp-socket-factory.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/sequence-number.h"
+
+namespace ns3 {
+
+class TcpHeader : public Header 
+{
+public:
+  TcpHeader ();
+  virtual ~TcpHeader ();
+
+  /**
+   * \brief Enable checksum calculation for TCP (XXX currently has no effect)
+   */
+  static void EnableChecksums (void);
+//Setters
+  /**
+   * \param port The source port for this TcpHeader
+   */
+  void SetSourcePort (uint16_t port);
+  /**
+   * \param port the destination port for this TcpHeader
+   */
+  void SetDestinationPort (uint16_t port);
+  /**
+   * \param sequenceNumber the sequence number for this TcpHeader
+   */
+  void SetSequenceNumber (SequenceNumber sequenceNumber);
+  /**
+   * \param ackNumber the ACK number for this TcpHeader
+   */
+  void SetAckNumber (SequenceNumber ackNumber);
+  /**
+   * \param length the length of this TcpHeader
+   */
+  void SetLength (uint8_t length);
+  /**
+   * \param flags the flags for this TcpHeader
+   */
+  void SetFlags (uint8_t flags);
+  /**
+   * \param windowSize the window size for this TcpHeader
+   */
+  void SetWindowSize (uint16_t windowSize);
+  /**
+   * \param checksum the checksum for this TcpHeader
+   */
+  void SetChecksum (uint16_t checksum);
+  /**
+   * \param urgentPointer the urgent pointer for this TcpHeader
+   */
+  void SetUrgentPointer (uint16_t urgentPointer);
+
+
+//Getters
+  /**
+   * \return The source port for this TcpHeader
+   */
+  uint16_t GetSourcePort () const;
+  /**
+   * \return the destination port for this TcpHeader
+   */
+  uint16_t GetDestinationPort () const;
+  /**
+   * \return the sequence number for this TcpHeader
+   */
+  SequenceNumber GetSequenceNumber () const;
+  /**
+   * \return the ACK number for this TcpHeader
+   */
+  SequenceNumber GetAckNumber () const;
+  /**
+   * \return the length of this TcpHeader
+   */
+  uint8_t  GetLength () const;
+  /**
+   * \return the flags for this TcpHeader
+   */
+  uint8_t  GetFlags () const;
+  /**
+   * \return the window size for this TcpHeader
+   */
+  uint16_t GetWindowSize () const;
+  /**
+   * \return the checksum for this TcpHeader
+   */
+  uint16_t GetChecksum () const;
+  /**
+   * \return the urgent pointer for this TcpHeader
+   */
+  uint16_t GetUrgentPointer () const;
+
+  /**
+   * \param source the ip source to use in the underlying
+   *        ip packet.
+   * \param destination the ip destination to use in the
+   *        underlying ip packet.
+   * \param protocol the protocol number to use in the underlying
+   *        ip packet.
+   *
+   * If you want to use tcp checksums, you should call this
+   * method prior to adding the header to a packet.
+   */
+  void InitializeChecksum (Ipv4Address source, 
+                           Ipv4Address destination,
+                           uint8_t protocol);
+
+  typedef enum { NONE = 0, FIN = 1, SYN = 2, RST = 4, PSH = 8, ACK = 16, 
+    URG = 32} Flags_t;
+
+  static TypeId GetTypeId (void);
+  virtual TypeId GetInstanceTypeId (void) const;
+  virtual void Print (std::ostream &os) const;
+  virtual uint32_t GetSerializedSize (void) const;
+  virtual void Serialize (Buffer::Iterator start) const;
+  virtual uint32_t Deserialize (Buffer::Iterator start);
+
+private:
+  uint16_t m_sourcePort;
+  uint16_t m_destinationPort;
+  uint32_t m_sequenceNumber;
+  uint32_t m_ackNumber;
+  uint8_t m_length; // really a uint4_t
+  uint8_t m_flags;      // really a uint6_t
+  uint16_t m_windowSize;
+  uint16_t m_checksum;
+  uint16_t m_urgentPointer;
+
+  static bool m_calcChecksum;
+};
+
+}; // namespace ns3
+
+#endif /* TCP_HEADER */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/tcp-l4-protocol.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,526 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 Georgia Tech Research Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Raj Bhattacharjea <raj.b@gatech.edu>
+ */
+
+#include "ns3/assert.h"
+#include "ns3/log.h"
+#include "ns3/nstime.h"
+
+#include "ns3/packet.h"
+#include "ns3/node.h"
+
+#include "tcp-l4-protocol.h"
+#include "tcp-header.h"
+#include "ipv4-end-point-demux.h"
+#include "ipv4-end-point.h"
+#include "ipv4-l3-protocol.h"
+#include "tcp-socket-impl.h"
+
+#include "tcp-typedefs.h"
+
+#include <vector>
+#include <sstream>
+#include <iomanip>
+
+NS_LOG_COMPONENT_DEFINE ("TcpL4Protocol");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (TcpL4Protocol);
+
+//State Machine things --------------------------------------------------------
+TcpStateMachine::TcpStateMachine() 
+  : aT (LAST_STATE, StateActionVec_t(LAST_EVENT)),
+       eV (MAX_FLAGS)
+{ 
+  NS_LOG_FUNCTION_NOARGS ();
+
+  // Create the state table
+  // Closed state
+  aT[CLOSED][APP_LISTEN]  = SA (LISTEN,   NO_ACT);
+  aT[CLOSED][APP_CONNECT] = SA (SYN_SENT, SYN_TX);
+  aT[CLOSED][APP_SEND]    = SA (CLOSED,   RST_TX);
+  aT[CLOSED][SEQ_RECV]    = SA (CLOSED,   NO_ACT);
+  aT[CLOSED][APP_CLOSE]   = SA (CLOSED,   NO_ACT);
+  aT[CLOSED][TIMEOUT]     = SA (CLOSED,   RST_TX);
+  aT[CLOSED][ACK_RX]      = SA (CLOSED,   RST_TX);
+  aT[CLOSED][SYN_RX]      = SA (CLOSED,   RST_TX);
+  aT[CLOSED][SYN_ACK_RX]  = SA (CLOSED,   RST_TX);
+  aT[CLOSED][FIN_RX]      = SA (CLOSED,   RST_TX);
+  aT[CLOSED][FIN_ACK_RX]  = SA (CLOSED,   RST_TX);
+  aT[CLOSED][RST_RX]      = SA (CLOSED,   CANCEL_TM);
+  aT[CLOSED][BAD_FLAGS]   = SA (CLOSED,   RST_TX);
+
+  // Listen State
+  // For the listen state, anything other than CONNECT or SEND
+  // is simply ignored....this likely indicates the child TCP
+  // has finished and issued unbind call, but the remote end
+  // has not yet  closed.
+  aT[LISTEN][APP_LISTEN]  = SA (LISTEN,   NO_ACT);
+  aT[LISTEN][APP_CONNECT] = SA (SYN_SENT, SYN_TX);
+  aT[LISTEN][APP_SEND]    = SA (SYN_SENT, SYN_TX);
+  aT[LISTEN][SEQ_RECV]    = SA (LISTEN,   NO_ACT);
+  aT[LISTEN][APP_CLOSE]   = SA (CLOSED,   NO_ACT);
+  aT[LISTEN][TIMEOUT]     = SA (LISTEN,   NO_ACT);
+  aT[LISTEN][ACK_RX]      = SA (LISTEN,   NO_ACT);
+  aT[LISTEN][SYN_RX]      = SA (LISTEN,   SYN_ACK_TX);//stay in listen and fork
+  aT[LISTEN][SYN_ACK_RX]  = SA (LISTEN,   NO_ACT);
+  aT[LISTEN][FIN_RX]      = SA (LISTEN,   NO_ACT);
+  aT[LISTEN][FIN_ACK_RX]  = SA (LISTEN,   NO_ACT);
+  aT[LISTEN][RST_RX]      = SA (LISTEN,   NO_ACT);
+  aT[LISTEN][BAD_FLAGS]   = SA (LISTEN,   NO_ACT);
+
+  // Syn Sent State
+  aT[SYN_SENT][APP_LISTEN]  = SA (CLOSED,      RST_TX);
+  aT[SYN_SENT][APP_CONNECT] = SA (SYN_SENT,    SYN_TX);
+  aT[SYN_SENT][APP_SEND]    = SA (SYN_SENT,    NO_ACT);
+  aT[SYN_SENT][SEQ_RECV]    = SA (ESTABLISHED, NEW_SEQ_RX);
+  aT[SYN_SENT][APP_CLOSE]   = SA (CLOSED,      RST_TX);
+  aT[SYN_SENT][TIMEOUT]     = SA (CLOSED,      NO_ACT);
+  aT[SYN_SENT][ACK_RX]      = SA (SYN_SENT,    NO_ACT);
+  aT[SYN_SENT][SYN_RX]      = SA (SYN_RCVD,    SYN_ACK_TX);
+  aT[SYN_SENT][SYN_ACK_RX]  = SA (ESTABLISHED, ACK_TX_1);
+  aT[SYN_SENT][FIN_RX]      = SA (CLOSED,      RST_TX);
+  aT[SYN_SENT][FIN_ACK_RX]  = SA (CLOSED,      RST_TX);
+  aT[SYN_SENT][RST_RX]      = SA (CLOSED,      APP_NOTIFY);
+  aT[SYN_SENT][BAD_FLAGS]   = SA (CLOSED,      RST_TX);
+
+  // Syn Recvd State
+  aT[SYN_RCVD][APP_LISTEN]  = SA (CLOSED,      RST_TX);
+  aT[SYN_RCVD][APP_CONNECT] = SA (CLOSED,      RST_TX);
+  aT[SYN_RCVD][APP_SEND]    = SA (CLOSED,      RST_TX);
+  aT[SYN_RCVD][SEQ_RECV]    = SA (ESTABLISHED, NEW_SEQ_RX);
+  aT[SYN_RCVD][APP_CLOSE]   = SA (FIN_WAIT_1,  FIN_TX);
+  aT[SYN_RCVD][TIMEOUT]     = SA (CLOSED,      RST_TX);
+  aT[SYN_RCVD][ACK_RX]      = SA (ESTABLISHED, SERV_NOTIFY);
+  aT[SYN_RCVD][SYN_RX]      = SA (SYN_RCVD,    SYN_ACK_TX);
+  aT[SYN_RCVD][SYN_ACK_RX]  = SA (CLOSED,      RST_TX);
+  aT[SYN_RCVD][FIN_RX]      = SA (CLOSED,      RST_TX);
+  aT[SYN_RCVD][FIN_ACK_RX]  = SA (CLOSE_WAIT,  PEER_CLOSE);
+  aT[SYN_RCVD][RST_RX]      = SA (CLOSED,      CANCEL_TM);
+  aT[SYN_RCVD][BAD_FLAGS]   = SA (CLOSED,      RST_TX);
+
+  // Established State
+  aT[ESTABLISHED][APP_LISTEN] = SA (CLOSED,     RST_TX);
+  aT[ESTABLISHED][APP_CONNECT]= SA (CLOSED,     RST_TX);
+  aT[ESTABLISHED][APP_SEND]   = SA (ESTABLISHED,TX_DATA);
+  aT[ESTABLISHED][SEQ_RECV]   = SA (ESTABLISHED,NEW_SEQ_RX);
+  aT[ESTABLISHED][APP_CLOSE]  = SA (FIN_WAIT_1, FIN_TX);
+  aT[ESTABLISHED][TIMEOUT]    = SA (ESTABLISHED,RETX);
+  aT[ESTABLISHED][ACK_RX]     = SA (ESTABLISHED,NEW_ACK);
+  aT[ESTABLISHED][SYN_RX]     = SA (SYN_RCVD,   SYN_ACK_TX);
+  aT[ESTABLISHED][SYN_ACK_RX] = SA (ESTABLISHED,NO_ACT);
+  aT[ESTABLISHED][FIN_RX]     = SA (CLOSE_WAIT, PEER_CLOSE);
+  aT[ESTABLISHED][FIN_ACK_RX] = SA (CLOSE_WAIT, PEER_CLOSE);
+  aT[ESTABLISHED][RST_RX]     = SA (CLOSED,     CANCEL_TM);
+  aT[ESTABLISHED][BAD_FLAGS]  = SA (CLOSED,     RST_TX);
+
+  // Close Wait State
+  aT[CLOSE_WAIT][APP_LISTEN]  = SA (CLOSED,     RST_TX);
+  aT[CLOSE_WAIT][APP_CONNECT] = SA (SYN_SENT,   SYN_TX);
+  aT[CLOSE_WAIT][APP_SEND]    = SA (CLOSE_WAIT, TX_DATA);
+  aT[CLOSE_WAIT][SEQ_RECV]    = SA (CLOSE_WAIT, NEW_SEQ_RX);
+  aT[CLOSE_WAIT][APP_CLOSE]   = SA (LAST_ACK,   FIN_ACK_TX);
+  aT[CLOSE_WAIT][TIMEOUT]     = SA (CLOSE_WAIT, NO_ACT);
+  aT[CLOSE_WAIT][ACK_RX]      = SA (CLOSE_WAIT, NO_ACT);
+  aT[CLOSE_WAIT][SYN_RX]      = SA (CLOSED,     RST_TX);
+  aT[CLOSE_WAIT][SYN_ACK_RX]  = SA (CLOSED,     RST_TX);
+  aT[CLOSE_WAIT][FIN_RX]      = SA (CLOSE_WAIT, ACK_TX);
+  aT[CLOSE_WAIT][FIN_ACK_RX]  = SA (CLOSE_WAIT, ACK_TX);
+  aT[CLOSE_WAIT][RST_RX]      = SA (CLOSED,     CANCEL_TM);
+  aT[CLOSE_WAIT][BAD_FLAGS]   = SA (CLOSED,     RST_TX);
+
+  // Close Last Ack State
+  aT[LAST_ACK][APP_LISTEN]  = SA (CLOSED,      RST_TX);
+  aT[LAST_ACK][APP_CONNECT] = SA (SYN_SENT,    SYN_TX);
+  aT[LAST_ACK][APP_SEND]    = SA (CLOSED,      RST_TX);
+  aT[LAST_ACK][SEQ_RECV]    = SA (LAST_ACK,    NEW_SEQ_RX);
+  aT[LAST_ACK][APP_CLOSE]   = SA (CLOSED,      NO_ACT);
+  aT[LAST_ACK][TIMEOUT]     = SA (CLOSED,      NO_ACT);
+  aT[LAST_ACK][ACK_RX]      = SA (CLOSED,      APP_CLOSED);
+  aT[LAST_ACK][SYN_RX]      = SA (CLOSED,      RST_TX);
+  aT[LAST_ACK][SYN_ACK_RX]  = SA (CLOSED,      RST_TX);
+  aT[LAST_ACK][FIN_RX]      = SA (LAST_ACK,    FIN_ACK_TX);
+  aT[LAST_ACK][FIN_ACK_RX]  = SA (CLOSED,      NO_ACT);
+  aT[LAST_ACK][RST_RX]      = SA (CLOSED,      CANCEL_TM);
+  aT[LAST_ACK][BAD_FLAGS]   = SA (CLOSED,      RST_TX);
+
+  // FIN_WAIT_1 state
+  aT[FIN_WAIT_1][APP_LISTEN]  = SA (CLOSED,     RST_TX);
+  aT[FIN_WAIT_1][APP_CONNECT] = SA (CLOSED,     RST_TX);
+  aT[FIN_WAIT_1][APP_SEND]    = SA (CLOSED,     RST_TX);
+  aT[FIN_WAIT_1][SEQ_RECV]    = SA (FIN_WAIT_1, NEW_SEQ_RX);
+  aT[FIN_WAIT_1][APP_CLOSE]   = SA (FIN_WAIT_1, NO_ACT);
+  aT[FIN_WAIT_1][TIMEOUT]     = SA (FIN_WAIT_1, NO_ACT);
+  aT[FIN_WAIT_1][ACK_RX]      = SA (FIN_WAIT_2, NEW_ACK);
+  aT[FIN_WAIT_1][SYN_RX]      = SA (CLOSED,     RST_TX);
+  aT[FIN_WAIT_1][SYN_ACK_RX]  = SA (CLOSED,     RST_TX);
+  aT[FIN_WAIT_1][FIN_RX]      = SA (CLOSING,    ACK_TX);
+  aT[FIN_WAIT_1][FIN_ACK_RX]  = SA (TIMED_WAIT, ACK_TX);
+  aT[FIN_WAIT_1][RST_RX]      = SA (CLOSED,     CANCEL_TM);
+  aT[FIN_WAIT_1][BAD_FLAGS]   = SA (CLOSED,     RST_TX);
+
+  // FIN_WAIT_2 state
+  aT[FIN_WAIT_2][APP_LISTEN]  = SA (CLOSED,      RST_TX);
+  aT[FIN_WAIT_2][APP_CONNECT] = SA (CLOSED,      RST_TX);
+  aT[FIN_WAIT_2][APP_SEND]    = SA (CLOSED,      RST_TX);
+  aT[FIN_WAIT_2][SEQ_RECV]    = SA (FIN_WAIT_2,  NEW_SEQ_RX);
+  aT[FIN_WAIT_2][APP_CLOSE]   = SA (FIN_WAIT_2,  NO_ACT);
+  aT[FIN_WAIT_2][TIMEOUT]     = SA (FIN_WAIT_2,  NO_ACT);
+  aT[FIN_WAIT_2][ACK_RX]      = SA (FIN_WAIT_2,  NEW_ACK);
+  aT[FIN_WAIT_2][SYN_RX]      = SA (CLOSED,      RST_TX);
+  aT[FIN_WAIT_2][SYN_ACK_RX]  = SA (CLOSED,      RST_TX);
+  aT[FIN_WAIT_2][FIN_RX]      = SA (TIMED_WAIT,  ACK_TX);
+  aT[FIN_WAIT_2][FIN_ACK_RX]  = SA (TIMED_WAIT,  ACK_TX);
+  aT[FIN_WAIT_2][RST_RX]      = SA (CLOSED,      CANCEL_TM);
+  aT[FIN_WAIT_2][BAD_FLAGS]   = SA (CLOSED,      RST_TX);
+
+  // CLOSING state
+  aT[CLOSING][APP_LISTEN]  = SA (CLOSED,      RST_TX);
+  aT[CLOSING][APP_CONNECT] = SA (CLOSED,      RST_TX);
+  aT[CLOSING][APP_SEND]    = SA (CLOSED,      RST_TX);
+  aT[CLOSING][SEQ_RECV]    = SA (CLOSED,      RST_TX);
+  aT[CLOSING][APP_CLOSE]   = SA (CLOSED,      RST_TX);
+  aT[CLOSING][TIMEOUT]     = SA (CLOSING,     NO_ACT);
+  aT[CLOSING][ACK_RX]      = SA (TIMED_WAIT,  NO_ACT);
+  aT[CLOSING][SYN_RX]      = SA (CLOSED,      RST_TX);
+  aT[CLOSING][SYN_ACK_RX]  = SA (CLOSED,      RST_TX);
+  aT[CLOSING][FIN_RX]      = SA (CLOSED,      ACK_TX);
+  aT[CLOSING][FIN_ACK_RX]  = SA (CLOSED,      ACK_TX);
+  aT[CLOSING][RST_RX]      = SA (CLOSED,      CANCEL_TM);
+  aT[CLOSING][BAD_FLAGS]   = SA (CLOSED,      RST_TX);
+
+  // TIMED_WAIT state
+  aT[TIMED_WAIT][APP_LISTEN]  = SA (TIMED_WAIT, NO_ACT);
+  aT[TIMED_WAIT][APP_CONNECT] = SA (TIMED_WAIT, NO_ACT);
+  aT[TIMED_WAIT][APP_SEND]    = SA (TIMED_WAIT, NO_ACT);
+  aT[TIMED_WAIT][SEQ_RECV]    = SA (TIMED_WAIT, NO_ACT);
+  aT[TIMED_WAIT][APP_CLOSE]   = SA (TIMED_WAIT, NO_ACT);
+  aT[TIMED_WAIT][TIMEOUT]     = SA (TIMED_WAIT, NO_ACT);
+  aT[TIMED_WAIT][ACK_RX]      = SA (TIMED_WAIT, NO_ACT);
+  aT[TIMED_WAIT][SYN_RX]      = SA (TIMED_WAIT, NO_ACT);
+  aT[TIMED_WAIT][SYN_ACK_RX]  = SA (TIMED_WAIT, NO_ACT);
+  aT[TIMED_WAIT][FIN_RX]      = SA (TIMED_WAIT, NO_ACT);
+  aT[TIMED_WAIT][FIN_ACK_RX]  = SA (TIMED_WAIT, NO_ACT);
+  aT[TIMED_WAIT][RST_RX]      = SA (TIMED_WAIT, NO_ACT);
+  aT[TIMED_WAIT][BAD_FLAGS]   = SA (TIMED_WAIT, NO_ACT);
+
+  // Create the flags lookup table
+  eV[ 0x00] = SEQ_RECV;  // No flags
+  eV[ 0x01] = FIN_RX;    // Fin
+  eV[ 0x02] = SYN_RX;    // Syn
+  eV[ 0x03] = BAD_FLAGS; // Illegal
+  eV[ 0x04] = RST_RX;    // Rst
+  eV[ 0x05] = BAD_FLAGS; // Illegal
+  eV[ 0x06] = BAD_FLAGS; // Illegal
+  eV[ 0x07] = BAD_FLAGS; // Illegal
+  eV[ 0x08] = SEQ_RECV;  // Psh flag is not used
+  eV[ 0x09] = FIN_RX;    // Fin
+  eV[ 0x0a] = SYN_RX;    // Syn
+  eV[ 0x0b] = BAD_FLAGS; // Illegal
+  eV[ 0x0c] = RST_RX;    // Rst
+  eV[ 0x0d] = BAD_FLAGS; // Illegal
+  eV[ 0x0e] = BAD_FLAGS; // Illegal
+  eV[ 0x0f] = BAD_FLAGS; // Illegal
+  eV[ 0x10] = ACK_RX;    // Ack
+  eV[ 0x11] = FIN_ACK_RX;// Fin/Ack
+  eV[ 0x12] = SYN_ACK_RX;// Syn/Ack
+  eV[ 0x13] = BAD_FLAGS; // Illegal
+  eV[ 0x14] = RST_RX;    // Rst
+  eV[ 0x15] = BAD_FLAGS; // Illegal
+  eV[ 0x16] = BAD_FLAGS; // Illegal
+  eV[ 0x17] = BAD_FLAGS; // Illegal
+  eV[ 0x18] = ACK_RX;    // Ack
+  eV[ 0x19] = FIN_ACK_RX;// Fin/Ack
+  eV[ 0x1a] = SYN_ACK_RX;// Syn/Ack
+  eV[ 0x1b] = BAD_FLAGS; // Illegal
+  eV[ 0x1c] = RST_RX;    // Rst
+  eV[ 0x1d] = BAD_FLAGS; // Illegal
+  eV[ 0x1e] = BAD_FLAGS; // Illegal
+  eV[ 0x1f] = BAD_FLAGS; // Illegal
+  eV[ 0x20] = SEQ_RECV;  // No flags (Urgent not presently used)
+  eV[ 0x21] = FIN_RX;    // Fin
+  eV[ 0x22] = SYN_RX;    // Syn
+  eV[ 0x23] = BAD_FLAGS; // Illegal
+  eV[ 0x24] = RST_RX;    // Rst
+  eV[ 0x25] = BAD_FLAGS; // Illegal
+  eV[ 0x26] = BAD_FLAGS; // Illegal
+  eV[ 0x27] = BAD_FLAGS; // Illegal
+  eV[ 0x28] = SEQ_RECV;  // Psh flag is not used
+  eV[ 0x29] = FIN_RX;    // Fin
+  eV[ 0x2a] = SYN_RX;    // Syn
+  eV[ 0x2b] = BAD_FLAGS; // Illegal
+  eV[ 0x2c] = RST_RX;    // Rst
+  eV[ 0x2d] = BAD_FLAGS; // Illegal
+  eV[ 0x2e] = BAD_FLAGS; // Illegal
+  eV[ 0x2f] = BAD_FLAGS; // Illegal
+  eV[ 0x30] = ACK_RX;    // Ack (Urgent not used)
+  eV[ 0x31] = FIN_ACK_RX;// Fin/Ack
+  eV[ 0x32] = SYN_ACK_RX;// Syn/Ack
+  eV[ 0x33] = BAD_FLAGS; // Illegal
+  eV[ 0x34] = RST_RX;    // Rst
+  eV[ 0x35] = BAD_FLAGS; // Illegal
+  eV[ 0x36] = BAD_FLAGS; // Illegal
+  eV[ 0x37] = BAD_FLAGS; // Illegal
+  eV[ 0x38] = ACK_RX;    // Ack
+  eV[ 0x39] = FIN_ACK_RX;// Fin/Ack
+  eV[ 0x3a] = SYN_ACK_RX;// Syn/Ack
+  eV[ 0x3b] = BAD_FLAGS; // Illegal
+  eV[ 0x3c] = RST_RX;    // Rst
+  eV[ 0x3d] = BAD_FLAGS; // Illegal
+  eV[ 0x3e] = BAD_FLAGS; // Illegal
+  eV[ 0x3f] = BAD_FLAGS; // Illegal
+}
+
+SA TcpStateMachine::Lookup (States_t s, Events_t e)
+{
+  NS_LOG_FUNCTION (this << s << e);
+  return aT[s][e];
+}
+
+Events_t TcpStateMachine::FlagsEvent (uint8_t f)
+{ 
+  NS_LOG_FUNCTION (this << f);
+  // Lookup event from flags
+  if (f >= MAX_FLAGS) return BAD_FLAGS;
+  return eV[f]; // Look up flags event
+}
+
+static TcpStateMachine tcpStateMachine; //only instance of a TcpStateMachine
+
+//TcpL4Protocol stuff----------------------------------------------------------
+
+
+/* see http://www.iana.org/assignments/protocol-numbers */
+const uint8_t TcpL4Protocol::PROT_NUMBER = 6;
+
+ObjectFactory
+TcpL4Protocol::GetDefaultRttEstimatorFactory (void)
+{
+  ObjectFactory factory;
+  factory.SetTypeId (RttMeanDeviation::GetTypeId ());
+  return factory;
+}
+
+TypeId 
+TcpL4Protocol::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::TcpL4Protocol")
+    .SetParent<Ipv4L4Protocol> ()
+    .AddAttribute ("RttEstimatorFactory",
+                   "How RttEstimator objects are created.",
+                   ObjectFactoryValue (GetDefaultRttEstimatorFactory ()),
+                   MakeObjectFactoryAccessor (&TcpL4Protocol::m_rttFactory),
+                   MakeObjectFactoryChecker ())
+    ;
+  return tid;
+}
+
+TcpL4Protocol::TcpL4Protocol ()
+  : m_endPoints (new Ipv4EndPointDemux ())
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  NS_LOG_LOGIC("Made a TcpL4Protocol "<<this);
+}
+
+TcpL4Protocol::~TcpL4Protocol ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+void 
+TcpL4Protocol::SetNode (Ptr<Node> node)
+{
+  m_node = node;
+}
+
+int 
+TcpL4Protocol::GetProtocolNumber (void) const
+{
+  return PROT_NUMBER;
+}
+int 
+TcpL4Protocol::GetVersion (void) const
+{
+  return 2;
+}
+
+void
+TcpL4Protocol::DoDispose (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  if (m_endPoints != 0)
+    {
+      delete m_endPoints;
+      m_endPoints = 0;
+    }
+  m_node = 0;
+  Ipv4L4Protocol::DoDispose ();
+}
+
+Ptr<Socket>
+TcpL4Protocol::CreateSocket (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  Ptr<RttEstimator> rtt = m_rttFactory.Create<RttEstimator> ();
+  Ptr<TcpSocketImpl> socket = CreateObject<TcpSocketImpl> ();
+  socket->SetNode (m_node);
+  socket->SetTcp (this);
+  socket->SetRtt (rtt);
+  return socket;
+}
+
+Ipv4EndPoint *
+TcpL4Protocol::Allocate (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_endPoints->Allocate ();
+}
+
+Ipv4EndPoint *
+TcpL4Protocol::Allocate (Ipv4Address address)
+{
+  NS_LOG_FUNCTION (this << address);
+  return m_endPoints->Allocate (address);
+}
+
+Ipv4EndPoint *
+TcpL4Protocol::Allocate (uint16_t port)
+{
+  NS_LOG_FUNCTION (this << port);
+  return m_endPoints->Allocate (port);
+}
+
+Ipv4EndPoint *
+TcpL4Protocol::Allocate (Ipv4Address address, uint16_t port)
+{
+  NS_LOG_FUNCTION (this << address << port);
+  return m_endPoints->Allocate (address, port);
+}
+
+Ipv4EndPoint *
+TcpL4Protocol::Allocate (Ipv4Address localAddress, uint16_t localPort,
+                         Ipv4Address peerAddress, uint16_t peerPort)
+{
+  NS_LOG_FUNCTION (this << localAddress << localPort << peerAddress << peerPort);
+  return m_endPoints->Allocate (localAddress, localPort,
+                                peerAddress, peerPort);
+}
+
+void 
+TcpL4Protocol::DeAllocate (Ipv4EndPoint *endPoint)
+{
+  NS_LOG_FUNCTION (this << endPoint);
+  m_endPoints->DeAllocate (endPoint);
+}
+
+void 
+TcpL4Protocol::Receive (Ptr<Packet> packet,
+             Ipv4Address const &source,
+             Ipv4Address const &destination,
+             Ptr<Ipv4Interface> incomingInterface)
+{
+  NS_LOG_FUNCTION (this << packet << source << destination << incomingInterface);
+
+  TcpHeader tcpHeader;
+  //these two do a peek, so that the packet can be forwarded up
+  packet->RemoveHeader (tcpHeader);
+  NS_LOG_LOGIC("TcpL4Protocol " << this
+               << " receiving seq " << tcpHeader.GetSequenceNumber()
+               << " ack " << tcpHeader.GetAckNumber()
+               << " flags "<< std::hex << (int)tcpHeader.GetFlags() << std::dec
+               << " data size " << packet->GetSize());
+  packet->AddHeader (tcpHeader); 
+  NS_LOG_LOGIC ("TcpL4Protocol "<<this<<" received a packet");
+  Ipv4EndPointDemux::EndPoints endPoints =
+    m_endPoints->Lookup (destination, tcpHeader.GetDestinationPort (),
+                         source, tcpHeader.GetSourcePort (),incomingInterface);
+  if (endPoints.empty ())
+  {
+    NS_LOG_LOGIC ("  No endpoints matched on TcpL4Protocol "<<this);
+    std::ostringstream oss;
+    oss<<"  destination IP: ";
+    destination.Print (oss);
+    oss<<" destination port: "<< tcpHeader.GetDestinationPort ()<<" source IP: ";
+    source.Print (oss);
+    oss<<" source port: "<<tcpHeader.GetSourcePort ();
+    NS_LOG_LOGIC (oss.str ());
+    return;
+  }
+  NS_ASSERT_MSG (endPoints.size() == 1 , "Demux returned more than one endpoint");
+  NS_LOG_LOGIC ("TcpL4Protocol "<<this<<" forwarding up to endpoint/socket");
+  (*endPoints.begin ())->ForwardUp (packet, source, tcpHeader.GetSourcePort ());
+}
+
+void
+TcpL4Protocol::Send (Ptr<Packet> packet, 
+           Ipv4Address saddr, Ipv4Address daddr, 
+           uint16_t sport, uint16_t dport)
+{
+  NS_LOG_FUNCTION (this << packet << saddr << daddr << sport << dport);
+
+  TcpHeader tcpHeader;
+  tcpHeader.SetDestinationPort (dport);
+  tcpHeader.SetSourcePort (sport);
+  tcpHeader.InitializeChecksum (saddr,
+                               daddr,
+                               PROT_NUMBER);
+  tcpHeader.SetFlags (TcpHeader::ACK);
+  tcpHeader.SetAckNumber (0);
+
+  packet->AddHeader (tcpHeader);
+
+  Ptr<Ipv4L3Protocol> ipv4 = 
+    m_node->GetObject<Ipv4L3Protocol> ();
+  if (ipv4 != 0)
+    {
+      ipv4->Send (packet, saddr, daddr, PROT_NUMBER);
+    }
+}
+
+void
+TcpL4Protocol::SendPacket (Ptr<Packet> packet, TcpHeader outgoingHeader,
+                               Ipv4Address saddr, Ipv4Address daddr)
+{
+  NS_LOG_LOGIC("TcpL4Protocol " << this
+              << " sending seq " << outgoingHeader.GetSequenceNumber()
+              << " ack " << outgoingHeader.GetAckNumber()
+              << " flags " << std::hex << (int)outgoingHeader.GetFlags() << std::dec
+              << " data size " << packet->GetSize());
+  NS_LOG_FUNCTION (this << packet << saddr << daddr);
+  // XXX outgoingHeader cannot be logged
+
+  outgoingHeader.SetLength (5); //header length in units of 32bit words
+  outgoingHeader.SetChecksum (0);  //XXX
+  outgoingHeader.SetUrgentPointer (0); //XXX
+
+  packet->AddHeader (outgoingHeader);
+
+  Ptr<Ipv4L3Protocol> ipv4 = 
+    m_node->GetObject<Ipv4L3Protocol> ();
+  if (ipv4 != 0)
+    {
+      ipv4->Send (packet, saddr, daddr, PROT_NUMBER);
+    }
+  else
+    NS_FATAL_ERROR("Trying to use Tcp on a node without an Ipv4 interface");
+}
+
+}; // namespace ns3
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/tcp-l4-protocol.h	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,117 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 Georgia Tech Research Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Raj Bhattacharjea <raj.b@gatech.edu>
+ */
+
+#ifndef TCP_L4_PROTOCOL_H
+#define TCP_L4_PROTOCOL_H
+
+#include <stdint.h>
+
+#include "ns3/packet.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/ptr.h"
+#include "ns3/object-factory.h"
+#include "ipv4-end-point-demux.h"
+#include "ipv4-l4-protocol.h"
+#include "ipv4-interface.h"
+
+#include "tcp-header.h"
+#include "tcp-typedefs.h"
+
+namespace ns3 {
+
+class Node;
+class Socket;
+class TcpHeader;
+/**
+ * \brief Implementation of the TCP protocol
+ */
+class TcpL4Protocol : public Ipv4L4Protocol {
+public:
+  static TypeId GetTypeId (void);
+  static const uint8_t PROT_NUMBER;
+  /**
+   * \brief Constructor
+   */
+  TcpL4Protocol ();
+  virtual ~TcpL4Protocol ();
+
+  void SetNode (Ptr<Node> node);
+
+  virtual int GetProtocolNumber (void) const;
+  virtual int GetVersion (void) const;
+
+  /**
+   * \return A smart Socket pointer to a TcpSocketImpl, allocated by this instance
+   * of the TCP 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 TcpSocketImpl.
+//   bool Connect (const Ipv4Address& saddr, const Ipv4Address& daddr,
+//                 uint16_t sport, uint16_t dport);
+
+  /**
+   * \brief Send a packet via TCP
+   * \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 (Ptr<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
+   * \param incomingInterface The Ipv4Interface it was received on
+   */
+  virtual void Receive (Ptr<Packet> p,
+                       Ipv4Address const &source,
+                       Ipv4Address const &destination,
+                       Ptr<Ipv4Interface> incomingInterface);
+
+protected:
+  virtual void DoDispose (void);
+private:
+  Ptr<Node> m_node;
+  Ipv4EndPointDemux *m_endPoints;
+  ObjectFactory m_rttFactory;
+private:
+  friend class TcpSocketImpl;
+  void SendPacket (Ptr<Packet>, TcpHeader,
+                  Ipv4Address, Ipv4Address);
+  static ObjectFactory GetDefaultRttEstimatorFactory (void);
+};
+
+}; // namespace ns3
+
+#endif /* TCP_L4_PROTOCOL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/tcp-socket-factory-impl.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,54 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 Georgia Tech Research Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Raj Bhattacharjea <raj.b@gatech.edu>
+ */
+#include "tcp-socket-factory-impl.h"
+#include "tcp-l4-protocol.h"
+#include "ns3/socket.h"
+#include "ns3/assert.h"
+
+namespace ns3 {
+
+TcpSocketFactoryImpl::TcpSocketFactoryImpl ()
+  : m_tcp (0)
+{}
+TcpSocketFactoryImpl::~TcpSocketFactoryImpl ()
+{
+  NS_ASSERT (m_tcp == 0);
+}
+
+void 
+TcpSocketFactoryImpl::SetTcp (Ptr<TcpL4Protocol> tcp)
+{
+  m_tcp = tcp;
+}
+
+Ptr<Socket>
+TcpSocketFactoryImpl::CreateSocket (void)
+{
+  return m_tcp->CreateSocket ();
+}
+
+void 
+TcpSocketFactoryImpl::DoDispose (void)
+{
+  m_tcp = 0;
+  TcpSocketFactory::DoDispose ();
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/tcp-socket-factory-impl.h	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,62 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 Georgia Tech Research Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Raj Bhattacharjea <raj.b@gatech.edu>
+ */
+#ifndef TCP_SOCKET_FACTORY_IMPL_H
+#define TCP_SOCKET_FACTORY_IMPL_H
+
+#include "ns3/tcp-socket-factory.h"
+#include "ns3/ptr.h"
+
+namespace ns3 {
+
+class TcpL4Protocol;
+
+/**
+ * \ingroup internetNode
+ * \defgroup Tcp Tcp
+ */
+/**
+ * \ingroup Tcp
+ * \section Tcp Overview
+ *
+ * The TCP code in ns3::InternetNode is ported from the  
+ * <a href="http://www.ece.gatech.edu/research/labs/MANIACS/GTNetS/">
+ * Georgia Tech Network Simulator (GTNetS)</a>.
+ * 
+ * Most of the logic is in class ns3::TcpSocketImpl.
+ */
+class TcpSocketFactoryImpl : public TcpSocketFactory
+{
+public:
+  TcpSocketFactoryImpl ();
+  virtual ~TcpSocketFactoryImpl ();
+
+  void SetTcp (Ptr<TcpL4Protocol> tcp);
+
+  virtual Ptr<Socket> CreateSocket (void);
+
+protected:
+  virtual void DoDispose (void);
+private:
+  Ptr<TcpL4Protocol> m_tcp;
+};
+
+} // namespace ns3
+
+#endif /* TCP_SOCKET_FACTORY_IMPL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/tcp-socket-impl.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,1448 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 Georgia Tech Research Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Raj Bhattacharjea <raj.b@gatech.edu>
+ */
+
+
+#include "ns3/node.h"
+#include "ns3/inet-socket-address.h"
+#include "ns3/log.h"
+#include "ns3/ipv4.h"
+#include "tcp-socket-impl.h"
+#include "tcp-l4-protocol.h"
+#include "ipv4-end-point.h"
+#include "ipv4-l4-demux.h"
+#include "ns3/simulation-singleton.h"
+#include "tcp-typedefs.h"
+#include "ns3/simulator.h"
+#include "ns3/packet.h"
+#include "ns3/uinteger.h"
+#include "ns3/trace-source-accessor.h"
+
+#include <algorithm>
+
+NS_LOG_COMPONENT_DEFINE ("TcpSocketImpl");
+
+using namespace std;
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (TcpSocketImpl);
+
+TypeId
+TcpSocketImpl::GetTypeId ()
+{
+  static TypeId tid = TypeId("ns3::TcpSocketImpl")
+    .SetParent<TcpSocket> ()
+    .AddTraceSource ("CongestionWindow",
+                     "The TCP connection's congestion window",
+                     MakeTraceSourceAccessor (&TcpSocketImpl::m_cWnd))
+    ;
+  return tid;
+}
+
+  TcpSocketImpl::TcpSocketImpl ()
+  : m_skipRetxResched (false),
+    m_dupAckCount (0),
+    m_delAckCount (0),
+    m_endPoint (0),
+    m_node (0),
+    m_tcp (0),
+    m_errno (ERROR_NOTERROR),
+    m_shutdownSend (false),
+    m_shutdownRecv (false),
+    m_connected (false),
+    m_state (CLOSED),
+    m_closeNotified (false),
+    m_closeRequestNotified (false),
+    m_closeOnEmpty (false),
+    m_pendingClose (false),
+    m_nextTxSequence (0),
+    m_highTxMark (0),
+    m_highestRxAck (0),
+    m_lastRxAck (0),
+    m_nextRxSequence (0),
+    m_pendingData (0),
+    m_rtt (0),
+    m_lastMeasuredRtt (Seconds(0.0)),
+    m_rxAvailable (0), 
+    m_wouldBlock (false) 
+{
+  NS_LOG_FUNCTION (this);
+}
+
+TcpSocketImpl::TcpSocketImpl(const TcpSocketImpl& sock)
+  : TcpSocket(sock), //copy the base class callbacks
+    m_skipRetxResched (sock.m_skipRetxResched),
+    m_dupAckCount (sock.m_dupAckCount),
+    m_delAckCount (0),
+    m_delAckMaxCount (sock.m_delAckMaxCount),
+    m_delAckTimeout (sock.m_delAckTimeout),
+    m_endPoint (0),
+    m_node (sock.m_node),
+    m_tcp (sock.m_tcp),
+    m_remoteAddress (sock.m_remoteAddress),
+    m_remotePort (sock.m_remotePort),
+    m_localAddress (sock.m_localAddress),
+    m_localPort (sock.m_localPort),
+    m_errno (sock.m_errno),
+    m_shutdownSend (sock.m_shutdownSend),
+    m_shutdownRecv (sock.m_shutdownRecv),
+    m_connected (sock.m_connected),
+    m_state (sock.m_state),
+    m_closeNotified (sock.m_closeNotified),
+    m_closeRequestNotified (sock.m_closeRequestNotified),
+    m_closeOnEmpty (sock.m_closeOnEmpty),
+    m_pendingClose (sock.m_pendingClose),
+    m_nextTxSequence (sock.m_nextTxSequence),
+    m_highTxMark (sock.m_highTxMark),
+    m_highestRxAck (sock.m_highestRxAck),
+    m_lastRxAck (sock.m_lastRxAck),
+    m_nextRxSequence (sock.m_nextRxSequence),
+    m_pendingData (0),
+    m_segmentSize (sock.m_segmentSize),
+    m_rxWindowSize (sock.m_rxWindowSize),
+    m_advertisedWindowSize (sock.m_advertisedWindowSize),
+    m_cWnd (sock.m_cWnd),
+    m_ssThresh (sock.m_ssThresh),
+    m_initialCWnd (sock.m_initialCWnd),
+    m_rtt (0),
+    m_lastMeasuredRtt (Seconds(0.0)),
+    m_cnTimeout (sock.m_cnTimeout),
+    m_cnCount (sock.m_cnCount),
+    m_rxAvailable (0),
+    m_wouldBlock (false),
+    m_sndBufSize (sock.m_sndBufSize),
+    m_rcvBufSize(sock.m_rcvBufSize)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  NS_LOG_LOGIC("Invoked the copy constructor");
+  //copy the pending data if necessary
+  if(sock.m_pendingData)
+    {
+      m_pendingData = sock.m_pendingData->Copy();
+    }
+  //copy the rtt if necessary
+  if (sock.m_rtt)
+    {
+      m_rtt = sock.m_rtt->Copy();
+    }
+  //can't "copy" the endpoint just yes, must do this when we know the peer info
+  //too; this is in SYN_ACK_TX
+}
+
+TcpSocketImpl::~TcpSocketImpl ()
+{
+  NS_LOG_FUNCTION(this);
+  m_node = 0;
+  if (m_endPoint != 0)
+    {
+      NS_ASSERT (m_tcp != 0);
+      /**
+       * Note that this piece of code is a bit tricky:
+       * when DeAllocate is called, it will call into
+       * Ipv4EndPointDemux::Deallocate which triggers
+       * a delete of the associated endPoint which triggers
+       * in turn a call to the method ::Destroy below
+       * will will zero the m_endPoint field.
+       */
+      NS_ASSERT (m_endPoint != 0);
+      m_tcp->DeAllocate (m_endPoint);
+      NS_ASSERT (m_endPoint == 0);
+    }
+  m_tcp = 0;
+  delete m_pendingData; //prevents leak
+  m_pendingData = 0;
+}
+
+void
+TcpSocketImpl::SetNode (Ptr<Node> node)
+{
+  m_node = node;
+  // Initialize some variables 
+  m_cWnd = m_initialCWnd * m_segmentSize;
+  m_rxWindowSize = m_advertisedWindowSize;
+}
+
+void 
+TcpSocketImpl::SetTcp (Ptr<TcpL4Protocol> tcp)
+{
+  m_tcp = tcp;
+}
+void 
+TcpSocketImpl::SetRtt (Ptr<RttEstimator> rtt)
+{
+  m_rtt = rtt;
+}
+
+
+enum Socket::SocketErrno
+TcpSocketImpl::GetErrno (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_errno;
+}
+
+Ptr<Node>
+TcpSocketImpl::GetNode (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_node;
+}
+
+void 
+TcpSocketImpl::Destroy (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_node = 0;
+  m_endPoint = 0;
+  m_tcp = 0;
+  m_retxEvent.Cancel ();
+}
+int
+TcpSocketImpl::FinishBind (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  if (m_endPoint == 0)
+    {
+      return -1;
+    }
+  m_endPoint->SetRxCallback (MakeCallback (&TcpSocketImpl::ForwardUp, Ptr<TcpSocketImpl>(this)));
+  m_endPoint->SetDestroyCallback (MakeCallback (&TcpSocketImpl::Destroy, Ptr<TcpSocketImpl>(this)));
+  m_localAddress = m_endPoint->GetLocalAddress ();
+  m_localPort = m_endPoint->GetLocalPort ();
+  return 0;
+}
+
+int
+TcpSocketImpl::Bind (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_endPoint = m_tcp->Allocate ();
+  return FinishBind ();
+}
+int 
+TcpSocketImpl::Bind (const Address &address)
+{
+  NS_LOG_FUNCTION (this<<address);
+  if (!InetSocketAddress::IsMatchingType (address))
+    {
+      return ERROR_INVAL;
+    }
+  InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
+  Ipv4Address ipv4 = transport.GetIpv4 ();
+  uint16_t port = transport.GetPort ();
+  if (ipv4 == Ipv4Address::GetAny () && port == 0)
+    {
+      m_endPoint = m_tcp->Allocate ();
+      NS_LOG_LOGIC ("TcpSocketImpl "<<this<<" got an endpoint: "<<m_endPoint);
+    }
+  else if (ipv4 == Ipv4Address::GetAny () && port != 0)
+    {
+      m_endPoint = m_tcp->Allocate (port);
+      NS_LOG_LOGIC ("TcpSocketImpl "<<this<<" got an endpoint: "<<m_endPoint);
+    }
+  else if (ipv4 != Ipv4Address::GetAny () && port == 0)
+    {
+      m_endPoint = m_tcp->Allocate (ipv4);
+      NS_LOG_LOGIC ("TcpSocketImpl "<<this<<" got an endpoint: "<<m_endPoint);
+    }
+  else if (ipv4 != Ipv4Address::GetAny () && port != 0)
+    {
+      m_endPoint = m_tcp->Allocate (ipv4, port);
+      NS_LOG_LOGIC ("TcpSocketImpl "<<this<<" got an endpoint: "<<m_endPoint);
+    }
+
+  return FinishBind ();
+}
+
+int 
+TcpSocketImpl::ShutdownSend (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_shutdownSend = true;
+  return 0;
+}
+int 
+TcpSocketImpl::ShutdownRecv (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_shutdownRecv = false;
+  return 0;
+}
+
+int
+TcpSocketImpl::Close (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  if (m_state == CLOSED) 
+    {
+      return -1;
+    }
+  if (m_pendingData && m_pendingData->Size() != 0)
+    { // App close with pending data must wait until all data transmitted
+      m_closeOnEmpty = true;
+      NS_LOG_LOGIC("Socket " << this << 
+                   " deferring close, state " << m_state);
+      return 0;
+    }
+
+  Actions_t action  = ProcessEvent (APP_CLOSE);
+  ProcessAction (action);
+  ShutdownSend ();
+  return 0;
+}
+
+int
+TcpSocketImpl::Connect (const Address & address)
+{
+  NS_LOG_FUNCTION (this << address);
+  if (m_endPoint == 0)
+    {
+      if (Bind () == -1)
+        {
+          NS_ASSERT (m_endPoint == 0);
+          return -1;
+        }
+      NS_ASSERT (m_endPoint != 0);
+    }
+  InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
+  m_remoteAddress = transport.GetIpv4 ();
+  m_remotePort = transport.GetPort ();
+  
+  uint32_t localIfIndex;
+  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
+
+  if (ipv4->GetIfIndexForDestination (m_remoteAddress, localIfIndex))
+    {
+      m_endPoint->SetLocalAddress (ipv4->GetAddress (localIfIndex));
+    }
+  else
+    {
+      m_errno = ERROR_NOROUTETOHOST;
+      return -1;
+    }
+
+  Actions_t action = ProcessEvent (APP_CONNECT);
+  bool success = ProcessAction (action);
+  if (success) 
+    {
+      return 0;
+    }
+  return -1;
+}
+int 
+TcpSocketImpl::Send (const Ptr<Packet> p) //p here is just data, no headers
+{
+  NS_LOG_FUNCTION (this << p);
+  if (m_state == ESTABLISHED || m_state == SYN_SENT || m_state == CLOSE_WAIT)
+  {
+    if (p->GetSize() > GetTxAvailable ())
+    {
+      m_wouldBlock = true;
+      m_errno = ERROR_MSGSIZE;
+      return -1;
+    }
+    if (!m_pendingData)
+    {
+      m_pendingData = new PendingData ();   // Create if non-existent
+      m_firstPendingSequence = m_nextTxSequence; // Note seq of first
+    }
+    //PendingData::Add stores a copy of the Ptr p
+    m_pendingData->Add (p);
+    NS_LOG_DEBUG("TcpSock::Send, pdsize " << m_pendingData->Size() << 
+        " state " << m_state);
+    Actions_t action = ProcessEvent (APP_SEND);
+    NS_LOG_DEBUG(" action " << action);
+    if (!ProcessAction (action)) 
+    {
+      return -1; // Failed, return zero
+    }
+    return p->GetSize();
+  }
+  else
+  {
+    m_errno = ERROR_NOTCONN;
+    return -1;
+  }
+}
+
+int TcpSocketImpl::Send (const uint8_t* buf, uint32_t size)
+{
+  return Send (Create<Packet> (buf, size));
+}
+
+int TcpSocketImpl::DoSendTo (Ptr<Packet> p, const Address &address)
+{
+  NS_LOG_FUNCTION (this << p << address);
+  InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
+  Ipv4Address ipv4 = transport.GetIpv4 ();
+  uint16_t port = transport.GetPort ();
+  return DoSendTo (p, ipv4, port);
+}
+
+int TcpSocketImpl::DoSendTo (Ptr<Packet> p, Ipv4Address ipv4, uint16_t port)
+{
+  NS_LOG_FUNCTION (this << p << ipv4 << port);
+  if (m_endPoint == 0)
+    {
+      if (Bind () == -1)
+	{
+          NS_ASSERT (m_endPoint == 0);
+	  return -1;
+	}
+      NS_ASSERT (m_endPoint != 0);
+    }
+  if (m_shutdownSend)
+    {
+      m_errno = ERROR_SHUTDOWN;
+      return -1;
+    }
+  m_tcp->Send (p, m_endPoint->GetLocalAddress (), ipv4,
+                  m_endPoint->GetLocalPort (), port);
+  NotifyDataSent (p->GetSize ());
+  return 0;
+}
+
+int 
+TcpSocketImpl::SendTo (Ptr<Packet> p, const Address &address)
+{
+  NS_LOG_FUNCTION (this << address << p);
+  if (!m_connected)
+    {
+      m_errno = ERROR_NOTCONN;
+      return -1;
+    }
+  else
+    {
+      return Send (p); //drop the address according to BSD manpages
+    }
+}
+
+uint32_t
+TcpSocketImpl::GetTxAvailable (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  if (m_pendingData != 0)
+    {
+      uint32_t unAckedDataSize = 
+        m_pendingData->SizeFromSeq (m_firstPendingSequence, m_highestRxAck);
+      NS_ASSERT (m_sndBufSize >= unAckedDataSize); //else a logical error
+      return m_sndBufSize-unAckedDataSize;
+    }
+  else
+    {
+      return m_sndBufSize;
+    }
+}
+
+int
+TcpSocketImpl::Listen (uint32_t q)
+{
+  NS_LOG_FUNCTION (this << q);
+  Actions_t action = ProcessEvent (APP_LISTEN);
+  ProcessAction (action);
+  return 0;
+}
+
+Ptr<Packet>
+TcpSocketImpl::Recv (uint32_t maxSize, uint32_t flags)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  if(m_bufferedData.empty())
+    {
+      return 0;
+    }
+  UnAckData_t out; //serves as buffer to return up to the user
+  UnAckData_t::iterator i;
+  while (!m_bufferedData.empty ())
+    { // Check the buffered data for delivery
+      NS_LOG_LOGIC("TCP " << this << " bufferedData.size() " 
+        << m_bufferedData.size () 
+        << " time " << Simulator::Now ());
+      i = m_bufferedData.begin ();
+      SequenceNumber s1 = 0;
+      if (i->first > m_nextRxSequence) 
+        {
+          break;  // we're done, no more in-sequence data exits
+        }
+      else // (i->first <= m_nextRxSequence)
+        { // Two cases here.
+          // 1) seq + length > nextRxSeq, can deliver partial
+          // 2) seq + length <= nextRxSeq, deliver whole
+          s1 = i->second->GetSize ();
+          if (i->first + s1 > m_nextRxSequence)
+            { // Remove partial data to prepare for delivery
+              uint32_t avail = s1 + i->first - m_nextRxSequence;
+              i->second = i->second->CreateFragment (0, avail);
+            }
+          // else this packet is okay to deliver whole
+          // so don't do anything else and output it
+          out[i->first]  = i->second;
+        }
+      m_rxAvailable -= i->second->GetSize ();
+      m_bufferedData.erase (i);     // Remove from list
+    }
+  if (out.size() == 0)
+    {
+      return 0;
+    }
+  Ptr<Packet> outPacket = Create<Packet>();
+  for(i = out.begin(); i!=out.end(); ++i)
+  {
+    if (outPacket->GetSize() + i->second->GetSize() <= maxSize )
+    {
+      outPacket->AddAtEnd(i->second);
+    }
+    else
+    {
+      //only append as much as will fit
+      uint32_t avail = maxSize - outPacket->GetSize();
+      outPacket->AddAtEnd(i->second->CreateFragment(0,avail));
+      //put the rest back into the buffer
+      m_bufferedData[i->first+SequenceNumber(avail)] 
+          = i->second->CreateFragment(avail,i->second->GetSize()-avail);
+      m_rxAvailable += i->second->GetSize()-avail;
+    }
+  }
+  return outPacket;
+}
+
+uint32_t
+TcpSocketImpl::GetRxAvailable (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  // We separately maintain this state to avoid walking the queue 
+  // every time this might be called
+  return m_rxAvailable;
+}
+
+void
+TcpSocketImpl::ForwardUp (Ptr<Packet> packet, Ipv4Address ipv4, uint16_t port)
+{
+  NS_LOG_DEBUG("Socket " << this << " got forward up" <<
+               " dport " << m_endPoint->GetLocalPort() <<
+               " daddr " << m_endPoint->GetLocalAddress() <<
+               " sport " << m_endPoint->GetPeerPort() <<
+               " saddr " << m_endPoint->GetPeerAddress());
+
+  NS_LOG_FUNCTION (this << packet << ipv4 << port);
+  if (m_shutdownRecv)
+    {
+      return;
+    }
+  TcpHeader tcpHeader;
+  packet->RemoveHeader (tcpHeader);
+
+  if (tcpHeader.GetFlags () & TcpHeader::ACK)
+    {
+      Time m = m_rtt->AckSeq (tcpHeader.GetAckNumber () );
+      if (m != Seconds (0.0))
+        {
+          m_lastMeasuredRtt = m;
+        }
+    }
+
+  Events_t event = SimulationSingleton<TcpStateMachine>::Get ()->FlagsEvent (tcpHeader.GetFlags () );
+  Actions_t action = ProcessEvent (event); //updates the state
+  Address address = InetSocketAddress (ipv4, port);
+  NS_LOG_DEBUG("Socket " << this << 
+               " processing pkt action, " << action <<
+               " current state " << m_state);
+  ProcessPacketAction (action, packet, tcpHeader, address);
+}
+
+Actions_t TcpSocketImpl::ProcessEvent (Events_t e)
+{
+  NS_LOG_FUNCTION (this << e);
+  States_t saveState = m_state;
+  NS_LOG_LOGIC ("TcpSocketImpl " << this << " processing event " << e);
+  // simulation singleton is a way to get a single global static instance of a
+  // class intended to be a singleton; see simulation-singleton.h
+  SA stateAction = SimulationSingleton<TcpStateMachine>::Get ()->Lookup (m_state,e);
+  // debug
+  if (stateAction.action == RST_TX)
+    {
+      NS_LOG_LOGIC ("TcpSocketImpl " << this << " sending RST from state "
+              << saveState << " event " << e);
+    }
+  bool needCloseNotify = (stateAction.state == CLOSED && m_state != CLOSED 
+    && e != TIMEOUT);
+  m_state = stateAction.state;
+  NS_LOG_LOGIC ("TcpSocketImpl " << this << " moved from state " << saveState 
+    << " to state " <<m_state);
+  NS_LOG_LOGIC ("TcpSocketImpl " << this << " pendingData " << m_pendingData);
+
+  //extra event logic is here for RX events
+  //e = SYN_ACK_RX
+  if (saveState == SYN_SENT && m_state == ESTABLISHED)
+    // this means the application side has completed its portion of 
+    // the handshaking
+    {
+      Simulator::ScheduleNow(&TcpSocketImpl::ConnectionSucceeded, this);
+      //NotifyConnectionSucceeded ();
+      m_connected = true;
+      m_endPoint->SetPeer (m_remoteAddress, m_remotePort);
+      NS_LOG_LOGIC ("TcpSocketImpl " << this << " Connected!");
+    }
+
+  if (needCloseNotify && !m_closeNotified)
+    {
+      NS_LOG_LOGIC ("TcpSocketImpl " << this << " transition to CLOSED from " 
+               << m_state << " event " << e << " closeNot " << m_closeNotified
+               << " action " << stateAction.action);
+      NotifyCloseCompleted ();
+      m_closeNotified = true;
+      NS_LOG_LOGIC ("TcpSocketImpl " << this << " calling Closed from PE"
+              << " origState " << saveState
+              << " event " << e);
+      NS_LOG_LOGIC ("TcpSocketImpl " << this << " transition to CLOSED from "
+          << m_state << " event " << e
+          << " set CloseNotif ");
+    }
+  return stateAction.action;
+}
+
+void TcpSocketImpl::SendEmptyPacket (uint8_t flags)
+{
+  NS_LOG_FUNCTION (this << flags);
+  Ptr<Packet> p = Create<Packet> ();
+  TcpHeader header;
+
+  header.SetFlags (flags);
+  header.SetSequenceNumber (m_nextTxSequence);
+  header.SetAckNumber (m_nextRxSequence);
+  header.SetSourcePort (m_endPoint->GetLocalPort ());
+  header.SetDestinationPort (m_remotePort);
+  header.SetWindowSize (m_advertisedWindowSize);
+  m_tcp->SendPacket (p, header, m_endPoint->GetLocalAddress (), 
+    m_remoteAddress);
+  Time rto = m_rtt->RetransmitTimeout ();
+  if (flags & TcpHeader::SYN)
+    {
+      rto = m_cnTimeout;
+      m_cnTimeout = m_cnTimeout + m_cnTimeout;
+      m_cnCount--;
+    }
+  if (m_retxEvent.IsExpired () ) //no outstanding timer
+  {
+    NS_LOG_LOGIC ("Schedule retransmission timeout at time " 
+          << Simulator::Now ().GetSeconds () << " to expire at time " 
+          << (Simulator::Now () + rto).GetSeconds ());
+    m_retxEvent = Simulator::Schedule (rto, &TcpSocketImpl::ReTxTimeout, this);
+  }
+}
+
+bool TcpSocketImpl::ProcessAction (Actions_t a)
+{ // These actions do not require a packet or any TCP Headers
+  NS_LOG_FUNCTION (this << a);
+  switch (a)
+  {
+    case NO_ACT:
+      NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action: NO_ACT");
+      break;
+    case ACK_TX:
+      SendEmptyPacket (TcpHeader::ACK);
+      break;
+    case ACK_TX_1:
+      NS_ASSERT (false); // This should be processed in ProcessPacketAction
+      break;
+    case RST_TX:
+      NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action RST_TX");
+      SendEmptyPacket (TcpHeader::RST);
+      break;
+    case SYN_TX:
+      NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action SYN_TX");
+      // TCP SYN Flag consumes one byte
+      // is the above correct? we're SENDING a syn, not acking back -- Raj
+      // commented out for now
+      // m_nextTxSequence+= 1;
+      SendEmptyPacket (TcpHeader::SYN);
+      break;
+    case SYN_ACK_TX:
+      NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action SYN_ACK_TX");
+      // TCP SYN Flag consumes one byte
+      ++m_nextRxSequence;
+      SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK);
+      break;
+    case FIN_TX:
+      NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action FIN_TX");
+      SendEmptyPacket (TcpHeader::FIN);
+      break;
+    case FIN_ACK_TX:
+      NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action FIN_ACK_TX");
+      SendEmptyPacket (TcpHeader::FIN | TcpHeader::ACK);
+      break;
+    case NEW_ACK:
+      NS_ASSERT (false); // This should be processed in ProcessPacketAction
+      break;
+    case NEW_SEQ_RX:
+      NS_ASSERT (false); // This should be processed in ProcessPacketAction
+      break;
+    case RETX:
+      NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action RETX");
+      break;
+    case TX_DATA:
+      NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action TX_DATA");
+      SendPendingData ();
+      break;
+    case PEER_CLOSE:
+      NS_ASSERT (false); // This should be processed in ProcessPacketAction
+      NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action PEER_CLOSE");
+      break;
+    case APP_CLOSED:
+      NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action APP_CLOSED");
+      break;
+    case CANCEL_TM:
+      NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action CANCEL_TM");
+      break;
+    case APP_NOTIFY:
+      NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action APP_NOTIFY");
+      break;
+    case SERV_NOTIFY:
+      NS_ASSERT (false); // This should be processed in ProcessPacketAction
+      break;
+    case LAST_ACTION:
+      NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action LAST_ACTION");
+      break;
+  }
+  return true;
+}
+
+bool TcpSocketImpl::ProcessPacketAction (Actions_t a, Ptr<Packet> p,
+                                     const TcpHeader& tcpHeader,
+                                     const Address& fromAddress)
+{
+  NS_LOG_FUNCTION (this << a << p  << fromAddress);
+  uint32_t localIfIndex;
+  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
+  switch (a)
+  {
+    case SYN_ACK_TX:
+      NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action SYN_ACK_TX");
+//      m_remotePort = InetSocketAddress::ConvertFrom (fromAddress).GetPort ();
+//      m_remoteAddress = InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 ();
+//       if (ipv4->GetIfIndexForDestination (m_remoteAddress, localIfIndex))
+//         {
+//           m_localAddress = ipv4->GetAddress (localIfIndex);
+//         }
+      if (m_state == LISTEN) //this means we should fork a new TcpSocketImpl
+        {
+          NS_LOG_DEBUG("In SYN_ACK_TX, m_state is LISTEN, this " << this);
+          //notify the server that we got a SYN
+          // If server refuses connection do nothing
+          if (!NotifyConnectionRequest(fromAddress)) return true;
+          // Clone the socket
+          Ptr<TcpSocketImpl> newSock = Copy ();
+          NS_LOG_LOGIC ("Cloned a TcpSocketImpl " << newSock);
+          //this listening socket should do nothing more
+          Simulator::ScheduleNow (&TcpSocketImpl::CompleteFork, newSock,
+                                  p, tcpHeader,fromAddress);
+          return true;
+        }
+        // This is the cloned endpoint
+        m_endPoint->SetPeer (m_remoteAddress, m_remotePort);
+        if (ipv4->GetIfIndexForDestination (m_remoteAddress, localIfIndex))
+          {
+            m_localAddress = ipv4->GetAddress (localIfIndex);
+            m_endPoint->SetLocalAddress (m_localAddress);
+            // Leave local addr in the portmap to any, as the path from
+            // remote can change and packets can arrive on different interfaces
+            //m_endPoint->SetLocalAddress (Ipv4Address::GetAny());
+          }
+        // TCP SYN consumes one byte
+        m_nextRxSequence = tcpHeader.GetSequenceNumber() + SequenceNumber(1);
+        SendEmptyPacket (TcpHeader::SYN | TcpHeader::ACK);
+      break;
+    case ACK_TX_1:
+      NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action ACK_TX_1");
+      // TCP SYN consumes one byte
+      m_nextRxSequence = tcpHeader.GetSequenceNumber() + SequenceNumber(1);
+      m_nextTxSequence = tcpHeader.GetAckNumber ();
+      m_firstPendingSequence = m_nextTxSequence;  //bug 166
+      NS_LOG_DEBUG ("TcpSocketImpl " << this << " ACK_TX_1" <<
+                    " nextRxSeq " << m_nextRxSequence);
+      SendEmptyPacket (TcpHeader::ACK);
+      m_rxWindowSize = tcpHeader.GetWindowSize ();
+      if (tcpHeader.GetAckNumber () > m_highestRxAck)
+      {
+        m_highestRxAck = tcpHeader.GetAckNumber ();
+        // Data freed from the send buffer; notify any blocked sender
+        if (m_wouldBlock)
+          {
+            NotifySend (GetTxAvailable ());
+            m_wouldBlock = false;
+          }
+      }
+      SendPendingData ();
+      break;
+    case NEW_ACK:
+      NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action NEW_ACK_TX");
+      if (tcpHeader.GetAckNumber () < m_highestRxAck) //old ack, do nothing
+      {
+        break;
+      }
+      if (tcpHeader.GetAckNumber () == m_highestRxAck && 
+         tcpHeader.GetAckNumber ()  < m_nextTxSequence)
+      {
+        DupAck (tcpHeader, ++m_dupAckCount);
+        break;
+      }
+      if (tcpHeader.GetAckNumber () > m_highestRxAck)  
+        {
+          m_dupAckCount = 0;
+        }
+      NewAck (tcpHeader.GetAckNumber ());
+      break;
+    case NEW_SEQ_RX:
+      NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action NEW_SEQ_RX");
+      NewRx (p, tcpHeader, fromAddress); // Process new data received
+      break;
+    case PEER_CLOSE:
+    {
+      // First we have to be sure the FIN packet was not received
+      // out of sequence.  If so, note pending close and process
+      // new sequence rx
+      if (tcpHeader.GetSequenceNumber () != m_nextRxSequence)
+        { // process close later
+          m_pendingClose = true;
+          NS_LOG_LOGIC ("TcpSocketImpl " << this << " setting pendingClose" 
+            << " rxseq " << tcpHeader.GetSequenceNumber () 
+            << " nextRxSeq " << m_nextRxSequence);
+          NewRx (p, tcpHeader, fromAddress);
+          return true;
+        }
+      // Now we need to see if any data came with the FIN
+      // if so, call NewRx
+      if (p->GetSize () != 0)
+        {
+          NewRx (p, tcpHeader, fromAddress);
+        }
+      States_t saveState = m_state; // Used to see if app responds
+      NS_LOG_LOGIC ("TcpSocketImpl " << this 
+          << " peer close, state " << m_state);
+      if (!m_closeRequestNotified)
+        {
+          NS_LOG_LOGIC ("TCP " << this 
+              << " calling AppCloseRequest");
+          NotifyCloseRequested(); 
+          m_closeRequestNotified = true;
+        }
+      NS_LOG_LOGIC ("TcpSocketImpl " << this 
+          << " peer close, state after " << m_state);
+      if (m_state == saveState)
+        { // Need to ack, the application will close later
+          SendEmptyPacket (TcpHeader::ACK);
+//               // Also need to re-tx the ack if we
+        }
+      if (m_state == LAST_ACK)
+        {
+          NS_LOG_LOGIC ("TcpSocketImpl " << this << " scheduling LATO1");
+          m_lastAckEvent = Simulator::Schedule (m_rtt->RetransmitTimeout (),
+                                                &TcpSocketImpl::LastAckTimeout,this);
+        }
+      break;
+    }
+    case SERV_NOTIFY:
+      NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action SERV_NOTIFY");
+      NS_LOG_LOGIC ("TcpSocketImpl " << this << " Connected!");
+      NotifyNewConnectionCreated (this, fromAddress);
+      m_connected = true; // ! This is bogus; fix when we clone the tcp
+      m_endPoint->SetPeer (m_remoteAddress, m_remotePort);
+      //treat the connection orientation final ack as a newack
+      CommonNewAck (tcpHeader.GetAckNumber (), true);
+      break;
+    default:
+      break;
+  }
+  return true;
+}
+
+void TcpSocketImpl::CompleteFork(Ptr<Packet> p, const TcpHeader& h, const Address& fromAddress)
+{
+  // Get port and address from peer (connecting host)
+  m_remotePort = InetSocketAddress::ConvertFrom (fromAddress).GetPort ();
+  m_remoteAddress = InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 ();
+  m_endPoint = m_tcp->Allocate (m_localAddress,
+                                m_localPort,
+                                m_remoteAddress,
+                                m_remotePort);
+  //the cloned socket with be in listen state, so manually change state
+  m_state = SYN_RCVD;
+  //equivalent to FinishBind
+  m_endPoint->SetRxCallback (MakeCallback (&TcpSocketImpl::ForwardUp, Ptr<TcpSocketImpl>(this)));
+  m_endPoint->SetDestroyCallback (MakeCallback (&TcpSocketImpl::Destroy, Ptr<TcpSocketImpl>(this)));
+  ProcessPacketAction(SYN_ACK_TX, p, h, fromAddress);
+ }
+
+void TcpSocketImpl::ConnectionSucceeded()
+{ // We would preferred to have scheduled an event directly to
+  // NotifyConnectionSucceeded, but (sigh) these are protected
+  // and we can get the address of it :(
+  NotifyConnectionSucceeded();
+}
+
+bool TcpSocketImpl::SendPendingData (bool withAck)
+{
+  NS_LOG_FUNCTION (this << withAck);
+  NS_LOG_LOGIC ("ENTERING SendPendingData");
+  if (!m_pendingData)
+    {
+      return false; // No data exists
+    }
+  uint32_t nPacketsSent = 0;
+  while (m_pendingData->SizeFromSeq (m_firstPendingSequence, m_nextTxSequence))
+    {
+      uint32_t w = AvailableWindow ();// Get available window size
+      NS_LOG_LOGIC ("TcpSocketImpl " << this << " SendPendingData"
+           << " w " << w 
+           << " rxwin " << m_rxWindowSize
+           << " cWnd " << m_cWnd
+           << " segsize " << m_segmentSize
+           << " nextTxSeq " << m_nextTxSequence
+           << " highestRxAck " << m_highestRxAck 
+           << " pd->Size " << m_pendingData->Size ()
+           << " pd->SFS " << m_pendingData->SizeFromSeq (m_firstPendingSequence, m_nextTxSequence));
+
+      if (w < m_segmentSize && m_pendingData->Size () > w)
+        {
+          break; // No more
+        }
+      uint32_t s = std::min (w, m_segmentSize);  // Send no more than window
+      Ptr<Packet> p = m_pendingData->CopyFromSeq (s, m_firstPendingSequence, 
+        m_nextTxSequence);
+      NS_LOG_LOGIC("TcpSocketImpl " << this << " SendPendingData"
+                   << " txseq " << m_nextTxSequence
+                   << " s " << s 
+                   << " datasize " << p->GetSize() );
+      uint8_t flags = 0;
+      if (withAck)
+        {
+          flags |= TcpHeader::ACK;
+        }
+      uint32_t sz = p->GetSize (); // Size of packet
+      uint32_t remainingData = m_pendingData->SizeFromSeq(
+          m_firstPendingSequence,
+          m_nextTxSequence + SequenceNumber (sz));
+      if (m_closeOnEmpty && (remainingData == 0))
+        {
+          flags = TcpHeader::FIN;
+          m_state = FIN_WAIT_1;
+        }
+
+      TcpHeader header;
+      header.SetFlags (flags);
+      header.SetSequenceNumber (m_nextTxSequence);
+      header.SetAckNumber (m_nextRxSequence);
+      header.SetSourcePort (m_endPoint->GetLocalPort());
+      header.SetDestinationPort (m_remotePort);
+      if (m_shutdownSend)
+        {
+          m_errno = ERROR_SHUTDOWN;
+          return -1;
+        }
+
+      
+      if (m_retxEvent.IsExpired () ) //go ahead and schedule the retransmit
+        {
+            Time rto = m_rtt->RetransmitTimeout (); 
+            NS_LOG_LOGIC ("SendPendingData Schedule retransmission timeout at time " << 
+              Simulator::Now ().GetSeconds () << " to expire at time " <<
+              (Simulator::Now () + rto).GetSeconds () );
+          m_retxEvent = Simulator::Schedule (rto,&TcpSocketImpl::ReTxTimeout,this);
+        }
+      NS_LOG_LOGIC ("About to send a packet with flags: " << flags);
+      m_tcp->SendPacket (p, header,
+                         m_endPoint->GetLocalAddress (),
+                         m_remoteAddress);
+      m_rtt->SentSeq(m_nextTxSequence, sz);       // notify the RTT
+      // Notify the application
+      Simulator::ScheduleNow(&TcpSocketImpl::NotifyDataSent, this, p->GetSize ());
+      nPacketsSent++;                             // Count sent this loop
+      m_nextTxSequence += sz;                     // Advance next tx sequence
+      // Note the high water mark
+      m_highTxMark = std::max (m_nextTxSequence, m_highTxMark);
+    }
+    NS_LOG_LOGIC ("SendPendingData Sent "<<nPacketsSent<<" packets");
+  NS_LOG_LOGIC("RETURN SendPendingData");
+  return (nPacketsSent>0);
+}
+
+uint32_t  TcpSocketImpl::UnAckDataCount ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_nextTxSequence - m_highestRxAck;
+}
+
+uint32_t  TcpSocketImpl::BytesInFlight ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_highTxMark - m_highestRxAck;
+}
+
+uint32_t  TcpSocketImpl::Window ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  NS_LOG_LOGIC ("TcpSocketImpl::Window() "<<this);
+  return std::min (m_rxWindowSize, m_cWnd.Get());
+}
+
+uint32_t  TcpSocketImpl::AvailableWindow ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  uint32_t unack = UnAckDataCount (); // Number of outstanding bytes
+  uint32_t win = Window ();
+  if (win < unack) 
+    {
+      return 0;  // No space available
+    }
+  return (win - unack);       // Amount of window space available
+}
+
+void TcpSocketImpl::NewRx (Ptr<Packet> p,
+                        const TcpHeader& tcpHeader, 
+                        const Address& fromAddress)
+{
+  NS_LOG_FUNCTION (this << p << "tcpHeader " << fromAddress);
+  NS_LOG_LOGIC ("TcpSocketImpl " << this << " NewRx,"
+                << " seq " << tcpHeader.GetSequenceNumber()
+                << " ack " << tcpHeader.GetAckNumber()
+                << " p.size is " << p->GetSize () );
+  NS_LOG_DEBUG ("TcpSocketImpl " << this <<
+                " NewRx," <<
+                " seq " << tcpHeader.GetSequenceNumber() <<
+                " ack " << tcpHeader.GetAckNumber() <<
+                " p.size is " << p->GetSize());
+  States_t origState = m_state;
+  uint32_t s = p->GetSize ();  // Size of associated data
+  if (s == 0)
+    {// Nothing to do if no associated data
+      return;
+    }
+  // Log sequence received if enabled
+  // NoteTimeSeq(LOG_SEQ_RX, h->sequenceNumber);
+  // Three possibilities
+  // 1) Received seq is expected, buffer this, update rxAvailable, and ack
+  // 2) Received seq is < expected, just re-ack previous
+  // 3) Received seq is > expected, just re-ack previous and buffer data
+  if (tcpHeader.GetSequenceNumber () == m_nextRxSequence)
+    { // If seq is expected seq
+      // 1) Update nextRxSeq
+      // 2) Buffer this packet so Recv can read it
+      // 3) Send the ack
+      m_nextRxSequence += s;           // Advance next expected sequence
+      //bytesReceived += s;       // Statistics
+      NS_LOG_LOGIC("Case 1, advanced nrxs to " << m_nextRxSequence );
+      SocketRxAddressTag tag;
+      tag.SetAddress (fromAddress);
+      p->AddTag (tag);
+      //buffer this, it'll be read by call to Recv
+      UnAckData_t::iterator i = 
+          m_bufferedData.find (tcpHeader.GetSequenceNumber () );
+      if (i != m_bufferedData.end () ) //we found it already in the buffer
+      {
+        i->second = 0; // relase reference to already buffered
+      }
+      // Save for later delivery
+      m_bufferedData[tcpHeader.GetSequenceNumber () ] = p;  
+      m_rxAvailable += p->GetSize ();
+      //putting this into the buffer might have filled in a sequence gap
+      //so we have to iterate through the list to find the largest contiguous
+      //sequenced chunk, and update m_rxAvailable appropriately
+      i = m_bufferedData.find (tcpHeader.GetSequenceNumber () );
+      UnAckData_t::iterator next = i;
+      next++;
+      while(next != m_bufferedData.end())
+        {
+          if(i->first + SequenceNumber(i->second->GetSize ()) == next->first)
+            {
+                //next packet is in sequence, count it
+                m_rxAvailable += next->second->GetSize();
+                m_nextRxSequence += next->second->GetSize();
+            }
+          else
+            {
+                break; //no more in this contiguous chunk
+            }
+          ++i;
+          ++next;
+        }
+      NotifyDataRecv ();
+      if (m_closeNotified)
+        {
+          NS_LOG_LOGIC ("Tcp " << this << " HuH?  Got data after closeNotif");
+        }
+      NS_LOG_LOGIC ("TcpSocketImpl " << this << " adv rxseq by " << s);
+      if (m_pendingClose || (origState > ESTABLISHED))
+        { // See if we can close now
+          if (m_bufferedData.empty())
+            {
+              ProcessPacketAction (PEER_CLOSE, p, tcpHeader, fromAddress);
+            }
+        }
+    }
+  else if (SequenceNumber (tcpHeader.GetSequenceNumber ()) >= m_nextRxSequence)
+    { // Need to buffer this one
+      NS_LOG_LOGIC ("Case 2, buffering " << tcpHeader.GetSequenceNumber () );
+      UnAckData_t::iterator i = 
+        m_bufferedData.find (tcpHeader.GetSequenceNumber () );
+      if (i != m_bufferedData.end () )
+        {
+          i->second = 0; // relase reference to already buffered
+        }
+      // Save for later delivery
+      SocketRxAddressTag tag;
+      tag.SetAddress (fromAddress);
+      p->AddTag (tag);
+      m_bufferedData[tcpHeader.GetSequenceNumber () ] = p;  
+    }
+  else
+    { // debug
+      NS_LOG_LOGIC("TCP " << this 
+               << " got seq " << tcpHeader.GetSequenceNumber ()
+               << " expected " << m_nextRxSequence
+               << "       flags " << tcpHeader.GetFlags ());
+    }
+  // Now send a new ack packet acknowledging all received and delivered data
+  if(++m_delAckCount >= m_delAckMaxCount)
+  {
+    m_delAckEvent.Cancel();
+    m_delAckCount = 0;
+    SendEmptyPacket (TcpHeader::ACK);
+  }
+  else
+  {
+    m_delAckEvent = Simulator::Schedule (m_delAckTimeout, &TcpSocketImpl::DelAckTimeout, this);
+  }
+}
+
+void TcpSocketImpl::DelAckTimeout ()
+{
+  m_delAckCount = 0;
+  SendEmptyPacket (TcpHeader::ACK);
+}
+
+void TcpSocketImpl::CommonNewAck (SequenceNumber ack, bool skipTimer)
+{ // CommonNewAck is called only for "New" (non-duplicate) acks
+  // and MUST be called by any subclass, from the NewAck function
+  // Always cancel any pending re-tx timer on new acknowledgement
+  NS_LOG_FUNCTION (this << ack << skipTimer); 
+  //DEBUG(1,(cout << "TCP " << this << "Cancelling retx timer " << endl));
+  if (!skipTimer)
+    {
+      m_retxEvent.Cancel ();  
+      //On recieving a "New" ack we restart retransmission timer .. RFC 2988
+      Time rto = m_rtt->RetransmitTimeout ();
+      NS_LOG_LOGIC ("Schedule retransmission timeout at time " 
+          << Simulator::Now ().GetSeconds () << " to expire at time " 
+          << (Simulator::Now () + rto).GetSeconds ());
+    m_retxEvent = Simulator::Schedule (rto, &TcpSocketImpl::ReTxTimeout, this);
+    }
+  NS_LOG_LOGIC ("TCP " << this << " NewAck " << ack 
+           << " numberAck " << (ack - m_highestRxAck)); // Number bytes ack'ed
+  m_highestRxAck = ack;         // Note the highest recieved Ack
+  if (m_wouldBlock)
+    {
+      // m_highestRxAck advancing means some data was acked, and the size 
+      // of free space in the buffer has increased
+      NotifySend (GetTxAvailable ());
+      m_wouldBlock = false;
+    }
+  if (ack > m_nextTxSequence) 
+    {
+      m_nextTxSequence = ack; // If advanced
+    }
+  // See if all pending ack'ed; if so we can delete the data
+  if (m_pendingData)
+    { // Data exists, see if can be deleted
+      if (m_pendingData->SizeFromSeq (m_firstPendingSequence, m_highestRxAck) == 0)
+        { // All pending acked, can be deleted
+          m_pendingData->Clear ();
+          delete m_pendingData;
+          m_pendingData = 0;
+          // Insure no re-tx timer
+          m_retxEvent.Cancel ();
+        }
+    }
+  // Try to send more data
+  SendPendingData();
+}
+
+Ptr<TcpSocketImpl> TcpSocketImpl::Copy ()
+{
+  return CopyObject<TcpSocketImpl> (this);
+}
+
+void TcpSocketImpl::NewAck (SequenceNumber seq)
+{ // New acknowledgement up to sequence number "seq"
+  // Adjust congestion window in response to new ack's received
+  NS_LOG_FUNCTION (this << seq);
+  NS_LOG_LOGIC ("TcpSocketImpl " << this << " NewAck "
+           << " seq " << seq
+           << " cWnd " << m_cWnd
+           << " ssThresh " << m_ssThresh);
+  if (m_cWnd < m_ssThresh)
+    { // Slow start mode, add one segSize to cWnd
+      m_cWnd += m_segmentSize;
+      NS_LOG_LOGIC ("TcpSocketImpl " << this << " NewCWnd SlowStart, cWnd " << m_cWnd 
+          << " sst " << m_ssThresh);
+    }
+  else
+    { // Congestion avoidance mode, adjust by (ackBytes*segSize) / cWnd
+      double adder =  ((double) m_segmentSize * m_segmentSize) / m_cWnd.Get();
+      if (adder < 1.0) 
+        {
+          adder = 1.0;
+        }
+      m_cWnd += (uint32_t) adder;
+      NS_LOG_LOGIC ("NewCWnd CongAvoid, cWnd " << m_cWnd 
+           << " sst " << m_ssThresh);
+    }
+  CommonNewAck (seq, false);           // Complete newAck processing
+}
+
+void TcpSocketImpl::DupAck (const TcpHeader& t, uint32_t count)
+{
+  NS_LOG_FUNCTION (this << "t " << count);
+  NS_LOG_LOGIC ("TcpSocketImpl " << this << " DupAck " <<  t.GetAckNumber ()
+      << ", count " << count
+      << ", time " << Simulator::Now ());
+  if (count == 3)
+  { // Count of three indicates triple duplicate ack
+    m_ssThresh = Window () / 2; // Per RFC2581
+    m_ssThresh = std::max (m_ssThresh, 2 * m_segmentSize);
+    NS_LOG_LOGIC("TcpSocketImpl " << this << "Tahoe TDA, time " << Simulator::Now ()
+        << " seq " << t.GetAckNumber ()
+        << " in flight " << BytesInFlight ()
+        << " new ssthresh " << m_ssThresh);
+
+    m_cWnd = m_segmentSize; // Collapse cwnd (re-enter slowstart)
+    // For Tahoe, we also reset nextTxSeq
+    m_nextTxSequence = m_highestRxAck;
+    SendPendingData ();
+  }
+}
+
+void TcpSocketImpl::ReTxTimeout ()
+{ // Retransmit timeout
+  NS_LOG_FUNCTION (this);
+  m_ssThresh = Window () / 2; // Per RFC2581
+  m_ssThresh = std::max (m_ssThresh, 2 * m_segmentSize);
+  // Set cWnd to segSize on timeout,  per rfc2581
+  // Collapse congestion window (re-enter slowstart)
+  m_cWnd = m_segmentSize;           
+  m_nextTxSequence = m_highestRxAck; // Start from highest Ack
+  m_rtt->IncreaseMultiplier (); // DoubleValue timeout value for next retx timer
+  Retransmit ();             // Retransmit the packet
+}
+
+void TcpSocketImpl::LastAckTimeout ()
+{
+  m_lastAckEvent.Cancel ();
+  if (m_state == LAST_ACK)
+    {
+      Actions_t action = ProcessEvent (TIMEOUT);
+      ProcessAction (action);
+    }
+  if (!m_closeNotified)
+    {
+      m_closeNotified = true;
+    }
+}
+
+void TcpSocketImpl::Retransmit ()
+{
+  NS_LOG_FUNCTION (this);
+  uint8_t flags = TcpHeader::NONE;
+  if (m_state == SYN_SENT) 
+    {
+      if (m_cnCount > 0) 
+        {
+          SendEmptyPacket (TcpHeader::SYN);
+          return;
+        }
+      else
+        {
+          NotifyConnectionFailed ();
+          return;
+        }
+    } 
+  if (!m_pendingData)
+    {
+      if (m_state == FIN_WAIT_1 || m_state == FIN_WAIT_2)
+        { // Must have lost FIN, re-send
+          SendEmptyPacket (TcpHeader::FIN);
+        }
+      return;
+    }
+  Ptr<Packet> p = m_pendingData->CopyFromSeq (m_segmentSize,
+                                            m_firstPendingSequence,
+                                            m_highestRxAck);
+  // Calculate remaining data for COE check
+  uint32_t remainingData = m_pendingData->SizeFromSeq (
+      m_firstPendingSequence,
+      m_nextTxSequence + SequenceNumber(p->GetSize ()));
+  if (m_closeOnEmpty && remainingData == 0)
+    { // Add the FIN flag
+      flags = flags | TcpHeader::FIN;
+    }
+
+  NS_LOG_LOGIC ("TcpSocketImpl " << this << " retxing seq " << m_highestRxAck);
+  if (m_retxEvent.IsExpired () )
+    {
+      Time rto = m_rtt->RetransmitTimeout ();
+      NS_LOG_LOGIC ("Schedule retransmission timeout at time "
+          << Simulator::Now ().GetSeconds () << " to expire at time "
+          << (Simulator::Now () + rto).GetSeconds ());
+      m_retxEvent = Simulator::Schedule (rto,&TcpSocketImpl::ReTxTimeout,this);
+    }
+  m_rtt->SentSeq (m_highestRxAck,p->GetSize ());
+  // And send the packet
+  TcpHeader tcpHeader;
+  tcpHeader.SetSequenceNumber (m_nextTxSequence);
+  tcpHeader.SetAckNumber (m_nextRxSequence);
+  tcpHeader.SetSourcePort (m_endPoint->GetLocalPort());
+  tcpHeader.SetDestinationPort (m_remotePort);
+  tcpHeader.SetFlags (flags);
+  tcpHeader.SetWindowSize (m_advertisedWindowSize);
+
+  m_tcp->SendPacket (p, tcpHeader, m_endPoint->GetLocalAddress (),
+    m_remoteAddress);
+}
+
+void
+TcpSocketImpl::SetSndBufSize (uint32_t size)
+{
+  m_sndBufSize = size;
+}
+
+uint32_t
+TcpSocketImpl::GetSndBufSize (void) const
+{
+  return m_sndBufSize;
+}
+
+void
+TcpSocketImpl::SetRcvBufSize (uint32_t size)
+{
+  m_rcvBufSize = size;
+}
+
+uint32_t
+TcpSocketImpl::GetRcvBufSize (void) const
+{
+  return m_rcvBufSize;
+}
+
+void
+TcpSocketImpl::SetSegSize (uint32_t size)
+{
+  m_segmentSize = size;
+}
+
+uint32_t
+TcpSocketImpl::GetSegSize (void) const
+{
+  return m_segmentSize;
+}
+
+void
+TcpSocketImpl::SetAdvWin (uint32_t window)
+{
+  m_advertisedWindowSize = window;
+}
+
+uint32_t
+TcpSocketImpl::GetAdvWin (void) const
+{
+  return m_advertisedWindowSize;
+}
+
+void
+TcpSocketImpl::SetSSThresh (uint32_t threshold)
+{
+  m_ssThresh = threshold;
+}
+
+uint32_t
+TcpSocketImpl::GetSSThresh (void) const
+{
+  return m_ssThresh;
+}
+
+void
+TcpSocketImpl::SetInitialCwnd (uint32_t cwnd)
+{
+  m_initialCWnd = cwnd;
+}
+
+uint32_t
+TcpSocketImpl::GetInitialCwnd (void) const
+{
+  return m_initialCWnd;
+}
+
+void 
+TcpSocketImpl::SetConnTimeout (Time timeout)
+{
+  m_cnTimeout = timeout;
+}
+
+Time
+TcpSocketImpl::GetConnTimeout (void) const
+{
+  return m_cnTimeout;
+}
+
+void 
+TcpSocketImpl::SetConnCount (uint32_t count)
+{
+  m_cnCount = count;
+}
+
+uint32_t 
+TcpSocketImpl::GetConnCount (void) const
+{
+  return m_cnCount;
+}
+
+void 
+TcpSocketImpl::SetDelAckTimeout (Time timeout)
+{
+  m_delAckTimeout = timeout;
+}
+
+Time
+TcpSocketImpl::GetDelAckTimeout (void) const
+{
+  return m_delAckTimeout;
+}
+
+void
+TcpSocketImpl::SetDelAckMaxCount (uint32_t count)
+{
+  m_delAckMaxCount = count;
+}
+
+uint32_t
+TcpSocketImpl::GetDelAckMaxCount (void) const
+{
+  return m_delAckMaxCount;
+}
+
+}//namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/tcp-socket-impl.h	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,214 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 Georgia Tech Research Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Raj Bhattacharjea <raj.b@gatech.edu>
+ */
+#ifndef TCP_SOCKET_IMPL_H
+#define TCP_SOCKET_IMPL_H
+
+#include <stdint.h>
+#include <queue>
+#include "ns3/callback.h"
+#include "ns3/traced-value.h"
+#include "ns3/tcp-socket.h"
+#include "ns3/ptr.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/event-id.h"
+#include "tcp-typedefs.h"
+#include "pending-data.h"
+#include "sequence-number.h"
+#include "rtt-estimator.h"
+
+
+namespace ns3 {
+
+class Ipv4EndPoint;
+class Node;
+class Packet;
+class TcpL4Protocol;
+class TcpHeader;
+
+class TcpSocketImpl : public TcpSocket
+{
+public:
+  static TypeId GetTypeId (void);
+  /**
+   * Create an unbound tcp socket.
+   */
+  TcpSocketImpl ();
+  TcpSocketImpl (const TcpSocketImpl& sock);
+  virtual ~TcpSocketImpl ();
+
+  void SetNode (Ptr<Node> node);
+  void SetTcp (Ptr<TcpL4Protocol> tcp);
+  void SetRtt (Ptr<RttEstimator> rtt);
+
+  virtual enum SocketErrno GetErrno (void) const;
+  virtual Ptr<Node> GetNode (void) const;
+  virtual int Bind (void);
+  virtual int Bind (const Address &address);
+  virtual int Close (void);
+  virtual int ShutdownSend (void);
+  virtual int ShutdownRecv (void);
+  virtual int Connect(const Address &address);
+  virtual int Send (Ptr<Packet> p);
+  virtual int Send (const uint8_t* buf, uint32_t size);
+  virtual int SendTo(Ptr<Packet> p, const Address &address);
+  virtual uint32_t GetTxAvailable (void) const;
+  virtual int Listen(uint32_t queueLimit);
+
+  virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags);
+  virtual uint32_t GetRxAvailable (void) const;
+
+private:
+  friend class Tcp;
+  // invoked by Tcp class
+  int FinishBind (void);
+  void ForwardUp (Ptr<Packet> p, Ipv4Address ipv4, uint16_t port);
+  void Destroy (void);
+  int DoSendTo (Ptr<Packet> p, const Address &daddr);
+  int DoSendTo (Ptr<Packet> p, Ipv4Address daddr, uint16_t dport);
+  void SendEmptyPacket(uint8_t flags);
+  //methods for state
+  bool ProcessAction (Actions_t a);
+  bool ProcessAction (Actions_t a, const TcpHeader& tcpHeader,
+                      Ipv4Address saddr, Ipv4Address daddr);
+  bool ProcessPacketAction (Actions_t a, Ptr<Packet> p,
+                                       const TcpHeader& tcpHeader,
+                                       const Address& fromAddress);
+  Actions_t ProcessEvent (Events_t e);
+  bool SendPendingData(bool withAck = false);
+  void CompleteFork(Ptr<Packet>, const TcpHeader&, const Address& fromAddress);
+  void ConnectionSucceeded();
+  
+  //methods for window management
+  virtual uint32_t  UnAckDataCount(); // Return count of number of unacked bytes
+  virtual uint32_t  BytesInFlight();  // Return total bytes in flight
+  virtual uint32_t  Window();         // Return window size (integer)
+  virtual uint32_t  AvailableWindow();// Return unfilled portion of window
+
+  // Manage data tx/rx
+  void NewRx (Ptr<Packet>, const TcpHeader&, const Address&);
+  // XXX This should be virtual and overridden
+  Ptr<TcpSocketImpl> Copy ();
+  void NewAck (SequenceNumber seq); 
+  // XXX This should be virtual and overridden
+  void DupAck (const TcpHeader& t, uint32_t count); 
+  void ReTxTimeout ();
+  void DelAckTimeout ();
+  void LastAckTimeout ();
+  void Retransmit ();
+  void CommonNewAck (SequenceNumber seq, bool skipTimer = false);
+
+  // attribute related
+  virtual void SetSndBufSize (uint32_t size);
+  virtual uint32_t GetSndBufSize (void) const;
+  virtual void SetRcvBufSize (uint32_t size);
+  virtual uint32_t GetRcvBufSize (void) const;
+  virtual void SetSegSize (uint32_t size);
+  virtual uint32_t GetSegSize (void) const;
+  virtual void SetAdvWin (uint32_t window);
+  virtual uint32_t GetAdvWin (void) const;
+  virtual void SetSSThresh (uint32_t threshold);
+  virtual uint32_t GetSSThresh (void) const;
+  virtual void SetInitialCwnd (uint32_t cwnd);
+  virtual uint32_t GetInitialCwnd (void) const;
+  virtual void SetConnTimeout (Time timeout);
+  virtual Time GetConnTimeout (void) const;
+  virtual void SetConnCount (uint32_t count);
+  virtual uint32_t GetConnCount (void) const;
+  virtual void SetDelAckTimeout (Time timeout);
+  virtual Time GetDelAckTimeout (void) const;
+  virtual void SetDelAckMaxCount (uint32_t count);
+  virtual uint32_t GetDelAckMaxCount (void) const;
+
+  bool m_skipRetxResched;
+  uint32_t m_dupAckCount;
+  EventId m_retxEvent;
+  EventId m_lastAckEvent;
+
+  EventId m_delAckEvent;
+  uint32_t m_delAckCount;
+  uint32_t m_delAckMaxCount;
+  Time m_delAckTimeout;
+
+  Ipv4EndPoint *m_endPoint;
+  Ptr<Node> m_node;
+  Ptr<TcpL4Protocol> m_tcp;
+  Ipv4Address m_remoteAddress;
+  uint16_t m_remotePort;
+  //these two are so that the socket/endpoint cloning works
+  Ipv4Address m_localAddress;
+  uint16_t m_localPort;
+  enum SocketErrno m_errno;
+  bool m_shutdownSend;
+  bool m_shutdownRecv;
+  bool m_connected;
+  
+  //manage the state infomation
+  States_t m_state;
+  bool m_closeNotified;
+  bool m_closeRequestNotified;
+  bool m_closeOnEmpty;
+  bool m_pendingClose;
+
+  
+  //sequence info, sender side
+  SequenceNumber m_nextTxSequence;
+  SequenceNumber m_highTxMark;
+  SequenceNumber m_highestRxAck;
+  SequenceNumber m_lastRxAck;
+  
+  //sequence info, reciever side
+  SequenceNumber m_nextRxSequence;
+
+  //history data
+  //this is the incoming data buffer which sorts out of sequence data
+  UnAckData_t m_bufferedData;
+  //this is kind of the tx buffer
+  PendingData* m_pendingData;
+  SequenceNumber m_firstPendingSequence;
+
+  // Window management
+  uint32_t                       m_segmentSize;          //SegmentSize
+  uint32_t                       m_rxWindowSize;
+  uint32_t                       m_advertisedWindowSize; //Window to advertise
+  TracedValue<uint32_t>          m_cWnd;                 //Congestion window
+  uint32_t                       m_ssThresh;             //Slow Start Threshold
+  uint32_t                       m_initialCWnd;          //Initial cWnd value
+
+  // Round trip time estimation
+  Ptr<RttEstimator> m_rtt;
+  Time m_lastMeasuredRtt;
+
+  // Timer-related members
+  Time              m_cnTimeout; 
+  uint32_t          m_cnCount;
+
+  // Temporary queue for delivering data to application
+  uint32_t m_rxAvailable;
+
+  bool m_wouldBlock;  // set to true whenever socket would block on send()
+
+  // Attributes
+  uint32_t m_sndBufSize;   // buffer limit for the outgoing queue
+  uint32_t m_rcvBufSize;   // maximum receive socket buffer size
+};
+
+}//namespace ns3
+
+#endif /* TCP_SOCKET_IMPL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/tcp-typedefs.h	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,111 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 Georgia Tech Research Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Raj Bhattacharjea <raj.b@gatech.edu>
+ * typedefs for tcp state machine
+ */ 
+
+#include <vector>
+#include <map>
+#include "sequence-number.h"
+
+#ifndef TCP_TYPEDEFS_H
+#define TCP_TYPEDEFS_H
+
+namespace ns3 {
+
+typedef enum { MAX_FLAGS = 0x40 } TCPMaxFlags_t;  // Flags are 6 bits
+
+typedef enum {
+  CLOSED,       // 0
+  LISTEN,       // 1
+  SYN_SENT,     // 2
+  SYN_RCVD,     // 3
+  ESTABLISHED,  // 4
+  CLOSE_WAIT,   // 5
+  LAST_ACK,     // 6
+  FIN_WAIT_1,   // 7
+  FIN_WAIT_2,   // 8
+  CLOSING,      // 9
+  TIMED_WAIT,   // 10
+  LAST_STATE } States_t;
+
+typedef enum {
+  APP_LISTEN,   // 0
+  APP_CONNECT,  // 1
+  APP_SEND,     // 2
+  SEQ_RECV,     // 3
+  APP_CLOSE,    // 4
+  TIMEOUT,      // 5
+  ACK_RX,       // 6
+  SYN_RX,       // 7
+  SYN_ACK_RX,   // 8
+  FIN_RX,       // 9
+  FIN_ACK_RX,   // 10
+  RST_RX,       // 11
+  BAD_FLAGS,    // 12
+  LAST_EVENT } Events_t;
+
+typedef enum {
+  NO_ACT,       // 0
+  ACK_TX,       // 1
+  ACK_TX_1,     // ACK response to syn
+  RST_TX,       // 2
+  SYN_TX,       // 3
+  SYN_ACK_TX,   // 4
+  FIN_TX,       // 5
+  FIN_ACK_TX,   // 6
+  NEW_ACK,      // 7
+  NEW_SEQ_RX,   // 8
+  RETX,         // 9
+  TX_DATA,      // 10
+  PEER_CLOSE,   // 11
+  APP_CLOSED,   // 12
+  CANCEL_TM,    // 13
+  APP_NOTIFY,   // 14 - Notify app that connection failed
+  SERV_NOTIFY,  // 15 - Notify server tcp that connection completed
+  LAST_ACTION } Actions_t;
+
+class SA  // State/Action pair
+{
+public:
+  SA () : state (LAST_STATE), action (LAST_ACTION) { }
+  SA (States_t s, Actions_t a) : state (s), action (a) { }
+public:
+  States_t  state;
+  Actions_t action;
+};
+typedef std::vector<SA>  StateActionVec_t;
+typedef std::vector<StateActionVec_t> StateActions_t;  // One per current state
+typedef std::vector<Events_t> EventVec_t;      // For flag events lookup
+
+//type for managing buffered out of sequence data
+typedef std::map<SequenceNumber, Ptr<Packet> > UnAckData_t;
+
+class TcpStateMachine {
+  public:
+    TcpStateMachine ();
+    SA Lookup (States_t, Events_t);
+    Events_t FlagsEvent (uint8_t); // Lookup event from flags
+
+  public:
+    StateActions_t aT; // Action table
+    EventVec_t     eV; // Flags event lookup  
+};
+
+}//namespace ns3
+#endif //TCP_TYPEDEFS_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/udp-header.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,162 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#include "udp-header.h"
+#include "ipv4-checksum.h"
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (UdpHeader);
+
+bool UdpHeader::m_calcChecksum = false;
+
+/* The magic values below are used only for debugging.
+ * They can be used to easily detect memory corruption
+ * problems so you can see the patterns in memory.
+ */
+UdpHeader::UdpHeader ()
+  : m_sourcePort (0xfffd),
+    m_destinationPort (0xfffd),
+    m_payloadSize (0xfffd),
+    m_initialChecksum (0)
+{}
+UdpHeader::~UdpHeader ()
+{
+  m_sourcePort = 0xfffe;
+  m_destinationPort = 0xfffe;
+  m_payloadSize = 0xfffe;
+}
+
+void 
+UdpHeader::EnableChecksums (void)
+{
+  m_calcChecksum = true;
+}
+
+void 
+UdpHeader::SetDestinationPort (uint16_t port)
+{
+  m_destinationPort = port;
+}
+void 
+UdpHeader::SetSourcePort (uint16_t port)
+{
+  m_sourcePort = port;
+}
+uint16_t 
+UdpHeader::GetSourcePort (void) const
+{
+  return m_sourcePort;
+}
+uint16_t 
+UdpHeader::GetDestinationPort (void) const
+{
+  return m_destinationPort;
+}
+void 
+UdpHeader::SetPayloadSize (uint16_t size)
+{
+  m_payloadSize = size;
+}
+void 
+UdpHeader::InitializeChecksum (Ipv4Address source, 
+                              Ipv4Address destination,
+                              uint8_t protocol)
+{
+  uint8_t buf[12];
+  source.Serialize (buf);
+  destination.Serialize (buf+4);
+  buf[8] = 0;
+  buf[9] = protocol;
+  uint16_t udpLength = m_payloadSize + GetSerializedSize ();
+  buf[10] = udpLength >> 8;
+  buf[11] = udpLength & 0xff;
+
+  m_initialChecksum = Ipv4ChecksumCalculate (0, buf, 12);
+}
+
+TypeId 
+UdpHeader::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::UdpHeader")
+    .SetParent<Header> ()
+    .AddConstructor<UdpHeader> ()
+    ;
+  return tid;
+}
+TypeId 
+UdpHeader::GetInstanceTypeId (void) const
+{
+  return GetTypeId ();
+}
+void 
+UdpHeader::Print (std::ostream &os) const
+{
+  os << "length: " << m_payloadSize + GetSerializedSize ()
+     << " " 
+     << m_sourcePort << " > " << m_destinationPort
+    ;
+}
+
+uint32_t 
+UdpHeader::GetSerializedSize (void) const
+{
+  return 8;
+}
+
+void
+UdpHeader::Serialize (Buffer::Iterator start) const
+{
+  Buffer::Iterator i = start;
+  i.WriteHtonU16 (m_sourcePort);
+  i.WriteHtonU16 (m_destinationPort);
+  i.WriteHtonU16 (m_payloadSize + GetSerializedSize ());
+  i.WriteU16 (0);
+
+  if (m_calcChecksum) 
+    {
+#if 0
+      //XXXX
+      uint16_t checksum = Ipv4ChecksumCalculate (m_initialChecksum, 
+                                                  buffer->PeekData (), 
+                                                  GetSerializedSize () + m_payloadSize);
+      checksum = Ipv4ChecksumComplete (checksum);
+      i = buffer->Begin ();
+      i.Next (6);
+      i.WriteU16 (checksum);
+#endif
+    }
+}
+uint32_t
+UdpHeader::Deserialize (Buffer::Iterator start)
+{
+  Buffer::Iterator i = start;
+  m_sourcePort = i.ReadNtohU16 ();
+  m_destinationPort = i.ReadNtohU16 ();
+  m_payloadSize = i.ReadNtohU16 () - GetSerializedSize ();
+  if (m_calcChecksum) 
+    {
+      // XXX verify checksum.
+    }
+  return GetSerializedSize ();
+}
+
+
+}; // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/udp-header.h	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,103 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#ifndef UDP_HEADER_H
+#define UDP_HEADER_H
+
+#include <stdint.h>
+#include <string>
+#include "ns3/header.h"
+#include "ns3/ipv4-address.h"
+
+namespace ns3 {
+/**
+ * \brief Packet header for UDP packets
+ */
+class UdpHeader : public Header 
+{
+public:
+
+  /**
+   * \brief Constructor
+   *
+   * Creates a null header
+   */
+  UdpHeader ();
+  ~UdpHeader ();
+
+  /**
+   * \brief Enable checksum calculation for UDP (XXX currently has no effect)
+   */
+  static void EnableChecksums (void);
+  /**
+   * \param port the destination port for this UdpHeader
+   */
+  void SetDestinationPort (uint16_t port);
+  /**
+   * \param port The source port for this UdpHeader
+   */
+  void SetSourcePort (uint16_t port);
+  /**
+   * \return The source port for this UdpHeader
+   */
+  uint16_t GetSourcePort (void) const;
+  /**
+   * \return the destination port for this UdpHeader
+   */
+  uint16_t GetDestinationPort (void) const;
+  /**
+   * \param size The payload size in bytes
+   */
+  void SetPayloadSize (uint16_t size);
+
+  /**
+   * \param source the ip source to use in the underlying
+   *        ip packet.
+   * \param destination the ip destination to use in the
+   *        underlying ip packet.
+   * \param protocol the protocol number to use in the underlying
+   *        ip packet.
+   *
+   * If you want to use udp checksums, you should call this
+   * method prior to adding the header to a packet.
+   */
+  void InitializeChecksum (Ipv4Address source, 
+                           Ipv4Address destination,
+                           uint8_t protocol);
+
+  static TypeId GetTypeId (void);
+  virtual TypeId GetInstanceTypeId (void) const;
+  virtual void Print (std::ostream &os) const;
+  virtual uint32_t GetSerializedSize (void) const;
+  virtual void Serialize (Buffer::Iterator start) const;
+  virtual uint32_t Deserialize (Buffer::Iterator start);
+
+private:
+  uint16_t m_sourcePort;
+  uint16_t m_destinationPort;
+  uint16_t m_payloadSize;
+  uint16_t m_initialChecksum;
+
+  static bool m_calcChecksum;
+};
+
+} // namespace ns3
+
+#endif /* UDP_HEADER */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/udp-l4-protocol.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,194 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#include "ns3/log.h"
+#include "ns3/assert.h"
+#include "ns3/packet.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 "udp-socket-impl.h"
+
+NS_LOG_COMPONENT_DEFINE ("UdpL4Protocol");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (UdpL4Protocol);
+
+/* see http://www.iana.org/assignments/protocol-numbers */
+const uint8_t UdpL4Protocol::PROT_NUMBER = 17;
+
+TypeId 
+UdpL4Protocol::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::UdpL4Protocol")
+    .SetParent<Ipv4L4Protocol> ()
+    .AddConstructor<UdpL4Protocol> ()
+    ;
+  return tid;
+}
+
+UdpL4Protocol::UdpL4Protocol ()
+  : m_endPoints (new Ipv4EndPointDemux ())
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+UdpL4Protocol::~UdpL4Protocol ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+void 
+UdpL4Protocol::SetNode (Ptr<Node> node)
+{
+  m_node = node;
+}
+
+int 
+UdpL4Protocol::GetProtocolNumber (void) const
+{
+  return PROT_NUMBER;
+}
+int 
+UdpL4Protocol::GetVersion (void) const
+{
+  return 2;
+}
+
+
+void
+UdpL4Protocol::DoDispose (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  if (m_endPoints != 0)
+    {
+      delete m_endPoints;
+      m_endPoints = 0;
+    }
+  m_node = 0;
+  Ipv4L4Protocol::DoDispose ();
+}
+
+Ptr<Socket>
+UdpL4Protocol::CreateSocket (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  Ptr<UdpSocketImpl> socket = CreateObject<UdpSocketImpl> ();
+  socket->SetNode (m_node);
+  socket->SetUdp (this);
+  return socket;
+}
+
+Ipv4EndPoint *
+UdpL4Protocol::Allocate (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_endPoints->Allocate ();
+}
+
+Ipv4EndPoint *
+UdpL4Protocol::Allocate (Ipv4Address address)
+{
+  NS_LOG_FUNCTION (this << address);
+  return m_endPoints->Allocate (address);
+}
+
+Ipv4EndPoint *
+UdpL4Protocol::Allocate (uint16_t port)
+{
+  NS_LOG_FUNCTION (this << port);
+  return m_endPoints->Allocate (port);
+}
+
+Ipv4EndPoint *
+UdpL4Protocol::Allocate (Ipv4Address address, uint16_t port)
+{
+  NS_LOG_FUNCTION (this << address << port);
+  return m_endPoints->Allocate (address, port);
+}
+Ipv4EndPoint *
+UdpL4Protocol::Allocate (Ipv4Address localAddress, uint16_t localPort,
+                         Ipv4Address peerAddress, uint16_t peerPort)
+{
+  NS_LOG_FUNCTION (this << localAddress << localPort << peerAddress << peerPort);
+  return m_endPoints->Allocate (localAddress, localPort,
+                                peerAddress, peerPort);
+}
+
+void 
+UdpL4Protocol::DeAllocate (Ipv4EndPoint *endPoint)
+{
+  NS_LOG_FUNCTION (this << endPoint);
+  m_endPoints->DeAllocate (endPoint);
+}
+
+void 
+UdpL4Protocol::Receive(Ptr<Packet> packet, 
+                       Ipv4Address const &source,
+                       Ipv4Address const &destination,
+                       Ptr<Ipv4Interface> interface)
+{
+  NS_LOG_FUNCTION (this << packet << source << destination);
+
+  UdpHeader udpHeader;
+  packet->RemoveHeader (udpHeader);
+  Ipv4EndPointDemux::EndPoints endPoints =
+    m_endPoints->Lookup (destination, udpHeader.GetDestinationPort (),
+                         source, udpHeader.GetSourcePort (), interface);
+  for (Ipv4EndPointDemux::EndPointsI endPoint = endPoints.begin ();
+       endPoint != endPoints.end (); endPoint++)
+    {
+      (*endPoint)->ForwardUp (packet->Copy (), source, udpHeader.GetSourcePort ());
+    }
+}
+
+void
+UdpL4Protocol::Send (Ptr<Packet> packet, 
+                     Ipv4Address saddr, Ipv4Address daddr, 
+                     uint16_t sport, uint16_t dport)
+{
+  NS_LOG_FUNCTION (this << packet << saddr << daddr << sport << dport);
+
+  UdpHeader udpHeader;
+  udpHeader.SetDestinationPort (dport);
+  udpHeader.SetSourcePort (sport);
+  udpHeader.SetPayloadSize (packet->GetSize ());
+  udpHeader.InitializeChecksum (saddr,
+                                daddr,
+                                PROT_NUMBER);
+
+  packet->AddHeader (udpHeader);
+
+  Ptr<Ipv4L3Protocol> ipv4 = m_node->GetObject<Ipv4L3Protocol> ();
+  if (ipv4 != 0)
+    {
+      NS_LOG_LOGIC ("Sending to IP");
+      ipv4->Send (packet, saddr, daddr, PROT_NUMBER);
+    }
+}
+
+
+}; // namespace ns3
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/udp-l4-protocol.h	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,100 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005,2006,2007 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
+ *
+ * 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 Socket;
+/**
+ * \brief Implementation of the UDP protocol
+ */
+class UdpL4Protocol : public Ipv4L4Protocol {
+public:
+  static TypeId GetTypeId (void);
+  static const uint8_t PROT_NUMBER;
+
+  UdpL4Protocol ();
+  virtual ~UdpL4Protocol ();
+
+  void SetNode (Ptr<Node> node);
+
+  virtual int GetProtocolNumber (void) const;
+  virtual int GetVersion (void) const;
+
+  /**
+   * \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 (Ptr<Packet> packet,
+             Ipv4Address saddr, Ipv4Address daddr, 
+             uint16_t sport, uint16_t dport);
+  /**
+   * \brief Receive 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
+   * \param interface the interface from which the packet is coming.
+   */
+  // inherited from Ipv4L4Protocol
+  virtual void Receive(Ptr<Packet> p, 
+                       Ipv4Address const &source,
+                       Ipv4Address const &destination,
+                       Ptr<Ipv4Interface> interface);
+protected:
+  virtual void DoDispose (void);
+private:
+  Ptr<Node> m_node;
+  Ipv4EndPointDemux *m_endPoints;
+};
+
+}; // namespace ns3
+
+#endif /* UDP_L4_PROTOCOL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/udp-socket-factory-impl.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,54 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "udp-socket-factory-impl.h"
+#include "udp-l4-protocol.h"
+#include "ns3/socket.h"
+#include "ns3/assert.h"
+
+namespace ns3 {
+
+UdpSocketFactoryImpl::UdpSocketFactoryImpl ()
+  : m_udp (0)
+{}
+UdpSocketFactoryImpl::~UdpSocketFactoryImpl ()
+{
+  NS_ASSERT (m_udp == 0);
+}
+
+void 
+UdpSocketFactoryImpl::SetUdp (Ptr<UdpL4Protocol> udp)
+{
+  m_udp = udp;
+}
+
+Ptr<Socket>
+UdpSocketFactoryImpl::CreateSocket (void)
+{
+  return m_udp->CreateSocket ();
+}
+
+void 
+UdpSocketFactoryImpl::DoDispose (void)
+{
+  m_udp = 0;
+  UdpSocketFactory::DoDispose ();
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/udp-socket-factory-impl.h	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,62 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef UDP_SOCKET_FACTORY_IMPL_H
+#define UDP_SOCKET_FACTORY_IMPL_H
+
+#include "ns3/udp-socket-factory.h"
+#include "ns3/ptr.h"
+
+namespace ns3 {
+
+class UdpL4Protocol;
+
+/**
+ * \brief Object to create UDP socket instances 
+ * \internal
+ *
+ * This class implements the API for creating UDP sockets.
+ * It is a socket factory (deriving from class SocketFactory).
+ */
+class UdpSocketFactoryImpl : public UdpSocketFactory
+{
+public:
+  UdpSocketFactoryImpl ();
+  virtual ~UdpSocketFactoryImpl ();
+
+  void SetUdp (Ptr<UdpL4Protocol> udp);
+
+  /**
+   * \brief Implements a method to create a Udp-based socket and return
+   * a base class smart pointer to the socket.
+   * \internal
+   *
+   * \return smart pointer to Socket
+   */
+  virtual Ptr<Socket> CreateSocket (void);
+
+protected:
+  virtual void DoDispose (void);
+private:
+  Ptr<UdpL4Protocol> m_udp;
+};
+
+} // namespace ns3
+
+#endif /* UDP_SOCKET_FACTORY_IMPL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/udp-socket-impl.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,694 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#include "ns3/log.h"
+#include "ns3/node.h"
+#include "ns3/inet-socket-address.h"
+#include "ns3/ipv4-route.h"
+#include "ns3/ipv4.h"
+#include "ns3/udp-socket-factory.h"
+#include "ns3/trace-source-accessor.h"
+#include "ns3/uinteger.h"
+#include "ns3/boolean.h"
+#include "udp-socket-impl.h"
+#include "udp-l4-protocol.h"
+#include "ipv4-end-point.h"
+#include "ipv4-l4-demux.h"
+
+NS_LOG_COMPONENT_DEFINE ("UdpSocketImpl");
+
+namespace ns3 {
+
+static const uint32_t MAX_IPV4_UDP_DATAGRAM_SIZE = 65507;
+
+// Add attributes generic to all UdpSockets to base class UdpSocket
+TypeId
+UdpSocketImpl::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::UdpSocketImpl")
+    .SetParent<UdpSocket> ()
+    .AddConstructor<UdpSocketImpl> ()
+    .AddTraceSource ("Drop", "Drop UDP packet due to receive buffer overflow",
+                     MakeTraceSourceAccessor (&UdpSocketImpl::m_dropTrace))
+    ;
+  return tid;
+}
+
+UdpSocketImpl::UdpSocketImpl ()
+  : m_endPoint (0),
+    m_node (0),
+    m_udp (0),
+    m_errno (ERROR_NOTERROR),
+    m_shutdownSend (false),
+    m_shutdownRecv (false),
+    m_connected (false),
+    m_rxAvailable (0)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+UdpSocketImpl::~UdpSocketImpl ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  m_node = 0;
+  if (m_endPoint != 0)
+    {
+      NS_ASSERT (m_udp != 0);
+      /**
+       * Note that this piece of code is a bit tricky:
+       * when DeAllocate is called, it will call into
+       * Ipv4EndPointDemux::Deallocate which triggers
+       * a delete of the associated endPoint which triggers
+       * in turn a call to the method ::Destroy below
+       * will will zero the m_endPoint field.
+       */
+      NS_ASSERT (m_endPoint != 0);
+      m_udp->DeAllocate (m_endPoint);
+      NS_ASSERT (m_endPoint == 0);
+    }
+  m_udp = 0;
+}
+
+void 
+UdpSocketImpl::SetNode (Ptr<Node> node)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_node = node;
+
+}
+void 
+UdpSocketImpl::SetUdp (Ptr<UdpL4Protocol> udp)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_udp = udp;
+}
+
+
+enum Socket::SocketErrno
+UdpSocketImpl::GetErrno (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_errno;
+}
+
+Ptr<Node>
+UdpSocketImpl::GetNode (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_node;
+}
+
+void 
+UdpSocketImpl::Destroy (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_node = 0;
+  m_endPoint = 0;
+  m_udp = 0;
+}
+
+int
+UdpSocketImpl::FinishBind (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  if (m_endPoint == 0)
+    {
+      return -1;
+    }
+  m_endPoint->SetRxCallback (MakeCallback (&UdpSocketImpl::ForwardUp, Ptr<UdpSocketImpl> (this)));
+  m_endPoint->SetDestroyCallback (MakeCallback (&UdpSocketImpl::Destroy, Ptr<UdpSocketImpl> (this)));
+  return 0;
+}
+
+int
+UdpSocketImpl::Bind (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_endPoint = m_udp->Allocate ();
+  return FinishBind ();
+}
+
+int 
+UdpSocketImpl::Bind (const Address &address)
+{
+  NS_LOG_FUNCTION (this << address);
+
+  if (!InetSocketAddress::IsMatchingType (address))
+    {
+      NS_LOG_ERROR ("Not IsMatchingType");
+      return ERROR_INVAL;
+    }
+  InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
+  Ipv4Address ipv4 = transport.GetIpv4 ();
+  uint16_t port = transport.GetPort ();
+  if (ipv4 == Ipv4Address::GetAny () && port == 0)
+    {
+      m_endPoint = m_udp->Allocate ();
+    }
+  else if (ipv4 == Ipv4Address::GetAny () && port != 0)
+    {
+      m_endPoint = m_udp->Allocate (port);
+    }
+  else if (ipv4 != Ipv4Address::GetAny () && port == 0)
+    {
+      m_endPoint = m_udp->Allocate (ipv4);
+    }
+  else if (ipv4 != Ipv4Address::GetAny () && port != 0)
+    {
+      m_endPoint = m_udp->Allocate (ipv4, port);
+    }
+
+  return FinishBind ();
+}
+
+int 
+UdpSocketImpl::ShutdownSend (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_shutdownSend = true;
+  return 0;
+}
+
+int 
+UdpSocketImpl::ShutdownRecv (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_shutdownRecv = false;
+  return 0;
+}
+
+int
+UdpSocketImpl::Close(void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  NotifyCloseCompleted ();
+  return 0;
+}
+
+int
+UdpSocketImpl::Connect(const Address & address)
+{
+  NS_LOG_FUNCTION (this << address);
+  InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
+  m_defaultAddress = transport.GetIpv4 ();
+  m_defaultPort = transport.GetPort ();
+  NotifyConnectionSucceeded ();
+  m_connected = true;
+
+  return 0;
+}
+
+int 
+UdpSocketImpl::Listen (uint32_t queueLimit)
+{
+  m_errno = Socket::ERROR_OPNOTSUPP;
+  return -1;
+}
+
+int 
+UdpSocketImpl::Send (Ptr<Packet> p)
+{
+  NS_LOG_FUNCTION (this << p);
+
+  if (!m_connected)
+    {
+      m_errno = ERROR_NOTCONN;
+      return -1;
+    }
+  return DoSend (p);
+}
+
+int 
+UdpSocketImpl::DoSend (Ptr<Packet> p)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  if (m_endPoint == 0)
+    {
+      if (Bind () == -1)
+       {
+          NS_ASSERT (m_endPoint == 0);
+         return -1;
+       }
+      NS_ASSERT (m_endPoint != 0);
+    }
+  if (m_shutdownSend)
+    {
+      m_errno = ERROR_SHUTDOWN;
+      return -1;
+    } 
+  
+  return DoSendTo (p, m_defaultAddress, m_defaultPort);
+}
+
+int
+UdpSocketImpl::DoSendTo (Ptr<Packet> p, const Address &address)
+{
+  NS_LOG_FUNCTION (this << p << address);
+
+  if (!m_connected)
+    {
+      NS_LOG_LOGIC ("Not connected");
+      InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
+      Ipv4Address ipv4 = transport.GetIpv4 ();
+      uint16_t port = transport.GetPort ();
+      return DoSendTo (p, ipv4, port);
+    }
+  else
+    {
+      // connected UDP socket must use default addresses
+      NS_LOG_LOGIC ("Connected");
+      return DoSendTo (p, m_defaultAddress, m_defaultPort);
+    }
+}
+
+int
+UdpSocketImpl::DoSendTo (Ptr<Packet> p, Ipv4Address dest, uint16_t port)
+{
+  NS_LOG_FUNCTION (this << p << dest << port);
+
+  if (m_endPoint == 0)
+    {
+      if (Bind () == -1)
+	{
+          NS_ASSERT (m_endPoint == 0);
+	  return -1;
+	}
+      NS_ASSERT (m_endPoint != 0);
+    }
+  if (m_shutdownSend)
+    {
+      m_errno = ERROR_SHUTDOWN;
+      return -1;
+    }
+
+  if (p->GetSize () > GetTxAvailable () )
+    {
+      m_errno = ERROR_MSGSIZE;
+      return -1;
+    }
+
+  uint32_t localIfIndex;
+  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
+
+  // Locally override the IP TTL for this socket
+  // We cannot directly modify the TTL at this stage, so we set a Packet tag
+  // The destination can be either multicast, unicast/anycast, or
+  // either all-hosts broadcast or limited (subnet-directed) broadcast.
+  // For the latter two broadcast types, the TTL will later be set to one
+  // irrespective of what is set in these socket options.  So, this tagging  
+  // may end up setting the TTL of a limited broadcast packet to be
+  // the same as a unicast, but it will be fixed further down the stack
+  //NS_LOG_UNCOND ("IPttl: " << m_ipTtl);
+  if (m_ipMulticastTtl != 0 && dest.IsMulticast ())
+    {
+      SocketIpTtlTag tag;
+      tag.SetTtl (m_ipMulticastTtl);
+      p->AddTag (tag);
+    }
+  else if (m_ipTtl != 0 && !dest.IsMulticast () && !dest.IsBroadcast ())
+    {
+      SocketIpTtlTag tag;
+      tag.SetTtl (m_ipTtl);
+      p->AddTag (tag);
+    }
+  //
+  // If dest is sent to the limited broadcast address (all ones),
+  // convert it to send a copy of the packet out of every interface
+  //
+  if (dest.IsBroadcast ())
+    {
+      NS_LOG_LOGIC ("Limited broadcast start.");
+      for (uint32_t i = 0; i < ipv4->GetNInterfaces (); i++ )
+        {
+          Ipv4Address addri = ipv4->GetAddress (i);
+          Ipv4Mask maski = ipv4->GetNetworkMask (i);
+          Ipv4Address bcast = addri.GetSubnetDirectedBroadcast (maski);
+          NS_LOG_LOGIC ("Sending one copy from " << addri << " to " << bcast
+                        << " (mask is " << maski << ")");
+          m_udp->Send (p->Copy (), addri, bcast,
+                       m_endPoint->GetLocalPort (), port);
+          NotifyDataSent (p->GetSize ());
+        }
+      NS_LOG_LOGIC ("Limited broadcast end.");
+      return p->GetSize();
+    }
+  else if (ipv4->GetIfIndexForDestination(dest, localIfIndex))
+    {
+      NS_LOG_LOGIC ("Route exists");
+      m_udp->Send (p->Copy (), ipv4->GetAddress (localIfIndex), dest,
+		   m_endPoint->GetLocalPort (), port);
+      NotifyDataSent (p->GetSize ());
+      return p->GetSize();;
+    }
+  else
+   {
+      NS_LOG_ERROR ("ERROR_NOROUTETOHOST");
+      m_errno = ERROR_NOROUTETOHOST;
+      return -1;
+   }
+
+  return 0;
+}
+
+// XXX maximum message size for UDP broadcast is limited by MTU
+// size of underlying link; we are not checking that now.
+uint32_t
+UdpSocketImpl::GetTxAvailable (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  // No finite send buffer is modelled, but we must respect
+  // the maximum size of an IP datagram (65535 bytes - headers).
+  return MAX_IPV4_UDP_DATAGRAM_SIZE;
+}
+
+int 
+UdpSocketImpl::SendTo (Ptr<Packet> p, const Address &address)
+{
+  NS_LOG_FUNCTION (this << address << p);
+  InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
+  Ipv4Address ipv4 = transport.GetIpv4 ();
+  uint16_t port = transport.GetPort ();
+  return DoSendTo (p, ipv4, port);
+}
+
+Ptr<Packet>
+UdpSocketImpl::Recv (uint32_t maxSize, uint32_t flags)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  if (m_deliveryQueue.empty() )
+    {
+      return 0;
+    }
+  Ptr<Packet> p = m_deliveryQueue.front ();
+  if (p->GetSize () <= maxSize) 
+    {
+      m_deliveryQueue.pop ();
+      m_rxAvailable -= p->GetSize ();
+    }
+  else
+    {
+      p = 0; 
+    }
+  return p;
+}
+
+uint32_t
+UdpSocketImpl::GetRxAvailable (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  // We separately maintain this state to avoid walking the queue 
+  // every time this might be called
+  return m_rxAvailable;
+}
+
+void 
+UdpSocketImpl::ForwardUp (Ptr<Packet> packet, Ipv4Address ipv4, uint16_t port)
+{
+  NS_LOG_FUNCTION (this << packet << ipv4 << port);
+
+  if (m_shutdownRecv)
+    {
+      return;
+    }
+  if ((m_rxAvailable + packet->GetSize ()) <= m_rcvBufSize)
+    {
+      Address address = InetSocketAddress (ipv4, port);
+      SocketRxAddressTag tag;
+      tag.SetAddress (address);
+      packet->AddTag (tag);
+      m_deliveryQueue.push (packet);
+      m_rxAvailable += packet->GetSize ();
+      NotifyDataRecv ();
+    }
+  else
+    {
+      // In general, this case should not occur unless the
+      // receiving application reads data from this socket slowly
+      // in comparison to the arrival rate
+      //
+      // drop and trace packet
+      NS_LOG_WARN ("No receive buffer space available.  Drop.");
+      m_dropTrace (packet);
+    }
+}
+
+
+void 
+UdpSocketImpl::SetRcvBufSize (uint32_t size)
+{
+  m_rcvBufSize = size;
+}
+
+uint32_t 
+UdpSocketImpl::GetRcvBufSize (void) const
+{
+  return m_rcvBufSize;
+}
+
+void 
+UdpSocketImpl::SetIpTtl (uint32_t ipTtl)
+{
+  m_ipTtl = ipTtl;
+}
+
+uint32_t 
+UdpSocketImpl::GetIpTtl (void) const
+{
+  return m_ipTtl;
+}
+
+void 
+UdpSocketImpl::SetIpMulticastTtl (uint32_t ipTtl)
+{
+  m_ipMulticastTtl = ipTtl;
+}
+
+uint32_t 
+UdpSocketImpl::GetIpMulticastTtl (void) const
+{
+  return m_ipMulticastTtl;
+}
+
+} //namespace ns3
+
+
+#ifdef RUN_SELF_TESTS
+
+#include "ns3/test.h"
+#include "ns3/socket-factory.h"
+#include "ns3/udp-socket-factory.h"
+#include "ns3/simulator.h"
+#include "ns3/simple-channel.h"
+#include "ns3/simple-net-device.h"
+#include "ns3/drop-tail-queue.h"
+#include "internet-stack.h"
+#include <string>
+
+namespace ns3 {
+
+class UdpSocketImplTest: public Test
+{
+  Ptr<Packet> m_receivedPacket;
+  Ptr<Packet> m_receivedPacket2;
+
+public:
+  virtual bool RunTests (void);
+  UdpSocketImplTest ();
+
+  void ReceivePacket (Ptr<Socket> socket, Ptr<Packet> packet, const Address &from);
+  void ReceivePacket2 (Ptr<Socket> socket, Ptr<Packet> packet, const Address &from);
+  void ReceivePkt (Ptr<Socket> socket);
+  void ReceivePkt2 (Ptr<Socket> socket);
+};
+
+
+UdpSocketImplTest::UdpSocketImplTest ()
+  : Test ("UdpSocketImpl") 
+{
+}
+
+void UdpSocketImplTest::ReceivePacket (Ptr<Socket> socket, Ptr<Packet> packet, const Address &from)
+{
+  m_receivedPacket = packet;
+}
+
+void UdpSocketImplTest::ReceivePacket2 (Ptr<Socket> socket, Ptr<Packet> packet, const Address &from)
+{
+  m_receivedPacket2 = packet;
+}
+
+void UdpSocketImplTest::ReceivePkt (Ptr<Socket> socket)
+{
+  uint32_t availableData;
+  availableData = socket->GetRxAvailable ();
+  m_receivedPacket = socket->Recv (std::numeric_limits<uint32_t>::max(), 0);
+  NS_ASSERT (availableData == m_receivedPacket->GetSize ());
+}
+
+void UdpSocketImplTest::ReceivePkt2 (Ptr<Socket> socket)
+{
+  uint32_t availableData;
+  availableData = socket->GetRxAvailable ();
+  m_receivedPacket2 = socket->Recv (std::numeric_limits<uint32_t>::max(), 0);
+  NS_ASSERT (availableData == m_receivedPacket2->GetSize ());
+}
+
+bool
+UdpSocketImplTest::RunTests (void)
+{
+  bool result = true;
+
+  // Create topology
+  
+  // Receiver Node
+  Ptr<Node> rxNode = CreateObject<Node> ();
+  AddInternetStack (rxNode);
+  Ptr<SimpleNetDevice> rxDev1, rxDev2;
+  { // first interface
+    rxDev1 = CreateObject<SimpleNetDevice> ();
+    rxDev1->SetAddress (Mac48Address::Allocate ());
+    rxNode->AddDevice (rxDev1);
+    Ptr<Ipv4> ipv4 = rxNode->GetObject<Ipv4> ();
+    uint32_t netdev_idx = ipv4->AddInterface (rxDev1);
+    ipv4->SetAddress (netdev_idx, Ipv4Address ("10.0.0.1"));
+    ipv4->SetNetworkMask (netdev_idx, Ipv4Mask (0xffff0000U));
+    ipv4->SetUp (netdev_idx);
+  }
+
+  { // second interface
+    rxDev2 = CreateObject<SimpleNetDevice> ();
+    rxDev2->SetAddress (Mac48Address::Allocate ());
+    rxNode->AddDevice (rxDev2);
+    Ptr<Ipv4> ipv4 = rxNode->GetObject<Ipv4> ();
+    uint32_t netdev_idx = ipv4->AddInterface (rxDev2);
+    ipv4->SetAddress (netdev_idx, Ipv4Address ("10.0.1.1"));
+    ipv4->SetNetworkMask (netdev_idx, Ipv4Mask (0xffff0000U));
+    ipv4->SetUp (netdev_idx);
+  }
+  
+  // Sender Node
+  Ptr<Node> txNode = CreateObject<Node> ();
+  AddInternetStack (txNode);
+  Ptr<SimpleNetDevice> txDev1;
+  {
+    txDev1 = CreateObject<SimpleNetDevice> ();
+    txDev1->SetAddress (Mac48Address::Allocate ());
+    txNode->AddDevice (txDev1);
+    Ptr<Ipv4> ipv4 = txNode->GetObject<Ipv4> ();
+    uint32_t netdev_idx = ipv4->AddInterface (txDev1);
+    ipv4->SetAddress (netdev_idx, Ipv4Address ("10.0.0.2"));
+    ipv4->SetNetworkMask (netdev_idx, Ipv4Mask (0xffff0000U));
+    ipv4->SetUp (netdev_idx);
+  }
+  Ptr<SimpleNetDevice> txDev2;
+  {
+    txDev2 = CreateObject<SimpleNetDevice> ();
+    txDev2->SetAddress (Mac48Address::Allocate ());
+    txNode->AddDevice (txDev2);
+    Ptr<Ipv4> ipv4 = txNode->GetObject<Ipv4> ();
+    uint32_t netdev_idx = ipv4->AddInterface (txDev2);
+    ipv4->SetAddress (netdev_idx, Ipv4Address ("10.0.1.2"));
+    ipv4->SetNetworkMask (netdev_idx, Ipv4Mask (0xffff0000U));
+    ipv4->SetUp (netdev_idx);
+  }
+
+  // link the two nodes
+  Ptr<SimpleChannel> channel1 = CreateObject<SimpleChannel> ();
+  rxDev1->SetChannel (channel1);
+  txDev1->SetChannel (channel1);
+
+  Ptr<SimpleChannel> channel2 = CreateObject<SimpleChannel> ();
+  rxDev2->SetChannel (channel2);
+  txDev2->SetChannel (channel2);
+
+
+  // Create the UDP sockets
+  Ptr<SocketFactory> rxSocketFactory = rxNode->GetObject<UdpSocketFactory> ();
+  Ptr<Socket> rxSocket = rxSocketFactory->CreateSocket ();
+  NS_TEST_ASSERT_EQUAL (rxSocket->Bind (InetSocketAddress (Ipv4Address ("10.0.0.1"), 1234)), 0);
+  rxSocket->SetRecvCallback (MakeCallback (&UdpSocketImplTest::ReceivePkt, this));
+
+  Ptr<Socket> rxSocket2 = rxSocketFactory->CreateSocket ();
+  rxSocket2->SetRecvCallback (MakeCallback (&UdpSocketImplTest::ReceivePkt2, this));
+  NS_TEST_ASSERT_EQUAL (rxSocket2->Bind (InetSocketAddress (Ipv4Address ("10.0.1.1"), 1234)), 0);
+
+  Ptr<SocketFactory> txSocketFactory = txNode->GetObject<UdpSocketFactory> ();
+  Ptr<Socket> txSocket = txSocketFactory->CreateSocket ();
+
+  // ------ Now the tests ------------
+
+  // Unicast test
+  m_receivedPacket = Create<Packet> ();
+  m_receivedPacket2 = Create<Packet> ();
+  NS_TEST_ASSERT_EQUAL (txSocket->SendTo ( Create<Packet> (123), 
+    InetSocketAddress (Ipv4Address("10.0.0.1"), 1234)), 123);
+  Simulator::Run ();
+  NS_TEST_ASSERT_EQUAL (m_receivedPacket->GetSize (), 123);
+  NS_TEST_ASSERT_EQUAL (m_receivedPacket2->GetSize (), 0); // second interface should receive it
+
+  m_receivedPacket->RemoveAllTags ();
+  m_receivedPacket2->RemoveAllTags ();
+
+  // Simple broadcast test
+
+  m_receivedPacket = Create<Packet> ();
+  m_receivedPacket2 = Create<Packet> ();
+  NS_TEST_ASSERT_EQUAL (txSocket->SendTo ( Create<Packet> (123), 
+    InetSocketAddress (Ipv4Address("255.255.255.255"), 1234)), 123);
+  Simulator::Run ();
+  NS_TEST_ASSERT_EQUAL (m_receivedPacket->GetSize (), 123);
+  // second socket should not receive it (it is bound specifically to the second interface's address
+  NS_TEST_ASSERT_EQUAL (m_receivedPacket2->GetSize (), 0);
+
+  m_receivedPacket->RemoveAllTags ();
+  m_receivedPacket2->RemoveAllTags ();
+
+  // Broadcast test with multiple receiving sockets
+
+  // When receiving broadcast packets, all sockets sockets bound to
+  // the address/port should receive a copy of the same packet -- if
+  // the socket address matches.
+  rxSocket2->Dispose ();
+  rxSocket2 = rxSocketFactory->CreateSocket ();
+  rxSocket2->SetRecvCallback (MakeCallback (&UdpSocketImplTest::ReceivePkt2, this));
+  NS_TEST_ASSERT_EQUAL (rxSocket2->Bind (InetSocketAddress (Ipv4Address ("0.0.0.0"), 1234)), 0);
+
+  m_receivedPacket = Create<Packet> ();
+  m_receivedPacket2 = Create<Packet> ();
+  NS_TEST_ASSERT_EQUAL (txSocket->SendTo (Create<Packet> (123),
+InetSocketAddress (Ipv4Address("255.255.255.255"), 1234)), 123);
+  Simulator::Run ();
+  NS_TEST_ASSERT_EQUAL (m_receivedPacket->GetSize (), 123);
+  NS_TEST_ASSERT_EQUAL (m_receivedPacket2->GetSize (), 123);
+
+  m_receivedPacket->RemoveAllTags ();
+  m_receivedPacket2->RemoveAllTags ();
+
+  Simulator::Destroy ();
+
+  return result;
+}
+
+static UdpSocketImplTest gUdpSocketImplTest;
+
+}; // namespace ns3
+
+#endif /* RUN_SELF_TESTS */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/udp-socket-impl.h	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,112 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef UDP_SOCKET_IMPL_H
+#define UDP_SOCKET_IMPL_H
+
+#include <stdint.h>
+#include <queue>
+#include "ns3/callback.h"
+#include "ns3/traced-callback.h"
+#include "ns3/socket.h"
+#include "ns3/ptr.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/udp-socket.h"
+
+namespace ns3 {
+
+class Ipv4EndPoint;
+class Node;
+class Packet;
+class UdpL4Protocol;
+
+class UdpSocketImpl : public UdpSocket
+{
+public:
+  static TypeId GetTypeId (void);
+  /**
+   * Create an unbound udp socket.
+   */
+  UdpSocketImpl ();
+  virtual ~UdpSocketImpl ();
+
+  void SetNode (Ptr<Node> node);
+  void SetUdp (Ptr<UdpL4Protocol> udp);
+
+  virtual enum SocketErrno GetErrno (void) const;
+  virtual Ptr<Node> GetNode (void) const;
+  virtual int Bind (void);
+  virtual int Bind (const Address &address);
+  virtual int Close (void);
+  virtual int ShutdownSend (void);
+  virtual int ShutdownRecv (void);
+  virtual int Connect(const Address &address);
+  virtual int Listen (uint32_t queueLimit);
+  virtual int Send (Ptr<Packet> p);
+  virtual int SendTo (Ptr<Packet> p, const Address &address);
+  virtual uint32_t GetTxAvailable (void) const;
+
+  virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags);
+  virtual uint32_t GetRxAvailable (void) const;
+
+private:
+  // Attributes set through UdpSocket base class 
+  virtual void SetRcvBufSize (uint32_t size);
+  virtual uint32_t GetRcvBufSize (void) const;
+  virtual void SetIpTtl (uint32_t ipTtl);
+  virtual uint32_t GetIpTtl (void) const;
+  virtual void SetIpMulticastTtl (uint32_t ipTtl);
+  virtual uint32_t GetIpMulticastTtl (void) const;
+
+  friend class UdpSocketFactory;
+  // invoked by Udp class
+  int FinishBind (void);
+  void ForwardUp (Ptr<Packet> p, Ipv4Address ipv4, uint16_t port);
+  void Destroy (void);
+  int DoSend (Ptr<Packet> p);
+  int DoSendTo (Ptr<Packet> p, const Address &daddr);
+  int DoSendTo (Ptr<Packet> p, Ipv4Address daddr, uint16_t dport);
+
+  Ipv4EndPoint *m_endPoint;
+  Ptr<Node> m_node;
+  Ptr<UdpL4Protocol> m_udp;
+  Ipv4Address m_defaultAddress;
+  uint16_t m_defaultPort;
+  Callback<void,Ptr<Socket>,uint32_t,const Address &> m_dummyRxCallback;
+  Callback<void,Ptr<Socket>,uint8_t const*,uint32_t,const Address &> m_rxCallback;
+  TracedCallback<Ptr<const Packet> > m_dropTrace;
+
+  enum SocketErrno m_errno;
+  bool m_shutdownSend;
+  bool m_shutdownRecv;
+  bool m_connected;
+
+  std::queue<Ptr<Packet> > m_deliveryQueue;
+  uint32_t m_rxAvailable;
+  
+  // Socket attributes
+  uint32_t m_rcvBufSize;
+  uint32_t m_ipTtl;
+  uint32_t m_ipMulticastTtl;
+
+};
+
+}//namespace ns3
+
+#endif /* UDP_SOCKET_IMPL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/waf	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,1 @@
+exec "`dirname "$0"`"/../../waf "$@"
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/wscript	Wed Jun 11 16:20:04 2008 -0700
@@ -0,0 +1,42 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+
+def build(bld):
+    obj = bld.create_ns3_module('internet-stack', ['node'])
+    obj.source = [
+        'internet-stack.cc',
+        'ipv4-l4-demux.cc',
+        'ipv4-l4-protocol.cc',
+        'udp-header.cc',
+        'tcp-header.cc',
+        'ipv4-checksum.cc',
+        'ipv4-interface.cc',
+        'ipv4-l3-protocol.cc',
+        'ipv4-static-routing.cc',
+        'ipv4-end-point.cc',
+        'udp-l4-protocol.cc',
+        'tcp-l4-protocol.cc',
+        'arp-header.cc',
+        'arp-cache.cc',
+        'arp-ipv4-interface.cc',
+        'arp-l3-protocol.cc',
+        'ipv4-loopback-interface.cc',
+        'udp-socket-impl.cc',
+        'tcp-socket-impl.cc',
+        'ipv4-end-point-demux.cc',
+        'ipv4-impl.cc',
+        'udp-socket-factory-impl.cc',
+        'tcp-socket-factory-impl.cc',
+        'pending-data.cc',
+        'sequence-number.cc',
+        'rtt-estimator.cc',
+        ]
+
+    headers = bld.create_obj('ns3header')
+    headers.module = 'internet-stack'
+    headers.source = [
+        'internet-stack.h',
+        'udp-header.h',
+        'tcp-header.h',
+        'sequence-number.h',
+        ]
--- a/src/node/ipv4.h	Wed Jun 11 16:19:28 2008 -0700
+++ b/src/node/ipv4.h	Wed Jun 11 16:20:04 2008 -0700
@@ -74,7 +74,7 @@
   typedef Callback<void, bool, const Ipv4Route&, Ptr<Packet>, const Ipv4Header&> RouteReplyCallback;
 
   /**
-   * \brief Asynchronously requests a route for a given packet and IP header
+   * \brief Request that a packet be routed.
    *
    * \param ifIndex The interface index on which the packet was received.
    * \param ipHeader IP header of the packet
@@ -94,7 +94,7 @@
    * RequestRoute() should return false and the routeReply callback
    * must not be invoked.
    *
-   * If the routing protocol implementations assumes it can provide
+   * If the routing protocol implementation assumes that it can provide
    * the requested route, then it should return true, and the
    * routeReply callback must be invoked, either immediately before
    * returning true (synchronously), or in the future (asynchronous).
@@ -105,6 +105,11 @@
    * allowed to add a new header to the packet, which will appear
    * immediately after the IP header, although most routing do not
    * insert any extra header.
+   *
+   * Multicast routing is expected to be supported in this method.  If a
+   * multicast route is encountered, all routes to a given multicast
+   * destination will be serviced by cloning the packet and calling the 
+   * route reply callback once for each outgoing interface in the route.
    */
   virtual bool RequestRoute (uint32_t ifIndex,
                              const Ipv4Header &ipHeader,
--- a/src/node/socket.cc	Wed Jun 11 16:19:28 2008 -0700
+++ b/src/node/socket.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -40,6 +40,13 @@
   NS_LOG_FUNCTION_NOARGS ();
 }
 
+void
+Socket::SetCloseUnblocksCallback (Callback<void,Ptr<Socket> > closeUnblocks)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_closeUnblocks = closeUnblocks;
+}
+
 Ptr<Socket> 
 Socket::CreateSocket (Ptr<Node> node, TypeId tid)
 {
@@ -103,6 +110,21 @@
   m_receivedData = receivedData;
 }
 
+void
+Socket::NotifyCloseUnblocks (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  if (!m_closeUnblocks.IsNull ())
+  {
+    m_closeUnblocks (this);
+  }
+}
+
+int Socket::Listen (uint32_t queueLimit)
+{
+  return 0; //XXX the base class version does nothing
+}
+
 int Socket::Send (const uint8_t* buf, uint32_t size)
 {
   NS_LOG_FUNCTION_NOARGS ();
--- a/src/node/socket.h	Wed Jun 11 16:19:28 2008 -0700
+++ b/src/node/socket.h	Wed Jun 11 16:20:04 2008 -0700
@@ -105,6 +105,8 @@
    */
   virtual Ptr<Node> GetNode (void) const = 0;
 
+  void SetCloseUnblocksCallback (Callback<void, Ptr<Socket> > closeUnblocks);
+
   /**
    * \param closeCompleted Callback invoked when the close operation is
    *        completed.
@@ -362,6 +364,7 @@
   virtual uint32_t GetRxAvailable (void) const = 0;
  
 protected:
+  void NotifyCloseUnblocks (void);
   void NotifyCloseCompleted (void);
   void NotifyConnectionSucceeded (void);
   void NotifyConnectionFailed (void);
@@ -373,6 +376,7 @@
   void NotifySend (uint32_t spaceAvailable);
   void NotifyDataRecv (void);
 
+  Callback<void, Ptr<Socket> >   m_closeUnblocks;
   Callback<void,Ptr<Socket> >    m_closeCompleted;
   Callback<void, Ptr<Socket> >   m_connectionSucceeded;
   Callback<void, Ptr<Socket> >   m_connectionFailed;
--- a/src/routing/olsr/wscript	Wed Jun 11 16:19:28 2008 -0700
+++ b/src/routing/olsr/wscript	Wed Jun 11 16:20:04 2008 -0700
@@ -1,7 +1,7 @@
 ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
 
 def build(bld):
-    module = bld.create_ns3_module('olsr', ['internet-node', 'contrib'])
+    module = bld.create_ns3_module('olsr', ['internet-stack', 'contrib'])
     module.includes = '.'
     module.source = [
         'olsr-header.cc',
--- a/src/wscript	Wed Jun 11 16:19:28 2008 -0700
+++ b/src/wscript	Wed Jun 11 16:20:04 2008 -0700
@@ -16,7 +16,7 @@
     'simulator',
     'contrib',
     'node',
-    'internet-node',
+    'internet-stack',
     'devices/point-to-point',
     'devices/csma',
     'applications/onoff',
--- a/tutorial/tutorial-bus-network.cc	Wed Jun 11 16:19:28 2008 -0700
+++ b/tutorial/tutorial-bus-network.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -40,7 +40,7 @@
   internet.Install (n);
 
   CsmaHelper csma;
-  csma.SetChannelParameter ("BitRate", StringValue ("10Mbps"));
+  csma.SetChannelParameter ("DataRate", StringValue ("10Mbps"));
   csma.SetChannelParameter ("Delay", StringValue ("10ms"));
   NetDeviceContainer nd = csma.Install (n);
 
--- a/tutorial/tutorial-csma-echo-ascii-trace.cc	Wed Jun 11 16:19:28 2008 -0700
+++ b/tutorial/tutorial-csma-echo-ascii-trace.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -38,7 +38,7 @@
   internet.Install (n);
 
   CsmaHelper csma;
-  csma.SetChannelParameter ("BitRate", StringValue ("5Mpbs"));
+  csma.SetChannelParameter ("DataRate", StringValue ("5Mpbs"));
   csma.SetChannelParameter ("Delay", StringValue ("2ms"));
   NetDeviceContainer nd = csma.Install (n);
 
--- a/tutorial/tutorial-csma-echo-pcap-trace.cc	Wed Jun 11 16:19:28 2008 -0700
+++ b/tutorial/tutorial-csma-echo-pcap-trace.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -36,7 +36,7 @@
   internet.Install (n);
 
   CsmaHelper csma;
-  csma.SetChannelParameter ("BitRate", StringValue ("5Mbps"));
+  csma.SetChannelParameter ("DataRate", StringValue ("5Mbps"));
   csma.SetChannelParameter ("Delay", StringValue ("2ms"));
   NetDeviceContainer nd = csma.Install (n);
 
--- a/tutorial/tutorial-csma-echo.cc	Wed Jun 11 16:19:28 2008 -0700
+++ b/tutorial/tutorial-csma-echo.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -36,7 +36,7 @@
   internet.Install (n);
 
   CsmaHelper csma;
-  csma.SetChannelParameter ("BitRate", StringValue ("5Mbps"));
+  csma.SetChannelParameter ("DataRate", StringValue ("5Mbps"));
   csma.SetChannelParameter ("Delay", StringValue ("2ms"));
   NetDeviceContainer nd = csma.Install (n);
 
--- a/tutorial/tutorial-linear-dumbbell.cc	Wed Jun 11 16:19:28 2008 -0700
+++ b/tutorial/tutorial-linear-dumbbell.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -53,7 +53,7 @@
   internet.Install (lan1);
 
   CsmaHelper csma;
-  csma.SetChannelParameter ("BitRate", StringValue ("10Mbps"));
+  csma.SetChannelParameter ("DataRate", StringValue ("10Mbps"));
   csma.SetChannelParameter ("Delay", StringValue ("2ms"));
   NetDeviceContainer dev1 = csma.Install (lan1);
   Ipv4AddressHelper ipv4;
@@ -78,7 +78,7 @@
 //
   NodeContainer backbone = NodeContainer (lan1.Get (3), lan2.Get (0));
   PointToPointHelper p2p;
-  p2p.SetChannelParameter ("BitRate", StringValue ("38400bps"));
+  p2p.SetChannelParameter ("DataRate", StringValue ("38400bps"));
   p2p.SetChannelParameter ("Delay", StringValue ("20ms"));
   NetDeviceContainer dev3 = p2p.Install (backbone);
   ipv4.SetBase ("10.1.3.0", "255.255.255.0");
--- a/tutorial/tutorial-point-to-point.cc	Wed Jun 11 16:19:28 2008 -0700
+++ b/tutorial/tutorial-point-to-point.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -45,7 +45,7 @@
   internet.Install (n);
 
   PointToPointHelper p2p;
-  p2p.SetChannelParameter ("BitRate", StringValue ("38400bps"));
+  p2p.SetDeviceParameter ("DataRate", StringValue ("38400bps"));
   p2p.SetChannelParameter ("Delay", StringValue ("20ms"));
   NetDeviceContainer nd = p2p.Install (n);
 
--- a/tutorial/tutorial-star-routing.cc	Wed Jun 11 16:19:28 2008 -0700
+++ b/tutorial/tutorial-star-routing.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -56,7 +56,7 @@
   internet.Install (n);
 
   PointToPointHelper p2p;
-  p2p.SetChannelParameter ("BitRate", StringValue ("38400bps"));
+  p2p.SetDeviceParameter ("DataRate", StringValue ("38400bps"));
   p2p.SetChannelParameter ("Delay", StringValue ("20ms"));
 
   NetDeviceContainer d01 = p2p.Install (n01);
--- a/tutorial/tutorial-star.cc	Wed Jun 11 16:19:28 2008 -0700
+++ b/tutorial/tutorial-star.cc	Wed Jun 11 16:20:04 2008 -0700
@@ -55,7 +55,7 @@
   internet.Install (n);
 
   PointToPointHelper p2p;
-  p2p.SetChannelParameter ("BitRate", StringValue ("38400bps"));
+  p2p.SetDeviceParameter ("DataRate", StringValue ("38400bps"));
   p2p.SetChannelParameter ("Delay", StringValue ("20ms"));
 
   NetDeviceContainer d01 = p2p.Install (n01);
--- a/tutorial/wscript	Wed Jun 11 16:19:28 2008 -0700
+++ b/tutorial/wscript	Wed Jun 11 16:20:04 2008 -0700
@@ -4,29 +4,29 @@
     obj = bld.create_ns3_program('hello-simulator', ['simulator'])
     obj.source = 'hello-simulator.cc'
 
-    obj = bld.create_ns3_program('tutorial-csma-echo', ['internet-node', 'csma'])
+    obj = bld.create_ns3_program('tutorial-csma-echo', ['internet-stack', 'csma'])
     obj.source = 'tutorial-csma-echo.cc'
 
-    obj = bld.create_ns3_program('tutorial-csma-echo-ascii-trace', ['internet-node', 'csma'])
+    obj = bld.create_ns3_program('tutorial-csma-echo-ascii-trace', ['internet-stack', 'csma'])
     obj.source = 'tutorial-csma-echo-ascii-trace.cc'
 
-    obj = bld.create_ns3_program('tutorial-csma-echo-pcap-trace', ['internet-node', 'csma'])
+    obj = bld.create_ns3_program('tutorial-csma-echo-pcap-trace', ['internet-stack', 'csma'])
     obj.source = 'tutorial-csma-echo-pcap-trace.cc'
 
-    obj = bld.create_ns3_program('tutorial-point-to-point', ['internet-node', 'point-to-point'])
+    obj = bld.create_ns3_program('tutorial-point-to-point', ['internet-stack', 'point-to-point'])
     obj.source = 'tutorial-point-to-point.cc'
 
-    obj = bld.create_ns3_program('tutorial-star', ['internet-node', 'point-to-point'])
+    obj = bld.create_ns3_program('tutorial-star', ['internet-stack', 'point-to-point'])
     obj.source = ['tutorial-star.cc']
 
-    obj = bld.create_ns3_program('tutorial-star-routing', ['internet-node', 'point-to-point'])
+    obj = bld.create_ns3_program('tutorial-star-routing', ['internet-stack', 'point-to-point'])
     obj.source = ['tutorial-star-routing.cc']
 
-    obj = bld.create_ns3_program('tutorial-linear-dumbbell', ['internet-node', 'point-to-point'])
+    obj = bld.create_ns3_program('tutorial-linear-dumbbell', ['internet-stack', 'point-to-point'])
     obj.source = 'tutorial-linear-dumbbell.cc'
 
     obj = bld.create_ns3_program('testipv4', ['node'])
     obj.source = ['testipv4.cc']
 
-    obj = bld.create_ns3_program('tutorial-bus-network', ['internet-node'])
+    obj = bld.create_ns3_program('tutorial-bus-network', ['internet-stack'])
     obj.source = ['tutorial-bus-network.cc']
--- a/utils/wscript	Wed Jun 11 16:19:28 2008 -0700
+++ b/utils/wscript	Wed Jun 11 16:20:04 2008 -0700
@@ -28,14 +28,14 @@
     obj.source = 'replay-simulation.cc'
 
     obj = bld.create_ns3_program('print-introspected-doxygen',
-                                 ['internet-node', 'csma-cd', 'point-to-point'])
+                                 ['internet-stack', 'csma-cd', 'point-to-point'])
     obj.source = 'print-introspected-doxygen.cc'
 
 # XXX: disable mobility visualizer code temporarily.
     env['ENABLE_MOBILITY_VISUALIZER'] = ''
     if env['ENABLE_MOBILITY_VISUALIZER']:
         obj = bld.create_ns3_program('mobility-visualizer',
-                                     ['internet-node', 'mobility'])
+                                     ['internet-stack', 'mobility'])
         obj.source = ['mobility-visualizer-model.cc', 'mobility-visualizer-view.cc']
         obj.uselib = 'MOBILITY_VISUALIZER'
         if os.path.basename(obj.env['CXX']).startswith("g++"):