NS-3 Click Integration merge
authorLalith Suresh <suresh.lalith@gmail.com>
Wed, 23 Feb 2011 17:50:31 +0000
changeset 6826 943a8b1adb26
parent 6825 f9a45d9a10d0
child 6827 a408d1944763
NS-3 Click Integration merge
src/routing/click/doc/click.h
src/routing/click/examples/nsclick-ip-router.click
src/routing/click/examples/nsclick-lan-single-interface.click
src/routing/click/examples/nsclick-raw-wlan.cc
src/routing/click/examples/nsclick-routing-node0.click
src/routing/click/examples/nsclick-routing-node2.click
src/routing/click/examples/nsclick-routing.cc
src/routing/click/examples/nsclick-simple-lan.cc
src/routing/click/examples/nsclick-udp-client-server-csma.cc
src/routing/click/examples/nsclick-udp-client-server-wifi.cc
src/routing/click/examples/nsclick-wifi-single-interface.click
src/routing/click/examples/wscript
src/routing/click/helper/click-internet-stack-helper.cc
src/routing/click/helper/click-internet-stack-helper.h
src/routing/click/model/ipv4-click-routing.cc
src/routing/click/model/ipv4-click-routing.h
src/routing/click/model/ipv4-l3-click-protocol.cc
src/routing/click/model/ipv4-l3-click-protocol.h
src/routing/click/test/ipv4-click-routing-test.cc
src/routing/click/waf
src/routing/click/wscript
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/click/doc/click.h	Wed Feb 23 17:50:31 2011 +0000
@@ -0,0 +1,106 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 Lalith Suresh 
+ *
+ * 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: Lalith Suresh <suresh.lalith@gmail.com>
+ */
+
+/**
+* \ingroup routing
+* \defgroup click Click
+*
+* \section model Model
+*
+* This model implements the interface to the Click Modular Router and
+* provides the Ipv4ClickRouting class to allow a node to use Click 
+* for external routing. Unlike normal Ipv4RoutingProtocol sub types,
+* Ipv4ClickRouting doesn't use a RouteInput() method, but instead, 
+* receives a packet on the appropriate interface and processes it 
+* accordingly. Note that you need to have a routing table type element 
+* in your Click graph to use Click for external routing. This is needed
+* by the RouteOutput() function inherited from Ipv4RoutingProtocol.
+* Furthermore, a Click based node uses a different kind of L3 in the
+* form of Ipv4L3ClickProtocol, which is a trimmed down version of
+* Ipv4L3Protocol. Ipv4L3ClickProtocol passes on packets passing through
+* the stack to Ipv4ClickRouting for processing.
+*
+* \section build Build Instructions
+*
+* The first step is to build Click. At the top of your Click source directory:
+*
+*   $: ./configure --enable-userlevel --disable-linuxmodule --enable-nsclick --enable-wifi
+*   $: make
+* 
+* The --enable wifi flag can be skipped in case you don't intend on using
+* Click with Wifi.
+* *Note: You don't need to do a 'make install'.
+*
+* Once Click has been built successfully, we proceed to configure ns-3 with 
+* Click Integration support:
+*
+*   $: ./waf configure --with-nsclick=/path/to/click/source
+*
+* If it says 'enabled' beside 'NS-3 Click Integration Support', then you're 
+* good to go.
+*
+* Next, try running one of the examples:
+*
+*   $: ./waf --run nsclick-simple-lan
+*
+* You will find a lot of output being generated. This is because of the 
+* IPPrint and Print elements present in the nsclick-simple-lan.click 
+* configuration file that the example script uses. 
+*
+* \section clickgraph Click Graph Instructions
+*
+* The following should be kept in mind when making your Click graph:
+*   - Only userlevel elements can be used.
+*   - You will need to replace FromDevice and ToDevice elements 
+*     with FromSimDevice and ToSimDevice elements.
+*   - Packets to the kernel are sent up using ToSimDevice(tap0,IP).
+*   - For any node, the 0th device will be tap0. The remaining devices 
+*     should be eth0, eth1 and so forth (even if you're using wifi). 
+*     Please note that the device numbering should begin from 0.
+*   - A routing table element is a mandatory. The OUTports of the routing 
+*     table element should correspond to the interface number of the device 
+*     through which the packet will ultimately be sent out. Violating this 
+*     rule will lead to really weird packet traces. This routing table element's 
+*     name should then be passed to the Ipv4ClickRouting protocol object as 
+*     a simulation parameter. See the Click examples for details.
+*   - When using Wifi with ns-3-click, do not use wifi specific elements like 
+*     WifiEncap, ExtraEncap, MadWifiRate etc. for outgoing packets. Incoming 
+*     packets should have their Wifi headers removed using WifiDecap + ExtraDecap 
+*     or Strip elements. See the nsclick-raw-wlan.click file for an idea of the same.
+*   - The current implementation leaves Click with mainly L3 functionality, 
+*     with ns-3 handling L2. We will soon begin working to support the use of 
+*     MAC protocols on Click as well.
+*
+* \section usage Usage
+*
+* To have a node run Click, the easiest way would be to use the ClickInternetStackHelper 
+* class in your simulation script. For instance:
+*
+*   ClickInternetStackHelper click;
+*   click.SetClickFile (myNodeContainer, "nsclick-simple-lan.click");
+*   click.SetRoutingTableElement (myNodeContainer, "u/rt");
+*   click.Install (myNodeContainer);
+* 
+* The example scripts inside examples/click/ demonstrate the use of Click based 
+* nodes in different scenarios.
+*
+*
+*/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/click/examples/nsclick-ip-router.click	Wed Feb 23 17:50:31 2011 +0000
@@ -0,0 +1,82 @@
+// Generated by make-ip-conf.pl
+// eth0 172.16.1.2 00:00:00:00:00:02
+// eth1 172.16.2.1 00:00:00:00:00:03
+
+elementclass IPRouter {
+  $myaddr1, $myaddr_ethernet1, $myaddr2, $myaddr_ethernet2 |
+
+// Shared IP input path and routing table
+ip :: Strip(14)
+    -> CheckIPHeader2(INTERFACES 172.16.1.2/255.255.255.0 172.16.2.1/255.255.255.0)
+    -> rt :: StaticIPLookup(
+	172.16.1.2/32 0,
+	172.16.1.255/32 0,
+	172.16.1.0/32 0,
+	172.16.2.1/32 0,
+	172.16.2.255/32 0,
+	172.16.2.0/32 0,
+	172.16.1.0/255.255.255.0 1,
+	172.16.2.0/255.255.255.0 2,
+	255.255.255.255/32 0.0.0.0 0,
+	0.0.0.0/32 0,
+	0.0.0.0/0.0.0.0 18.26.4.1 1);
+
+// ARP responses are copied to each ARPQuerier and the host.
+arpt :: Tee(3);
+
+// Input and output paths for eth0
+c0 :: Classifier(12/0806 20/0001, 12/0806 20/0002, 12/0800, -);
+FromSimDevice(eth0, 4096) -> c0;
+out0 :: Queue(200) -> todevice0 :: ToSimDevice(eth0);
+c0[0] -> ar0 :: ARPResponder(eth0) -> out0;
+arpq0 :: ARPQuerier(eth0) -> out0;
+c0[1] -> arpt;
+arpt[0] -> [1]arpq0;
+c0[2] -> Paint(1) -> ip;
+c0[3] -> Discard;
+
+// Input and output paths for eth1
+c1 :: Classifier(12/0806 20/0001, 12/0806 20/0002, 12/0800, -);
+FromSimDevice(eth1, 4096) -> c1;
+out1 :: Queue(200) -> todevice1 :: ToSimDevice(eth1);
+c1[0] -> ar1 :: ARPResponder(eth0) -> out1;
+arpq1 :: ARPQuerier(eth1) -> out1;
+c1[1] -> arpt;
+arpt[1] -> [1]arpq1;
+c1[2] -> Paint(2) -> ip;
+c1[3] -> Discard;
+
+// Local delivery
+//toh :: ToSimDevice(tap0,IP);
+arpt[2] -> Discard;
+rt[0] -> Discard;
+
+// Forwarding path for eth0
+rt[1] -> DropBroadcasts
+    -> cp0 :: PaintTee(1)
+    -> gio0 :: IPGWOptions($myaddr1)
+    -> FixIPSrc($myaddr1)
+    -> dt0 :: DecIPTTL
+    -> fr0 :: IPFragmenter(1500)
+    -> [0]arpq0;
+dt0[1] -> ICMPError($myaddr1, timeexceeded) -> rt;
+fr0[1] -> ICMPError($myaddr1, unreachable, needfrag) -> rt;
+gio0[1] -> ICMPError($myaddr1, parameterproblem) -> rt;
+cp0[1] -> ICMPError($myaddr1, redirect, host) -> rt;
+
+// Forwarding path for eth1
+rt[2] -> DropBroadcasts
+    -> cp1 :: PaintTee(2)
+    -> gio1 :: IPGWOptions($myaddr2)
+    -> FixIPSrc($myaddr2)
+    -> dt1 :: DecIPTTL
+    -> fr1 :: IPFragmenter(1500)
+    -> [0]arpq1;
+dt1[1] -> ICMPError($myaddr2, timeexceeded) -> rt;
+fr1[1] -> ICMPError($myaddr2, unreachable, needfrag) -> rt;
+gio1[1] -> ICMPError($myaddr2, parameterproblem) -> rt;
+cp1[1] -> ICMPError($myaddr2, redirect, host) -> rt;
+
+}
+
+u :: IPRouter(eth0,eth0,eth1,eth1);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/click/examples/nsclick-lan-single-interface.click	Wed Feb 23 17:50:31 2011 +0000
@@ -0,0 +1,113 @@
+// nsclick-lan-single-interface.click
+//
+// Copyright (c) 2011, Deutsche Telekom Laboratories
+//
+// 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: Ruben Merz <ruben@net.t-labs.tu-berlin.de>
+//
+// This is a single host Click configuration for a LAN.
+// The node broadcasts ARP requests if it wants to find a destination
+// address, and it responds to ARP requests made for it.
+
+elementclass LanSimHost {
+  $ipaddr, $hwaddr |
+
+  cl::Classifier(12/0806 20/0001,12/0806 20/0002, -);
+  forhost::IPClassifier(dst host $ipaddr,-);
+  arpquerier::ARPQuerier(eth0);
+  arpresponder::ARPResponder(eth0);
+
+  ethout::Queue 	
+    -> ToDump(out_eth0.pcap,PER_NODE 1)
+    -> ToSimDevice(eth0);
+
+  // All packets received on eth0 are silently
+  // dropped if they are destined for another location
+  FromSimDevice(eth0,4096)
+    -> ToDump(in_eth0.pcap,PER_NODE 1,ENCAP ETHER)
+    -> cl;
+
+  // ARP queries from other nodes go to the ARP responder element
+  cl[0] -> arpresponder;
+
+  // ARP responses go to our ARP query element
+  cl[1] -> [1]arpquerier;
+
+  // All other packets get checked whether they are meant for us
+  cl[2]				
+    -> Strip(14)
+    -> CheckIPHeader2
+    -> MarkIPHeader
+    -> GetIPAddress(16) // Sets destination IP address annotation from packet data
+    -> forhost; 
+
+  // Packets for us are pushed outside
+  forhost[0]
+    ->[0]output;
+
+  // Packets for other folks or broadcast packets get sent to output 1
+  forhost[1]
+    -> ToDump(discard.pcap,2000,PER_NODE 1,ENCAP IP)
+    -> [1]output;
+
+  // Incoming packets get pushed into the ARP query module
+  input[0]
+    -> arpquerier;
+
+  // Both the ARP query and response modules send data out to
+  // the simulated network device, eth0.
+  arpquerier
+    -> ToDump(out_arpquery.pcap,PER_NODE 1)
+    -> ethout;
+
+  arpresponder
+    -> ToDump(out_arprespond.pcap,PER_NODE 1)
+    -> ethout;
+
+}
+
+elementclass TapSimHost {
+  $dev |
+
+  // Packets go to "tap0" which sends them to the kernel
+  input[0]
+    -> ToDump(tokernel.pcap,2000,IP,PER_NODE 1) 
+    -> ToSimDevice($dev,IP);
+
+  // Packets sent out by the "kernel" get pushed outside
+  FromSimDevice($dev,4096)
+    -> CheckIPHeader2
+    -> ToDump(fromkernel.pcap,2000,IP,PER_NODE 1)
+    -> GetIPAddress(16)
+    -> [0]output;
+}
+
+// Instantiate elements
+lan::LanSimHost(eth0:ip,eth0:eth);
+kernel::TapSimHost(tap0);
+
+// Users can do some processing between the two elements
+lan[0] -> kernel;
+kernel -> lan;
+// Packets for others or broadcasts are discarded
+lan[1] -> Discard;
+
+// It is mandatory to use an IPRouteTable element with ns-3-click
+// (but we do not use it in this example)
+rt :: LinearIPLookup (172.16.1.0/24 0.0.0.0 1);
+// We are actually not using the routing table
+Idle () -> rt;
+rt[0] -> Discard;
+rt[1] -> Discard;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/click/examples/nsclick-raw-wlan.cc	Wed Feb 23 17:50:31 2011 +0000
@@ -0,0 +1,142 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * 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: Lalith Suresh <suresh.lalith@gmail.com>
+ */
+
+// Scenario: node A (using Click) sends packets to node B (not using
+// Click)
+//
+//  (Click)             (non-Click)
+//    A )))     WLAN      ((( B
+// (172.16.1.1)         (172.16.1.2)   
+//    (eth0)
+//
+
+#include "ns3/core-module.h"
+#include "ns3/network-module.h"
+#include "ns3/helper-module.h"
+#include "ns3/click-internet-stack-helper.h"
+#include "ns3/log.h"
+
+using namespace ns3;
+
+void ReceivePacket (Ptr<Socket> socket)
+{
+  NS_LOG_UNCOND ("Received one packet!");
+}
+
+int main (int argc, char *argv[])
+{
+#ifdef NS3_CLICK
+  double rss = -80;
+  Time interPacketInterval = Seconds(1.0);
+
+  // Setup nodes
+  NodeContainer wifiNodes;
+  wifiNodes.Create (2);
+
+  // Get Wifi devices installed on both nodes.
+  // Adapted from examples/wireless/wifi-simple-adhoc.cc
+  std::string phyMode ("DsssRate1Mbps");
+
+  // disable fragmentation for frames below 2200 bytes
+  Config::SetDefault ("ns3::WifiRemoteStationManager::FragmentationThreshold", StringValue ("2200"));
+  // turn off RTS/CTS for frames below 2200 bytes
+  Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue ("2200"));
+  // Fix non-unicast data rate to be the same as that of unicast
+  Config::SetDefault ("ns3::WifiRemoteStationManager::NonUnicastMode",
+                      StringValue (phyMode));
+
+  WifiHelper wifi;
+  wifi.SetStandard (WIFI_PHY_STANDARD_80211b);
+
+  YansWifiPhyHelper wifiPhy =  YansWifiPhyHelper::Default ();
+  // This is one parameter that matters when using FixedRssLossModel
+  // set it to zero; otherwise, gain will be added
+  wifiPhy.Set ("RxGain", DoubleValue (0) );
+  // ns-3 supports RadioTap and Prism tracing extensions for 802.11b
+  wifiPhy.SetPcapDataLinkType (YansWifiPhyHelper::DLT_IEEE802_11_RADIO);
+
+  YansWifiChannelHelper wifiChannel ;
+  wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
+  // The below FixedRssLossModel will cause the rss to be fixed regardless
+  // of the distance between the two stations, and the transmit power
+  wifiChannel.AddPropagationLoss ("ns3::FixedRssLossModel","Rss",DoubleValue(rss));
+  wifiPhy.SetChannel (wifiChannel.Create ());
+
+  // Add a non-QoS upper mac, and disable rate control
+  NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
+  wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
+                                "DataMode",StringValue(phyMode),
+                                   "ControlMode",StringValue(phyMode));
+  // Set it to adhoc mode
+  wifiMac.SetType ("ns3::AdhocWifiMac");
+  NetDeviceContainer wifiDevices = wifi.Install (wifiPhy, wifiMac, wifiNodes);
+
+  // Setup mobility models
+  MobilityHelper mobility;
+  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
+  positionAlloc->Add (Vector (0.0, 0.0, 0.0));
+  positionAlloc->Add (Vector (5.0, 0.0, 0.0));
+  mobility.SetPositionAllocator (positionAlloc);
+  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
+  mobility.Install (wifiNodes); 
+
+  // Install normal internet stack on node B
+  InternetStackHelper internet;
+  internet.Install (wifiNodes.Get (1));
+
+  // Install Click on node A
+  ClickInternetStackHelper clickinternet;
+  clickinternet.SetClickFile (wifiNodes.Get (0), "src/routing/click/examples/nsclick-wifi-single-interface.click");
+  clickinternet.SetRoutingTableElement(wifiNodes.Get (0), "rt");
+  clickinternet.Install (wifiNodes.Get (0));
+
+  // Configure IP addresses
+  Ipv4AddressHelper ipv4;
+  ipv4.SetBase ("172.16.1.0", "255.255.255.0");
+  ipv4.Assign (wifiDevices);
+
+  // Setup traffic application and sockets
+  Address LocalAddress (InetSocketAddress (Ipv4Address::GetAny (), 50000));
+  PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", LocalAddress);
+  ApplicationContainer recvapp = packetSinkHelper.Install (wifiNodes.Get (1));
+  recvapp.Start (Seconds (5.0));
+  recvapp.Stop (Seconds (10.0));
+
+  OnOffHelper onOffHelper ("ns3::TcpSocketFactory", Address ());
+  onOffHelper.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
+  onOffHelper.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
+
+  ApplicationContainer appcont;
+
+  AddressValue remoteAddress (InetSocketAddress (Ipv4Address ("172.16.1.2"), 50000));
+  onOffHelper.SetAttribute ("Remote", remoteAddress);
+  appcont.Add (onOffHelper.Install (wifiNodes.Get (0)));
+
+  appcont.Start (Seconds (5.0));
+  appcont.Stop (Seconds (10.0));
+
+  // For tracing
+  wifiPhy.EnablePcap ("nsclick-raw-wlan", wifiDevices);
+
+  Simulator::Stop (Seconds(20.0));
+  Simulator::Run();
+  return 0;
+#else
+  NS_FATAL_ERROR ("Can't use ns-3-click without NSCLICK compiled in");
+#endif
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/click/examples/nsclick-routing-node0.click	Wed Feb 23 17:50:31 2011 +0000
@@ -0,0 +1,112 @@
+// nsclick-lan-single-interface.click
+//
+// Copyright (c) 2011, Deutsche Telekom Laboratories
+//
+// 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: Ruben Merz <ruben@net.t-labs.tu-berlin.de>
+//
+// This is a single host Click configuration for a LAN.
+// The node broadcasts ARP requests if it wants to find a destination
+// address, and it responds to ARP requests made for it.
+
+elementclass LanSimHost {
+  $ipaddr, $hwaddr |
+
+  cl::Classifier(12/0806 20/0001,12/0806 20/0002, -);
+  forhost::IPClassifier(dst host $ipaddr,-);
+  arpquerier::ARPQuerier(eth0);
+  arpresponder::ARPResponder(eth0);
+
+  ethout::Queue 	
+    -> ToDump(out_eth0.pcap,PER_NODE 1)
+    -> ToSimDevice(eth0);
+
+  // All packets received on eth0 are silently
+  // dropped if they are destined for another location
+  FromSimDevice(eth0,4096)
+    -> ToDump(in_eth0.pcap,PER_NODE 1,ENCAP ETHER)
+    -> cl;
+
+  // ARP queries from other nodes go to the ARP responder element
+  cl[0] -> arpresponder;
+
+  // ARP responses go to our ARP query element
+  cl[1] -> [1]arpquerier;
+
+  // All other packets get checked whether they are meant for us
+  cl[2]				
+    -> Strip(14)
+    -> CheckIPHeader2
+    -> MarkIPHeader
+    -> GetIPAddress(16) // Sets destination IP address annotation from packet data
+    -> forhost; 
+
+  // Packets for us are pushed outside
+  forhost[0]
+    ->[0]output;
+
+  // Packets for other folks or broadcast packets get sent to output 1
+  forhost[1]
+    -> ToDump(discard.pcap,2000,PER_NODE 1,ENCAP IP)
+    -> [1]output;
+
+  // Incoming packets get pushed into the ARP query module
+  input[0]
+    -> arpquerier;
+
+  // Both the ARP query and response modules send data out to
+  // the simulated network device, eth0.
+  arpquerier
+    -> ToDump(out_arpquery.pcap,PER_NODE 1)
+    -> ethout;
+
+  arpresponder
+    -> ToDump(out_arprespond.pcap,PER_NODE 1)
+    -> ethout;
+
+}
+
+elementclass TapSimHost {
+  $dev |
+
+  // It is mandatory to use an IPRouteTable element with ns-3-click
+  rt :: LinearIPLookup (172.16.1.0/24 0.0.0.0 1, 172.16.2.0/24 172.16.1.2 1);
+
+  // Packets go to "tap0" which sends them to the kernel
+  input[0]
+    -> ToDump(tokernel.pcap,2000,IP,PER_NODE 1) 
+    -> ToSimDevice($dev,IP);
+
+  // Packets sent out by the "kernel" get pushed outside
+  FromSimDevice($dev,4096)
+    -> CheckIPHeader2
+    -> ToDump(fromkernel.pcap,2000,IP,PER_NODE 1)
+    -> GetIPAddress(16)
+    -> rt
+    -> [0]output;
+
+  rt[1] -> [0] output;
+}
+
+// Instantiate elements
+lan::LanSimHost(eth0:ip,eth0:eth);
+kernel::TapSimHost(tap0);
+
+// Users can do some processing between the two elements
+lan[0] -> kernel;
+kernel -> lan;
+// Packets for others or broadcasts are discarded
+lan[1] -> Discard;
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/click/examples/nsclick-routing-node2.click	Wed Feb 23 17:50:31 2011 +0000
@@ -0,0 +1,112 @@
+// nsclick-lan-single-interface.click
+//
+// Copyright (c) 2011, Deutsche Telekom Laboratories
+//
+// 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: Ruben Merz <ruben@net.t-labs.tu-berlin.de>
+//
+// This is a single host Click configuration for a LAN.
+// The node broadcasts ARP requests if it wants to find a destination
+// address, and it responds to ARP requests made for it.
+
+elementclass LanSimHost {
+  $ipaddr, $hwaddr |
+
+  cl::Classifier(12/0806 20/0001,12/0806 20/0002, -);
+  forhost::IPClassifier(dst host $ipaddr,-);
+  arpquerier::ARPQuerier(eth0);
+  arpresponder::ARPResponder(eth0);
+
+  ethout::Queue 	
+    -> ToDump(out_eth0.pcap,PER_NODE 1)
+    -> ToSimDevice(eth0);
+
+  // All packets received on eth0 are silently
+  // dropped if they are destined for another location
+  FromSimDevice(eth0,4096)
+    -> ToDump(in_eth0.pcap,PER_NODE 1,ENCAP ETHER)
+    -> cl;
+
+  // ARP queries from other nodes go to the ARP responder element
+  cl[0] -> arpresponder;
+
+  // ARP responses go to our ARP query element
+  cl[1] -> [1]arpquerier;
+
+  // All other packets get checked whether they are meant for us
+  cl[2]				
+    -> Strip(14)
+    -> CheckIPHeader2
+    -> MarkIPHeader
+    -> GetIPAddress(16) // Sets destination IP address annotation from packet data
+    -> forhost; 
+
+  // Packets for us are pushed outside
+  forhost[0]
+    ->[0]output;
+
+  // Packets for other folks or broadcast packets get sent to output 1
+  forhost[1]
+    -> ToDump(discard.pcap,2000,PER_NODE 1,ENCAP IP)
+    -> [1]output;
+
+  // Incoming packets get pushed into the ARP query module
+  input[0]
+    -> arpquerier;
+
+  // Both the ARP query and response modules send data out to
+  // the simulated network device, eth0.
+  arpquerier
+    -> ToDump(out_arpquery.pcap,PER_NODE 1)
+    -> ethout;
+
+  arpresponder
+    -> ToDump(out_arprespond.pcap,PER_NODE 1)
+    -> ethout;
+
+}
+
+elementclass TapSimHost {
+  $dev |
+
+  // It is mandatory to use an IPRouteTable element with ns-3-click
+  rt :: LinearIPLookup (172.16.2.0/24 0.0.0.0 1,172.16.1.0/24 172.16.1.2 1);
+
+  // Packets go to "tap0" which sends them to the kernel
+  input[0]
+    -> ToDump(tokernel.pcap,2000,IP,PER_NODE 1) 
+    -> ToSimDevice($dev,IP);
+
+  // Packets sent out by the "kernel" get pushed outside
+  FromSimDevice($dev,4096)
+    -> CheckIPHeader2
+    -> ToDump(fromkernel.pcap,2000,IP,PER_NODE 1)
+    -> GetIPAddress(16)
+    -> rt
+    -> [0]output;
+
+  rt[1] -> [0] output;
+}
+
+// Instantiate elements
+lan::LanSimHost(eth0:ip,eth0:eth);
+kernel::TapSimHost(tap0);
+
+// Users can do some processing between the two elements
+lan[0] -> kernel;
+kernel -> lan;
+// Packets for others or broadcasts are discarded
+lan[1] -> Discard;
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/click/examples/nsclick-routing.cc	Wed Feb 23 17:50:31 2011 +0000
@@ -0,0 +1,134 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * 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: Lalith Suresh <suresh.lalith@gmail.com>
+ */
+
+// Network topology
+//
+//
+//              172.16.1.0/24
+//        (1.1)  (1.2)  (1.3)  (1.4)
+//
+//         eth0   eth0  eth1    eth0
+//       n0 ========= n1 ========= n2
+//            LAN 1       LAN 2
+//
+// - UDP flows from n0 to n2 via n1.
+// - All nodes are Click based.
+//
+
+#include "ns3/core-module.h"
+#include "ns3/network-module.h"
+#include "ns3/helper-module.h"
+#include "ns3/ipv4-click-routing.h"
+#include "ns3/ipv4-l3-click-protocol.h"
+#include "ns3/click-internet-stack-helper.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("NsclickRouting");
+
+int
+main (int argc, char *argv[])
+{
+#ifdef NS3_CLICK
+//
+// Enable logging for UdpClient and
+//
+  LogComponentEnable ("NsclickRoutingClient", LOG_LEVEL_INFO);
+  LogComponentEnable ("NsclickRoutingServer", LOG_LEVEL_INFO);
+
+//
+// Explicitly create the nodes required by the topology (shown above).
+//
+  NS_LOG_INFO ("Create nodes.");
+  NodeContainer n;
+  n.Create (3);
+
+//
+// Install Click on the nodes
+//
+  ClickInternetStackHelper clickinternet;
+  clickinternet.SetClickFile (n.Get (0), "src/routing/click/examples/nsclick-routing-node0.click");
+  clickinternet.SetClickFile (n.Get (1), "src/routing/click/examples/nsclick-ip-router.click");
+  clickinternet.SetClickFile (n.Get (2), "src/routing/click/examples/nsclick-routing-node2.click");
+  clickinternet.SetRoutingTableElement (n.Get (0), "kernel/rt");
+  clickinternet.SetRoutingTableElement (n.Get (1), "u/rt");
+  clickinternet.SetRoutingTableElement (n.Get (2), "kernel/rt");
+  clickinternet.Install (n);
+
+  NS_LOG_INFO ("Create channels.");
+//
+// Explicitly create the channels required by the topology (shown above).
+//
+  CsmaHelper csma;
+  csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate(5000000)));
+  csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
+  csma.SetDeviceAttribute ("Mtu", UintegerValue (1400));
+  NetDeviceContainer d01 = csma.Install (NodeContainer (n.Get (0), n.Get (1)));
+  NetDeviceContainer d12 = csma.Install (NodeContainer (n.Get (1), n.Get (2)));
+
+  Ipv4AddressHelper ipv4;
+//
+// We've got the "hardware" in place.  Now we need to add IP addresses.
+//
+  NS_LOG_INFO ("Assign IP Addresses.");
+  ipv4.SetBase ("172.16.1.0", "255.255.255.0");
+  Ipv4InterfaceContainer i01 = ipv4.Assign (d01);
+
+  ipv4.SetBase ("172.16.2.0", "255.255.255.0");
+  Ipv4InterfaceContainer i12 = ipv4.Assign (d12);
+
+  NS_LOG_INFO ("Create Applications.");
+//
+// Create one udpServer applications on node one.
+//
+  uint16_t port = 4000;
+  UdpServerHelper server (port);
+  ApplicationContainer apps = server.Install (n.Get(2));
+  apps.Start (Seconds (1.0));
+  apps.Stop (Seconds (10.0));
+
+//
+// Create one UdpClient application to send UDP datagrams from node zero to
+// node one.
+//
+  uint32_t MaxPacketSize = 1024;
+  Time interPacketInterval = Seconds (0.05);
+  uint32_t maxPacketCount = 320;
+  UdpClientHelper client (i12.GetAddress (1), port);
+  client.SetAttribute ("MaxPackets", UintegerValue (maxPacketCount));
+  client.SetAttribute ("Interval", TimeValue (interPacketInterval));
+  client.SetAttribute ("PacketSize", UintegerValue (MaxPacketSize));
+  apps = client.Install (NodeContainer (n.Get (0)));
+  apps.Start (Seconds (2.0));
+  apps.Stop (Seconds (10.0));
+
+  csma.EnablePcap ("nsclick-routing", d01, false);
+  csma.EnablePcap ("nsclick-routing", d12, false);
+
+//
+// Now, do the actual simulation.
+//
+  NS_LOG_INFO ("Run Simulation.");
+  Simulator::Stop (Seconds(20.0));
+  Simulator::Run ();
+  Simulator::Destroy ();
+  NS_LOG_INFO ("Done.");
+#else
+  NS_FATAL_ERROR ("Can't use ns-3-click without NSCLICK compiled in");
+#endif
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/click/examples/nsclick-simple-lan.cc	Wed Feb 23 17:50:31 2011 +0000
@@ -0,0 +1,97 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * 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: Lalith Suresh <suresh.lalith@gmail.com>
+ */
+
+// Scenario:
+//
+// (Click)       CSMA    (non-Click)
+//    A   ================   B
+// (172.16.1.1)         (172.16.1.2)   
+//    (eth0)
+//
+//
+
+#include "ns3/core-module.h"
+#include "ns3/network-module.h"
+#include "ns3/helper-module.h"
+#include "ns3/click-internet-stack-helper.h"
+#include "ns3/log.h"
+
+using namespace ns3;
+
+void ReceivePacket (Ptr<Socket> socket)
+{
+  NS_LOG_UNCOND ("Received one packet!");
+}
+
+int main (int argc, char *argv[])
+{
+#ifdef NS3_CLICK
+  NodeContainer csmaNodes;
+  csmaNodes.Create (2);
+
+  // Setup CSMA channel between the nodes
+  CsmaHelper csma;
+  csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate (5000000)));
+  csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
+  NetDeviceContainer csmaDevices = csma.Install (csmaNodes);
+
+  // Install normal internet stack on node B
+  InternetStackHelper internet;
+  internet.Install (csmaNodes.Get (1));
+
+  // Install Click on node A
+  ClickInternetStackHelper clickinternet;
+  clickinternet.SetClickFile (csmaNodes.Get (0), "src/routing/click/examples/nsclick-lan-single-interface.click");
+  clickinternet.SetRoutingTableElement (csmaNodes.Get (0), "rt");
+  clickinternet.Install (csmaNodes.Get (0));
+
+  // Configure IP addresses for the nodes
+  Ipv4AddressHelper ipv4;
+  ipv4.SetBase ("172.16.1.0", "255.255.255.0");
+  ipv4.Assign (csmaDevices);
+
+  // Configure traffic application and sockets
+  Address LocalAddress (InetSocketAddress (Ipv4Address::GetAny (), 50000));
+  PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", LocalAddress);
+  ApplicationContainer recvapp = packetSinkHelper.Install (csmaNodes.Get (1));
+  recvapp.Start (Seconds (5.0));
+  recvapp.Stop (Seconds (10.0));
+
+  OnOffHelper onOffHelper ("ns3::TcpSocketFactory", Address ());
+  onOffHelper.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
+  onOffHelper.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
+
+  ApplicationContainer appcont;
+
+  AddressValue remoteAddress (InetSocketAddress (Ipv4Address ("172.16.1.2"), 50000));
+  onOffHelper.SetAttribute ("Remote", remoteAddress);
+  appcont.Add (onOffHelper.Install (csmaNodes.Get (0)));
+
+  appcont.Start (Seconds (5.0));
+  appcont.Stop (Seconds (10.0));
+
+  // For tracing
+  csma.EnablePcap ("nsclick-simple-lan", csmaDevices, false);
+
+  Simulator::Stop (Seconds(20.0));
+  Simulator::Run();
+  return 0;
+#else
+  NS_FATAL_ERROR ("Can't use ns-3-click without NSCLICK compiled in");
+#endif
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/click/examples/nsclick-udp-client-server-csma.cc	Wed Feb 23 17:50:31 2011 +0000
@@ -0,0 +1,126 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * 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
+ */
+
+// Adaptation of examples/udp/udp-client-server.cc for
+// Click based nodes.
+//
+// Network topology
+//
+//         172.16.1.0/24
+//      (1.1) (1.2)  (1.3)
+//        n0    n1    n2
+//        |     |     |
+//        =============
+//             LAN
+//
+// - UDP flows from n0 to n1 and n2 to n1
+// - All nodes are Click based.
+// - The single ethernet interface that each node
+//   uses is named 'eth0' in the Click file.
+//
+
+#include <fstream>
+#include "ns3/core-module.h"
+#include "ns3/network-module.h"
+#include "ns3/helper-module.h"
+#include "ns3/ipv4-click-routing.h"
+#include "ns3/click-internet-stack-helper.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("NsclickUdpClientServerCsma");
+
+int
+main (int argc, char *argv[])
+{
+#ifdef NS3_CLICK
+//
+// Enable logging for UdpClient and
+//
+  LogComponentEnable ("NsclickUdpClientServerCsma", LOG_LEVEL_INFO);
+
+//
+// Explicitly create the nodes required by the topology (shown above).
+//
+  NS_LOG_INFO ("Create nodes.");
+  NodeContainer n;
+  n.Create (3);
+
+  NS_LOG_INFO ("Create channels.");
+//
+// Explicitly create the channels required by the topology (shown above).
+//
+  CsmaHelper csma;
+  csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate(5000000)));
+  csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
+  csma.SetDeviceAttribute ("Mtu", UintegerValue (1400));
+  NetDeviceContainer d = csma.Install (n);
+
+//
+// Install Click on the nodes
+//
+  ClickInternetStackHelper clickinternet;
+  clickinternet.SetClickFile (n, "src/routing/click/examples/nsclick-lan-single-interface.click");
+  clickinternet.SetRoutingTableElement (n, "rt");
+  clickinternet.Install (n);
+
+  Ipv4AddressHelper ipv4;
+//
+// We've got the "hardware" in place.  Now we need to add IP addresses.
+//
+  NS_LOG_INFO ("Assign IP Addresses.");
+  ipv4.SetBase ("172.16.1.0", "255.255.255.0");
+  Ipv4InterfaceContainer i = ipv4.Assign (d);
+
+  NS_LOG_INFO ("Create Applications.");
+//
+// Create one udpServer applications on node one.
+//
+  uint16_t port = 4000;
+  UdpServerHelper server (port);
+  ApplicationContainer apps = server.Install (n.Get(1));
+  apps.Start (Seconds (1.0));
+  apps.Stop (Seconds (10.0));
+
+//
+// Create one UdpClient application to send UDP datagrams from node zero to
+// node one.
+//
+  uint32_t MaxPacketSize = 1024;
+  Time interPacketInterval = Seconds (0.05);
+  uint32_t maxPacketCount = 320;
+  UdpClientHelper client (i.GetAddress (1), port);
+  client.SetAttribute ("MaxPackets", UintegerValue (maxPacketCount));
+  client.SetAttribute ("Interval", TimeValue (interPacketInterval));
+  client.SetAttribute ("PacketSize", UintegerValue (MaxPacketSize));
+  apps = client.Install (NodeContainer (n.Get (0), n.Get (2)));
+  apps.Start (Seconds (2.0));
+  apps.Stop (Seconds (10.0));
+
+  csma.EnablePcap ("nsclick-udp-client-server-csma", d, false);
+
+//
+// Now, do the actual simulation.
+//
+  NS_LOG_INFO ("Run Simulation.");
+  Simulator::Stop (Seconds(20.0));
+  Simulator::Run ();
+  Simulator::Destroy ();
+  NS_LOG_INFO ("Done.");
+#else
+  NS_FATAL_ERROR ("Can't use ns-3-click without NSCLICK compiled in");
+#endif
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/click/examples/nsclick-udp-client-server-wifi.cc	Wed Feb 23 17:50:31 2011 +0000
@@ -0,0 +1,199 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * 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
+ */
+
+// Adaptation of examples/udp/udp-client-server.cc for
+// Click based nodes running wifi.
+//
+// Network topology
+//
+//          172.16.1.0/24
+//   (1.1)      (1.2)       (1.3)
+//     n0 ))   (( n1 ))   (( n2
+//               WLAN
+//
+// - UDP flows from n0 to n1
+// - All nodes are Click based.
+// - The single ethernet interface that each node
+//   uses is named 'eth0' in the Click file.
+//
+
+#include <fstream>
+#include "ns3/core-module.h"
+#include "ns3/network-module.h"
+#include "ns3/helper-module.h"
+#include "ns3/ipv4-click-routing.h"
+#include "ns3/click-internet-stack-helper.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("NsclickUdpClientServerWifi");
+
+#ifdef NS3_CLICK
+void
+readArp(Ptr<Ipv4ClickRouting> clickRouter)
+{
+  // Access the handlers
+  NS_LOG_INFO(clickRouter->ReadHandler ("wifi/arpquerier", "table"));
+  NS_LOG_INFO(clickRouter->ReadHandler ("wifi/arpquerier", "stats"));
+}
+
+void
+writeArp(Ptr<Ipv4ClickRouting> clickRouter)
+{
+  // Access the handler
+  NS_LOG_INFO(clickRouter->WriteHandler ("wifi/arpquerier", "insert", "172.16.1.2 00:00:00:00:00:02"));
+}
+#endif
+
+int
+main (int argc, char *argv[])
+{
+#ifdef NS3_CLICK
+
+  //
+  // Enable logging
+  //
+  LogComponentEnable ("NsclickUdpClientServerWifi", LOG_LEVEL_INFO);
+
+  //
+  // Explicitly create the nodes required by the topology (shown above).
+  //
+  NS_LOG_INFO ("Create nodes.");
+  NodeContainer n;
+  n.Create (4);
+
+  NS_LOG_INFO ("Create channels.");
+  //
+  // Explicitly create the channels required by the topology (shown above).
+  //
+  std::string phyMode ("DsssRate1Mbps");
+
+  // disable fragmentation for frames below 2200 bytes
+  Config::SetDefault ("ns3::WifiRemoteStationManager::FragmentationThreshold", StringValue ("2200"));
+  // turn off RTS/CTS for frames below 2200 bytes
+  Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue ("2200"));
+  // Fix non-unicast data rate to be the same as that of unicast
+  Config::SetDefault ("ns3::WifiRemoteStationManager::NonUnicastMode",
+                      StringValue (phyMode));
+
+  WifiHelper wifi;
+  wifi.SetStandard (WIFI_PHY_STANDARD_80211b);
+
+  YansWifiPhyHelper wifiPhy =  YansWifiPhyHelper::Default ();
+  // This is one parameter that matters when using FixedRssLossModel
+  // set it to zero; otherwise, gain will be added
+  wifiPhy.Set ("RxGain", DoubleValue (0) );
+  // ns-3 supports RadioTap and Prism tracing extensions for 802.11b
+  wifiPhy.SetPcapDataLinkType (YansWifiPhyHelper::DLT_IEEE802_11_RADIO);
+
+  YansWifiChannelHelper wifiChannel ;
+  wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
+  // The below FixedRssLossModel will cause the rss to be fixed regardless
+  // of the distance between the two stations, and the transmit power
+  wifiChannel.AddPropagationLoss ("ns3::FixedRssLossModel","Rss",DoubleValue(-80));
+  wifiPhy.SetChannel (wifiChannel.Create ());
+
+  // Add a non-QoS upper mac, and disable rate control
+  NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
+  wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
+                                "DataMode",StringValue(phyMode),
+                                   "ControlMode",StringValue(phyMode));
+  // Set it to adhoc mode
+  wifiMac.SetType ("ns3::AdhocWifiMac");
+  NetDeviceContainer d = wifi.Install (wifiPhy, wifiMac, n); 
+
+  MobilityHelper mobility;
+  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
+  positionAlloc->Add (Vector (0.0, 0.0, 0.0));
+  positionAlloc->Add (Vector (10.0, 0.0, 0.0));
+  positionAlloc->Add (Vector (20.0, 0.0, 0.0));
+  positionAlloc->Add (Vector (0.0, 10.0, 0.0));
+  mobility.SetPositionAllocator (positionAlloc);
+  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
+  mobility.Install (n);
+
+  //
+  // Install Click on the nodes
+  //
+  ClickInternetStackHelper clickinternet;
+  clickinternet.SetClickFile (n, "src/routing/click/examples/nsclick-wifi-single-interface.click");
+  clickinternet.SetRoutingTableElement (n, "rt");
+  clickinternet.Install (n);
+  // 4th node can listen to traffic in promisc mode
+  // Note: Promiscuous mode support for Click has
+  // been added ahead of the official Wifi support
+  // for promiscuous mode. Thus, the below line will
+  // not work until then.
+  n.Get(3)->GetObject<Ipv4ClickRouting>()->SetPromiscuous ("eth0");
+
+  Ipv4AddressHelper ipv4;
+  //
+  // We've got the "hardware" in place.  Now we need to add IP addresses.
+  //
+  NS_LOG_INFO ("Assign IP Addresses.");
+  ipv4.SetBase ("172.16.1.0", "255.255.255.0");
+  Ipv4InterfaceContainer i = ipv4.Assign (d);
+
+  NS_LOG_INFO ("Create Applications.");
+  //
+  // Create one udpServer applications on node one.
+  //
+  uint16_t port = 4000;
+  UdpServerHelper server (port);
+  ApplicationContainer apps = server.Install (n.Get(1));
+  apps.Start (Seconds (1.0));
+  apps.Stop (Seconds (10.0));
+
+  //
+  // Create one UdpClient application to send UDP datagrams from node zero to
+  // node one.
+  //
+  uint32_t MaxPacketSize = 1024;
+  Time interPacketInterval = Seconds (0.5);
+  uint32_t maxPacketCount = 320;
+  UdpClientHelper client (i.GetAddress (1), port);
+  client.SetAttribute ("MaxPackets", UintegerValue (maxPacketCount));
+  client.SetAttribute ("Interval", TimeValue (interPacketInterval));
+  client.SetAttribute ("PacketSize", UintegerValue (MaxPacketSize));
+  apps = client.Install (NodeContainer (n.Get (0), n.Get (2)));
+  apps.Start (Seconds (2.0));
+  apps.Stop (Seconds (10.0));
+
+  wifiPhy.EnablePcap ("nsclick-udp-client-server-wifi", d);
+
+  // Force the MAC address of the second node: The current ARP
+  // implementation of Click sends only one ARP request per incoming
+  // packet for an unknown destination and does not retransmit if no
+  // response is received. With the scenario of this example, all ARP
+  // requests of node 3 are lost due to interference from node
+  // 1. Hence, we fill in the ARP table of node 2 before at the
+  // beginning of the simulation
+  Simulator::Schedule (Seconds (0.5), &readArp,n.Get(2)->GetObject<Ipv4ClickRouting>());
+  Simulator::Schedule (Seconds (0.6), &writeArp,n.Get(2)->GetObject<Ipv4ClickRouting>());
+  Simulator::Schedule (Seconds (0.7), &readArp,n.Get(2)->GetObject<Ipv4ClickRouting>());
+
+  //
+  // Now, do the actual simulation.
+  //
+  NS_LOG_INFO ("Run Simulation.");
+  Simulator::Stop (Seconds(20.0));
+  Simulator::Run ();
+  Simulator::Destroy ();
+  NS_LOG_INFO ("Done.");
+#else
+  NS_FATAL_ERROR ("Can't use ns-3-click without NSCLICK compiled in");
+#endif
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/click/examples/nsclick-wifi-single-interface.click	Wed Feb 23 17:50:31 2011 +0000
@@ -0,0 +1,113 @@
+// nsclick-wifi-single-interface.click
+//
+// Copyright (c) 2011, Deutsche Telekom Laboratories
+//
+// 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: Ruben Merz <ruben@net.t-labs.tu-berlin.de>
+//
+// This is a single host Click configuration for wifi.
+// The node broadcasts ARP requests if it wants to find a destination
+// address, and it responds to ARP requests made for it.
+
+elementclass WiFiSimHost {
+  $ipaddr, $hwaddr |
+
+  cl::Classifier(12/0806 20/0001,12/0806 20/0002, -);
+  forhost::IPClassifier(dst host $ipaddr,-);
+  arpquerier::ARPQuerier(eth0);
+  arpresponder::ARPResponder(eth0);
+
+  ethout::Queue 	
+    -> ToDump(out_eth0.pcap,PER_NODE 1)
+    -> ToSimDevice(eth0);
+
+  // All packets received on eth0 are silently
+  // dropped if they are destined for another location
+  FromSimDevice(eth0,4096)
+    -> ToDump(in_eth0.pcap,PER_NODE 1,ENCAP ETHER)
+    -> cl;
+
+  // ARP queries from other nodes go to the ARP responder element
+  cl[0] -> arpresponder;
+
+  // ARP responses go to our ARP query element
+  cl[1] -> [1]arpquerier;
+
+  // All other packets get checked whether they are meant for us
+  cl[2]				
+    -> Strip (14)
+    -> CheckIPHeader2
+    -> MarkIPHeader
+    -> GetIPAddress(16) // Sets destination IP address annotation from packet data
+    -> forhost; 
+
+  // Packets for us are pushed outside
+  forhost[0]
+    ->[0]output;
+
+  // Packets for other folks or broadcast packets get sent to output 1
+  forhost[1]
+    -> ToDump(discard.pcap,2000,PER_NODE 1,ENCAP IP)
+    -> [1]output;
+
+  // Incoming packets get pushed into the ARP query module
+  input[0]
+    -> arpquerier;
+
+  // Both the ARP query and response modules send data out to
+  // the simulated network device, eth0.
+  arpquerier
+    -> ToDump(out_arpquery.pcap,PER_NODE 1)
+    -> ethout;
+
+  arpresponder
+    -> ToDump(out_arprespond.pcap,PER_NODE 1)
+    -> ethout;
+
+}
+
+elementclass TapSimHost {
+  $dev |
+
+  // Packets go to "tap0" which sends them to the kernel
+  input[0]
+    -> ToDump(tokernel.pcap,2000,IP,PER_NODE 1) 
+    -> ToSimDevice($dev,IP);
+
+  // Packets sent out by the "kernel" get pushed outside
+  FromSimDevice($dev,4096)
+    -> CheckIPHeader2
+    -> ToDump(fromkernel.pcap,2000,IP,PER_NODE 1)
+    -> GetIPAddress(16)
+    -> [0]output;
+}
+
+// Instantiate elements
+wifi::WiFiSimHost(eth0:ip,eth0:eth);
+kernel::TapSimHost(tap0);
+
+// Users can do some processing between the two elements
+wifi[0] -> kernel;
+kernel -> wifi;
+// Packets not for us are discarded
+wifi[1] -> Discard;
+
+// It is mandatory to use an IPRouteTable element with ns-3-click
+// (but we do not use it in this example)
+rt :: LinearIPLookup (172.16.1.0/24 0.0.0.0 1);
+// We are actually not using the routing table
+Idle () -> rt;
+rt[0] -> Discard;
+rt[1] -> Discard;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/click/examples/wscript	Wed Feb 23 17:50:31 2011 +0000
@@ -0,0 +1,22 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+def build(bld):
+   obj = bld.create_ns3_program('nsclick-simple-lan',
+                                ['click', 'csma', 'internet-stack'])
+   obj.source = 'nsclick-simple-lan.cc'
+
+   obj = bld.create_ns3_program('nsclick-raw-wlan',
+                                ['click', 'wifi', 'internet-stack'])
+   obj.source = 'nsclick-raw-wlan.cc'
+
+   obj = bld.create_ns3_program('nsclick-udp-client-server-csma',
+                                ['click', 'csma', 'internet-stack'])
+   obj.source = 'nsclick-udp-client-server-csma.cc'
+
+   obj = bld.create_ns3_program('nsclick-udp-client-server-wifi',
+                                ['click', 'wifi', 'internet-stack'])
+   obj.source = 'nsclick-udp-client-server-wifi.cc'
+
+   obj = bld.create_ns3_program('nsclick-routing',
+                                ['click', 'csma', 'internet-stack'])
+   obj.source = 'nsclick-routing.cc'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/click/helper/click-internet-stack-helper.cc	Wed Feb 23 17:50:31 2011 +0000
@@ -0,0 +1,503 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 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>
+ * Author: Faker Moatamri <faker.moatamri@sophia.inria.fr>
+ * Author: Lalith Suresh  <suresh.lalith@gmail.com>
+ */
+
+#ifdef NS3_CLICK
+
+#include "ns3/assert.h"
+#include "ns3/log.h"
+#include "ns3/object.h"
+#include "ns3/names.h"
+#include "ns3/ipv4.h"
+#include "ns3/packet-socket-factory.h"
+#include "ns3/config.h"
+#include "ns3/simulator.h"
+#include "ns3/string.h"
+#include "ns3/net-device.h"
+#include "ns3/callback.h"
+#include "ns3/node.h"
+#include "ns3/core-config.h"
+#include "ns3/arp-l3-protocol.h"
+#include "ns3/ipv4-click-routing.h"
+#include "ns3/ipv4-l3-click-protocol.h"
+#include "ns3/trace-helper.h"
+#include "click-internet-stack-helper.h"
+#include <limits>
+#include <map>
+
+NS_LOG_COMPONENT_DEFINE ("ClickInternetStackHelper");
+
+namespace ns3 {
+
+#define INTERFACE_CONTEXT
+
+typedef std::pair<Ptr<Ipv4>, uint32_t> InterfacePairIpv4; 
+typedef std::map<InterfacePairIpv4, Ptr<PcapFileWrapper> > InterfaceFileMapIpv4;
+typedef std::map<InterfacePairIpv4, Ptr<OutputStreamWrapper> > InterfaceStreamMapIpv4;
+
+static InterfaceFileMapIpv4 g_interfaceFileMapIpv4; /**< A mapping of Ipv4/interface pairs to pcap files */
+static InterfaceStreamMapIpv4 g_interfaceStreamMapIpv4; /**< A mapping of Ipv4/interface pairs to ascii streams */
+
+ClickInternetStackHelper::ClickInternetStackHelper ()
+  : m_ipv4Enabled (true)
+{
+  Initialize ();
+}
+
+// private method called by both constructor and Reset ()
+void
+ClickInternetStackHelper::Initialize ()
+{
+  SetTcp ("ns3::TcpL4Protocol");
+}
+
+ClickInternetStackHelper::~ClickInternetStackHelper ()
+{
+}
+
+ClickInternetStackHelper::ClickInternetStackHelper (const ClickInternetStackHelper &o)
+{
+  m_ipv4Enabled = o.m_ipv4Enabled;
+  m_tcpFactory = o.m_tcpFactory;
+}
+
+ClickInternetStackHelper &
+ClickInternetStackHelper::operator = (const ClickInternetStackHelper &o)
+{
+  if (this == &o)
+    {
+      return *this;
+    }
+  return *this;
+}
+
+void
+ClickInternetStackHelper::Reset (void)
+{
+  m_ipv4Enabled = true;
+  Initialize ();
+}
+
+void
+ClickInternetStackHelper::SetTcp (const std::string tid)
+{
+  m_tcpFactory.SetTypeId (tid);
+}
+
+void 
+ClickInternetStackHelper::SetTcp (std::string tid, std::string n0, const AttributeValue &v0)
+{
+  m_tcpFactory.SetTypeId (tid);
+  m_tcpFactory.Set (n0,v0);
+}
+
+void
+ClickInternetStackHelper::SetClickFile (NodeContainer c, std::string clickfile)
+{
+  for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
+    {
+      SetClickFile (*i, clickfile);
+    }
+}
+
+void
+ClickInternetStackHelper::SetClickFile (Ptr<Node> node, std::string clickfile)
+{
+  m_nodeToClickFileMap.insert (std::make_pair (node, clickfile));
+}
+
+void
+ClickInternetStackHelper::SetRoutingTableElement (NodeContainer c, std::string rt)
+{
+  for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
+    {
+      SetRoutingTableElement (*i, rt);
+    }
+}
+
+void
+ClickInternetStackHelper::SetRoutingTableElement (Ptr<Node> node, std::string rt)
+{
+  m_nodeToRoutingTableElementMap.insert (std::make_pair (node, rt));
+}
+
+void 
+ClickInternetStackHelper::Install (NodeContainer c) const
+{
+  for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
+    {
+      Install (*i);
+    }
+}
+
+void 
+ClickInternetStackHelper::InstallAll (void) const
+{
+  Install (NodeContainer::GetGlobal ());
+}
+
+void
+ClickInternetStackHelper::CreateAndAggregateObjectFromTypeId (Ptr<Node> node, const std::string typeId)
+{
+  ObjectFactory factory;
+  factory.SetTypeId (typeId);
+  Ptr<Object> protocol = factory.Create <Object> ();
+  node->AggregateObject (protocol);
+}
+
+void
+ClickInternetStackHelper::Install (Ptr<Node> node) const
+{
+  if (m_ipv4Enabled)
+    {
+      if (node->GetObject<Ipv4> () != 0)
+        {
+          NS_FATAL_ERROR ("ClickInternetStackHelper::Install (): Aggregating " 
+                          "an InternetStack to a node with an existing Ipv4 object");
+          return;
+        }
+
+      CreateAndAggregateObjectFromTypeId (node, "ns3::ArpL3Protocol");
+      CreateAndAggregateObjectFromTypeId (node, "ns3::Ipv4L3ClickProtocol");
+      CreateAndAggregateObjectFromTypeId (node, "ns3::Icmpv4L4Protocol");
+      CreateAndAggregateObjectFromTypeId (node, "ns3::UdpL4Protocol");
+      node->AggregateObject (m_tcpFactory.Create<Object> ());
+      Ptr<PacketSocketFactory> factory = CreateObject<PacketSocketFactory> ();
+      node->AggregateObject (factory);
+      // Set routing
+      Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+      Ptr<Ipv4ClickRouting> ipv4Routing = CreateObject<Ipv4ClickRouting> ();
+      std::map< Ptr<Node>, std::string >::const_iterator it;
+      it = m_nodeToClickFileMap.find (node);
+
+      if (it != m_nodeToClickFileMap.end ())
+        {
+          ipv4Routing->SetClickFile (it->second);
+        }
+
+      it = m_nodeToRoutingTableElementMap.find (node);
+      if (it != m_nodeToRoutingTableElementMap.end ())
+        {
+          ipv4Routing->SetClickRoutingTableElement (it->second);
+        }
+      ipv4->SetRoutingProtocol (ipv4Routing);
+      node->AggregateObject (ipv4Routing);
+    }
+}
+
+void
+ClickInternetStackHelper::Install (std::string nodeName) const
+{
+  Ptr<Node> node = Names::Find<Node> (nodeName);
+  Install (node);
+}
+
+static void
+Ipv4L3ProtocolRxTxSink (Ptr<const Packet> p, Ptr<Ipv4> ipv4, uint32_t interface)
+{
+  NS_LOG_FUNCTION (p << ipv4 << interface);
+
+  //
+  // Since trace sources are independent of interface, if we hook a source
+  // on a particular protocol we will get traces for all of its interfaces.
+  // We need to filter this to only report interfaces for which the user 
+  // has expressed interest.
+  //
+  InterfacePairIpv4 pair = std::make_pair (ipv4, interface);
+  if (g_interfaceFileMapIpv4.find (pair) == g_interfaceFileMapIpv4.end ())
+    {
+      NS_LOG_INFO ("Ignoring packet to/from interface " << interface);
+      return;
+    }
+
+  Ptr<PcapFileWrapper> file = g_interfaceFileMapIpv4[pair];
+  file->Write(Simulator::Now(), p);
+}
+
+bool
+ClickInternetStackHelper::PcapHooked (Ptr<Ipv4> ipv4)
+{
+  for (  InterfaceFileMapIpv4::const_iterator i = g_interfaceFileMapIpv4.begin (); 
+         i != g_interfaceFileMapIpv4.end (); 
+         ++i)
+    {
+      if ((*i).first.first == ipv4)
+        {
+          return true;
+        }
+    }
+  return false;
+}
+
+void 
+ClickInternetStackHelper::EnablePcapIpv4Internal (std::string prefix, Ptr<Ipv4> ipv4, uint32_t interface, bool explicitFilename)
+{
+  NS_LOG_FUNCTION (prefix << ipv4 << interface);
+
+  if (!m_ipv4Enabled)
+    {
+      NS_LOG_INFO ("Call to enable Ipv4 pcap tracing but Ipv4 not enabled");
+      return;
+    }
+
+  //
+  // We have to create a file and a mapping from protocol/interface to file 
+  // irrespective of how many times we want to trace a particular protocol.
+  //
+  PcapHelper pcapHelper;
+
+  std::string filename;
+  if (explicitFilename)
+    {
+      filename = prefix;
+    }
+  else
+    {
+      filename = pcapHelper.GetFilenameFromInterfacePair (prefix, ipv4, interface);
+    }
+
+  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, std::ios::out, PcapHelper::DLT_RAW);
+
+  //
+  // However, we only hook the trace source once to avoid multiple trace sink
+  // calls per event (connect is independent of interface).
+  //
+  if (!PcapHooked (ipv4))
+    {
+      //
+      // Ptr<Ipv4> is aggregated to node and Ipv4L3Protocol is aggregated to 
+      // node so we can get to Ipv4L3Protocol through Ipv4.
+      //
+      Ptr<Ipv4L3Protocol> ipv4L3Protocol = ipv4->GetObject<Ipv4L3Protocol> ();
+      NS_ASSERT_MSG (ipv4L3Protocol, "ClickInternetStackHelper::EnablePcapIpv4Internal(): "
+                     "m_ipv4Enabled and ipv4L3Protocol inconsistent");
+
+      bool result = ipv4L3Protocol->TraceConnectWithoutContext ("Tx", MakeCallback (&Ipv4L3ProtocolRxTxSink));
+      NS_ASSERT_MSG (result == true, "ClickInternetStackHelper::EnablePcapIpv4Internal():  "
+                     "Unable to connect ipv4L3Protocol \"Tx\"");
+
+      result = ipv4L3Protocol->TraceConnectWithoutContext ("Rx", MakeCallback (&Ipv4L3ProtocolRxTxSink));
+      NS_ASSERT_MSG (result == true, "ClickInternetStackHelper::EnablePcapIpv4Internal():  "
+                     "Unable to connect ipv4L3Protocol \"Rx\"");
+    }
+
+  g_interfaceFileMapIpv4[std::make_pair (ipv4, interface)] = file;
+}
+
+static void
+Ipv4L3ProtocolDropSinkWithoutContext (
+  Ptr<OutputStreamWrapper> stream,
+  Ipv4Header const &header, 
+  Ptr<const Packet> packet,
+  Ipv4L3Protocol::DropReason reason, 
+  Ptr<Ipv4> ipv4, 
+  uint32_t interface)
+{
+  //
+  // Since trace sources are independent of interface, if we hook a source
+  // on a particular protocol we will get traces for all of its interfaces.
+  // We need to filter this to only report interfaces for which the user 
+  // has expressed interest.
+  //
+  InterfacePairIpv4 pair = std::make_pair (ipv4, interface);
+  if (g_interfaceStreamMapIpv4.find (pair) == g_interfaceStreamMapIpv4.end ())
+    {
+      NS_LOG_INFO ("Ignoring packet to/from interface " << interface);
+      return;
+    }
+
+  Ptr<Packet> p = packet->Copy ();
+  p->AddHeader (header);
+  *stream->GetStream () << "d " << Simulator::Now ().GetSeconds () << " " << *p << std::endl;
+}
+
+static void
+Ipv4L3ProtocolDropSinkWithContext (
+  Ptr<OutputStreamWrapper> stream,
+  std::string context,
+  Ipv4Header const &header, 
+  Ptr<const Packet> packet,
+  Ipv4L3Protocol::DropReason reason, 
+  Ptr<Ipv4> ipv4, 
+  uint32_t interface)
+{
+  //
+  // Since trace sources are independent of interface, if we hook a source
+  // on a particular protocol we will get traces for all of its interfaces.
+  // We need to filter this to only report interfaces for which the user 
+  // has expressed interest.
+  //
+  InterfacePairIpv4 pair = std::make_pair (ipv4, interface);
+  if (g_interfaceStreamMapIpv4.find (pair) == g_interfaceStreamMapIpv4.end ())
+    {
+      NS_LOG_INFO ("Ignoring packet to/from interface " << interface);
+      return;
+    }
+
+  Ptr<Packet> p = packet->Copy ();
+  p->AddHeader (header);
+#ifdef INTERFACE_CONTEXT
+  *stream->GetStream () << "d " << Simulator::Now ().GetSeconds () << " " << context << "(" << interface << ") " 
+                        << *p << std::endl;
+#else
+  *stream->GetStream () << "d " << Simulator::Now ().GetSeconds () << " " << context << " "  << *p << std::endl;
+#endif
+}
+
+bool
+ClickInternetStackHelper::AsciiHooked (Ptr<Ipv4> ipv4)
+{
+  for (  InterfaceStreamMapIpv4::const_iterator i = g_interfaceStreamMapIpv4.begin (); 
+         i != g_interfaceStreamMapIpv4.end (); 
+         ++i)
+    {
+      if ((*i).first.first == ipv4)
+        {
+          return true;
+        }
+    }
+  return false;
+}
+
+void 
+ClickInternetStackHelper::EnableAsciiIpv4Internal (
+  Ptr<OutputStreamWrapper> stream, 
+  std::string prefix, 
+  Ptr<Ipv4> ipv4, 
+  uint32_t interface,
+  bool explicitFilename)
+{
+  if (!m_ipv4Enabled)
+    {
+      NS_LOG_INFO ("Call to enable Ipv4 ascii tracing but Ipv4 not enabled");
+      return;
+    }
+
+  //
+  // Our trace sinks are going to use packet printing, so we have to 
+  // make sure that is turned on.
+  //
+  Packet::EnablePrinting ();
+
+  //
+  // If we are not provided an OutputStreamWrapper, we are expected to create 
+  // one using the usual trace filename conventions and hook WithoutContext
+  // since there will be one file per context and therefore the context would
+  // be redundant.
+  //
+  if (stream == 0)
+    {
+      //
+      // Set up an output stream object to deal with private ofstream copy 
+      // constructor and lifetime issues.  Let the helper decide the actual
+      // name of the file given the prefix.
+      //
+      // We have to create a stream and a mapping from protocol/interface to 
+      // stream irrespective of how many times we want to trace a particular 
+      // protocol.
+      //
+      AsciiTraceHelper asciiTraceHelper;
+
+      std::string filename;
+      if (explicitFilename)
+        {
+          filename = prefix;
+        }
+      else
+        {
+          filename = asciiTraceHelper.GetFilenameFromInterfacePair (prefix, ipv4, interface);
+        }
+
+      Ptr<OutputStreamWrapper> theStream = asciiTraceHelper.CreateFileStream (filename);
+
+      //
+      // However, we only hook the trace sources once to avoid multiple trace sink
+      // calls per event (connect is independent of interface).
+      //
+      if (!AsciiHooked (ipv4))
+        {
+          //
+          // We can use the default drop sink for the ArpL3Protocol since it has
+          // the usual signature.  We can get to the Ptr<ArpL3Protocol> through
+          // our Ptr<Ipv4> since they must both be aggregated to the same node.
+          //
+          Ptr<ArpL3Protocol> arpL3Protocol = ipv4->GetObject<ArpL3Protocol> ();
+          asciiTraceHelper.HookDefaultDropSinkWithoutContext<ArpL3Protocol> (arpL3Protocol, "Drop", theStream);
+
+          //
+          // The drop sink for the Ipv4L3Protocol uses a different signature than
+          // the default sink, so we have to cook one up for ourselves.  We can get
+          // to the Ptr<Ipv4L3Protocol> through our Ptr<Ipv4> since they must both 
+          // be aggregated to the same node.
+          //
+          Ptr<Ipv4L3Protocol> ipv4L3Protocol = ipv4->GetObject<Ipv4L3Protocol> ();
+          bool __attribute__ ((unused)) result = ipv4L3Protocol->TraceConnectWithoutContext ("Drop", 
+                                                                                             MakeBoundCallback (&Ipv4L3ProtocolDropSinkWithoutContext,
+                                                                                                                theStream));
+          NS_ASSERT_MSG (result == true, "ClickInternetStackHelper::EanableAsciiIpv4Internal():  "
+                         "Unable to connect ipv4L3Protocol \"Drop\"");
+        }
+
+      g_interfaceStreamMapIpv4[std::make_pair (ipv4, interface)] = theStream;
+      return;
+    }
+
+  //
+  // If we are provided an OutputStreamWrapper, we are expected to use it, and
+  // to provide a context.  We are free to come up with our own context if we
+  // want, and use the AsciiTraceHelper Hook*WithContext functions, but for 
+  // compatibility and simplicity, we just use Config::Connect and let it deal
+  // with the context.
+  //
+  // We need to associate the ipv4/interface with a stream to express interest
+  // in tracing events on that pair, however, we only hook the trace sources 
+  // once to avoid multiple trace sink calls per event (connect is independent
+  // of interface).
+  //
+  if (!AsciiHooked (ipv4))
+    {
+      Ptr<Node> node = ipv4->GetObject<Node> ();
+      std::ostringstream oss;
+
+      //
+      // For the ARP Drop, we are going to use the default trace sink provided by 
+      // the ascii trace helper.  There is actually no AsciiTraceHelper in sight 
+      // here, but the default trace sinks are actually publicly available static 
+      // functions that are always there waiting for just such a case.
+      //
+      oss << "/NodeList/" << node->GetId () << "/$ns3::ArpL3Protocol/Drop";
+      Config::Connect (oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultDropSinkWithContext, stream));
+
+      //
+      // This has all kinds of parameters coming with, so we have to cook up our
+      // own sink.
+      //
+      oss.str ("");
+      oss << "/NodeList/" << node->GetId () << "/$ns3::Ipv4L3Protocol/Drop";
+      Config::Connect (oss.str (), MakeBoundCallback (&Ipv4L3ProtocolDropSinkWithContext, stream));
+    }
+
+  g_interfaceStreamMapIpv4[std::make_pair (ipv4, interface)] = stream;
+}
+
+} // namespace ns3
+
+#endif // NS3_CLICK
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/click/helper/click-internet-stack-helper.h	Wed Feb 23 17:50:31 2011 +0000
@@ -0,0 +1,230 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 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>
+ * Author: Lalith Suresh  <suresh.lalith@gmail.com>
+ */
+
+#ifdef NS3_CLICK
+
+#ifndef CLICK_INTERNET_STACK_HELPER_H
+#define CLICK_INTERNET_STACK_HELPER_H
+
+#include "ns3/node-container.h"
+#include "ns3/net-device-container.h"
+#include "ns3/packet.h"
+#include "ns3/ptr.h"
+#include "ns3/object-factory.h"
+#include "ns3/ipv4-l3-protocol.h"
+#include "ns3/ipv6-l3-protocol.h"
+#include "ns3/trace-helper.h"
+#include <map>
+
+namespace ns3 {
+
+class Node;
+class Ipv4RoutingHelper;
+
+/**
+ * \brief aggregate Click/IP/TCP/UDP functionality to existing Nodes.
+ *
+ * This helper has been adapted from the InternetStackHelper class and
+ * nodes will not be able to use Ipv6 functionalities.
+ *
+ */
+class ClickInternetStackHelper : public PcapHelperForIpv4, public AsciiTraceHelperForIpv4
+{
+public:
+  /**
+   * Create a new ClickInternetStackHelper which uses Ipv4ClickRouting for routing
+   */
+  ClickInternetStackHelper(void);
+
+  /**
+   * Destroy the ClickInternetStackHelper
+   */
+  virtual ~ClickInternetStackHelper(void);
+  ClickInternetStackHelper (const ClickInternetStackHelper &);
+  ClickInternetStackHelper &operator = (const ClickInternetStackHelper &o);
+
+  /**
+   * Return helper internal state to that of a newly constructed one
+   */
+  void Reset (void);
+
+  /**
+   * Aggregate implementations of the ns3::Ipv4L3ClickProtocol, ns3::ArpL3Protocol, 
+   * ns3::Udp, and ns3::Tcp classes onto the provided node.  This method will 
+   * assert if called on a node that already has an Ipv4 object aggregated to it.
+   * 
+   * \param nodeName The name of the node on which to install the stack.
+   */
+  void Install (std::string nodeName) const;
+
+  /**
+   * Aggregate implementations of the ns3::Ipv4L3ClickProtocol, ns3::ArpL3Protocol,
+   * ns3::Udp, and ns3::Tcp classes onto the provided node.  This method will 
+   * assert if called on a node that already has an Ipv4 object aggregated to it.
+   * 
+   * \param node The node on which to install the stack.
+   */
+  void Install (Ptr<Node> node) const;
+
+  /**
+   * For each node in the input container, aggregate implementations of the 
+   * ns3::Ipv4L3ClickProtocol, ns3::ArpL3Protocol, ns3::Udp, and, ns3::Tcp classes.  
+   * The program will assert if this method is called on a container with a 
+   * node that already has an Ipv4 object aggregated to it.
+   * 
+   * \param c NodeContainer that holds the set of nodes on which to install the
+   * new stacks.
+   */
+  void Install (NodeContainer c) const;
+
+  /**
+   * Aggregate IPv4, UDP, and TCP stacks to all nodes in the simulation
+   */
+  void InstallAll (void) const;
+
+  /**
+   * \brief set the Tcp stack which will not need any other parameter.
+   *
+   * This function sets up the tcp stack to the given TypeId. It should not be 
+   * used for NSC stack setup because the nsc stack needs the Library attribute
+   * to be setup, please use instead the version that requires an attribute
+   * and a value. If you choose to use this function anyways to set nsc stack
+   * the default value for the linux library will be used: "liblinux2.6.26.so".
+   *
+   * \param tid the type id, typically it is set to  "ns3::TcpL4Protocol"
+   */
+  void SetTcp(std::string tid);
+
+  /**
+   * \brief This function is used to setup the Network Simulation Cradle stack with library value.
+   * 
+   * Give the NSC stack a shared library file name to use when creating the 
+   * stack implementation.  The attr string is actually the attribute name to 
+   * be setup and val is its value. The attribute is the stack implementation 
+   * to be used and the value is the shared library name.
+   * 
+   * \param tid The type id, for the case of nsc it would be "ns3::NscTcpL4Protocol" 
+   * \param attr The attribute name that must be setup, for example "Library"
+   * \param val The attribute value, which will be in fact the shared library name (example:"liblinux2.6.26.so")
+   */
+  void SetTcp (std::string tid, std::string attr, const AttributeValue &val); 
+
+  /**
+   * \brief Set a Click file to be used for a group of nodes.
+   * \param c NodeContainer of nodes
+   * \param clickfile Click file to be used
+   */
+  void SetClickFile (NodeContainer c, std::string clickfile);
+
+  /**
+   * \brief Set a Click file to be used for a node.
+   * \param node Node for which Click file is to be set
+   * \param clickfile Click file to be used
+   */
+  void SetClickFile (Ptr<Node> node, std::string clickfile);
+
+  /**
+   * \brief Set a Click routing table element for a group of nodes.
+   * \param c NodeContainer of nodes
+   * \param rt Click Routing Table element name
+   */
+  void SetRoutingTableElement (NodeContainer c, std::string rt);
+
+  /**
+   * \brief Set a Click routing table element for a node.
+   * \param node Node for which Click file is to be set
+   * \param rt Click Routing Table element name
+   */
+  void SetRoutingTableElement (Ptr<Node> node, std::string rt);
+private:
+  /**
+   * @brief Enable pcap output the indicated Ipv4 and interface pair.
+   * @internal
+   *
+   * @param prefix Filename prefix to use for pcap files.
+   * @param ipv4 Ptr to the Ipv4 interface on which you want to enable tracing.
+   * @param interface Interface ID on the Ipv4 on which you want to enable tracing.
+   */
+  virtual void EnablePcapIpv4Internal (std::string prefix, 
+                                       Ptr<Ipv4> ipv4, 
+                                       uint32_t interface,
+                                       bool explicitFilename);
+
+  /**
+   * @brief Enable ascii trace output on the indicated Ipv4 and interface pair.
+   * @internal
+   *
+   * @param stream An OutputStreamWrapper representing an existing file to use
+   *               when writing trace data.
+   * @param prefix Filename prefix to use for ascii trace files.
+   * @param ipv4 Ptr to the Ipv4 interface on which you want to enable tracing.
+   * @param interface Interface ID on the Ipv4 on which you want to enable tracing.
+   */
+  virtual void EnableAsciiIpv4Internal (Ptr<OutputStreamWrapper> stream, 
+                                        std::string prefix, 
+                                        Ptr<Ipv4> ipv4, 
+                                        uint32_t interface,
+                                        bool explicitFilename);
+
+  void Initialize (void);
+  ObjectFactory m_tcpFactory;
+
+  /**
+   * \internal
+   */
+  static void CreateAndAggregateObjectFromTypeId (Ptr<Node> node, const std::string typeId);
+
+  /**
+   * \internal
+   */
+  static void Cleanup (void);
+
+  /**
+   * \internal
+   */
+  bool PcapHooked (Ptr<Ipv4> ipv4);
+
+  /**
+   * \internal
+   */
+  bool AsciiHooked (Ptr<Ipv4> ipv4);
+
+  /**
+   * \brief IPv4 install state (enabled/disabled) ?
+   */
+  bool m_ipv4Enabled;
+
+  /**
+   * \brief Node to Click file mapping
+   */
+  std::map < Ptr<Node>, std::string  > m_nodeToClickFileMap;
+
+  /**
+   * \brief Node to Routing Table Element mapping
+   */
+  std::map < Ptr<Node>, std::string  > m_nodeToRoutingTableElementMap;
+};
+
+} // namespace ns3
+
+#endif /* CLICK_INTERNET_STACK_HELPER_H */
+
+#endif // NS3_CLICK
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/click/model/ipv4-click-routing.cc	Wed Feb 23 17:50:31 2011 +0000
@@ -0,0 +1,646 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 Lalith Suresh
+ *
+ * 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: Lalith Suresh <suresh.lalith@gmail.com>
+ */
+
+
+#ifdef NS3_CLICK
+
+#include "ns3/node.h"
+#include "ns3/simulator.h"
+#include "ns3/log.h"
+#include "ns3/mac48-address.h"
+#include "ns3/ipv4-interface.h"
+#include "ns3/ipv4-l3-click-protocol.h"
+
+#include "ipv4-click-routing.h"
+#include <string>
+#include <map>
+
+#include <cstdlib>
+#include <cstdarg>
+
+NS_LOG_COMPONENT_DEFINE ("Ipv4ClickRouting");
+
+namespace ns3 {
+
+// Values from nsclick ExtRouter implementation
+#define INTERFACE_ID_KERNELTAP 0
+#define INTERFACE_ID_FIRST 1
+#define INTERFACE_ID_FIRST_DROP 33 
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv4ClickRouting);
+
+std::map < simclick_node_t *, Ptr<Ipv4ClickRouting> > Ipv4ClickRouting::m_clickInstanceFromSimNode;
+
+TypeId
+Ipv4ClickRouting::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::Ipv4ClickRouting")
+    .SetParent<Ipv4RoutingProtocol> ()
+    .AddConstructor<Ipv4ClickRouting> ()
+  ;
+
+  return tid;
+}
+
+Ipv4ClickRouting::Ipv4ClickRouting ()
+  : m_nonDefaultName (false),
+    m_ipv4 (0)
+{
+}
+
+Ipv4ClickRouting::~Ipv4ClickRouting ()
+{
+}
+
+void
+Ipv4ClickRouting::DoStart ()
+{
+  uint32_t id = m_ipv4->GetObject<Node> ()->GetId ();
+
+  if (!m_nonDefaultName)
+    {
+      std::stringstream name;
+      name << "Node" << id;
+      m_nodeName = name.str ();
+    }
+
+  m_simNode = new simclick_node_t;
+  timerclear (&m_simNode->curtime);
+
+  AddSimNodeToClickMapping ();
+
+  NS_ASSERT (m_clickFile.length () > 0);
+
+  // Even though simclick_click_create() will halt programme execution
+  // if it is unable to initialise a Click router, we play safe
+  if (simclick_click_create (m_simNode, m_clickFile.c_str ()) >= 0)
+    {
+      NS_LOG_DEBUG (m_nodeName << " has initialised a Click Router");
+      m_clickInitialised = true;
+    }
+  else
+    {
+      NS_LOG_DEBUG ("Click Router Initialisation failed for " << m_nodeName);
+      m_clickInitialised = false;
+    }
+
+  NS_ASSERT (m_clickInitialised == true);
+  simclick_click_run (m_simNode);
+}
+
+void
+Ipv4ClickRouting::SetIpv4 (Ptr<Ipv4> ipv4)
+{
+  m_ipv4 = ipv4;
+}
+
+void
+Ipv4ClickRouting::DoDispose ()
+{
+  m_ipv4 = 0;
+  delete m_simNode;
+  Ipv4RoutingProtocol::DoDispose ();
+}
+
+void
+Ipv4ClickRouting::SetClickFile (std::string clickfile)
+{
+  m_clickFile = clickfile;
+}
+
+void
+Ipv4ClickRouting::SetClickRoutingTableElement (std::string name)
+{
+  m_clickRoutingTableElement = name;
+}
+
+void
+Ipv4ClickRouting::SetNodeName (std::string name)
+{
+  m_nodeName = name;
+  m_nonDefaultName = true;
+}
+
+std::string
+Ipv4ClickRouting::GetNodeName ()
+{
+  return m_nodeName;
+}
+
+int
+Ipv4ClickRouting::GetInterfaceId (const char *ifname)
+{
+  int retval = -1;
+
+  // The below hard coding of interface names follows the
+  // same approach as used in the original nsclick code for
+  // ns-2. The interface names map directly to what is to
+  // be used in the Click configuration files.
+  // Thus eth0 will refer to the first network device of
+  // the node, and is to be named so in the Click graph.
+  // This function is called by Click during the intialisation
+  // phase of the Click graph, during which it tries to map
+  // interface IDs to interface names. The return value
+  // corresponds to the interface ID that Click will use.
+
+  // Tap/tun devices refer to the kernel devices
+  if (strstr(ifname, "tap") || strstr(ifname, "tun"))
+    {
+      retval = 0;
+    }
+  else if (const char *devname = strstr(ifname, "eth"))
+    {
+      while (*devname && !isdigit((unsigned char) *devname))
+        {
+          devname++;
+        }
+
+      if (*devname)
+        {
+          retval = atoi(devname) + INTERFACE_ID_FIRST;
+        }
+    }
+  else if (const char *devname = strstr(ifname, "drop"))
+    {
+      while (*devname && !isdigit((unsigned char) *devname))
+        {
+          devname++;
+        }
+      if (*devname)
+        {
+          retval = atoi(devname) + INTERFACE_ID_FIRST_DROP;
+        }
+    }
+
+  return retval;
+}
+
+bool
+Ipv4ClickRouting::IsInterfaceReady (int ifid)
+{
+  if (ifid >= 0 && ifid < (int) m_ipv4->GetNInterfaces ())
+    {
+      return true;
+    }
+  else
+    {
+      return false;
+    }
+}
+
+std::string
+Ipv4ClickRouting::GetIpAddressFromInterfaceId (int ifid)
+{
+  std::stringstream addr;
+  m_ipv4->GetAddress (ifid, 0).GetLocal ().Print (addr);
+
+  return addr.str ();
+}
+
+std::string
+Ipv4ClickRouting::GetMacAddressFromInterfaceId (int ifid)
+{
+  std::stringstream addr;
+
+  Ptr<NetDevice> device = m_ipv4->GetNetDevice (ifid);
+  Address devAddr = device->GetAddress ();
+  addr << Mac48Address::ConvertFrom(devAddr);
+
+  return addr.str ();
+}
+
+void
+Ipv4ClickRouting::AddSimNodeToClickMapping ()
+{
+  m_clickInstanceFromSimNode.insert (std::make_pair (m_simNode, this));
+}
+
+Ptr<Ipv4ClickRouting>
+Ipv4ClickRouting::GetClickInstanceFromSimNode (simclick_node_t *simnode)
+{
+  return m_clickInstanceFromSimNode[simnode];
+}
+
+void
+Ipv4ClickRouting::RunClickEvent ()
+{
+  m_simNode->curtime.tv_sec = Simulator::Now ().GetSeconds ();
+  m_simNode->curtime.tv_usec = Simulator::Now ().GetMicroSeconds () % 1000000;
+  simclick_click_run (m_simNode);
+}
+
+void
+Ipv4ClickRouting::HandleScheduleFromClick (const struct timeval *when)
+{
+  NS_LOG_DEBUG ("HandleScheduleFromClick at " << when->tv_sec << " " << when->tv_usec << " " << Simulator::Now ());
+
+  double simtime = when->tv_sec + (when->tv_usec / 1.0e6);
+  double simdelay = simtime - Simulator::Now ().GetMicroSeconds () / 1.0e6; 
+
+  Simulator::Schedule (Seconds (simdelay), &Ipv4ClickRouting::RunClickEvent, this);
+}
+
+void
+Ipv4ClickRouting::HandlePacketFromClick (int ifid, int ptype, const unsigned char* data, int len)
+{
+  NS_LOG_DEBUG ("HandlePacketFromClick"); 
+
+  // Figure out packet's destination here:
+  // If ifid == 0, then the packet's going up
+  // else, the packet's going down
+  if (ifid == 0)
+    {
+      NS_LOG_DEBUG ("Incoming packet from tap0. Sending Packet up the stack.");
+      Ptr<Ipv4L3ClickProtocol> ipv4l3 = DynamicCast<Ipv4L3ClickProtocol> (m_ipv4);
+
+      Ptr<Packet> p = Create<Packet> (data, len);
+
+      Ipv4Header ipHeader;
+      p->RemoveHeader (ipHeader);
+
+      ipv4l3->LocalDeliver (p, ipHeader, (uint32_t) ifid);
+    }
+  else if (ifid)
+    {
+      NS_LOG_DEBUG ("Incoming packet from eth" << ifid - 1 << " of type " << ptype <<". Sending packet down the stack.");
+
+      Ptr<Packet> p = Create<Packet> (data, len);
+
+      DynamicCast<Ipv4L3ClickProtocol> (m_ipv4)->SendDown (p, ifid);
+    }
+}
+
+void
+Ipv4ClickRouting::SendPacketToClick (int ifid, int ptype, const unsigned char* data, int len)
+{
+  NS_LOG_FUNCTION (this << ifid);
+  m_simNode->curtime.tv_sec = Simulator::Now ().GetSeconds ();
+  m_simNode->curtime.tv_usec = Simulator::Now ().GetMicroSeconds () % 1000000;
+
+  // Since packets in ns-3 don't have global Packet ID's and Flow ID's, we
+  // feed dummy values into pinfo. This avoids the need to make changes in the Click code
+  simclick_simpacketinfo pinfo;
+  pinfo.id = 0;
+  pinfo.fid = 0;
+
+  simclick_click_send(m_simNode,ifid,ptype,data,len,&pinfo);
+}
+
+void
+Ipv4ClickRouting::Send (Ptr<Packet> p, Ipv4Address src, Ipv4Address dst)
+{
+  uint32_t ifid;
+
+  // Find out which interface holds the src address of the packet...
+  for (ifid = 0; ifid < m_ipv4->GetNInterfaces (); ifid++)
+    {
+      Ipv4Address addr = m_ipv4->GetAddress (ifid, 0).GetLocal ();
+
+      if (addr == src)
+        {
+          break;
+        }
+    }
+
+  int len = p->GetSize ();
+  uint8_t *buf = new uint8_t [len];
+  p->CopyData (buf, len);
+
+  // ... and send the packet on the corresponding Click interface.
+  SendPacketToClick (0, SIMCLICK_PTYPE_IP, buf, len);
+
+  delete [] buf;
+}
+
+void
+Ipv4ClickRouting::Receive (Ptr<Packet> p, Mac48Address receiverAddr, Mac48Address dest)
+{
+  NS_LOG_FUNCTION (this << p << receiverAddr << dest);
+
+  uint32_t ifid;
+
+  // Find out which device this packet was received from...
+  for (ifid = 0; ifid < m_ipv4->GetNInterfaces (); ifid++)
+    {
+      Ptr<NetDevice> device = m_ipv4->GetNetDevice (ifid);
+
+      if (Mac48Address::ConvertFrom (device->GetAddress ()) == receiverAddr)
+        {
+          break;
+        }
+    }
+
+  int len = p->GetSize ();
+  uint8_t *buf = new uint8_t [len];
+  p->CopyData (buf, len);
+
+  //... and send the packet to the corresponding Click interface
+  SendPacketToClick (ifid, SIMCLICK_PTYPE_ETHER, buf, len);
+
+  delete [] buf;
+}
+
+std::string
+Ipv4ClickRouting::ReadHandler (std::string elementName, std::string handlerName)
+{
+  std::string s = simclick_click_read_handler (m_simNode, elementName.c_str (), handlerName.c_str (), 0, 0);
+  return s;
+}
+
+int
+Ipv4ClickRouting::WriteHandler (std::string elementName, std::string handlerName, std::string writeString)
+{
+  int r = simclick_click_write_handler (m_simNode, elementName.c_str (), handlerName.c_str (), writeString.c_str ());
+
+  // Note: There are probably use-cases for returning
+  // a write handler's error code, so don't assert.
+  // For example, the 'add' handler for IPRouteTable
+  // type elements fails if the route to be added
+  // already exists.
+
+  return r;
+}
+
+void
+Ipv4ClickRouting::SetPromiscuous (std::string ifName)
+{
+  Ptr<Ipv4L3ClickProtocol> ipv4l3 = DynamicCast<Ipv4L3ClickProtocol> (m_ipv4);
+  NS_ASSERT(ipv4l3);
+  // Interface ethN gets index 1+N, but netdevice will start at 0
+  // To ensure this, install a Click stack on a node only after
+  // all NetDevices have been installed.
+  ipv4l3->SetPromisc (GetInterfaceId (ifName.c_str ()) - 1);
+}
+
+Ptr<Ipv4Route>
+Ipv4ClickRouting::RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
+{
+  Ptr<Ipv4Route> rtentry;
+
+  std::stringstream addr;
+  addr << "lookup ";
+  header.GetDestination ().Print (addr);
+  // Probe the Click Routing Table for the required IP
+  // This returns a string of the form "InterfaceID GatewayAddr"
+  std::string s = ReadHandler (m_clickRoutingTableElement, addr.str ());
+
+  int pos = s.find (" ");
+
+  int interfaceId = atoi (s.substr (0, pos).c_str ());
+  Ipv4Address destination (s.substr (pos + 1).c_str ());
+
+  if (interfaceId != -1)
+    {
+      rtentry = Create<Ipv4Route> ();
+      rtentry->SetDestination (header.GetDestination ());
+      // the source address is the interface address that matches
+      // the destination address (when multiple are present on the 
+      // outgoing interface, one is selected via scoping rules)
+      NS_ASSERT (m_ipv4);
+      uint32_t numOifAddresses = m_ipv4->GetNAddresses (interfaceId);
+      NS_ASSERT (numOifAddresses > 0);
+      Ipv4InterfaceAddress ifAddr;
+      if (numOifAddresses == 1)
+        {
+          ifAddr = m_ipv4->GetAddress (interfaceId, 0);
+        }
+      else
+        {
+          NS_FATAL_ERROR ("XXX Not implemented yet:  IP aliasing and Click");
+        }
+      rtentry->SetSource (ifAddr.GetLocal ());
+      rtentry->SetGateway (destination);
+      rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceId));
+      sockerr = Socket::ERROR_NOTERROR;
+      NS_LOG_DEBUG ("Found route to " << rtentry->GetDestination () 
+                                      << " via nh " << rtentry->GetGateway ()
+                                      << " with source addr " << rtentry->GetSource ()
+                                      << " and output dev " << rtentry->GetOutputDevice());
+    }
+  else
+    {
+      NS_LOG_DEBUG ("Click node " << m_nodeName
+                                  << ": RouteOutput for dest=" << header.GetDestination ()
+                                  << " No route to host");
+      sockerr = Socket::ERROR_NOROUTETOHOST;
+    }
+
+  return rtentry;
+}
+
+// This method should never be called since Click handles
+// forwarding directly
+bool
+Ipv4ClickRouting::RouteInput  (Ptr<const Packet> p, const Ipv4Header &header,
+                               Ptr<const NetDevice> idev, UnicastForwardCallback ucb,
+                               MulticastForwardCallback mcb, LocalDeliverCallback lcb, 
+                               ErrorCallback ecb)
+{
+  NS_FATAL_ERROR ("Click router does not have a RouteInput() interface!");
+  return false;
+}
+
+void
+Ipv4ClickRouting::PrintRoutingTable (Ptr<OutputStreamWrapper> stream) const
+{
+}
+
+void
+Ipv4ClickRouting::NotifyInterfaceUp (uint32_t i)
+{}
+
+void
+Ipv4ClickRouting::NotifyInterfaceDown (uint32_t i)
+{}
+
+void
+Ipv4ClickRouting::NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address)
+{}
+
+void
+Ipv4ClickRouting::NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address)
+{}
+
+
+} // namespace ns3
+
+static int simstrlcpy(char *buf, int len, const std::string &s)
+{
+  if (len)
+    {
+      len--;
+
+      if ((unsigned) len > s.length())
+        {
+          len = s.length();
+        }
+
+      s.copy(buf, len);
+      buf[len] = '\0';
+    }
+  return 0;
+}
+
+// Sends a Packet from Click to the Simulator: Defined in simclick.h. Click
+// calls these methods.
+int simclick_sim_send(simclick_node_t *simnode,
+                      int ifid, int type, const unsigned char* data, int len,
+                      simclick_simpacketinfo *pinfo)
+{
+  NS_LOG_DEBUG ("simclick_sim_send called at " << ns3::Simulator::Now().GetSeconds()<<": " << ifid << " " << type << " " << data << " "<< len);
+
+  if (simnode == NULL)
+    {
+      return -1;
+    }
+
+  ns3::Ptr<ns3::Ipv4ClickRouting> clickInstance = ns3::Ipv4ClickRouting::GetClickInstanceFromSimNode (simnode);
+
+  clickInstance->HandlePacketFromClick (ifid, type, data, len);
+
+  return 0;
+}
+
+// Click Service Methods: Defined in simclick.h
+int simclick_sim_command(simclick_node_t *simnode, int cmd, ...)
+{
+  va_list val;
+  va_start (val, cmd);
+
+  int retval = 0;
+
+  ns3::Ptr<ns3::Ipv4ClickRouting> clickInstance = ns3::Ipv4ClickRouting::GetClickInstanceFromSimNode (simnode);
+  switch (cmd) 
+    {
+    case SIMCLICK_VERSION:
+      {
+        retval = 0;
+        break;
+      }
+
+    case SIMCLICK_SUPPORTS:
+      {
+        int othercmd = va_arg (val, int);
+        retval = (othercmd >= SIMCLICK_VERSION && othercmd <= SIMCLICK_GET_NODE_ID);
+        break;
+      }
+
+    case SIMCLICK_IFID_FROM_NAME:
+      {
+        const char *ifname = va_arg(val, const char *);
+
+        retval = clickInstance->GetInterfaceId (ifname);
+ 
+        NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_IFID_FROM_NAME: " << ifname << " " << retval);
+        break;
+      }
+
+    case SIMCLICK_IPADDR_FROM_NAME:
+      {
+        const char *ifname = va_arg(val, const char *);
+        char *buf = va_arg(val, char *);
+        int len = va_arg(val, int);
+
+        int ifid = clickInstance->GetInterfaceId (ifname);
+
+        if (ifid >= 0)
+          {
+            retval = simstrlcpy(buf, len, clickInstance->GetIpAddressFromInterfaceId (ifid));
+          }
+        else
+          {
+            retval = -1;
+          }
+
+        NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_IPADDR_FROM_NAME: "<< ifname << " "<< buf << " " << len);
+        break;
+      }
+
+    case SIMCLICK_MACADDR_FROM_NAME:
+      {
+        const char *ifname = va_arg(val, const char *);
+        char *buf = va_arg(val, char *);
+        int len = va_arg(val, int);
+        int ifid = clickInstance->GetInterfaceId (ifname);
+
+        if (ifid >= 0)
+          {
+            retval = simstrlcpy(buf, len, clickInstance->GetMacAddressFromInterfaceId (ifid));
+          }
+        else
+          {
+            retval = -1;
+          }
+
+        NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_MACADDR_FROM_NAME: "<< ifname << " "<< buf << " "<< len);
+        break;
+      }
+
+    case SIMCLICK_SCHEDULE:
+      {
+        const struct timeval *when = va_arg(val, const struct timeval *);
+
+        clickInstance->HandleScheduleFromClick (when);
+
+        retval = 0;
+        NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_SCHEDULE: "<< when->tv_sec << "s and " << when->tv_usec << "usecs later.");
+
+        break;
+      }
+
+    case SIMCLICK_GET_NODE_NAME:
+      {
+        char *buf = va_arg(val, char *);
+        int len = va_arg(val, int);
+        retval = simstrlcpy(buf, len, clickInstance->GetNodeName ());
+
+        NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_GET_NODE_NAME: " << buf << " " << len);
+        break;
+      }
+
+    case SIMCLICK_IF_READY:
+      {
+        int ifid = va_arg(val, int); // Commented out so that optimized build works
+
+        // We're not using a ClickQueue, so we're always ready (for the timebeing)
+        retval = clickInstance->IsInterfaceReady (ifid);
+
+        NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_IF_READY: " << ifid << " " << ns3::Simulator::Now ());
+        break;
+      }
+
+    case SIMCLICK_TRACE:
+      {
+        // Used only for tracing
+        NS_LOG_DEBUG (clickInstance->GetNodeName () << " Received a call for SIMCLICK_TRACE");
+        break;
+      }
+
+    case SIMCLICK_GET_NODE_ID:
+      {
+        // Used only for tracing
+        NS_LOG_DEBUG (clickInstance->GetNodeName () << " Received a call for SIMCLICK_GET_NODE_ID");
+        break;
+      }
+    }
+  return retval;
+}
+
+#endif // NS3_CLICK
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/click/model/ipv4-click-routing.h	Wed Feb 23 17:50:31 2011 +0000
@@ -0,0 +1,247 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 Lalith Suresh 
+ *
+ * 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: Lalith Suresh <suresh.lalith@gmail.com>
+ */
+
+#ifndef __IPV4_CLICK_ROUTING_H__
+#define __IPV4_CLICK_ROUTING_H__
+
+#include "ns3/object.h"
+#include "ns3/packet.h"
+#include "ns3/ipv4.h"
+#include "ns3/ipv4-routing-protocol.h"
+#include "ns3/test.h"
+
+#include <sys/time.h>
+#include <sys/types.h>
+
+#ifdef NS3_CLICK
+#include <click/simclick.h>
+#endif
+
+#include <map>
+#include <string>
+
+namespace ns3 {
+
+/**
+* \ingroup click
+* \brief Class to allow a node to use Click for external routing
+*/
+
+class Ipv4ClickRouting : public Ipv4RoutingProtocol
+{
+#ifdef NS3_CLICK
+public:
+  // Allow test cases to access private members
+  friend class ClickTrivialTest;
+  friend class ClickIfidFromNameTest;
+  friend class ClickIpMacAddressFromNameTest;
+
+  static TypeId GetTypeId (void);
+
+  Ipv4ClickRouting ();
+  virtual ~Ipv4ClickRouting ();
+
+protected:
+  virtual void DoStart (void);
+
+public:
+  virtual void DoDispose ();
+
+  /**
+  * \brief Click configuration file to be used by the node's Click Instance.
+  * \param clickfile name of .click configuration file
+  */
+  void SetClickFile (std::string clickfile);
+
+  /**
+   * \brief Name of the node as to be used by Click. Required for Click Dumps.
+   * \param name Name to be assigned to the node.
+   */
+  void SetNodeName (std::string name);
+
+  /**
+   * \brief Name of the routing table element being used by Click. Required for RouteOutput ()
+   * \param name Name of the routing table element.
+   */
+  void SetClickRoutingTableElement (std::string name);
+
+  /**
+   * \brief Read Handler interface for a node's Click Elements.
+   *        Allows a user to read state information of a Click element.
+   * \param elementName name of the Click element
+   * \param handlerName name of the handler to be read
+   */
+  std::string ReadHandler (std::string elementName, std::string handlerName);
+
+  /**
+   * \brief Write Handler interface for a node's Click Elements
+   *        Allows a user to modify state information of a Click element.
+   * \param elementName name of the Click element
+   * \param handlerName name of the handler to be read
+   * \param writeString string to be written using the write handler
+   */
+  int WriteHandler (std::string elementName, std::string handlerName, std::string writeString);
+
+  /**
+   *
+   * \brief Sets an interface to run on promiscuous mode.
+   */
+  void SetPromiscuous (std::string ifName);
+
+private:
+  simclick_node_t *m_simNode;
+
+  /**
+   * \brief Provide a mapping between the node reference used by Click and the corresponding Ipv4ClickRouting instance.
+   */
+  static std::map < simclick_node_t *, Ptr<Ipv4ClickRouting> > m_clickInstanceFromSimNode;
+
+public:
+  /**
+   * \brief Allows the Click service methods, which reside outside Ipv4ClickRouting, to get the required Ipv4ClickRouting instances.
+   * \param simnode The Click simclick_node_t instance for which the Ipv4ClickRouting instance is required
+   * \return A Ptr to the required Ipv4ClickRouting instance
+   */
+  static Ptr<Ipv4ClickRouting> GetClickInstanceFromSimNode (simclick_node_t *simnode);
+
+public:
+
+  /**
+   * \brief Provides for SIMCLICK_IFID_FROM_NAME
+   * \param ifname The name of the interface
+   * \return The interface ID which corresponds to ifname
+   */
+  int GetInterfaceId (const char *ifname);
+
+  /**
+   * \brief Provides for SIMCLICK_IPADDR_FROM_NAME
+   * \param ifid The interface ID for which the IP Address is required
+   * \return The IP Address of the interface in string format
+   */
+  std::string GetIpAddressFromInterfaceId (int ifid);
+
+  /**
+   * \brief Provides for SIMCLICK_MACADDR_FROM_NAME
+   * \param ifid The interface ID for which the MAC Address is required
+   * \return The MAC Address of the interface in string format
+   */
+  std::string GetMacAddressFromInterfaceId (int ifid);
+
+  /**
+   * \brief Provides for SIMCLICK_GET_NODE_NAME
+   * \return The Node name
+   */
+  std::string GetNodeName ();
+
+  /**
+   * \brief Provides for SIMCLICK_IF_READY
+   * \return Returns 1, if the interface is ready, -1 if ifid is invalid
+   */
+  bool IsInterfaceReady (int ifid);
+
+  /**
+   * \brief Set the Ipv4 instance to be used
+   * \param ipv4 The Ipv4 instance
+   */
+  virtual void SetIpv4 (Ptr<Ipv4> ipv4);
+
+private:
+  /**
+   * \brief Used internally in DoStart () to Add a mapping to m_clickInstanceFromSimNode mapping
+   */
+  void AddSimNodeToClickMapping ();
+
+  /**
+   * \brief This method has to be scheduled everytime Click calls SIMCLICK_SCHEDULE
+   */
+  void RunClickEvent ();
+
+public:
+
+  /**
+   * \brief Schedules simclick_click_run to run at the given time
+   * \param when Time at which the simclick_click_run instance should be run
+   */
+  void HandleScheduleFromClick (const struct timeval *when);
+
+  /**
+   * \brief Receives a packet from Click
+   * \param ifid The interface ID from which the packet is arriving
+   * \param type The type of packet as defined in click/simclick.h
+   * \param data The contents of the packet
+   * \param len The length of the packet
+   */
+  void HandlePacketFromClick (int ifid, int type, const unsigned char *data, int len);
+
+  /**
+   * \brief Sends a packet to Click
+   * \param ifid The interface ID from which the packet is arriving
+   * \param type The type of packet as defined in click/simclick.h
+   * \param data The contents of the packet
+   * \param len The length of the packet
+   */
+  void SendPacketToClick (int ifid, int type, const unsigned char *data, int len);
+
+  /**
+   * \brief Allow a higher layer to send data through Click. (From Ipv4ExtRouting)
+   * \param p The packet to be sent
+   * \param src The source IP Address
+   * \param dest The destination IP Address
+   */
+  void Send (Ptr<Packet> p, Ipv4Address src, Ipv4Address dest); 
+
+  /**
+   * \brief Allow a lower layer to send data to Click. (From Ipv4ExtRouting)
+   * \param p The packet to be sent
+   * \param receiverAddr Receiving interface's address
+   * \param dest The Destination MAC address
+   */
+  void Receive (Ptr<Packet> p, Mac48Address receiverAddr, Mac48Address dest);
+
+  // From Ipv4RoutingProtocol
+  virtual Ptr<Ipv4Route> RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr);
+  virtual bool RouteInput  (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev,
+                            UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+                            LocalDeliverCallback lcb, ErrorCallback ecb);
+  virtual void PrintRoutingTable (Ptr<OutputStreamWrapper> stream) const;
+  virtual void NotifyInterfaceUp (uint32_t interface);
+  virtual void NotifyInterfaceDown (uint32_t interface);
+  virtual void NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address);
+  virtual void NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address);
+
+private:
+  std::string m_clickFile;
+  std::string m_nodeName;
+  std::string m_clickRoutingTableElement;
+
+
+  std::map < std::string, uint32_t > m_ifaceIdFromName;
+  std::map < std::string, Address > m_ifaceMacFromName;
+  std::map < std::string, Ipv4Address > m_ifaceAddrFromName;
+  bool m_clickInitialised;
+  bool m_nonDefaultName;
+
+  Ptr<Ipv4> m_ipv4;
+#endif //NS3_CLICK
+};
+
+} // namespace ns3
+
+#endif // __IPV4_CLICK_ROUTING_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/click/model/ipv4-l3-click-protocol.cc	Wed Feb 23 17:50:31 2011 +0000
@@ -0,0 +1,818 @@
+/* -*- 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>
+// Author: Lalith Suresh <suresh.lalith@gmail.com>
+//
+
+#ifdef NS3_CLICK
+
+#include "ipv4-l3-click-protocol.h"
+#include "ns3/ipv4-click-routing.h"
+#include "ns3/node.h"
+#include "ns3/socket.h"
+#include "ns3/ethernet-header.h"
+#include "ns3/llc-snap-header.h"
+#include "ns3/net-device.h"
+#include "ns3/uinteger.h"
+#include "ns3/object-vector.h"
+
+#include "ns3/ipv4-raw-socket-impl.h"
+#include "ns3/arp-l3-protocol.h"
+#include "ns3/ipv4-l4-protocol.h"
+#include "ns3/icmpv4-l4-protocol.h"
+#include "ns3/loopback-net-device.h"
+
+NS_LOG_COMPONENT_DEFINE ("Ipv4L3ClickProtocol");
+
+namespace ns3 {
+
+const uint16_t Ipv4L3ClickProtocol::PROT_NUMBER = 0x0800;
+
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv4L3ClickProtocol);
+
+TypeId
+Ipv4L3ClickProtocol::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::Ipv4L3ClickProtocol")
+    .SetParent<Ipv4> ()
+    .AddConstructor<Ipv4L3ClickProtocol> ()
+    .AddAttribute ("DefaultTtl", "The TTL value set by default on all outgoing packets generated on this node.",
+                   UintegerValue (64),
+                   MakeUintegerAccessor (&Ipv4L3ClickProtocol::m_defaultTtl),
+                   MakeUintegerChecker<uint8_t> ())
+    .AddAttribute ("InterfaceList", "The set of Ipv4 interfaces associated to this Ipv4 stack.",
+                   ObjectVectorValue (),
+                   MakeObjectVectorAccessor (&Ipv4L3ClickProtocol::m_interfaces),
+                   MakeObjectVectorChecker<Ipv4Interface> ())
+  ;
+  return tid;
+}
+
+Ipv4L3ClickProtocol::Ipv4L3ClickProtocol ()
+  : m_identification (0)
+{
+}
+
+Ipv4L3ClickProtocol::~Ipv4L3ClickProtocol ()
+{
+}
+
+void
+Ipv4L3ClickProtocol::DoDispose (void)
+{
+  NS_LOG_FUNCTION (this);
+  for (L4List_t::iterator i = m_protocols.begin(); i != m_protocols.end(); ++i)
+    {
+      *i = 0;
+    }
+  m_protocols.clear ();
+
+  for (Ipv4InterfaceList::iterator i = m_interfaces.begin (); i != m_interfaces.end (); ++i)
+    {
+      *i = 0;
+    }
+  m_interfaces.clear ();
+  m_sockets.clear ();
+  m_node = 0;
+  m_routingProtocol = 0;
+  Object::DoDispose ();
+}
+
+void
+Ipv4L3ClickProtocol::NotifyNewAggregate ()
+{
+  if (m_node == 0)
+    {
+      Ptr<Node>node = this->GetObject<Node>();
+      // verify that it's a valid node and that
+      // the node has not been set before
+      if (node != 0)
+        {
+          this->SetNode (node);
+        }
+    }
+  Object::NotifyNewAggregate ();
+}
+
+void
+Ipv4L3ClickProtocol::SetRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol)
+{
+  NS_LOG_FUNCTION (this);
+  m_routingProtocol = routingProtocol;
+  m_routingProtocol->SetIpv4 (this);
+}
+
+
+Ptr<Ipv4RoutingProtocol>
+Ipv4L3ClickProtocol::GetRoutingProtocol (void) const
+{
+  return m_routingProtocol;
+}
+
+Ptr<Ipv4Interface>
+Ipv4L3ClickProtocol::GetInterface (uint32_t index) const
+{
+  NS_LOG_FUNCTION (this << index);
+  if (index < m_interfaces.size ())
+    {
+      return m_interfaces[index];
+    }
+  return 0;
+}
+
+uint32_t
+Ipv4L3ClickProtocol::GetNInterfaces (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_interfaces.size ();
+}
+
+int32_t
+Ipv4L3ClickProtocol::GetInterfaceForAddress (
+  Ipv4Address address) const
+{
+  NS_LOG_FUNCTION (this << address);
+
+  int32_t interface = 0;
+  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
+       i != m_interfaces.end ();
+       i++, interface++)
+    {
+      for (uint32_t j = 0; j < (*i)->GetNAddresses (); j++)
+        {
+          if ((*i)->GetAddress (j).GetLocal () == address)
+            {
+              return interface;
+            }
+        }
+    }
+
+  return -1;
+}
+
+int32_t
+Ipv4L3ClickProtocol::GetInterfaceForPrefix (
+  Ipv4Address address,
+  Ipv4Mask mask) const
+{
+  NS_LOG_FUNCTION (this << address << mask);
+
+  int32_t interface = 0;
+  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
+       i != m_interfaces.end ();
+       i++, interface++)
+    {
+      for (uint32_t j = 0; j < (*i)->GetNAddresses (); j++)
+        {
+          if ((*i)->GetAddress (j).GetLocal ().CombineMask (mask) == address.CombineMask (mask))
+            {
+              return interface;
+            }
+        }
+    }
+
+  return -1;
+}
+
+int32_t
+Ipv4L3ClickProtocol::GetInterfaceForDevice (
+  Ptr<const NetDevice> device) const
+{
+  NS_LOG_FUNCTION (this << device->GetIfIndex());
+
+  int32_t interface = 0;
+  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
+       i != m_interfaces.end ();
+       i++, interface++)
+    {
+      if ((*i)->GetDevice () == device)
+        {
+          return interface;
+        }
+    }
+
+  return -1;
+}
+
+bool
+Ipv4L3ClickProtocol::IsDestinationAddress (Ipv4Address address, uint32_t iif) const
+{
+  NS_LOG_FUNCTION (this << address << " " << iif);
+
+  // First check the incoming interface for a unicast address match
+  for (uint32_t i = 0; i < GetNAddresses (iif); i++)
+    {
+      Ipv4InterfaceAddress iaddr = GetAddress (iif, i);
+      if (address == iaddr.GetLocal ())
+        {
+          NS_LOG_LOGIC ("For me (destination " << address << " match)");
+          return true;
+        }
+      if (address == iaddr.GetBroadcast ())
+        {
+          NS_LOG_LOGIC ("For me (interface broadcast address)");
+          return true;
+        }
+    }
+
+  if (address.IsMulticast ())
+    {
+#ifdef NOTYET
+      if (MulticastCheckGroup (iif, address ))
+#endif
+      if (true)
+        {
+          NS_LOG_LOGIC ("For me (Ipv4Addr multicast address");
+          return true;
+        }
+    }
+
+  if (address.IsBroadcast ())
+    {
+      NS_LOG_LOGIC ("For me (Ipv4Addr broadcast address)");
+      return true;
+    }
+
+  if (GetWeakEsModel ())  // Check other interfaces
+    {
+      for (uint32_t j = 0; j < GetNInterfaces (); j++)
+        {
+          if (j == uint32_t (iif)) continue;
+          for (uint32_t i = 0; i < GetNAddresses (j); i++)
+            {
+              Ipv4InterfaceAddress iaddr = GetAddress (j, i);
+              if (address == iaddr.GetLocal ())
+                {
+                  NS_LOG_LOGIC ("For me (destination " << address << " match) on another interface");
+                  return true;
+                }
+              //  This is a small corner case:  match another interface's broadcast address
+              if (address == iaddr.GetBroadcast ())
+                {
+                  NS_LOG_LOGIC ("For me (interface broadcast address on another interface)");
+                  return true;
+                }
+            }
+        }
+    }
+  return false;
+}
+
+void
+Ipv4L3ClickProtocol::SetIpForward (bool forward)
+{
+  NS_LOG_FUNCTION (this << forward);
+  m_ipForward = forward;
+  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
+    {
+      (*i)->SetForwarding (forward);
+    }
+}
+
+bool
+Ipv4L3ClickProtocol::GetIpForward (void) const
+{
+  return m_ipForward;
+}
+
+void
+Ipv4L3ClickProtocol::SetWeakEsModel (bool model)
+{
+  m_weakEsModel = model;
+}
+
+bool
+Ipv4L3ClickProtocol::GetWeakEsModel (void) const
+{
+  return m_weakEsModel;
+}
+
+Ptr<NetDevice>
+Ipv4L3ClickProtocol::GetNetDevice (uint32_t i)
+{
+  NS_LOG_FUNCTION (this << i);
+  return GetInterface (i)->GetDevice ();
+}
+
+void
+Ipv4L3ClickProtocol::SetDefaultTtl (uint8_t ttl)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_defaultTtl = ttl;
+}
+
+void
+Ipv4L3ClickProtocol::SetupLoopback (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  Ptr<Ipv4Interface> interface = CreateObject<Ipv4Interface> ();
+  Ptr<LoopbackNetDevice> device = 0;
+  // First check whether an existing LoopbackNetDevice exists on the node
+  for (uint32_t i = 0; i < m_node->GetNDevices (); i++)
+    {
+      if (device = DynamicCast<LoopbackNetDevice> (m_node->GetDevice (i)))
+        {
+          break;
+        }
+    }
+  if (device == 0)
+    {
+      device = CreateObject<LoopbackNetDevice> ();
+      m_node->AddDevice (device);
+    }
+  interface->SetDevice (device);
+  interface->SetNode (m_node);
+  Ipv4InterfaceAddress ifaceAddr = Ipv4InterfaceAddress (Ipv4Address::GetLoopback (), Ipv4Mask::GetLoopback ());
+  interface->AddAddress (ifaceAddr);
+  uint32_t index = AddIpv4Interface (interface);
+  Ptr<Node> node = GetObject<Node> ();
+  node->RegisterProtocolHandler (MakeCallback (&Ipv4L3ClickProtocol::Receive, this),
+                                 Ipv4L3ClickProtocol::PROT_NUMBER, device);
+  interface->SetUp ();
+  if (m_routingProtocol != 0)
+    {
+      m_routingProtocol->NotifyInterfaceUp (index);
+    }
+}
+
+Ptr<Socket>
+Ipv4L3ClickProtocol::CreateRawSocket (void)
+{
+  NS_LOG_FUNCTION (this);
+  Ptr<Ipv4RawSocketImpl> socket = CreateObject<Ipv4RawSocketImpl> ();
+  socket->SetNode (m_node);
+  m_sockets.push_back (socket);
+  return socket;
+}
+void
+Ipv4L3ClickProtocol::DeleteRawSocket (Ptr<Socket> socket)
+{
+  NS_LOG_FUNCTION (this << socket);
+  for (SocketList::iterator i = m_sockets.begin (); i != m_sockets.end (); ++i)
+    {
+      if ((*i) == socket)
+        {
+          m_sockets.erase (i);
+          return;
+        }
+    }
+  return;
+}
+
+
+void
+Ipv4L3ClickProtocol::SetNode (Ptr<Node> node)
+{
+  m_node = node;
+  // Add a LoopbackNetDevice if needed, and an Ipv4Interface on top of it
+  SetupLoopback ();
+}
+
+bool
+Ipv4L3ClickProtocol::AddAddress (uint32_t i, Ipv4InterfaceAddress address)
+{
+  NS_LOG_FUNCTION (this << i << address);
+  Ptr<Ipv4Interface> interface = GetInterface (i);
+  bool retVal = interface->AddAddress (address);
+  if (m_routingProtocol != 0)
+    {
+      m_routingProtocol->NotifyAddAddress (i, address);
+    }
+  return retVal;
+}
+
+Ipv4InterfaceAddress
+Ipv4L3ClickProtocol::GetAddress (uint32_t interfaceIndex, uint32_t addressIndex) const
+{
+  NS_LOG_FUNCTION (this << interfaceIndex << addressIndex);
+  Ptr<Ipv4Interface> interface = GetInterface (interfaceIndex);
+  return interface->GetAddress (addressIndex);
+}
+
+uint32_t
+Ipv4L3ClickProtocol::GetNAddresses (uint32_t interface) const
+{
+  NS_LOG_FUNCTION (this << interface);
+  Ptr<Ipv4Interface> iface = GetInterface (interface);
+  return iface->GetNAddresses ();
+}
+
+bool
+Ipv4L3ClickProtocol::RemoveAddress (uint32_t i, uint32_t addressIndex)
+{
+  NS_LOG_FUNCTION (this << i << addressIndex);
+  Ptr<Ipv4Interface> interface = GetInterface (i);
+  Ipv4InterfaceAddress address = interface->RemoveAddress (addressIndex);
+  if (address != Ipv4InterfaceAddress ())
+    {
+      if (m_routingProtocol != 0)
+        {
+          m_routingProtocol->NotifyRemoveAddress (i, address);
+        }
+      return true;
+    }
+  return false;
+}
+
+Ipv4Address
+Ipv4L3ClickProtocol::SelectSourceAddress (Ptr<const NetDevice> device,
+                                          Ipv4Address dst, Ipv4InterfaceAddress::InterfaceAddressScope_e scope)
+{
+  NS_LOG_FUNCTION (device << dst << scope);
+  Ipv4Address addr ("0.0.0.0");
+  Ipv4InterfaceAddress iaddr;
+  bool found = false;
+
+  if (device != 0)
+    {
+      int32_t i = GetInterfaceForDevice (device);
+      NS_ASSERT_MSG (i >= 0, "No device found on node");
+      for (uint32_t j = 0; j < GetNAddresses (i); j++)
+        {
+          iaddr = GetAddress (i, j);
+          if (iaddr.IsSecondary ()) continue;
+          if (iaddr.GetScope () > scope) continue;
+          if (dst.CombineMask (iaddr.GetMask ())  == iaddr.GetLocal ().CombineMask (iaddr.GetMask ()) )
+            {
+              return iaddr.GetLocal ();
+            }
+          if (!found)
+            {
+              addr = iaddr.GetLocal ();
+              found = true;
+            }
+        }
+    }
+  if (found)
+    {
+      return addr;
+    }
+
+  // Iterate among all interfaces
+  for (uint32_t i = 0; i < GetNInterfaces (); i++)
+    {
+      for (uint32_t j = 0; j < GetNAddresses (i); j++)
+        {
+          iaddr = GetAddress (i, j);
+          if (iaddr.IsSecondary ()) continue;
+          if (iaddr.GetScope () != Ipv4InterfaceAddress::LINK
+              && iaddr.GetScope () <= scope)
+            {
+              return iaddr.GetLocal ();
+            }
+        }
+    }
+  NS_LOG_WARN ("Could not find source address for " << dst << " and scope "
+                                                    << scope << ", returning 0");
+  return addr;
+}
+
+void
+Ipv4L3ClickProtocol::SetMetric (uint32_t i, uint16_t metric)
+{
+  NS_LOG_FUNCTION (i << metric);
+  Ptr<Ipv4Interface> interface = GetInterface (i);
+  interface->SetMetric (metric);
+}
+
+uint16_t
+Ipv4L3ClickProtocol::GetMetric (uint32_t i) const
+{
+  NS_LOG_FUNCTION (i);
+  Ptr<Ipv4Interface> interface = GetInterface (i);
+  return interface->GetMetric ();
+}
+
+uint16_t
+Ipv4L3ClickProtocol::GetMtu (uint32_t i) const
+{
+  NS_LOG_FUNCTION (this << i);
+  Ptr<Ipv4Interface> interface = GetInterface (i);
+  return interface->GetDevice ()->GetMtu ();
+}
+
+bool
+Ipv4L3ClickProtocol::IsUp (uint32_t i) const
+{
+  NS_LOG_FUNCTION (this << i);
+  Ptr<Ipv4Interface> interface = GetInterface (i);
+  return interface->IsUp ();
+}
+
+void
+Ipv4L3ClickProtocol::SetUp (uint32_t i)
+{
+  NS_LOG_FUNCTION (this << i);
+  Ptr<Ipv4Interface> interface = GetInterface (i);
+  interface->SetUp ();
+
+  if (m_routingProtocol != 0)
+    {
+      m_routingProtocol->NotifyInterfaceUp (i);
+    }
+}
+
+void
+Ipv4L3ClickProtocol::SetDown (uint32_t ifaceIndex)
+{
+  NS_LOG_FUNCTION (this << ifaceIndex);
+  Ptr<Ipv4Interface> interface = GetInterface (ifaceIndex);
+  interface->SetDown ();
+
+  if (m_routingProtocol != 0)
+    {
+      m_routingProtocol->NotifyInterfaceDown (ifaceIndex);
+    }
+}
+
+bool
+Ipv4L3ClickProtocol::IsForwarding (uint32_t i) const
+{
+  NS_LOG_FUNCTION (this << i);
+  Ptr<Ipv4Interface> interface = GetInterface (i);
+  NS_LOG_LOGIC ("Forwarding state: " << interface->IsForwarding ());
+  return interface->IsForwarding ();
+}
+
+void
+Ipv4L3ClickProtocol::SetForwarding (uint32_t i, bool val)
+{
+  NS_LOG_FUNCTION (this << i);
+  Ptr<Ipv4Interface> interface = GetInterface (i);
+  interface->SetForwarding (val);
+}
+
+void
+Ipv4L3ClickProtocol::SetPromisc (uint32_t i)
+{
+  NS_ASSERT(i <= m_node->GetNDevices ());
+  if (i > m_promiscDeviceList.size ())
+    {
+      m_promiscDeviceList.resize (i);
+    }
+  std::vector<bool>::iterator it = m_promiscDeviceList.begin();
+  std::advance (it, i);
+  m_promiscDeviceList.insert (it, true);
+}
+
+uint32_t
+Ipv4L3ClickProtocol::AddInterface (Ptr<NetDevice> device)
+{
+  NS_LOG_FUNCTION (this << &device);
+
+  Ptr<Node> node = GetObject<Node> ();
+  NS_LOG_DEBUG("Size:" << m_promiscDeviceList.size () << " Interface index" << device->GetIfIndex ());
+  if (m_promiscDeviceList.size () > 0 &&
+      (m_promiscDeviceList.size () >= device->GetIfIndex ()) &&
+      (m_promiscDeviceList[device->GetIfIndex ()]))
+    {
+      node->RegisterProtocolHandler (MakeCallback (&Ipv4L3ClickProtocol::Receive, this),
+                                     0, device,true);
+    }
+  else
+    {
+      node->RegisterProtocolHandler (MakeCallback (&Ipv4L3ClickProtocol::Receive, this),
+                                     Ipv4L3ClickProtocol::PROT_NUMBER, device);
+    }
+  node->RegisterProtocolHandler (MakeCallback (&Ipv4L3ClickProtocol::Receive, this),
+                                 ArpL3Protocol::PROT_NUMBER, device);
+
+  Ptr<Ipv4Interface> interface = CreateObject<Ipv4Interface> ();
+  interface->SetNode (m_node);
+  interface->SetDevice (device);
+  interface->SetForwarding (m_ipForward);
+  return AddIpv4Interface (interface);
+}
+
+uint32_t
+Ipv4L3ClickProtocol::AddIpv4Interface (Ptr<Ipv4Interface>interface)
+{
+  NS_LOG_FUNCTION (this << interface);
+  uint32_t index = m_interfaces.size ();
+  m_interfaces.push_back (interface);
+  return index;
+}
+
+// XXX when should we set ip_id?   check whether we are incrementing
+// m_identification on packets that may later be dropped in this stack
+// and whether that deviates from Linux
+Ipv4Header
+Ipv4L3ClickProtocol::BuildHeader (
+  Ipv4Address source,
+  Ipv4Address destination,
+  uint8_t protocol,
+  uint16_t payloadSize,
+  uint8_t ttl,
+  bool mayFragment)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  Ipv4Header ipHeader;
+  ipHeader.SetSource (source);
+  ipHeader.SetDestination (destination);
+  ipHeader.SetProtocol (protocol);
+  ipHeader.SetPayloadSize (payloadSize);
+  ipHeader.SetTtl (ttl);
+  if (mayFragment == true)
+    {
+      ipHeader.SetMayFragment ();
+      ipHeader.SetIdentification (m_identification);
+      m_identification++;
+    }
+  else
+    {
+      ipHeader.SetDontFragment ();
+      // TBD:  set to zero here; will cause traces to change
+      ipHeader.SetIdentification (m_identification);
+      m_identification++;
+    }
+  if (Node::ChecksumEnabled ())
+    {
+      ipHeader.EnableChecksum ();
+    }
+  return ipHeader;
+}
+
+void
+Ipv4L3ClickProtocol::Send (Ptr<Packet> packet,
+                           Ipv4Address source,
+                           Ipv4Address destination,
+                           uint8_t protocol,
+                           Ptr<Ipv4Route> route)
+{
+  NS_LOG_FUNCTION (this << packet << source << destination << uint32_t(protocol) << route);
+
+  Ipv4Header ipHeader;
+  bool mayFragment = true;
+  uint8_t ttl = m_defaultTtl;
+  SocketIpTtlTag tag;
+  bool found = packet->RemovePacketTag (tag);
+  if (found)
+    {
+      ttl = tag.GetTtl ();
+    }
+
+  ipHeader = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, mayFragment);
+  Ptr<Ipv4ClickRouting> click = DynamicCast<Ipv4ClickRouting> (m_routingProtocol);
+  if (Node::ChecksumEnabled ())
+    {
+      ipHeader.EnableChecksum ();
+    }
+  packet->AddHeader (ipHeader);
+  click->Send (packet->Copy (), source, destination);
+  return;
+}
+
+void
+Ipv4L3ClickProtocol::SendDown (Ptr<Packet> p, int ifid)
+{
+  // Called by Ipv4ClickRouting.
+
+  // NetDevice::Send () attaches ethernet headers,
+  // so the one that Click attaches isn't required
+  // but we need the destination address and
+  // protocol values from the header.
+
+  Ptr<NetDevice> netdev = GetNetDevice (ifid);
+
+  EthernetHeader header;
+  p->RemoveHeader (header);
+
+  uint16_t protocol;
+
+  if (header.GetLengthType () <= 1500)
+    {
+      LlcSnapHeader llc;
+      p->RemoveHeader (llc);
+      protocol = llc.GetType ();
+    }
+  else
+    {
+      protocol = header.GetLengthType ();
+    }
+
+  // Use the destination address and protocol obtained
+  // from above to send the packet.
+  netdev->Send (p, header.GetDestination (), protocol); 
+}
+
+void
+Ipv4L3ClickProtocol::Receive( Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol, const Address &from,
+                              const Address &to, NetDevice::PacketType packetType)
+{
+  NS_LOG_FUNCTION (this << device << p << from << to);
+  Ptr<Packet> packet = p->Copy ();
+  
+  // Add an ethernet frame. This allows
+  // Click to work with csma and wifi
+  EthernetHeader hdr;
+  hdr.SetSource (Mac48Address::ConvertFrom (from));
+  hdr.SetDestination (Mac48Address::ConvertFrom (to));
+  hdr.SetLengthType (protocol);
+  packet->AddHeader (hdr);
+  
+  Ptr<Ipv4ClickRouting> click = DynamicCast<Ipv4ClickRouting> (GetRoutingProtocol ());
+  click->Receive (packet->Copy (), Mac48Address::ConvertFrom (device->GetAddress ()), Mac48Address::ConvertFrom (to));
+}
+
+void
+Ipv4L3ClickProtocol::LocalDeliver (Ptr<const Packet> packet, Ipv4Header const&ip, uint32_t iif)
+{
+  NS_LOG_FUNCTION (this << packet << &ip);
+  Ptr<Packet> p = packet->Copy (); // need to pass a non-const packet up
+
+  m_localDeliverTrace (ip, packet, iif);
+
+  Ptr<Ipv4L4Protocol> protocol = GetProtocol (ip.GetProtocol ());
+  if (protocol != 0)
+    {
+      // we need to make a copy in the unlikely event we hit the
+      // RX_ENDPOINT_UNREACH codepath
+      Ptr<Packet> copy = p->Copy ();
+      enum Ipv4L4Protocol::RxStatus status =
+        protocol->Receive (p, ip, GetInterface (iif));
+      switch (status) {
+        case Ipv4L4Protocol::RX_OK:
+        // fall through
+        case Ipv4L4Protocol::RX_ENDPOINT_CLOSED:
+        // fall through
+        case Ipv4L4Protocol::RX_CSUM_FAILED:
+          break;
+        case Ipv4L4Protocol::RX_ENDPOINT_UNREACH:
+          if (ip.GetDestination ().IsBroadcast () == true ||
+              ip.GetDestination ().IsMulticast () == true)
+            {
+              break; // Do not reply to broadcast or multicast
+            }
+          // Another case to suppress ICMP is a subnet-directed broadcast
+          bool subnetDirected = false;
+          for (uint32_t i = 0; i < GetNAddresses (iif); i++)
+            {
+              Ipv4InterfaceAddress addr = GetAddress (iif, i);
+              if (addr.GetLocal ().CombineMask (addr.GetMask ()) == ip.GetDestination().CombineMask (addr.GetMask ()) &&
+                  ip.GetDestination ().IsSubnetDirectedBroadcast (addr.GetMask ()))
+                {
+                  subnetDirected = true;
+                }
+            }
+          if (subnetDirected == false)
+            {
+              GetIcmp ()->SendDestUnreachPort (ip, copy);
+            }
+        }
+    }
+}
+
+Ptr<Icmpv4L4Protocol>
+Ipv4L3ClickProtocol::GetIcmp (void) const
+{
+  Ptr<Ipv4L4Protocol> prot = GetProtocol (Icmpv4L4Protocol::GetStaticProtocolNumber ());
+  if (prot != 0)
+    {
+      return prot->GetObject<Icmpv4L4Protocol> ();
+    }
+  else
+    {
+      return 0;
+    }
+}
+
+void
+Ipv4L3ClickProtocol::Insert(Ptr<Ipv4L4Protocol> protocol)
+{
+  m_protocols.push_back (protocol);
+}
+
+Ptr<Ipv4L4Protocol>
+Ipv4L3ClickProtocol::GetProtocol(int protocolNumber) const
+{
+  for (L4List_t::const_iterator i = m_protocols.begin(); i != m_protocols.end(); ++i)
+    {
+      if ((*i)->GetProtocolNumber () == protocolNumber)
+        {
+          return *i;
+        }
+    }
+  return 0;
+}
+
+
+} // namespace ns3
+
+#endif // NS3_CLICK
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/click/model/ipv4-l3-click-protocol.h	Wed Feb 23 17:50:31 2011 +0000
@@ -0,0 +1,270 @@
+/* -*- 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>
+// Author: Lalith Suresh <suresh.lalith@gmail.com>
+//
+
+#ifndef IPV4_L3_CLICK_PROTOCOL_H
+#define IPV4_L3_CLICK_PROTOCOL_H
+
+#include "ns3/ipv4.h"
+#include "ns3/net-device.h"
+#include "ns3/packet.h"
+#include "ns3/ipv4-routing-protocol.h"
+#include "ns3/traced-callback.h"
+#include "ns3/ipv4-interface.h"
+#include "ns3/log.h"
+
+namespace ns3 {
+
+class Packet;
+class NetDevice;
+class Ipv4Interface;
+class Ipv4Address;
+class Ipv4Header;
+class Ipv4RoutingTableEntry;
+class Ipv4Route;
+class Node;
+class Socket;
+class Ipv4RawSocketImpl;
+class Ipv4L4Protocol;
+class Icmpv4L4Protocol;
+
+/**
+ * \brief Implement the Ipv4 layer specifically for Click nodes
+ * to allow a clean integration of Click.
+ * 
+ * This is code is mostly repeated from the Ipv4L3Protocol implementation.
+ * Changes include:
+ *   - A stripped down version of Send().
+ *   - A stripped down version of Receive().
+ *   - A public version of LocalDeliver().
+ *   - Modifications to AddInterface().
+ */
+
+class Ipv4L3ClickProtocol : public Ipv4
+{
+#ifdef NS3_CLICK
+public:
+  static TypeId GetTypeId (void);
+
+  /**
+   * Protocol number for Ipv4 L3 (0x0800).
+   */
+  static const uint16_t PROT_NUMBER;
+
+  Ipv4L3ClickProtocol();
+  virtual ~Ipv4L3ClickProtocol();
+
+  /**
+   * \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) const;
+
+  /**
+   * \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 packet packet to send
+   * \param source source address of packet
+   * \param destination address of packet
+   * \param protocol number of packet
+   * \param route route entry
+   *
+   * Higher-level layers call this method to send a packet
+   * to Click
+   */
+  void Send (Ptr<Packet> packet, Ipv4Address source,
+             Ipv4Address destination, uint8_t protocol, Ptr<Ipv4Route> route);
+
+  /**
+   * \param packet packet to send down the stack
+   * \param ifid interface to be used for sending down packet
+   *
+   * Ipv4ClickRouting calls this method to send a packet further
+   * down the stack
+   */
+  void SendDown (Ptr<Packet> packet, int ifid);
+
+  /**
+   * Lower layer calls this method to send a packet to Click
+   * \param device network device
+   * \param p the packet
+   * \param protocol protocol value
+   * \param from address of the correspondant
+   * \param to address of the destination
+   * \param packetType type of the packet
+   */
+  void Receive( Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol, const Address &from,
+                const Address &to, NetDevice::PacketType packetType);
+
+  /**
+   * Ipv4ClickRouting calls this to locally deliver a packet
+   * \param p the packet
+   * \param ip The Ipv4Header of the packet
+   * \param iif The interface on which the packet was received
+   */
+  void LocalDeliver (Ptr<const Packet> p, Ipv4Header const&ip, uint32_t iif);
+
+  /**
+   * Get a pointer to the i'th Ipv4Interface
+   * \param i index of interface, pointer to which is to be returned
+   * \returns Pointer to the i'th Ipv4Interface if any.
+   */
+  Ptr<Ipv4Interface> GetInterface (uint32_t i) const;
+
+  /**
+   * Adds an Ipv4Interface to the interfaces list
+   * \param interface Pointer to the Ipv4Interface to be added
+   * \returns Index of the device which was added
+   */
+  uint32_t AddIpv4Interface (Ptr<Ipv4Interface> interface);
+
+  /**
+   * Calls m_node = node and sets up Loopback if needed
+   * \param node Pointer to the node
+   */
+  void SetNode (Ptr<Node> node);
+
+  /**
+   * Returns the Icmpv4L4Protocol for the node
+   * \returns Icmpv4L4Protocol instance of the node
+   */
+  Ptr<Icmpv4L4Protocol> GetIcmp (void) const;
+
+  /**
+   * Sets up a Loopback device
+   */
+  void SetupLoopback (void);
+
+  /**
+   * Creates a raw-socket
+   * \returns Pointer to the created socket
+   */
+  Ptr<Socket> CreateRawSocket (void);
+
+  /**
+   * Deletes a particular raw socket
+   * \param socket Pointer of socket to be deleted
+   */
+  void DeleteRawSocket (Ptr<Socket> socket);
+
+  // functions defined in base class Ipv4
+  void SetRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol);
+  Ptr<Ipv4RoutingProtocol> GetRoutingProtocol (void) const;
+
+  Ptr<NetDevice> GetNetDevice (uint32_t i);
+
+  uint32_t AddInterface (Ptr<NetDevice> device);
+  uint32_t GetNInterfaces (void) const;
+
+  int32_t GetInterfaceForAddress (Ipv4Address addr) const;
+  int32_t GetInterfaceForPrefix (Ipv4Address addr, Ipv4Mask mask) const;
+  int32_t GetInterfaceForDevice (Ptr<const NetDevice> device) const;
+  bool IsDestinationAddress (Ipv4Address address, uint32_t iif) const;
+
+  bool AddAddress (uint32_t i, Ipv4InterfaceAddress address);
+  Ipv4InterfaceAddress GetAddress (uint32_t interfaceIndex, uint32_t addressIndex) const;
+  uint32_t GetNAddresses (uint32_t interface) const;
+  bool RemoveAddress (uint32_t interfaceIndex, uint32_t addressIndex);
+  Ipv4Address SelectSourceAddress (Ptr<const NetDevice> device,
+                                   Ipv4Address dst, Ipv4InterfaceAddress::InterfaceAddressScope_e scope);
+
+  void SetMetric (uint32_t i, uint16_t metric);
+  uint16_t GetMetric (uint32_t i) const;
+  uint16_t GetMtu (uint32_t i) const;
+  bool IsUp (uint32_t i) const;
+  void SetUp (uint32_t i);
+  void SetDown (uint32_t i);
+  bool IsForwarding (uint32_t i) const;
+  void SetForwarding (uint32_t i, bool val);
+  void SetPromisc(uint32_t i);
+protected:
+
+  virtual void DoDispose (void);
+  /**
+   * This function will notify other components connected to the node that a new stack member is now connected
+   * This will be used to notify Layer 3 protocol of layer 4 protocol stack to connect them together.
+   */
+  virtual void NotifyNewAggregate ();
+
+private:
+  Ipv4Header BuildHeader (
+    Ipv4Address source,
+    Ipv4Address destination,
+    uint8_t protocol,
+    uint16_t payloadSize,
+    uint8_t ttl,
+    bool mayFragment);
+
+  virtual void SetIpForward (bool forward);
+  virtual bool GetIpForward (void) const;
+  virtual void SetWeakEsModel (bool model);
+  virtual bool GetWeakEsModel (void) const;
+
+  typedef std::vector<Ptr<Ipv4Interface> > Ipv4InterfaceList;
+  typedef std::list<Ptr<Ipv4RawSocketImpl> > SocketList;
+  typedef std::list<Ptr<Ipv4L4Protocol> > L4List_t;
+
+  Ptr<Ipv4RoutingProtocol> m_routingProtocol;
+  bool m_ipForward;
+  bool m_weakEsModel;
+  L4List_t m_protocols;
+  Ipv4InterfaceList m_interfaces;
+  uint8_t m_defaultTtl;
+  uint16_t m_identification;
+
+  Ptr<Node> m_node;
+
+  TracedCallback<const Ipv4Header &, Ptr<const Packet>, uint32_t> m_sendOutgoingTrace;
+  TracedCallback<const Ipv4Header &, Ptr<const Packet>, uint32_t> m_unicastForwardTrace;
+  TracedCallback<const Ipv4Header &, Ptr<const Packet>, uint32_t> m_localDeliverTrace;
+
+  SocketList m_sockets;
+
+  std::vector<bool> m_promiscDeviceList;
+
+#endif //NS3_CLICK
+};
+
+} //namespace ns3
+
+#endif // IPV4_L3_CLICK_ROUTING_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/click/test/ipv4-click-routing-test.cc	Wed Feb 23 17:50:31 2011 +0000
@@ -0,0 +1,222 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 Lalith Suresh
+ *
+ * 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: Lalith Suresh <suresh.lalith@gmail.com>
+ */
+
+#ifdef NS3_CLICK
+
+#include "ns3/test.h"
+#include "ns3/log.h"
+#include "ns3/node.h"
+#include "ns3/ipv4-l3-protocol.h"
+#include "ns3/simple-net-device.h"
+#include "ns3/ipv4-click-routing.h"
+#include "ns3/icmpv4-l4-protocol.h"
+#include "ns3/arp-l3-protocol.h"
+
+#include <click/simclick.h>
+
+namespace ns3 {
+
+static void
+AddClickInternetStack (Ptr<Node> node)
+{
+  // Setup ArpL3Protocol
+  Ptr<ArpL3Protocol> arp = CreateObject<ArpL3Protocol> ();
+  node->AggregateObject (arp);
+
+  // Setup Ipv4L3Protocol
+  Ptr<Ipv4L3Protocol> ipv4l3 = CreateObject<Ipv4L3Protocol> ();
+  node->AggregateObject (ipv4l3);
+
+  // Setup Click instance
+  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+  Ptr<Ipv4ClickRouting> click = CreateObject<Ipv4ClickRouting> ();
+  click->SetClickFile ("examples/click/nsclick-lan-single-interface.click");
+  ipv4->SetRoutingProtocol (click);
+}
+
+static void
+AddNetworkDevice (Ptr<Node> node, Mac48Address macaddr, Ipv4Address ipv4addr, Ipv4Mask ipv4mask)
+{
+  Ptr<SimpleNetDevice> rxDev1;
+
+  rxDev1 = CreateObject<SimpleNetDevice> ();
+  rxDev1->SetAddress (Mac48Address(macaddr));
+  node->AddDevice (rxDev1);
+
+  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+  uint32_t netdev_idx = ipv4->AddInterface (rxDev1);
+  Ipv4InterfaceAddress ipv4Addr = Ipv4InterfaceAddress (ipv4addr, ipv4mask);
+  ipv4->AddAddress (netdev_idx, ipv4Addr);
+  ipv4->SetUp (netdev_idx);
+}
+
+class ClickIfidFromNameTest : public TestCase
+{
+public:
+  ClickIfidFromNameTest ();
+  virtual void DoRun ();
+};
+
+ClickIfidFromNameTest::ClickIfidFromNameTest ()
+  : TestCase ("Test SIMCLICK_IFID_FROM_NAME")
+{
+}
+
+void
+ClickIfidFromNameTest::DoRun ()
+{
+  Ptr<Node> node = CreateObject<Node> ();
+  AddClickInternetStack (node);
+  AddNetworkDevice (node, Mac48Address("00:00:00:00:00:01"), Ipv4Address ("10.1.1.1"), Ipv4Mask ("255.255.255.0"));
+  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+  Ptr<Ipv4ClickRouting> click = DynamicCast<Ipv4ClickRouting> (ipv4->GetRoutingProtocol ());
+  click->DoStart ();
+
+  int ret;
+
+  ret = simclick_sim_command (click->m_simNode, SIMCLICK_IFID_FROM_NAME, "tap0");
+  NS_TEST_EXPECT_MSG_EQ (ret, 0, "tap0 is interface 0");
+
+  ret = simclick_sim_command (click->m_simNode, SIMCLICK_IFID_FROM_NAME, "tun0");
+  NS_TEST_EXPECT_MSG_EQ (ret, 0, "tun0 is interface 0");
+
+  ret = simclick_sim_command (click->m_simNode, SIMCLICK_IFID_FROM_NAME, "eth0");
+  NS_TEST_EXPECT_MSG_EQ (ret, 1, "Eth0 is interface 1");
+
+  ret = simclick_sim_command (click->m_simNode, SIMCLICK_IFID_FROM_NAME, "tap1");
+  NS_TEST_EXPECT_MSG_EQ (ret, 0, "tap1 is interface 0");
+
+  ret = simclick_sim_command (click->m_simNode, SIMCLICK_IFID_FROM_NAME, "tun1");
+  NS_TEST_EXPECT_MSG_EQ (ret, 0, "tun1 is interface 0");
+
+  ret = simclick_sim_command (click->m_simNode, SIMCLICK_IFID_FROM_NAME, "eth1");
+  NS_TEST_EXPECT_MSG_EQ (ret, -1, "No eth1 on node");
+
+}
+
+class ClickIpMacAddressFromNameTest : public TestCase
+{
+public:
+  ClickIpMacAddressFromNameTest (); 
+  virtual void DoRun ();
+};
+
+ClickIpMacAddressFromNameTest::ClickIpMacAddressFromNameTest ()
+  : TestCase ("Test SIMCLICK_IPADDR_FROM_NAME")
+{
+}
+
+void
+ClickIpMacAddressFromNameTest::DoRun ()
+{
+  Ptr<Node> node = CreateObject<Node> ();
+  AddClickInternetStack (node);
+  AddNetworkDevice (node, Mac48Address("00:00:00:00:00:01"), Ipv4Address ("10.1.1.1"), Ipv4Mask ("255.255.255.0"));
+  AddNetworkDevice (node, Mac48Address("00:00:00:00:00:02"), Ipv4Address ("10.1.1.2"), Ipv4Mask ("255.255.255.0"));
+  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+  Ptr<Ipv4ClickRouting> click = DynamicCast<Ipv4ClickRouting> (ipv4->GetRoutingProtocol ());
+  click->DoStart ();
+
+  int ret = 0;
+  char *buf = NULL;
+  buf = new char [255];
+
+  ret = simclick_sim_command (click->m_simNode, SIMCLICK_IPADDR_FROM_NAME, "eth0", buf, 255);
+  NS_TEST_EXPECT_MSG_EQ (strcmp (buf, "10.1.1.1"), 0, "eth0 has IP 10.1.1.1");
+
+  ret = simclick_sim_command (click->m_simNode, SIMCLICK_MACADDR_FROM_NAME, "eth0", buf, 255);
+  NS_TEST_EXPECT_MSG_EQ (strcmp (buf, "00:00:00:00:00:01"), 0, "eth0 has Mac Address 00:00:00:00:00:01");
+
+  ret = simclick_sim_command (click->m_simNode, SIMCLICK_IPADDR_FROM_NAME, "eth1", buf, 255);
+  NS_TEST_EXPECT_MSG_EQ (strcmp(buf, "10.1.1.2"), 0, "eth1 has IP 10.1.1.2");
+
+  ret = simclick_sim_command (click->m_simNode, SIMCLICK_MACADDR_FROM_NAME, "eth1", buf, 255);
+  NS_TEST_EXPECT_MSG_EQ (strcmp (buf, "00:00:00:00:00:02"), 0, "eth0 has Mac Address 00:00:00:00:00:02");
+
+  // Not sure how to test the below case, because the Ipv4ClickRouting code is to ASSERT for such inputs
+  // ret = simclick_sim_command (click->m_simNode, SIMCLICK_IPADDR_FROM_NAME, "eth2", buf, 255);
+  // NS_TEST_EXPECT_MSG_EQ (buf, NULL, "No eth2");
+
+  ret = simclick_sim_command (click->m_simNode, SIMCLICK_IPADDR_FROM_NAME, "tap0", buf, 255);
+  NS_TEST_EXPECT_MSG_EQ (strcmp(buf, "127.0.0.1"), 0, "tun0 has IP 127.0.0.1");
+
+  ret = simclick_sim_command (click->m_simNode, SIMCLICK_MACADDR_FROM_NAME, "tap0", buf, 255);
+  NS_TEST_EXPECT_MSG_EQ (strcmp(buf, "00:00:00:00:00:00"), 0, "tun0 has IP 127.0.0.1");
+
+  delete [] buf;
+}
+
+class ClickTrivialTest : public TestCase
+{
+public:
+  ClickTrivialTest ();
+  virtual void DoRun ();
+};
+
+ClickTrivialTest::ClickTrivialTest ()
+  : TestCase ("Test SIMCLICK_GET_NODE_NAME and SIMCLICK_IF_READY")
+{
+}
+
+void
+ClickTrivialTest::DoRun ()
+{
+  Ptr<Node> node = CreateObject<Node> ();
+  AddClickInternetStack (node);
+  AddNetworkDevice (node, Mac48Address("00:00:00:00:00:01"), Ipv4Address ("10.1.1.1"), Ipv4Mask ("255.255.255.0"));
+  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+  Ptr<Ipv4ClickRouting> click = DynamicCast<Ipv4ClickRouting> (ipv4->GetRoutingProtocol ());
+  click->SetNodeName ("myNode");
+  click->DoStart ();
+
+  int ret = 0;
+  char *buf = NULL;
+  buf = new char [255];
+
+  ret = simclick_sim_command (click->m_simNode, SIMCLICK_GET_NODE_NAME, buf, 255);
+  NS_TEST_EXPECT_MSG_EQ (strcmp (buf, "myNode"), 0, "Node name is Node");
+
+  ret = simclick_sim_command (click->m_simNode, SIMCLICK_IF_READY, 0);
+  NS_TEST_EXPECT_MSG_EQ (ret, 1, "tap0 is ready");
+
+  ret = simclick_sim_command (click->m_simNode, SIMCLICK_IF_READY, 1);
+  NS_TEST_EXPECT_MSG_EQ (ret, 1, "eth0 is ready");
+
+  ret = simclick_sim_command (click->m_simNode, SIMCLICK_IF_READY, 2);
+  NS_TEST_EXPECT_MSG_EQ (ret, -1, "eth1 does not exist, so return -1");
+
+  delete [] buf;
+  ret = 1;
+}
+
+class ClickIfidFromNameTestSuite : public TestSuite
+{
+public:
+  ClickIfidFromNameTestSuite () : TestSuite ("routing-click", UNIT)
+  {
+    AddTestCase (new ClickTrivialTest);
+    AddTestCase (new ClickIfidFromNameTest);
+    AddTestCase (new ClickIpMacAddressFromNameTest);
+  }
+} g_ipv4ClickRoutingTestSuite;
+
+} // namespace ns3
+
+#endif // NS3_CLICK
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/click/waf	Wed Feb 23 17:50:31 2011 +0000
@@ -0,0 +1,1 @@
+exec "`dirname "$0"`"/../../../waf "$@"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/routing/click/wscript	Wed Feb 23 17:50:31 2011 +0000
@@ -0,0 +1,93 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+import os
+import Options
+
+
+def set_options(opt):
+    opt.add_option('--with-nsclick',
+                   help=('Path to Click source for NS-3 Click Integration support'),
+                   dest='with_nsclick', default=None)
+
+def configure(conf):
+    if Options.options.with_nsclick:
+        if os.path.isdir(Options.options.with_nsclick):
+            conf.check_message("libnsclick.so location", '', True, ("%s (given)" % Options.options.with_nsclick))
+            conf.env['WITH_NSCLICK'] = os.path.abspath(Options.options.with_nsclick)
+    else:
+        nsclick_dir = os.path.join('..','click')
+        if os.path.isdir(nsclick_dir):
+            conf.check_message("click location", '', True, ("%s (guessed)" % nsclick_dir))
+            conf.env['WITH_NSCLICK'] = os.path.abspath(nsclick_dir)
+        del nsclick_dir
+    if not conf.env['WITH_NSCLICK']:
+        conf.check_message("click location", '', False)
+        conf.report_optional_feature("nsclick", "NS-3 Click Integration", False,
+                                     "nsclick not enabled (see option --with-nsclick)")
+        return
+
+    test_code = '''
+#include<sys/types.h>
+#include<sys/time.h>
+#include<click/simclick.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int simclick_sim_send(simclick_node_t *sim,int ifid,int type, const unsigned char* data,int len,simclick_simpacketinfo *pinfo)
+{
+  return 0;
+}
+
+int simclick_sim_command(simclick_node_t *sim, int cmd, ...)
+{
+  return 0;
+}
+#ifdef __cplusplus
+}
+#endif
+
+int main()
+{
+  return 0;
+}
+'''
+    conf.env['DL'] = conf.check(mandatory=True, lib='dl', define_name='DL', uselib='DL')
+
+    conf.env.append_value('NS3_MODULE_PATH',os.path.abspath(os.path.join(conf.env['WITH_NSCLICK'],'ns')))
+
+    conf.env['CPPPATH_NSCLICK'] = [os.path.abspath(os.path.join(conf.env['WITH_NSCLICK'],'include'))]
+    conf.env['LIBPATH_NSCLICK'] = [os.path.abspath(os.path.join(conf.env['WITH_NSCLICK'],'ns'))]
+    
+    conf.env['NSCLICK'] = conf.check(fragment=test_code, lib='nsclick', uselib='NSCLICK DL')
+    conf.report_optional_feature("nsclick", "NS-3 Click Integration",
+                                  conf.env['NSCLICK'], "nsclick library not found")
+    if conf.env['NSCLICK']:
+        conf.env.append_value('CXXDEFINES', 'NS3_CLICK')
+        conf.env.append_value('CPPPATH', conf.env['CPPPATH_NSCLICK'])
+
+def build(bld):
+
+    module = bld.create_ns3_module('click', ['internet-stack', 'contrib'])
+    module.includes = '. CPPPATH_NSCLICK'
+    module.source = [
+        'model/ipv4-click-routing.cc',
+        'model/ipv4-l3-click-protocol.cc',
+        'test/ipv4-click-routing-test.cc',
+        'helper/click-internet-stack-helper.cc',
+        ]
+
+    if bld.env['NSCLICK'] and bld.env['DL']:
+        module.uselib = 'NSCLICK DL'
+
+    headers = bld.new_task_gen('ns3header')
+    headers.module = 'click'
+    headers.source = [
+        'model/ipv4-click-routing.h',
+        'model/ipv4-l3-click-protocol.h',
+        'helper/click-internet-stack-helper.h',
+        ]
+
+    if bld.env['ENABLE_EXAMPLES']:
+        bld.add_subdirs('examples')