Convert the virtual-net-device module to the new layout
authorGustavo J. A. M. Carneiro <gjc@inescporto.pt>
Mon, 25 Oct 2010 15:13:44 +0100
changeset 6636 913bcb88a6a8
parent 6635 d52752c85699
child 6637 b7903dd92942
Convert the virtual-net-device module to the new layout
examples/tunneling/virtual-net-device.cc
examples/tunneling/waf
examples/tunneling/wscript
src/devices/virtual-net-device/examples/virtual-net-device.cc
src/devices/virtual-net-device/examples/wscript
src/devices/virtual-net-device/model/virtual-net-device.cc
src/devices/virtual-net-device/model/virtual-net-device.h
src/devices/virtual-net-device/virtual-net-device.cc
src/devices/virtual-net-device/virtual-net-device.h
src/devices/virtual-net-device/wscript
--- a/examples/tunneling/virtual-net-device.cc	Mon Oct 25 15:00:28 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,300 +0,0 @@
-/* -*- 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
- *
- * Based on simple-global-routing.cc
- */
-
-// Network topology
-//
-//  n0
-//     \ 5 Mb/s, 2ms
-//      \          1.5Mb/s, 10ms
-//       n2 -------------------------n3
-//      /
-//     / 5 Mb/s, 2ms
-//   n1
-//
-// - all links are point-to-point links with indicated one-way BW/delay
-// - CBR/UDP flows from n0 to n3, and from n3 to n1
-// - FTP/TCP flow from n0 to n3, starting at time 1.2 to time 1.35 sec.
-// - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec.
-//   (i.e., DataRate of 448,000 bps)
-// - DropTail queues 
-// - Tracing of queues and packet receptions to file "virtual-net-device.tr"
-
-// Tunneling changes (relative to the simple-global-routing example):
-// n0 will receive an extra virtual interface with address 11.0.0.1
-// n1 will also receive an extra virtual interface with the same address 11.0.0.1
-// n3 will receive an extra virtual interface with address 11.0.0.254
-// The flows will be between 11.0.0.x (tunnel) addresses instead of 10.1.x.y ones
-// n3 will decide, on a per-packet basis, via random number, whether to
-// send the packet to n0 or to n1.
-//
-// Note: here we create a tunnel where IP packets are tunneled over
-// UDP/IP, but tunneling directly IP-over-IP would also be possible;
-// see src/node/ipv4-raw-socket-factory.h.
-
-#include <iostream>
-#include <fstream>
-#include <string>
-#include <cassert>
-
-#include "ns3/core-module.h"
-#include "ns3/simulator-module.h"
-#include "ns3/node-module.h"
-#include "ns3/helper-module.h"
-#include "ns3/virtual-net-device.h"
-
-using namespace ns3;
-
-NS_LOG_COMPONENT_DEFINE ("VirtualNetDeviceExample");
-
-class Tunnel
-{
-  Ptr<Socket> m_n3Socket;
-  Ptr<Socket> m_n0Socket;
-  Ptr<Socket> m_n1Socket;
-  Ipv4Address m_n3Address;
-  Ipv4Address m_n0Address;
-  Ipv4Address m_n1Address;
-  UniformVariable m_rng;
-  Ptr<VirtualNetDevice> m_n0Tap;
-  Ptr<VirtualNetDevice> m_n1Tap;
-  Ptr<VirtualNetDevice> m_n3Tap;
-  
-  
-  bool
-  N0VirtualSend (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber)
-  {
-    NS_LOG_DEBUG ("Send to " << m_n3Address << ": " << *packet);
-    m_n0Socket->SendTo (packet, 0, InetSocketAddress (m_n3Address, 667));
-    return true;
-  }
-
-  bool
-  N1VirtualSend (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber)
-  {
-    NS_LOG_DEBUG ("Send to " << m_n3Address << ": " << *packet);
-    m_n1Socket->SendTo (packet, 0, InetSocketAddress (m_n3Address, 667));
-    return true;
-  }
-
-  bool
-  N3VirtualSend (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber)
-  {
-    if (m_rng.GetValue () < 0.25)
-      {
-        NS_LOG_DEBUG ("Send to " << m_n0Address << ": " << *packet);
-        m_n3Socket->SendTo (packet, 0, InetSocketAddress (m_n0Address, 667));
-      }
-    else 
-      {
-        NS_LOG_DEBUG ("Send to " << m_n1Address << ": " << *packet);
-        m_n3Socket->SendTo (packet, 0, InetSocketAddress (m_n1Address, 667));
-      }
-    return true;
-  }
-
-  void N3SocketRecv (Ptr<Socket> socket)
-  {
-    Ptr<Packet> packet = socket->Recv (65535, 0);
-    NS_LOG_DEBUG ("N3SocketRecv: " << *packet);
-    SocketAddressTag socketAddressTag;
-    packet->RemovePacketTag (socketAddressTag);
-    m_n3Tap->Receive (packet, 0x0800, m_n3Tap->GetAddress (), m_n3Tap->GetAddress (), NetDevice::PACKET_HOST);
-  }
-
-  void N0SocketRecv (Ptr<Socket> socket)
-  {
-    Ptr<Packet> packet = socket->Recv (65535, 0);
-    NS_LOG_DEBUG ("N0SocketRecv: " << *packet);
-    SocketAddressTag socketAddressTag;
-    packet->RemovePacketTag (socketAddressTag);
-    m_n0Tap->Receive (packet, 0x0800, m_n0Tap->GetAddress (), m_n0Tap->GetAddress (), NetDevice::PACKET_HOST);
-  }
-
-  void N1SocketRecv (Ptr<Socket> socket)
-  {
-    Ptr<Packet> packet = socket->Recv (65535, 0);
-    NS_LOG_DEBUG ("N1SocketRecv: " << *packet);
-    SocketAddressTag socketAddressTag;
-    packet->RemovePacketTag (socketAddressTag);
-    m_n1Tap->Receive (packet, 0x0800, m_n1Tap->GetAddress (), m_n1Tap->GetAddress (), NetDevice::PACKET_HOST);
-  }
-
-public:
-  
-  Tunnel (Ptr<Node> n3, Ptr<Node> n0, Ptr<Node> n1,
-          Ipv4Address n3Addr, Ipv4Address n0Addr, Ipv4Address n1Addr)
-    : m_n3Address (n3Addr), m_n0Address (n0Addr), m_n1Address (n1Addr)
-  {
-    m_n3Socket = Socket::CreateSocket (n3, TypeId::LookupByName ("ns3::UdpSocketFactory"));
-    m_n3Socket->Bind (InetSocketAddress (Ipv4Address::GetAny (), 667));
-    m_n3Socket->SetRecvCallback (MakeCallback (&Tunnel::N3SocketRecv, this));    
-    
-    m_n0Socket = Socket::CreateSocket (n0, TypeId::LookupByName ("ns3::UdpSocketFactory"));
-    m_n0Socket->Bind (InetSocketAddress (Ipv4Address::GetAny (), 667));
-    m_n0Socket->SetRecvCallback (MakeCallback (&Tunnel::N0SocketRecv, this));    
-    
-    m_n1Socket = Socket::CreateSocket (n1, TypeId::LookupByName ("ns3::UdpSocketFactory"));
-    m_n1Socket->Bind (InetSocketAddress (Ipv4Address::GetAny (), 667));
-    m_n1Socket->SetRecvCallback (MakeCallback (&Tunnel::N1SocketRecv, this));
-    
-    // n0 tap device
-    m_n0Tap = CreateObject<VirtualNetDevice> ();
-    m_n0Tap->SetAddress (Mac48Address ("11:00:01:02:03:01"));
-    m_n0Tap->SetSendCallback (MakeCallback (&Tunnel::N0VirtualSend, this));
-    n0->AddDevice (m_n0Tap);
-    Ptr<Ipv4> ipv4 = n0->GetObject<Ipv4> ();
-    uint32_t i = ipv4->AddInterface (m_n0Tap);
-    ipv4->AddAddress (i, Ipv4InterfaceAddress (Ipv4Address ("11.0.0.1"), Ipv4Mask ("255.255.255.0")));
-    ipv4->SetUp (i);
-    
-    // n1 tap device
-    m_n1Tap = CreateObject<VirtualNetDevice> ();
-    m_n1Tap->SetAddress (Mac48Address ("11:00:01:02:03:02"));
-    m_n1Tap->SetSendCallback (MakeCallback (&Tunnel::N1VirtualSend, this));
-    n1->AddDevice (m_n1Tap);
-    ipv4 = n1->GetObject<Ipv4> ();
-    i = ipv4->AddInterface (m_n1Tap);
-    ipv4->AddAddress (i, Ipv4InterfaceAddress (Ipv4Address ("11.0.0.1"), Ipv4Mask ("255.255.255.0")));
-    ipv4->SetUp (i);
-
-    // n3 tap device
-    m_n3Tap = CreateObject<VirtualNetDevice> ();
-    m_n3Tap->SetAddress (Mac48Address ("11:00:01:02:03:04"));
-    m_n3Tap->SetSendCallback (MakeCallback (&Tunnel::N3VirtualSend, this));
-    n3->AddDevice (m_n3Tap);
-    ipv4 = n3->GetObject<Ipv4> ();
-    i = ipv4->AddInterface (m_n3Tap);
-    ipv4->AddAddress (i, Ipv4InterfaceAddress (Ipv4Address ("11.0.0.254"), Ipv4Mask ("255.255.255.0")));
-    ipv4->SetUp (i);
-    
-  }
-  
-  
-};
-
-  
-
-int 
-main (int argc, char *argv[])
-{
-  // Users may find it convenient to turn on explicit debugging
-  // for selected modules; the below lines suggest how to do this
-#if 0 
-  LogComponentEnable ("VirtualNetDeviceExample", LOG_LEVEL_INFO);
-#endif
-  Packet::EnablePrinting ();
-  
-
-  // Set up some default values for the simulation.  Use the 
-  Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (210));
-  Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("448kb/s"));
-
-  //DefaultValue::Bind ("DropTailQueue::m_maxPackets", 30);   
-
-  // Allow the user to override any of the defaults and the above
-  // DefaultValue::Bind ()s at run-time, via command-line arguments
-  CommandLine cmd;
-  cmd.Parse (argc, argv);
-
-  // Here, we will explicitly create four nodes.  In more sophisticated
-  // topologies, we could configure a node factory.
-  NS_LOG_INFO ("Create nodes.");
-  NodeContainer c;
-  c.Create (4);
-  NodeContainer n0n2 = NodeContainer (c.Get(0), c.Get (2));
-  NodeContainer n1n2 = NodeContainer (c.Get(1), c.Get (2));
-  NodeContainer n3n2 = NodeContainer (c.Get(3), c.Get (2));
-
-  InternetStackHelper internet;
-  internet.Install (c);
-
-  // We create the channels first without any IP addressing information
-  NS_LOG_INFO ("Create channels.");
-  PointToPointHelper p2p;
-  p2p.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
-  p2p.SetChannelAttribute ("Delay", StringValue ("2ms"));
-  NetDeviceContainer d0d2 = p2p.Install (n0n2);
-
-  NetDeviceContainer d1d2 = p2p.Install (n1n2);
-  
-  p2p.SetDeviceAttribute ("DataRate", StringValue ("1500kbps"));
-  p2p.SetChannelAttribute ("Delay", StringValue ("10ms"));
-  NetDeviceContainer d3d2 = p2p.Install (n3n2);
-  
-  // Later, we add IP addresses.  
-  NS_LOG_INFO ("Assign IP Addresses.");
-  Ipv4AddressHelper ipv4;
-  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
-  Ipv4InterfaceContainer i0i2 = ipv4.Assign (d0d2);
-
-  ipv4.SetBase ("10.1.2.0", "255.255.255.0");
-  Ipv4InterfaceContainer i1i2 = ipv4.Assign (d1d2);
-  
-  ipv4.SetBase ("10.1.3.0", "255.255.255.0");
-  Ipv4InterfaceContainer i3i2 = ipv4.Assign (d3d2);
-
-  // Create router nodes, initialize routing database and set up the routing
-  // tables in the nodes.
-  Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
-
-  // Add the tunnels
-  Tunnel tunnel (c.Get (3), c.Get (0), c.Get (1),
-                 i3i2.GetAddress (0), i0i2.GetAddress (0), i1i2.GetAddress (0));
-
-  // Create the OnOff application to send UDP datagrams of size
-  // 210 bytes at a rate of 448 Kb/s
-  NS_LOG_INFO ("Create Applications.");
-  uint16_t port = 9;   // Discard port (RFC 863)
-  OnOffHelper onoff ("ns3::UdpSocketFactory", 
-                     Address (InetSocketAddress (Ipv4Address ("11.0.0.254"), port)));
-  onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
-  onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
-  ApplicationContainer apps = onoff.Install (c.Get (0));
-  apps.Start (Seconds (1.0));
-  apps.Stop (Seconds (10.0));
-
-  // Create a packet sink to receive these packets
-  PacketSinkHelper sink ("ns3::UdpSocketFactory",
-    Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
-  apps = sink.Install (c.Get (3));
-  apps.Start (Seconds (1.0));
-  //apps.Stop (Seconds (10.0));
-
-  // Create a similar flow from n3 to n1, starting at time 1.1 seconds
-  onoff.SetAttribute ("Remote", 
-                      AddressValue (InetSocketAddress (Ipv4Address ("11.0.0.1"), port)));
-  apps = onoff.Install (c.Get (3));
-  apps.Start (Seconds (1.1));
-  apps.Stop (Seconds (10.0));
-
-  // Create a packet sink to receive these packets
-  apps = sink.Install (c.Get (1));
-  apps.Start (Seconds (1.1));
-  //apps.Stop (Seconds (10.0));
-
-  AsciiTraceHelper ascii;
-  p2p.EnableAsciiAll (ascii.CreateFileStream ("virtual-net-device.tr"));
-  p2p.EnablePcapAll ("virtual-net-device");
-
-  NS_LOG_INFO ("Run Simulation.");
-  Simulator::Run ();
-  Simulator::Destroy ();
-  NS_LOG_INFO ("Done.");
-
-  return 0;
-}
--- a/examples/tunneling/waf	Mon Oct 25 15:00:28 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-exec "`dirname "$0"`"/../../waf "$@"
--- a/examples/tunneling/wscript	Mon Oct 25 15:00:28 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
-
-def build(bld):
-    obj = bld.create_ns3_program('virtual-net-device', ['point-to-point', 'internet-stack', 'global-routing', 
-                                                        'virtual-net-device'])
-    obj.source = 'virtual-net-device.cc'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/virtual-net-device/examples/virtual-net-device.cc	Mon Oct 25 15:13:44 2010 +0100
@@ -0,0 +1,300 @@
+/* -*- 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
+ *
+ * Based on simple-global-routing.cc
+ */
+
+// Network topology
+//
+//  n0
+//     \ 5 Mb/s, 2ms
+//      \          1.5Mb/s, 10ms
+//       n2 -------------------------n3
+//      /
+//     / 5 Mb/s, 2ms
+//   n1
+//
+// - all links are point-to-point links with indicated one-way BW/delay
+// - CBR/UDP flows from n0 to n3, and from n3 to n1
+// - FTP/TCP flow from n0 to n3, starting at time 1.2 to time 1.35 sec.
+// - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec.
+//   (i.e., DataRate of 448,000 bps)
+// - DropTail queues 
+// - Tracing of queues and packet receptions to file "virtual-net-device.tr"
+
+// Tunneling changes (relative to the simple-global-routing example):
+// n0 will receive an extra virtual interface with address 11.0.0.1
+// n1 will also receive an extra virtual interface with the same address 11.0.0.1
+// n3 will receive an extra virtual interface with address 11.0.0.254
+// The flows will be between 11.0.0.x (tunnel) addresses instead of 10.1.x.y ones
+// n3 will decide, on a per-packet basis, via random number, whether to
+// send the packet to n0 or to n1.
+//
+// Note: here we create a tunnel where IP packets are tunneled over
+// UDP/IP, but tunneling directly IP-over-IP would also be possible;
+// see src/node/ipv4-raw-socket-factory.h.
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <cassert>
+
+#include "ns3/core-module.h"
+#include "ns3/simulator-module.h"
+#include "ns3/node-module.h"
+#include "ns3/helper-module.h"
+#include "ns3/virtual-net-device.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("VirtualNetDeviceExample");
+
+class Tunnel
+{
+  Ptr<Socket> m_n3Socket;
+  Ptr<Socket> m_n0Socket;
+  Ptr<Socket> m_n1Socket;
+  Ipv4Address m_n3Address;
+  Ipv4Address m_n0Address;
+  Ipv4Address m_n1Address;
+  UniformVariable m_rng;
+  Ptr<VirtualNetDevice> m_n0Tap;
+  Ptr<VirtualNetDevice> m_n1Tap;
+  Ptr<VirtualNetDevice> m_n3Tap;
+  
+  
+  bool
+  N0VirtualSend (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber)
+  {
+    NS_LOG_DEBUG ("Send to " << m_n3Address << ": " << *packet);
+    m_n0Socket->SendTo (packet, 0, InetSocketAddress (m_n3Address, 667));
+    return true;
+  }
+
+  bool
+  N1VirtualSend (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber)
+  {
+    NS_LOG_DEBUG ("Send to " << m_n3Address << ": " << *packet);
+    m_n1Socket->SendTo (packet, 0, InetSocketAddress (m_n3Address, 667));
+    return true;
+  }
+
+  bool
+  N3VirtualSend (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber)
+  {
+    if (m_rng.GetValue () < 0.25)
+      {
+        NS_LOG_DEBUG ("Send to " << m_n0Address << ": " << *packet);
+        m_n3Socket->SendTo (packet, 0, InetSocketAddress (m_n0Address, 667));
+      }
+    else 
+      {
+        NS_LOG_DEBUG ("Send to " << m_n1Address << ": " << *packet);
+        m_n3Socket->SendTo (packet, 0, InetSocketAddress (m_n1Address, 667));
+      }
+    return true;
+  }
+
+  void N3SocketRecv (Ptr<Socket> socket)
+  {
+    Ptr<Packet> packet = socket->Recv (65535, 0);
+    NS_LOG_DEBUG ("N3SocketRecv: " << *packet);
+    SocketAddressTag socketAddressTag;
+    packet->RemovePacketTag (socketAddressTag);
+    m_n3Tap->Receive (packet, 0x0800, m_n3Tap->GetAddress (), m_n3Tap->GetAddress (), NetDevice::PACKET_HOST);
+  }
+
+  void N0SocketRecv (Ptr<Socket> socket)
+  {
+    Ptr<Packet> packet = socket->Recv (65535, 0);
+    NS_LOG_DEBUG ("N0SocketRecv: " << *packet);
+    SocketAddressTag socketAddressTag;
+    packet->RemovePacketTag (socketAddressTag);
+    m_n0Tap->Receive (packet, 0x0800, m_n0Tap->GetAddress (), m_n0Tap->GetAddress (), NetDevice::PACKET_HOST);
+  }
+
+  void N1SocketRecv (Ptr<Socket> socket)
+  {
+    Ptr<Packet> packet = socket->Recv (65535, 0);
+    NS_LOG_DEBUG ("N1SocketRecv: " << *packet);
+    SocketAddressTag socketAddressTag;
+    packet->RemovePacketTag (socketAddressTag);
+    m_n1Tap->Receive (packet, 0x0800, m_n1Tap->GetAddress (), m_n1Tap->GetAddress (), NetDevice::PACKET_HOST);
+  }
+
+public:
+  
+  Tunnel (Ptr<Node> n3, Ptr<Node> n0, Ptr<Node> n1,
+          Ipv4Address n3Addr, Ipv4Address n0Addr, Ipv4Address n1Addr)
+    : m_n3Address (n3Addr), m_n0Address (n0Addr), m_n1Address (n1Addr)
+  {
+    m_n3Socket = Socket::CreateSocket (n3, TypeId::LookupByName ("ns3::UdpSocketFactory"));
+    m_n3Socket->Bind (InetSocketAddress (Ipv4Address::GetAny (), 667));
+    m_n3Socket->SetRecvCallback (MakeCallback (&Tunnel::N3SocketRecv, this));    
+    
+    m_n0Socket = Socket::CreateSocket (n0, TypeId::LookupByName ("ns3::UdpSocketFactory"));
+    m_n0Socket->Bind (InetSocketAddress (Ipv4Address::GetAny (), 667));
+    m_n0Socket->SetRecvCallback (MakeCallback (&Tunnel::N0SocketRecv, this));    
+    
+    m_n1Socket = Socket::CreateSocket (n1, TypeId::LookupByName ("ns3::UdpSocketFactory"));
+    m_n1Socket->Bind (InetSocketAddress (Ipv4Address::GetAny (), 667));
+    m_n1Socket->SetRecvCallback (MakeCallback (&Tunnel::N1SocketRecv, this));
+    
+    // n0 tap device
+    m_n0Tap = CreateObject<VirtualNetDevice> ();
+    m_n0Tap->SetAddress (Mac48Address ("11:00:01:02:03:01"));
+    m_n0Tap->SetSendCallback (MakeCallback (&Tunnel::N0VirtualSend, this));
+    n0->AddDevice (m_n0Tap);
+    Ptr<Ipv4> ipv4 = n0->GetObject<Ipv4> ();
+    uint32_t i = ipv4->AddInterface (m_n0Tap);
+    ipv4->AddAddress (i, Ipv4InterfaceAddress (Ipv4Address ("11.0.0.1"), Ipv4Mask ("255.255.255.0")));
+    ipv4->SetUp (i);
+    
+    // n1 tap device
+    m_n1Tap = CreateObject<VirtualNetDevice> ();
+    m_n1Tap->SetAddress (Mac48Address ("11:00:01:02:03:02"));
+    m_n1Tap->SetSendCallback (MakeCallback (&Tunnel::N1VirtualSend, this));
+    n1->AddDevice (m_n1Tap);
+    ipv4 = n1->GetObject<Ipv4> ();
+    i = ipv4->AddInterface (m_n1Tap);
+    ipv4->AddAddress (i, Ipv4InterfaceAddress (Ipv4Address ("11.0.0.1"), Ipv4Mask ("255.255.255.0")));
+    ipv4->SetUp (i);
+
+    // n3 tap device
+    m_n3Tap = CreateObject<VirtualNetDevice> ();
+    m_n3Tap->SetAddress (Mac48Address ("11:00:01:02:03:04"));
+    m_n3Tap->SetSendCallback (MakeCallback (&Tunnel::N3VirtualSend, this));
+    n3->AddDevice (m_n3Tap);
+    ipv4 = n3->GetObject<Ipv4> ();
+    i = ipv4->AddInterface (m_n3Tap);
+    ipv4->AddAddress (i, Ipv4InterfaceAddress (Ipv4Address ("11.0.0.254"), Ipv4Mask ("255.255.255.0")));
+    ipv4->SetUp (i);
+    
+  }
+  
+  
+};
+
+  
+
+int 
+main (int argc, char *argv[])
+{
+  // Users may find it convenient to turn on explicit debugging
+  // for selected modules; the below lines suggest how to do this
+#if 0 
+  LogComponentEnable ("VirtualNetDeviceExample", LOG_LEVEL_INFO);
+#endif
+  Packet::EnablePrinting ();
+  
+
+  // Set up some default values for the simulation.  Use the 
+  Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (210));
+  Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("448kb/s"));
+
+  //DefaultValue::Bind ("DropTailQueue::m_maxPackets", 30);   
+
+  // Allow the user to override any of the defaults and the above
+  // DefaultValue::Bind ()s at run-time, via command-line arguments
+  CommandLine cmd;
+  cmd.Parse (argc, argv);
+
+  // Here, we will explicitly create four nodes.  In more sophisticated
+  // topologies, we could configure a node factory.
+  NS_LOG_INFO ("Create nodes.");
+  NodeContainer c;
+  c.Create (4);
+  NodeContainer n0n2 = NodeContainer (c.Get(0), c.Get (2));
+  NodeContainer n1n2 = NodeContainer (c.Get(1), c.Get (2));
+  NodeContainer n3n2 = NodeContainer (c.Get(3), c.Get (2));
+
+  InternetStackHelper internet;
+  internet.Install (c);
+
+  // We create the channels first without any IP addressing information
+  NS_LOG_INFO ("Create channels.");
+  PointToPointHelper p2p;
+  p2p.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
+  p2p.SetChannelAttribute ("Delay", StringValue ("2ms"));
+  NetDeviceContainer d0d2 = p2p.Install (n0n2);
+
+  NetDeviceContainer d1d2 = p2p.Install (n1n2);
+  
+  p2p.SetDeviceAttribute ("DataRate", StringValue ("1500kbps"));
+  p2p.SetChannelAttribute ("Delay", StringValue ("10ms"));
+  NetDeviceContainer d3d2 = p2p.Install (n3n2);
+  
+  // Later, we add IP addresses.  
+  NS_LOG_INFO ("Assign IP Addresses.");
+  Ipv4AddressHelper ipv4;
+  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
+  Ipv4InterfaceContainer i0i2 = ipv4.Assign (d0d2);
+
+  ipv4.SetBase ("10.1.2.0", "255.255.255.0");
+  Ipv4InterfaceContainer i1i2 = ipv4.Assign (d1d2);
+  
+  ipv4.SetBase ("10.1.3.0", "255.255.255.0");
+  Ipv4InterfaceContainer i3i2 = ipv4.Assign (d3d2);
+
+  // Create router nodes, initialize routing database and set up the routing
+  // tables in the nodes.
+  Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
+
+  // Add the tunnels
+  Tunnel tunnel (c.Get (3), c.Get (0), c.Get (1),
+                 i3i2.GetAddress (0), i0i2.GetAddress (0), i1i2.GetAddress (0));
+
+  // Create the OnOff application to send UDP datagrams of size
+  // 210 bytes at a rate of 448 Kb/s
+  NS_LOG_INFO ("Create Applications.");
+  uint16_t port = 9;   // Discard port (RFC 863)
+  OnOffHelper onoff ("ns3::UdpSocketFactory", 
+                     Address (InetSocketAddress (Ipv4Address ("11.0.0.254"), port)));
+  onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
+  onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
+  ApplicationContainer apps = onoff.Install (c.Get (0));
+  apps.Start (Seconds (1.0));
+  apps.Stop (Seconds (10.0));
+
+  // Create a packet sink to receive these packets
+  PacketSinkHelper sink ("ns3::UdpSocketFactory",
+    Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
+  apps = sink.Install (c.Get (3));
+  apps.Start (Seconds (1.0));
+  //apps.Stop (Seconds (10.0));
+
+  // Create a similar flow from n3 to n1, starting at time 1.1 seconds
+  onoff.SetAttribute ("Remote", 
+                      AddressValue (InetSocketAddress (Ipv4Address ("11.0.0.1"), port)));
+  apps = onoff.Install (c.Get (3));
+  apps.Start (Seconds (1.1));
+  apps.Stop (Seconds (10.0));
+
+  // Create a packet sink to receive these packets
+  apps = sink.Install (c.Get (1));
+  apps.Start (Seconds (1.1));
+  //apps.Stop (Seconds (10.0));
+
+  AsciiTraceHelper ascii;
+  p2p.EnableAsciiAll (ascii.CreateFileStream ("virtual-net-device.tr"));
+  p2p.EnablePcapAll ("virtual-net-device");
+
+  NS_LOG_INFO ("Run Simulation.");
+  Simulator::Run ();
+  Simulator::Destroy ();
+  NS_LOG_INFO ("Done.");
+
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/virtual-net-device/examples/wscript	Mon Oct 25 15:13:44 2010 +0100
@@ -0,0 +1,8 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+def build(bld):
+
+    obj = bld.create_ns3_program('virtual-net-device', ['point-to-point', 'internet-stack', 'global-routing', 
+                                                        'virtual-net-device'])
+    obj.source = 'virtual-net-device.cc'
+    
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/virtual-net-device/model/virtual-net-device.cc	Mon Oct 25 15:13:44 2010 +0100
@@ -0,0 +1,306 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,2009 INESC Porto
+ *
+ * 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:  Gustavo J. A. M. Carneiro  <gjc@inescporto.pt>
+ */
+
+#include "ns3/log.h"
+#include "ns3/queue.h"
+#include "ns3/simulator.h"
+#include "ns3/mac48-address.h"
+#include "ns3/llc-snap-header.h"
+#include "ns3/error-model.h"
+#include "virtual-net-device.h"
+#include "ns3/channel.h"
+#include "ns3/trace-source-accessor.h"
+#include "ns3/uinteger.h"
+
+
+NS_LOG_COMPONENT_DEFINE ("VirtualNetDevice");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (VirtualNetDevice);
+
+TypeId
+VirtualNetDevice::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::VirtualNetDevice")
+    .SetParent<NetDevice> ()
+    .AddConstructor<VirtualNetDevice> ()
+    .AddAttribute ("Mtu", "The MAC-level Maximum Transmission Unit",
+                   UintegerValue (1500),
+                   MakeUintegerAccessor (&VirtualNetDevice::SetMtu,
+                                         &VirtualNetDevice::GetMtu),
+                   MakeUintegerChecker<uint16_t> ())                   
+    .AddTraceSource ("MacTx", 
+                     "Trace source indicating a packet has arrived for transmission by this device",
+                     MakeTraceSourceAccessor (&VirtualNetDevice::m_macTxTrace))
+    .AddTraceSource ("MacPromiscRx", 
+                     "A packet has been received by this device, has been passed up from the physical layer "
+                     "and is being forwarded up the local protocol stack.  This is a promiscuous trace,",
+                     MakeTraceSourceAccessor (&VirtualNetDevice::m_macPromiscRxTrace))
+    .AddTraceSource ("MacRx", 
+                     "A packet has been received by this device, has been passed up from the physical layer "
+                     "and is being forwarded up the local protocol stack.  This is a non-promiscuous trace,",
+                     MakeTraceSourceAccessor (&VirtualNetDevice::m_macRxTrace))
+    //
+    // Trace sources designed to simulate a packet sniffer facility (tcpdump). 
+    //
+    .AddTraceSource ("Sniffer", 
+                     "Trace source simulating a non-promiscuous packet sniffer attached to the device",
+                     MakeTraceSourceAccessor (&VirtualNetDevice::m_snifferTrace))
+    .AddTraceSource ("PromiscSniffer", 
+                     "Trace source simulating a promiscuous packet sniffer attached to the device",
+                     MakeTraceSourceAccessor (&VirtualNetDevice::m_promiscSnifferTrace))
+    ;
+  return tid;
+}
+
+VirtualNetDevice::VirtualNetDevice ()
+{
+  m_needsArp = false;
+  m_supportsSendFrom = true;
+  m_isPointToPoint = true;
+}
+
+
+void
+VirtualNetDevice::SetSendCallback (SendCallback sendCb)
+{
+  m_sendCb = sendCb;
+}
+
+void
+VirtualNetDevice::SetNeedsArp (bool needsArp)
+{
+  m_needsArp = needsArp;
+}
+
+void
+VirtualNetDevice::SetSupportsSendFrom (bool supportsSendFrom)
+{
+  m_supportsSendFrom = supportsSendFrom;
+}
+
+void
+VirtualNetDevice::SetIsPointToPoint (bool isPointToPoint)
+{
+  m_isPointToPoint = isPointToPoint;
+}
+
+bool
+VirtualNetDevice::SetMtu (const uint16_t mtu)
+{
+  m_mtu = mtu;
+  return true;
+}
+
+
+VirtualNetDevice::~VirtualNetDevice()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+
+void VirtualNetDevice::DoDispose()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_node = 0;
+  NetDevice::DoDispose ();
+}
+
+bool
+VirtualNetDevice::Receive (Ptr<Packet> packet, uint16_t protocol,
+                           const Address &source, const Address &destination,
+                           PacketType packetType)
+{
+  // 
+  // For all kinds of packetType we receive, we hit the promiscuous sniffer
+  // hook and pass a copy up to the promiscuous callback.  Pass a copy to 
+  // make sure that nobody messes with our packet.
+  //
+  m_promiscSnifferTrace (packet);
+  if (!m_promiscRxCallback.IsNull ())
+    {
+      m_macPromiscRxTrace (packet);
+      m_promiscRxCallback (this, packet, protocol, source, destination, packetType);
+    }
+
+  //
+  // If this packet is not destined for some other host, it must be for us
+  // as either a broadcast, multicast or unicast.  We need to hit the mac
+  // packet received trace hook and forward the packet up the stack.
+  //
+  if (packetType != PACKET_OTHERHOST)
+    {
+      m_snifferTrace (packet);
+      m_macRxTrace (packet);
+      return m_rxCallback (this, packet, protocol, source);
+    }
+  return true;
+}
+
+
+void
+VirtualNetDevice::SetIfIndex (const uint32_t index)
+{
+  m_index = index;
+}
+
+uint32_t
+VirtualNetDevice::GetIfIndex (void) const
+{
+  return m_index;
+}
+
+Ptr<Channel>
+VirtualNetDevice::GetChannel (void) const
+{
+  return Ptr<Channel> ();
+}
+
+Address
+VirtualNetDevice::GetAddress (void) const
+{
+  return m_myAddress;
+}
+
+void
+VirtualNetDevice::SetAddress (Address addr)
+{
+  m_myAddress = addr;
+}
+
+uint16_t
+VirtualNetDevice::GetMtu (void) const
+{
+  return m_mtu;
+}
+
+bool
+VirtualNetDevice::IsLinkUp (void) const
+{
+  return true;
+}
+
+void
+VirtualNetDevice::AddLinkChangeCallback (Callback<void> callback)
+{
+}
+
+bool
+VirtualNetDevice::IsBroadcast (void) const
+{
+  return true;
+}
+
+Address
+VirtualNetDevice::GetBroadcast (void) const
+{
+  return Mac48Address ("ff:ff:ff:ff:ff:ff");
+}
+
+bool
+VirtualNetDevice::IsMulticast (void) const
+{
+  return false;
+}
+
+Address VirtualNetDevice::GetMulticast (Ipv4Address multicastGroup) const
+{
+  return Mac48Address ("ff:ff:ff:ff:ff:ff");
+}
+
+Address VirtualNetDevice::GetMulticast (Ipv6Address addr) const
+{
+  return Mac48Address ("ff:ff:ff:ff:ff:ff");  
+}
+
+
+bool
+VirtualNetDevice::IsPointToPoint (void) const
+{
+  return m_isPointToPoint;
+}
+
+bool
+VirtualNetDevice::Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
+{
+  m_macTxTrace (packet);
+  if (m_sendCb (packet, GetAddress (), dest, protocolNumber))
+    {
+      return true;
+    }
+  return false;
+}
+
+bool
+VirtualNetDevice::SendFrom (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber)
+{
+  NS_ASSERT (m_supportsSendFrom);
+  m_macTxTrace (packet);
+  if (m_sendCb (packet, source, dest, protocolNumber))
+    {
+      return true;
+    }
+  return false;
+}
+
+Ptr<Node>
+VirtualNetDevice::GetNode (void) const
+{
+  return m_node;
+}
+
+void
+VirtualNetDevice::SetNode (Ptr<Node> node)
+{
+  m_node = node;
+}
+
+bool
+VirtualNetDevice::NeedsArp (void) const
+{
+  return m_needsArp;
+}
+
+void
+VirtualNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb)
+{
+  m_rxCallback = cb;
+}
+
+void
+VirtualNetDevice::SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb)
+{
+  m_promiscRxCallback = cb;
+}
+
+bool
+VirtualNetDevice::SupportsSendFrom () const
+{
+  return m_supportsSendFrom;
+}
+
+bool VirtualNetDevice::IsBridge (void) const
+{
+  return false;
+}
+
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/virtual-net-device/model/virtual-net-device.h	Mon Oct 25 15:13:44 2010 +0100
@@ -0,0 +1,169 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,2009 INESC Porto
+ *
+ * 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: Gustavo J. A. M. Carneiro  <gjc@inescporto.pt>
+ */
+
+#ifndef VIRTUAL_NET_DEVICE_H
+#define VIRTUAL_NET_DEVICE_H
+
+#include "ns3/address.h"
+#include "ns3/node.h"
+#include "ns3/net-device.h"
+#include "ns3/callback.h"
+#include "ns3/packet.h"
+#include "ns3/ptr.h"
+#include "ns3/traced-callback.h"
+
+namespace ns3 {
+
+
+/**
+ * \class VirtualNetDevice
+ * \brief A virtual device, similar to Linux TUN/TAP interfaces.
+ *
+ * A VirtualNetDevice is a "virtual" NetDevice implementation which
+ * delegates to a user callback (see method SetSendCallback()) the
+ * task of actually transmitting a packet.  It also allows the user
+ * code to inject the packet as if it had been received by the
+ * VirtualNetDevice.  Together, these features allow one to build tunnels.
+ * For instance, by transmitting packets into a UDP socket we end up
+ * building an IP-over-UDP-over-IP tunnel, or IP-over-IP tunnels.
+ *
+ * The same thing could be accomplished by subclassing NetDevice
+ * directly.  However, VirtualNetDevice is usually much simpler to program
+ * than a NetDevice subclass.
+ */
+class VirtualNetDevice : public NetDevice
+{
+public:
+  /**
+   * Callback the be invoked when the VirtualNetDevice is asked to queue/transmit a packet.
+   * For more information, consult the documentation of NetDevice::SendFrom().
+   */
+  typedef Callback<bool, Ptr<Packet>, const Address&, const Address&, uint16_t> SendCallback;
+
+  static TypeId GetTypeId (void);
+  VirtualNetDevice ();
+
+  virtual ~VirtualNetDevice ();
+
+  /**
+   * \brief Set the user callback to be called when a L2 packet is to be transmitted
+   * \param transmitCb the new transmit callback
+   */
+  void SetSendCallback (SendCallback transmitCb);
+
+  /**
+   * \brief Configure whether the virtual device needs ARP
+   *
+   * \param needsArp the the 'needs arp' value that will be returned
+   * by the NeedsArp() method.  The method IsBroadcast() will also
+   * return this value.
+   */
+  void SetNeedsArp (bool needsArp);
+
+  /**
+   * \brief Configure whether the virtual device is point-to-point
+   *
+   * \param isPointToPoint the value that should be returned by the
+   * IsPointToPoint method for this instance.
+   */
+  void SetIsPointToPoint (bool isPointToPoint);
+
+  /**
+   * \brief Configure whether the virtual device supports SendFrom
+   */
+  void SetSupportsSendFrom (bool supportsSendFrom);
+
+  /**
+   * \brief Configure the reported MTU for the virtual device.
+   * \param mtu MTU value to set
+   * \return whether the MTU value was within legal bounds
+   */
+  bool SetMtu (const uint16_t mtu);
+
+
+  /**
+   * \param packet packet sent from below up to Network Device
+   * \param protocol Protocol type
+   * \param source the address of the sender of this packet.
+   * \param destination the address of the receiver of this packet.
+   * \param packetType type of packet received (broadcast/multicast/unicast/otherhost)
+   * \returns true if the packet was forwarded successfully, false otherwise.
+   *
+   * Forward a "virtually received" packet up
+   * the node's protocol stack.
+   */
+  bool Receive (Ptr<Packet> packet, uint16_t protocol,
+                const Address &source, const Address &destination,
+                PacketType packetType);
+
+
+  // inherited from NetDevice base class.
+  virtual void SetIfIndex(const uint32_t index);
+  virtual uint32_t GetIfIndex(void) const;
+  virtual Ptr<Channel> GetChannel (void) const;
+  virtual void SetAddress (Address address);
+  virtual Address GetAddress (void) const;
+  virtual uint16_t GetMtu (void) const;
+  virtual bool IsLinkUp (void) const;
+  virtual void AddLinkChangeCallback (Callback<void> callback);
+  virtual bool IsBroadcast (void) const;
+  virtual Address GetBroadcast (void) const;
+  virtual bool IsMulticast (void) const;
+  virtual Address GetMulticast (Ipv4Address multicastGroup) const;
+  virtual Address GetMulticast (Ipv6Address addr) const;
+  virtual bool IsPointToPoint (void) const;
+  virtual bool Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber);
+  virtual bool SendFrom (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber);
+  virtual Ptr<Node> GetNode (void) const;
+  virtual void SetNode (Ptr<Node> node);
+  virtual bool NeedsArp (void) const;
+  virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
+  virtual void SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb);
+  virtual bool SupportsSendFrom () const;
+  virtual bool IsBridge (void) const;
+
+protected:
+
+  virtual void DoDispose (void);
+
+private:
+
+  Address m_myAddress;
+  SendCallback m_sendCb;
+  TracedCallback<Ptr<const Packet> > m_macRxTrace;
+  TracedCallback<Ptr<const Packet> > m_macTxTrace;
+  TracedCallback<Ptr<const Packet> > m_macPromiscRxTrace;
+  TracedCallback<Ptr<const Packet> > m_snifferTrace;
+  TracedCallback<Ptr<const Packet> > m_promiscSnifferTrace;
+  Ptr<Node> m_node;
+  ReceiveCallback m_rxCallback;
+  PromiscReceiveCallback m_promiscRxCallback;
+  std::string m_name;
+  uint32_t m_index;
+  uint16_t m_mtu;
+  bool m_needsArp;
+  bool m_supportsSendFrom;
+  bool m_isPointToPoint;
+};
+
+}; // namespace ns3
+
+#endif
+
--- a/src/devices/virtual-net-device/virtual-net-device.cc	Mon Oct 25 15:00:28 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,306 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2008,2009 INESC Porto
- *
- * 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:  Gustavo J. A. M. Carneiro  <gjc@inescporto.pt>
- */
-
-#include "ns3/log.h"
-#include "ns3/queue.h"
-#include "ns3/simulator.h"
-#include "ns3/mac48-address.h"
-#include "ns3/llc-snap-header.h"
-#include "ns3/error-model.h"
-#include "virtual-net-device.h"
-#include "ns3/channel.h"
-#include "ns3/trace-source-accessor.h"
-#include "ns3/uinteger.h"
-
-
-NS_LOG_COMPONENT_DEFINE ("VirtualNetDevice");
-
-namespace ns3 {
-
-NS_OBJECT_ENSURE_REGISTERED (VirtualNetDevice);
-
-TypeId
-VirtualNetDevice::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::VirtualNetDevice")
-    .SetParent<NetDevice> ()
-    .AddConstructor<VirtualNetDevice> ()
-    .AddAttribute ("Mtu", "The MAC-level Maximum Transmission Unit",
-                   UintegerValue (1500),
-                   MakeUintegerAccessor (&VirtualNetDevice::SetMtu,
-                                         &VirtualNetDevice::GetMtu),
-                   MakeUintegerChecker<uint16_t> ())                   
-    .AddTraceSource ("MacTx", 
-                     "Trace source indicating a packet has arrived for transmission by this device",
-                     MakeTraceSourceAccessor (&VirtualNetDevice::m_macTxTrace))
-    .AddTraceSource ("MacPromiscRx", 
-                     "A packet has been received by this device, has been passed up from the physical layer "
-                     "and is being forwarded up the local protocol stack.  This is a promiscuous trace,",
-                     MakeTraceSourceAccessor (&VirtualNetDevice::m_macPromiscRxTrace))
-    .AddTraceSource ("MacRx", 
-                     "A packet has been received by this device, has been passed up from the physical layer "
-                     "and is being forwarded up the local protocol stack.  This is a non-promiscuous trace,",
-                     MakeTraceSourceAccessor (&VirtualNetDevice::m_macRxTrace))
-    //
-    // Trace sources designed to simulate a packet sniffer facility (tcpdump). 
-    //
-    .AddTraceSource ("Sniffer", 
-                     "Trace source simulating a non-promiscuous packet sniffer attached to the device",
-                     MakeTraceSourceAccessor (&VirtualNetDevice::m_snifferTrace))
-    .AddTraceSource ("PromiscSniffer", 
-                     "Trace source simulating a promiscuous packet sniffer attached to the device",
-                     MakeTraceSourceAccessor (&VirtualNetDevice::m_promiscSnifferTrace))
-    ;
-  return tid;
-}
-
-VirtualNetDevice::VirtualNetDevice ()
-{
-  m_needsArp = false;
-  m_supportsSendFrom = true;
-  m_isPointToPoint = true;
-}
-
-
-void
-VirtualNetDevice::SetSendCallback (SendCallback sendCb)
-{
-  m_sendCb = sendCb;
-}
-
-void
-VirtualNetDevice::SetNeedsArp (bool needsArp)
-{
-  m_needsArp = needsArp;
-}
-
-void
-VirtualNetDevice::SetSupportsSendFrom (bool supportsSendFrom)
-{
-  m_supportsSendFrom = supportsSendFrom;
-}
-
-void
-VirtualNetDevice::SetIsPointToPoint (bool isPointToPoint)
-{
-  m_isPointToPoint = isPointToPoint;
-}
-
-bool
-VirtualNetDevice::SetMtu (const uint16_t mtu)
-{
-  m_mtu = mtu;
-  return true;
-}
-
-
-VirtualNetDevice::~VirtualNetDevice()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-}
-
-
-void VirtualNetDevice::DoDispose()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_node = 0;
-  NetDevice::DoDispose ();
-}
-
-bool
-VirtualNetDevice::Receive (Ptr<Packet> packet, uint16_t protocol,
-                           const Address &source, const Address &destination,
-                           PacketType packetType)
-{
-  // 
-  // For all kinds of packetType we receive, we hit the promiscuous sniffer
-  // hook and pass a copy up to the promiscuous callback.  Pass a copy to 
-  // make sure that nobody messes with our packet.
-  //
-  m_promiscSnifferTrace (packet);
-  if (!m_promiscRxCallback.IsNull ())
-    {
-      m_macPromiscRxTrace (packet);
-      m_promiscRxCallback (this, packet, protocol, source, destination, packetType);
-    }
-
-  //
-  // If this packet is not destined for some other host, it must be for us
-  // as either a broadcast, multicast or unicast.  We need to hit the mac
-  // packet received trace hook and forward the packet up the stack.
-  //
-  if (packetType != PACKET_OTHERHOST)
-    {
-      m_snifferTrace (packet);
-      m_macRxTrace (packet);
-      return m_rxCallback (this, packet, protocol, source);
-    }
-  return true;
-}
-
-
-void
-VirtualNetDevice::SetIfIndex (const uint32_t index)
-{
-  m_index = index;
-}
-
-uint32_t
-VirtualNetDevice::GetIfIndex (void) const
-{
-  return m_index;
-}
-
-Ptr<Channel>
-VirtualNetDevice::GetChannel (void) const
-{
-  return Ptr<Channel> ();
-}
-
-Address
-VirtualNetDevice::GetAddress (void) const
-{
-  return m_myAddress;
-}
-
-void
-VirtualNetDevice::SetAddress (Address addr)
-{
-  m_myAddress = addr;
-}
-
-uint16_t
-VirtualNetDevice::GetMtu (void) const
-{
-  return m_mtu;
-}
-
-bool
-VirtualNetDevice::IsLinkUp (void) const
-{
-  return true;
-}
-
-void
-VirtualNetDevice::AddLinkChangeCallback (Callback<void> callback)
-{
-}
-
-bool
-VirtualNetDevice::IsBroadcast (void) const
-{
-  return true;
-}
-
-Address
-VirtualNetDevice::GetBroadcast (void) const
-{
-  return Mac48Address ("ff:ff:ff:ff:ff:ff");
-}
-
-bool
-VirtualNetDevice::IsMulticast (void) const
-{
-  return false;
-}
-
-Address VirtualNetDevice::GetMulticast (Ipv4Address multicastGroup) const
-{
-  return Mac48Address ("ff:ff:ff:ff:ff:ff");
-}
-
-Address VirtualNetDevice::GetMulticast (Ipv6Address addr) const
-{
-  return Mac48Address ("ff:ff:ff:ff:ff:ff");  
-}
-
-
-bool
-VirtualNetDevice::IsPointToPoint (void) const
-{
-  return m_isPointToPoint;
-}
-
-bool
-VirtualNetDevice::Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
-{
-  m_macTxTrace (packet);
-  if (m_sendCb (packet, GetAddress (), dest, protocolNumber))
-    {
-      return true;
-    }
-  return false;
-}
-
-bool
-VirtualNetDevice::SendFrom (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber)
-{
-  NS_ASSERT (m_supportsSendFrom);
-  m_macTxTrace (packet);
-  if (m_sendCb (packet, source, dest, protocolNumber))
-    {
-      return true;
-    }
-  return false;
-}
-
-Ptr<Node>
-VirtualNetDevice::GetNode (void) const
-{
-  return m_node;
-}
-
-void
-VirtualNetDevice::SetNode (Ptr<Node> node)
-{
-  m_node = node;
-}
-
-bool
-VirtualNetDevice::NeedsArp (void) const
-{
-  return m_needsArp;
-}
-
-void
-VirtualNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb)
-{
-  m_rxCallback = cb;
-}
-
-void
-VirtualNetDevice::SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb)
-{
-  m_promiscRxCallback = cb;
-}
-
-bool
-VirtualNetDevice::SupportsSendFrom () const
-{
-  return m_supportsSendFrom;
-}
-
-bool VirtualNetDevice::IsBridge (void) const
-{
-  return false;
-}
-
-
-} // namespace ns3
--- a/src/devices/virtual-net-device/virtual-net-device.h	Mon Oct 25 15:00:28 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,169 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2008,2009 INESC Porto
- *
- * 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: Gustavo J. A. M. Carneiro  <gjc@inescporto.pt>
- */
-
-#ifndef VIRTUAL_NET_DEVICE_H
-#define VIRTUAL_NET_DEVICE_H
-
-#include "ns3/address.h"
-#include "ns3/node.h"
-#include "ns3/net-device.h"
-#include "ns3/callback.h"
-#include "ns3/packet.h"
-#include "ns3/ptr.h"
-#include "ns3/traced-callback.h"
-
-namespace ns3 {
-
-
-/**
- * \class VirtualNetDevice
- * \brief A virtual device, similar to Linux TUN/TAP interfaces.
- *
- * A VirtualNetDevice is a "virtual" NetDevice implementation which
- * delegates to a user callback (see method SetSendCallback()) the
- * task of actually transmitting a packet.  It also allows the user
- * code to inject the packet as if it had been received by the
- * VirtualNetDevice.  Together, these features allow one to build tunnels.
- * For instance, by transmitting packets into a UDP socket we end up
- * building an IP-over-UDP-over-IP tunnel, or IP-over-IP tunnels.
- *
- * The same thing could be accomplished by subclassing NetDevice
- * directly.  However, VirtualNetDevice is usually much simpler to program
- * than a NetDevice subclass.
- */
-class VirtualNetDevice : public NetDevice
-{
-public:
-  /**
-   * Callback the be invoked when the VirtualNetDevice is asked to queue/transmit a packet.
-   * For more information, consult the documentation of NetDevice::SendFrom().
-   */
-  typedef Callback<bool, Ptr<Packet>, const Address&, const Address&, uint16_t> SendCallback;
-
-  static TypeId GetTypeId (void);
-  VirtualNetDevice ();
-
-  virtual ~VirtualNetDevice ();
-
-  /**
-   * \brief Set the user callback to be called when a L2 packet is to be transmitted
-   * \param transmitCb the new transmit callback
-   */
-  void SetSendCallback (SendCallback transmitCb);
-
-  /**
-   * \brief Configure whether the virtual device needs ARP
-   *
-   * \param needsArp the the 'needs arp' value that will be returned
-   * by the NeedsArp() method.  The method IsBroadcast() will also
-   * return this value.
-   */
-  void SetNeedsArp (bool needsArp);
-
-  /**
-   * \brief Configure whether the virtual device is point-to-point
-   *
-   * \param isPointToPoint the value that should be returned by the
-   * IsPointToPoint method for this instance.
-   */
-  void SetIsPointToPoint (bool isPointToPoint);
-
-  /**
-   * \brief Configure whether the virtual device supports SendFrom
-   */
-  void SetSupportsSendFrom (bool supportsSendFrom);
-
-  /**
-   * \brief Configure the reported MTU for the virtual device.
-   * \param mtu MTU value to set
-   * \return whether the MTU value was within legal bounds
-   */
-  bool SetMtu (const uint16_t mtu);
-
-
-  /**
-   * \param packet packet sent from below up to Network Device
-   * \param protocol Protocol type
-   * \param source the address of the sender of this packet.
-   * \param destination the address of the receiver of this packet.
-   * \param packetType type of packet received (broadcast/multicast/unicast/otherhost)
-   * \returns true if the packet was forwarded successfully, false otherwise.
-   *
-   * Forward a "virtually received" packet up
-   * the node's protocol stack.
-   */
-  bool Receive (Ptr<Packet> packet, uint16_t protocol,
-                const Address &source, const Address &destination,
-                PacketType packetType);
-
-
-  // inherited from NetDevice base class.
-  virtual void SetIfIndex(const uint32_t index);
-  virtual uint32_t GetIfIndex(void) const;
-  virtual Ptr<Channel> GetChannel (void) const;
-  virtual void SetAddress (Address address);
-  virtual Address GetAddress (void) const;
-  virtual uint16_t GetMtu (void) const;
-  virtual bool IsLinkUp (void) const;
-  virtual void AddLinkChangeCallback (Callback<void> callback);
-  virtual bool IsBroadcast (void) const;
-  virtual Address GetBroadcast (void) const;
-  virtual bool IsMulticast (void) const;
-  virtual Address GetMulticast (Ipv4Address multicastGroup) const;
-  virtual Address GetMulticast (Ipv6Address addr) const;
-  virtual bool IsPointToPoint (void) const;
-  virtual bool Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber);
-  virtual bool SendFrom (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber);
-  virtual Ptr<Node> GetNode (void) const;
-  virtual void SetNode (Ptr<Node> node);
-  virtual bool NeedsArp (void) const;
-  virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
-  virtual void SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb);
-  virtual bool SupportsSendFrom () const;
-  virtual bool IsBridge (void) const;
-
-protected:
-
-  virtual void DoDispose (void);
-
-private:
-
-  Address m_myAddress;
-  SendCallback m_sendCb;
-  TracedCallback<Ptr<const Packet> > m_macRxTrace;
-  TracedCallback<Ptr<const Packet> > m_macTxTrace;
-  TracedCallback<Ptr<const Packet> > m_macPromiscRxTrace;
-  TracedCallback<Ptr<const Packet> > m_snifferTrace;
-  TracedCallback<Ptr<const Packet> > m_promiscSnifferTrace;
-  Ptr<Node> m_node;
-  ReceiveCallback m_rxCallback;
-  PromiscReceiveCallback m_promiscRxCallback;
-  std::string m_name;
-  uint32_t m_index;
-  uint16_t m_mtu;
-  bool m_needsArp;
-  bool m_supportsSendFrom;
-  bool m_isPointToPoint;
-};
-
-}; // namespace ns3
-
-#endif
-
--- a/src/devices/virtual-net-device/wscript	Mon Oct 25 15:00:28 2010 +0100
+++ b/src/devices/virtual-net-device/wscript	Mon Oct 25 15:13:44 2010 +0100
@@ -4,11 +4,13 @@
 def build(bld):
     module = bld.create_ns3_module('virtual-net-device', ['node'])
     module.source = [
-        'virtual-net-device.cc',
+        'model/virtual-net-device.cc',
         ]
     headers = bld.new_task_gen('ns3header')
     headers.module = 'virtual-net-device'
     headers.source = [
-        'virtual-net-device.h',
+        'model/virtual-net-device.h',
         ]
 
+    if bld.env['ENABLE_EXAMPLES']:
+        bld.add_subdirs('examples')