give up on merging tap and emulated, break apart
authorCraig Dowell <craigdo@ee.washington.edu>
Mon Oct 27 22:01:24 2008 -0700 (16 months ago)
changeset 38274b603cd4ee42
parent 3826 40c5841b616d
child 3828 337b244e6d8f
give up on merging tap and emulated, break apart
src/devices/emulated/emulated-net-device.cc
src/devices/emulated/emulated-net-device.h
src/devices/emulated/emulated.h
src/devices/emulated/waf
src/devices/emulated/wscript
src/devices/emutap/host-tap-net-device.cc
src/devices/emutap/host-tap-net-device.h
src/devices/emutap/tap-channel.cc
src/devices/emutap/tap-channel.h
src/devices/emutap/tap-manager-client.cc
src/devices/emutap/tap-manager-client.h
src/devices/emutap/tap-manager.cc
src/devices/emutap/tap-net-device.cc
src/devices/emutap/tap-net-device.h
src/devices/emutap/wscript
src/devices/tap/host-tap-net-device.cc
src/devices/tap/host-tap-net-device.h
src/devices/tap/tap-channel.cc
src/devices/tap/tap-channel.h
src/devices/tap/tap-manager-client.cc
src/devices/tap/tap-manager-client.h
src/devices/tap/tap-manager.cc
src/devices/tap/tap-net-device.cc
src/devices/tap/tap-net-device.h
src/devices/tap/wscript
src/node/net-device.h
src/wscript
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/devices/emulated/emulated-net-device.cc	Mon Oct 27 22:01:24 2008 -0700
     1.3 @@ -0,0 +1,642 @@
     1.4 +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
     1.5 +/*
     1.6 + * Copyright (c) 2008 University of Washington
     1.7 + *
     1.8 + * This program is free software; you can redistribute it and/or modify
     1.9 + * it under the terms of the GNU General Public License version 2 as
    1.10 + * published by the Free Software Foundation;
    1.11 + *
    1.12 + * This program is distributed in the hope that it will be useful,
    1.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1.15 + * GNU General Public License for more details.
    1.16 + *
    1.17 + * You should have received a copy of the GNU General Public License
    1.18 + * along with this program; if not, write to the Free Software
    1.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    1.20 + */
    1.21 +
    1.22 +#include "emulated-net-device.h"
    1.23 +
    1.24 +#include "ns3/log.h"
    1.25 +#include "ns3/queue.h"
    1.26 +#include "ns3/simulator.h"
    1.27 +#include "ns3/realtime-simulator-impl.h"
    1.28 +#include "ns3/mac48-address.h"
    1.29 +#include "ns3/ethernet-header.h"
    1.30 +#include "ns3/ethernet-trailer.h"
    1.31 +#include "ns3/llc-snap-header.h"
    1.32 +#include "ns3/trace-source-accessor.h"
    1.33 +#include "ns3/pointer.h"
    1.34 +#include "ns3/channel.h"
    1.35 +#include "ns3/system-thread.h"
    1.36 +#include "ns3/string.h"
    1.37 +#include "ns3/boolean.h"
    1.38 +
    1.39 +#include <sys/socket.h>
    1.40 +#include <sys/ioctl.h>
    1.41 +#include <net/ethernet.h>
    1.42 +#include <net/if.h>
    1.43 +#include <netinet/in.h>
    1.44 +#include <netpacket/packet.h>
    1.45 +#include <arpa/inet.h>
    1.46 +
    1.47 +NS_LOG_COMPONENT_DEFINE ("EmulatedNetDevice");
    1.48 +
    1.49 +namespace ns3 {
    1.50 +
    1.51 +NS_OBJECT_ENSURE_REGISTERED (EmulatedNetDevice);
    1.52 +
    1.53 +TypeId 
    1.54 +EmulatedNetDevice::GetTypeId (void)
    1.55 +{
    1.56 +  static TypeId tid = TypeId ("ns3::EmulatedNetDevice")
    1.57 +    .SetParent<NetDevice> ()
    1.58 +    .AddConstructor<EmulatedNetDevice> ()
    1.59 +    .AddAttribute ("Address", 
    1.60 +                   "The ns-3 MAC address of this (virtual) device.",
    1.61 +                   Mac48AddressValue (Mac48Address ("ff:ff:ff:ff:ff:ff")),
    1.62 +                   MakeMac48AddressAccessor (&EmulatedNetDevice::m_address),
    1.63 +                   MakeMac48AddressChecker ())
    1.64 +    .AddAttribute ("DeviceName", 
    1.65 +                   "The name of the underlying real device (e.g. eth1).",
    1.66 +                   StringValue ("eth1"),
    1.67 +                   MakeStringAccessor (&EmulatedNetDevice::m_deviceName),
    1.68 +                   MakeStringChecker ())
    1.69 +    .AddAttribute ("Start", 
    1.70 +                   "The simulation time at which to spin up the device thread.",
    1.71 +                   TimeValue (Seconds (0.)),
    1.72 +                   MakeTimeAccessor (&EmulatedNetDevice::m_tStart),
    1.73 +                   MakeTimeChecker ())
    1.74 +    .AddAttribute ("Stop", 
    1.75 +                   "The simulation time at which to tear down the device thread.",
    1.76 +                   TimeValue (Seconds (0.)),
    1.77 +                   MakeTimeAccessor (&EmulatedNetDevice::m_tStop),
    1.78 +                   MakeTimeChecker ())
    1.79 +    .AddAttribute ("TxQueue", 
    1.80 +                   "A queue to use as the transmit queue in the device.",
    1.81 +                   PointerValue (),
    1.82 +                   MakePointerAccessor (&EmulatedNetDevice::m_queue),
    1.83 +                   MakePointerChecker<Queue> ())
    1.84 +    .AddTraceSource ("Rx", 
    1.85 +                     "Trace source to fire on reception of a MAC packet.",
    1.86 +                     MakeTraceSourceAccessor (&EmulatedNetDevice::m_rxTrace))
    1.87 +    .AddTraceSource ("Drop", 
    1.88 +                     "Trace source to fire on when a MAC packet is dropped.",
    1.89 +                     MakeTraceSourceAccessor (&EmulatedNetDevice::m_dropTrace))
    1.90 +    ;
    1.91 +  return tid;
    1.92 +}
    1.93 +
    1.94 +
    1.95 +EmulatedNetDevice::EmulatedNetDevice () 
    1.96 +: 
    1.97 +  m_startEvent (),
    1.98 +  m_stopEvent (),
    1.99 +  m_sock (-1),
   1.100 +  m_readThread (0),
   1.101 +  m_ifIndex (-1),
   1.102 +  m_sll_ifindex (-1),
   1.103 +  m_name ("Emulated NetDevice")
   1.104 +{
   1.105 +  NS_LOG_FUNCTION (this);
   1.106 +  Start (m_tStart);
   1.107 +}
   1.108 +
   1.109 +EmulatedNetDevice::~EmulatedNetDevice ()
   1.110 +{
   1.111 +}
   1.112 +
   1.113 +void 
   1.114 +EmulatedNetDevice::DoDispose()
   1.115 +{
   1.116 +  NS_LOG_FUNCTION_NOARGS ();
   1.117 +  m_node = 0;
   1.118 +  NetDevice::DoDispose ();
   1.119 +}
   1.120 +
   1.121 +void
   1.122 +EmulatedNetDevice::Start (Time tStart)
   1.123 +{
   1.124 +  NS_LOG_FUNCTION (tStart);
   1.125 +
   1.126 +  //
   1.127 +  // Cancel any pending start event and schedule a new one at some relative time in the future.
   1.128 +  //
   1.129 +  Simulator::Cancel (m_startEvent);
   1.130 +  m_startEvent = Simulator::Schedule (tStart, &EmulatedNetDevice::StartDevice, this);
   1.131 +}
   1.132 +
   1.133 +  void
   1.134 +EmulatedNetDevice::Stop (Time tStop)
   1.135 +{
   1.136 +  NS_LOG_FUNCTION (tStop);
   1.137 +  //
   1.138 +  // Cancel any pending stop event and schedule a new one at some relative time in the future.
   1.139 +  //
   1.140 +  Simulator::Cancel (m_stopEvent);
   1.141 +  m_startEvent = Simulator::Schedule (tStop, &EmulatedNetDevice::StopDevice, this);
   1.142 +}
   1.143 +
   1.144 +  void
   1.145 +EmulatedNetDevice::StartDevice (void)
   1.146 +{
   1.147 +  NS_LOG_FUNCTION_NOARGS ();
   1.148 +
   1.149 +  //
   1.150 +  // Spin up the emulated net device and start receiving packets.
   1.151 +  //
   1.152 +  NS_ASSERT_MSG (m_sock == -1, "EmulatedNetDevice::StartDevice(): Device is already started");
   1.153 +
   1.154 +  NS_LOG_LOGIC ("Creating socket");
   1.155 +
   1.156 +  m_sock = socket (PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
   1.157 +  //  m_sock = socket (AF_INET, SOCK_PACKET, htons(ETH_P_ALL));
   1.158 +  NS_ASSERT_MSG (m_sock != -1, "EmulatedNetDevice::StartDevice(): Unable to open socket");
   1.159 +
   1.160 +  //
   1.161 +  // Figure out which interface index corresponds to the device name in the corresponding attribute.
   1.162 +  //
   1.163 +  struct ifreq ifr;
   1.164 +  bzero (&ifr, sizeof(ifr));
   1.165 +  strncpy ((char *)ifr.ifr_name, m_deviceName.c_str (), IFNAMSIZ);
   1.166 +
   1.167 +  NS_LOG_LOGIC ("Getting interface index");
   1.168 +  int32_t rc = ioctl (m_sock, SIOCGIFINDEX, &ifr);
   1.169 +  NS_ASSERT_MSG (rc != -1, "EmulatedNetDevice::StartDevice(): Can't get interface index");
   1.170 +
   1.171 +  //
   1.172 +  // Save the real interface index for later calls to sendto
   1.173 +  //
   1.174 +  m_sll_ifindex = ifr.ifr_ifindex;
   1.175 +
   1.176 +  //
   1.177 +  // Bind the socket to the interface we just found.
   1.178 +  //
   1.179 +  struct sockaddr_ll ll;
   1.180 +  bzero (&ll, sizeof(ll));
   1.181 +
   1.182 +  ll.sll_family = AF_PACKET;
   1.183 +  ll.sll_ifindex = m_sll_ifindex;
   1.184 +  ll.sll_protocol = htons(ETH_P_ALL); 
   1.185 +
   1.186 +  NS_LOG_LOGIC ("Binding socket to interface");
   1.187 +
   1.188 +  rc = bind (m_sock, (struct sockaddr *)&ll, sizeof (ll));
   1.189 +  NS_ASSERT_MSG (rc != -1, "EmulatedNetDevice::StartDevice(): Can't bind to specified interface");
   1.190 +
   1.191 +  //
   1.192 +  // Now spin up a read thread to read packets.
   1.193 +  //
   1.194 +  NS_ASSERT_MSG (m_readThread == 0, "EmulatedNetDevice::StartDevice(): Receive thread is already running");
   1.195 +
   1.196 +  NS_LOG_LOGIC ("Spinning up read thread");
   1.197 +
   1.198 +  m_readThread = Create<SystemThread> (MakeCallback (&EmulatedNetDevice::ReadThread, this));
   1.199 +  m_readThread->Start ();
   1.200 +
   1.201 +  NotifyLinkUp ();
   1.202 +}
   1.203 +
   1.204 +void
   1.205 +EmulatedNetDevice::StopDevice (void)
   1.206 +{
   1.207 +  NS_LOG_FUNCTION_NOARGS ();
   1.208 +
   1.209 +  close (m_sock);
   1.210 +  m_sock = -1;
   1.211 +
   1.212 +  NS_ASSERT_MSG (m_readThread != 0, "EmulatedNetDevice::StopDevice(): Receive thread is not running");
   1.213 +
   1.214 +  NS_LOG_LOGIC ("Joining read thread");
   1.215 +  m_readThread->Join ();
   1.216 +  m_readThread = 0;
   1.217 +}
   1.218 +
   1.219 +void
   1.220 +EmulatedNetDevice::ForwardUp (uint8_t *buf, uint32_t len)
   1.221 +{
   1.222 +  NS_LOG_FUNCTION (buf << len);
   1.223 +
   1.224 +  //
   1.225 +  // Create a packet out of the buffer we received and free that buffer.
   1.226 +  //
   1.227 +  Ptr<Packet> packet = Create<Packet> (reinterpret_cast<const uint8_t *> (buf), len);
   1.228 +  free (buf);
   1.229 +  buf = 0;
   1.230 +
   1.231 +  //
   1.232 +  // Trace sinks will expect complete packets, not packets without some of the
   1.233 +  // headers.
   1.234 +  //
   1.235 +  Ptr<Packet> originalPacket = packet->Copy ();
   1.236 +
   1.237 +  //
   1.238 +  // Checksum the packet
   1.239 +  //
   1.240 +  EthernetTrailer trailer;
   1.241 +  packet->RemoveTrailer (trailer);
   1.242 +  trailer.CheckFcs (packet);
   1.243 +
   1.244 +  EthernetHeader header (false);
   1.245 +  packet->RemoveHeader (header);
   1.246 +
   1.247 +  NS_LOG_LOGIC ("Pkt source is " << header.GetSource ());
   1.248 +  NS_LOG_LOGIC ("Pkt destination is " << header.GetDestination ());
   1.249 +
   1.250 +  //
   1.251 +  // An IP host group address is mapped to an Ethernet multicast address
   1.252 +  // by placing the low-order 23-bits of the IP address into the low-order
   1.253 +  // 23 bits of the Ethernet multicast address 01-00-5E-00-00-00 (hex).
   1.254 +  //
   1.255 +  // We are going to receive all packets destined to any multicast address,
   1.256 +  // which means clearing the low-order 23 bits the header destination 
   1.257 +  //
   1.258 +  Mac48Address mcDest;
   1.259 +  uint8_t      mcBuf[6];
   1.260 +
   1.261 +  header.GetDestination ().CopyTo (mcBuf);
   1.262 +  mcBuf[3] &= 0x80;
   1.263 +  mcBuf[4] = 0;
   1.264 +  mcBuf[5] = 0;
   1.265 +  mcDest.CopyFrom (mcBuf);
   1.266 +
   1.267 +  Mac48Address multicast = Mac48Address::ConvertFrom (GetMulticast ());
   1.268 +  Mac48Address broadcast = Mac48Address::ConvertFrom (GetBroadcast ());
   1.269 +  Mac48Address destination = Mac48Address::ConvertFrom (GetAddress ());
   1.270 +
   1.271 +  LlcSnapHeader llc;
   1.272 +  packet->RemoveHeader (llc);
   1.273 +  uint16_t protocol = llc.GetType ();
   1.274 +
   1.275 +  PacketType packetType;
   1.276 +      
   1.277 +  if (header.GetDestination () == broadcast)
   1.278 +    {
   1.279 +      NS_LOG_LOGIC ("Pkt destination is PACKET_BROADCAST");
   1.280 +      packetType = NS3_PACKET_BROADCAST;
   1.281 +    }
   1.282 +  else if (mcDest == multicast)
   1.283 +    {
   1.284 +      NS_LOG_LOGIC ("Pkt destination is PACKET_MULTICAST");
   1.285 +      packetType = NS3_PACKET_MULTICAST;
   1.286 +    }
   1.287 +  else if (header.GetDestination () == destination)
   1.288 +    {
   1.289 +      NS_LOG_LOGIC ("Pkt destination is PACKET_HOST");
   1.290 +      packetType = NS3_PACKET_HOST;
   1.291 +    }
   1.292 +  else
   1.293 +    {
   1.294 +      NS_LOG_LOGIC ("Pkt destination is PACKET_OTHERHOST");
   1.295 +      packetType = NS3_PACKET_OTHERHOST;
   1.296 +    }
   1.297 +
   1.298 +  if (!m_promiscRxCallback.IsNull ())
   1.299 +    {
   1.300 +      NS_LOG_LOGIC ("calling m_promiscRxCallback");
   1.301 +      m_promiscRxCallback (this, packet->Copy (), protocol, header.GetSource (), header.GetDestination (), packetType);
   1.302 +    }
   1.303 +
   1.304 +  if (packetType != NS3_PACKET_OTHERHOST)
   1.305 +    {
   1.306 +      m_rxTrace (originalPacket);
   1.307 +      NS_LOG_LOGIC ("calling m_rxCallback");
   1.308 +      m_rxCallback (this, packet, protocol, header.GetSource ());
   1.309 +    }
   1.310 +}
   1.311 +
   1.312 +void
   1.313 +EmulatedNetDevice::ReadThread (void)
   1.314 +{
   1.315 +  NS_LOG_FUNCTION_NOARGS ();
   1.316 +
   1.317 +  //
   1.318 +  // It's important to remember that we're in a completely different thread than the simulator is running in.  We
   1.319 +  // need to synchronize with that other thread to get the packet up into ns-3.  What we will need to do is to schedule 
   1.320 +  // a method to forward up the packet using the multithreaded simulator we are most certainly running.  However, I just 
   1.321 +  // said it -- we are talking about two threads here, so it is very, very dangerous to do any kind of reference couning
   1.322 +  // on a shared object.  Just don't do it.  So what we're going to do is to allocate a buffer on the heap and pass that
   1.323 +  // buffer into the ns-3 context thread where it will create the packet.
   1.324 +  //
   1.325 +
   1.326 +  int32_t len = -1;
   1.327 +  struct sockaddr_ll addr;
   1.328 +  socklen_t addrSize = sizeof (addr);
   1.329 +
   1.330 +  for (;;) 
   1.331 +    {
   1.332 +      uint32_t bufferSize = 65536;
   1.333 +      uint8_t *buf = (uint8_t *)malloc (bufferSize);
   1.334 +      NS_ASSERT_MSG (buf, "EmulatedNetDevice::ReadThread(): malloc packet buffer failed");
   1.335 +      NS_LOG_LOGIC ("Calling recvfrom");
   1.336 +      len = recvfrom (m_sock, buf, bufferSize, 0, (struct sockaddr *)&addr, &addrSize);
   1.337 +
   1.338 +      if (len == -1)
   1.339 +        {
   1.340 +          free (buf);
   1.341 +          buf = 0;
   1.342 +          return;
   1.343 +        }
   1.344 +
   1.345 +      NS_LOG_INFO ("EmulatedNetDevice::ReadThread(): Received packet");
   1.346 +      NS_LOG_INFO ("EmulatedNetDevice::ReadThread(): Scheduling handler");
   1.347 +      DynamicCast<RealtimeSimulatorImpl> (Simulator::GetImplementation ())->ScheduleRealtimeNow (
   1.348 +        MakeEvent (&EmulatedNetDevice::ForwardUp, this, buf, len));
   1.349 +      buf = 0;
   1.350 +    }
   1.351 +}
   1.352 +
   1.353 +bool 
   1.354 +EmulatedNetDevice::Send (Ptr<Packet> packet, const Address &dest, uint16_t protocolNumber)
   1.355 +{
   1.356 +  NS_LOG_FUNCTION (packet << dest << protocolNumber);
   1.357 +  //
   1.358 +  // The immediate questions here are how are we going to encapsulate packets and what do we use as the MAC source and 
   1.359 +  // destination (hardware) addresses?
   1.360 +  //
   1.361 +  // If we return false from EmulatedNetDevice::NeedsArp, the ArpIpv4Interface will pass the broadcast address as the 
   1.362 +  // hardware (Ethernet) destination by default.  If we return true from EmulatedNetDevice::NeedsArp, then the hardware
   1.363 +  // destination is actually meaningful, but we'll have an ns-3 ARP running on this device.  There can also be an ARP
   1.364 +  // running on the underlying OS so we have to be very careful, both about multiple ARPs and also about TCP, UDP, etc.
   1.365 +  //
   1.366 +  // We are operating in promiscuous mode on the receive side (all ns-3 net devices are required to implement the 
   1.367 +  // promiscuous callback in a meaningful way), so we have an option regarding the hardware addresses.  We don't actually have
   1.368 +  // to use the real hardware addresses and IP addresses of the underlying system.  We can completely use MAC-spoofing to
   1.369 +  // fake out the OS by using the ns-3 assigned MAC address (and also the ns-3 assigned IP addresses).  Ns-3 starts its 
   1.370 +  // MAC address allocation using the OUI (vendor-code) 00:00:00 which is unassigned to any organization and is a globally
   1.371 +  // administered address, so there shouldn't be any collisions with real hardware.
   1.372 +  //
   1.373 +  // So what we do is we return true from EmulatedNetDevice::NeedsArp which tells ns-3 to use its own ARP.  We spoof the 
   1.374 +  // MAC address of the device and use promiscuous mode to receive traffic destined to that address.
   1.375 +  //
   1.376 +  return SendFrom (packet, m_address, dest, protocolNumber);
   1.377 +}
   1.378 +
   1.379 +bool 
   1.380 +EmulatedNetDevice::SendFrom (Ptr<Packet> packet, const Address &src, const Address &dest, uint16_t protocolNumber)
   1.381 +{
   1.382 +  NS_LOG_FUNCTION (packet << src << dest << protocolNumber);
   1.383 +
   1.384 +  if (IsLinkUp () == false)
   1.385 +    {
   1.386 +      NS_LOG_LOGIC ("Link is down, returning");
   1.387 +      return false;
   1.388 +    }
   1.389 +
   1.390 +  Mac48Address destination = Mac48Address::ConvertFrom (dest);
   1.391 +  Mac48Address source = Mac48Address::ConvertFrom (src);
   1.392 +
   1.393 +  NS_LOG_LOGIC ("Transmit packet with UID " << packet->GetUid ());
   1.394 +  NS_LOG_LOGIC ("Transmit packet from " << source);
   1.395 +  NS_LOG_LOGIC ("Transmit packet to " << destination);
   1.396 +
   1.397 +#if 0
   1.398 +  {
   1.399 +    struct ifreq ifr;
   1.400 +    bzero (&ifr, sizeof(ifr));
   1.401 +    strncpy ((char *)ifr.ifr_name, m_deviceName.c_str (), IFNAMSIZ);
   1.402 +
   1.403 +    NS_LOG_LOGIC ("Getting MAC address");
   1.404 +    int32_t rc = ioctl (m_sock, SIOCGIFHWADDR, &ifr);
   1.405 +    NS_ASSERT_MSG (rc != -1, "EmulatedNetDevice::SendFrom(): Can't get MAC address");
   1.406 +
   1.407 +    std::ostringstream oss;
   1.408 +    oss << std::hex <<
   1.409 +      (ifr.ifr_hwaddr.sa_data[0] & 0xff) << ":" <<
   1.410 +      (ifr.ifr_hwaddr.sa_data[1] & 0xff) << ":" <<
   1.411 +      (ifr.ifr_hwaddr.sa_data[2] & 0xff) << ":" <<
   1.412 +      (ifr.ifr_hwaddr.sa_data[3] & 0xff) << ":" <<
   1.413 +      (ifr.ifr_hwaddr.sa_data[4] & 0xff) << ":" <<
   1.414 +      (ifr.ifr_hwaddr.sa_data[5] & 0xff) << std::dec;
   1.415 +
   1.416 +    NS_LOG_LOGIC ("Fixup source to HW MAC " << oss.str ());
   1.417 +    source = Mac48Address (oss.str ().c_str ());
   1.418 +    NS_LOG_LOGIC ("source now " << source);
   1.419 +  }
   1.420 +#endif
   1.421 +
   1.422 +  LlcSnapHeader llc;
   1.423 +  llc.SetType (protocolNumber);
   1.424 +  packet->AddHeader (llc);
   1.425 +
   1.426 +  EthernetHeader header (false);
   1.427 +  header.SetSource (source);
   1.428 +  header.SetDestination (destination);
   1.429 +  header.SetLengthType (packet->GetSize ());
   1.430 +  packet->AddHeader (header);
   1.431 +
   1.432 +  EthernetTrailer trailer;
   1.433 +  trailer.CalcFcs (packet);
   1.434 +  packet->AddTrailer (trailer);
   1.435 +
   1.436 +  // 
   1.437 +  // Enqueue and dequeue the packet to hit the tracing hooks.
   1.438 +  //
   1.439 +  m_queue->Enqueue (packet);
   1.440 +  packet = m_queue->Dequeue ();
   1.441 +
   1.442 +  struct sockaddr_ll ll;
   1.443 +  bzero (&ll, sizeof (ll));
   1.444 +
   1.445 +  ll.sll_family = AF_PACKET;
   1.446 +  ll.sll_ifindex = m_sll_ifindex;
   1.447 +  ll.sll_protocol = htons(ETH_P_ALL); 
   1.448 +
   1.449 +  NS_LOG_LOGIC ("calling sendto");
   1.450 +
   1.451 +  int32_t rc;
   1.452 +  rc = sendto (m_sock, packet->PeekData (), packet->GetSize (), 0, reinterpret_cast<struct sockaddr *> (&ll), sizeof (ll));
   1.453 +
   1.454 +  NS_LOG_LOGIC ("sendto returns " << rc);
   1.455 +
   1.456 +  return rc == -1 ? false : true;
   1.457 +}
   1.458 +
   1.459 +void 
   1.460 +EmulatedNetDevice::SetDataRate(DataRate bps)
   1.461 +{
   1.462 +  NS_LOG_FUNCTION (this << bps);
   1.463 +  NS_ASSERT_MSG (false, "EmulatedNetDevice::SetDataRate():  Unable."); 
   1.464 +}
   1.465 +
   1.466 +void
   1.467 +EmulatedNetDevice::SetQueue (Ptr<Queue> q)
   1.468 +{
   1.469 +  NS_LOG_FUNCTION (this << q);
   1.470 +  m_queue = q;
   1.471 +}
   1.472 +
   1.473 +Ptr<Queue> 
   1.474 +EmulatedNetDevice::GetQueue(void) const 
   1.475 +{ 
   1.476 +  NS_LOG_FUNCTION_NOARGS ();
   1.477 +  return m_queue;
   1.478 +}
   1.479 +
   1.480 +void
   1.481 +EmulatedNetDevice::NotifyLinkUp (void)
   1.482 +{
   1.483 +  m_linkUp = true;
   1.484 +  if (!m_linkChangeCallback.IsNull ())
   1.485 +    {
   1.486 +      m_linkChangeCallback ();
   1.487 +    }
   1.488 +}
   1.489 +
   1.490 +void 
   1.491 +EmulatedNetDevice::SetName(const std::string name)
   1.492 +{
   1.493 +  m_name = name;
   1.494 +}
   1.495 +
   1.496 +std::string 
   1.497 +EmulatedNetDevice::GetName(void) const
   1.498 +{
   1.499 +  return m_name;
   1.500 +}
   1.501 +
   1.502 +void 
   1.503 +EmulatedNetDevice::SetIfIndex(const uint32_t index)
   1.504 +{
   1.505 +  m_ifIndex = index;
   1.506 +}
   1.507 +
   1.508 +uint32_t 
   1.509 +EmulatedNetDevice::GetIfIndex(void) const
   1.510 +{
   1.511 +  return m_ifIndex;
   1.512 +}
   1.513 +
   1.514 +Ptr<Channel> 
   1.515 +EmulatedNetDevice::GetChannel (void) const
   1.516 +{
   1.517 +  NS_ASSERT_MSG (false, "EmulatedNetDevice::GetChannel():  Unable."); 
   1.518 +  return 0;
   1.519 +}
   1.520 +
   1.521 +void 
   1.522 +EmulatedNetDevice::SetAddress (Mac48Address addr)
   1.523 +{
   1.524 +  NS_LOG_FUNCTION (addr);
   1.525 +  m_address = addr;
   1.526 +}
   1.527 +
   1.528 +Address 
   1.529 +EmulatedNetDevice::GetAddress (void) const
   1.530 +{
   1.531 +  NS_LOG_FUNCTION_NOARGS ();
   1.532 +  return m_address;
   1.533 +}
   1.534 +
   1.535 +bool 
   1.536 +EmulatedNetDevice::SetMtu (const uint16_t mtu)
   1.537 +{
   1.538 +  NS_ASSERT_MSG (false, "EmulatedNetDevice::SetMtu():  Unable."); 
   1.539 +  return false;
   1.540 +}
   1.541 +
   1.542 +uint16_t 
   1.543 +EmulatedNetDevice::GetMtu (void) const
   1.544 +{
   1.545 +  struct ifreq ifr;
   1.546 +  bzero (&ifr, sizeof (ifr));
   1.547 +  strcpy(ifr.ifr_name, m_deviceName.c_str ());
   1.548 +
   1.549 +  int32_t fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
   1.550 +
   1.551 +  int32_t rc = ioctl(fd, SIOCGIFMTU, &ifr);
   1.552 +  NS_ASSERT_MSG (rc != -1, "EmulatedNetDevice::GetMtu(): Can't ioctl SIOCGIFMTU");
   1.553 +
   1.554 +  close (fd);
   1.555 +
   1.556 +  return ifr.ifr_mtu;
   1.557 +}
   1.558 +
   1.559 +bool 
   1.560 +EmulatedNetDevice::IsLinkUp (void) const
   1.561 +{
   1.562 +  return m_linkUp;
   1.563 +}
   1.564 +
   1.565 +void 
   1.566 +EmulatedNetDevice::SetLinkChangeCallback (Callback<void> callback)
   1.567 +{
   1.568 +  m_linkChangeCallback = callback;
   1.569 +}
   1.570 +
   1.571 +bool 
   1.572 +EmulatedNetDevice::IsBroadcast (void) const
   1.573 +{
   1.574 +  return true;
   1.575 +}
   1.576 +
   1.577 +Address
   1.578 +EmulatedNetDevice::GetBroadcast (void) const
   1.579 +{
   1.580 +  return Mac48Address ("ff:ff:ff:ff:ff:ff");
   1.581 +}
   1.582 +
   1.583 +bool 
   1.584 +EmulatedNetDevice::IsMulticast (void) const
   1.585 +{
   1.586 +  return false;
   1.587 +}
   1.588 +
   1.589 +Address 
   1.590 +EmulatedNetDevice::GetMulticast (void) const
   1.591 +{
   1.592 +  return Mac48Address ("01:00:5e:00:00:00");
   1.593 +}
   1.594 +
   1.595 +Address 
   1.596 +EmulatedNetDevice::MakeMulticastAddress (Ipv4Address multicastGroup) const
   1.597 +{
   1.598 +  return Mac48Address ("01:00:5e:00:00:00");
   1.599 +}
   1.600 +
   1.601 +bool 
   1.602 +EmulatedNetDevice::IsPointToPoint (void) const
   1.603 +{
   1.604 +  return false;
   1.605 +}
   1.606 +
   1.607 +void
   1.608 +EmulatedNetDevice::SetPromiscReceiveCallback (PromiscReceiveCallback cb)
   1.609 +{
   1.610 +  NS_ASSERT_MSG (false, "EmulatedNetDevice::SetPromiscReceiveCallback(): Not implemented");
   1.611 +}
   1.612 +
   1.613 +  bool 
   1.614 +EmulatedNetDevice::SupportsSendFrom () const
   1.615 +{
   1.616 +  NS_LOG_FUNCTION_NOARGS ();
   1.617 +  return true;
   1.618 +}
   1.619 +
   1.620 +
   1.621 +Ptr<Node> 
   1.622 +EmulatedNetDevice::GetNode (void) const
   1.623 +{
   1.624 +  return m_node;
   1.625 +}
   1.626 +
   1.627 +void 
   1.628 +EmulatedNetDevice::SetNode (Ptr<Node> node)
   1.629 +{
   1.630 +  m_node = node;
   1.631 +}
   1.632 +
   1.633 +bool 
   1.634 +EmulatedNetDevice::NeedsArp (void) const
   1.635 +{
   1.636 +  return true;
   1.637 +}
   1.638 +
   1.639 +void 
   1.640 +EmulatedNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb)
   1.641 +{
   1.642 +  m_rxCallback = cb;
   1.643 +}
   1.644 +
   1.645 +} // namespace ns3
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/src/devices/emulated/emulated-net-device.h	Mon Oct 27 22:01:24 2008 -0700
     2.3 @@ -0,0 +1,321 @@
     2.4 +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
     2.5 +/*
     2.6 + * Copyright (c) 2008 University of Washington
     2.7 + *
     2.8 + * This program is free software; you can redistribute it and/or modify
     2.9 + * it under the terms of the GNU General Public License version 2 as
    2.10 + * published by the Free Software Foundation;
    2.11 + *
    2.12 + * This program is distributed in the hope that it will be useful,
    2.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    2.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    2.15 + * GNU General Public License for more details.
    2.16 + *
    2.17 + * You should have received a copy of the GNU General Public License
    2.18 + * along with this program; if not, write to the Free Software
    2.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    2.20 + */
    2.21 +
    2.22 +#ifndef EMULATED_NET_DEVICE_H
    2.23 +#define EMULATED_NET_DEVICE_H
    2.24 +
    2.25 +#include <string.h>
    2.26 +#include "ns3/address.h"
    2.27 +#include "ns3/net-device.h"
    2.28 +#include "ns3/node.h"
    2.29 +#include "ns3/callback.h"
    2.30 +#include "ns3/packet.h"
    2.31 +#include "ns3/traced-callback.h"
    2.32 +#include "ns3/event-id.h"
    2.33 +#include "ns3/nstime.h"
    2.34 +#include "ns3/data-rate.h"
    2.35 +#include "ns3/ptr.h"
    2.36 +#include "ns3/mac48-address.h"
    2.37 +#include "ns3/system-thread.h"
    2.38 +
    2.39 +namespace ns3 {
    2.40 +
    2.41 +class Queue;
    2.42 +
    2.43 +/**
    2.44 + * \class EmulatedNetDevice
    2.45 + * \brief A Device for an Emulated Network Link.
    2.46 + */
    2.47 +class EmulatedNetDevice : public NetDevice 
    2.48 +{
    2.49 +public:
    2.50 +  static TypeId GetTypeId (void);
    2.51 +
    2.52 +  /**
    2.53 +   * Construct a EmulatedNetDevice
    2.54 +   *
    2.55 +   * This is the constructor for the EmulatedNetDevice.  It takes as a
    2.56 +   */
    2.57 +  EmulatedNetDevice ();
    2.58 +
    2.59 +  /**
    2.60 +   * Destroy a EmulatedNetDevice
    2.61 +   *
    2.62 +   * This is the destructor for the EmulatedNetDevice.
    2.63 +   */
    2.64 +  virtual ~EmulatedNetDevice ();
    2.65 +
    2.66 +  /**
    2.67 +   * Set the Data Rate used for transmission of packets.  
    2.68 +   *
    2.69 +   * @see Attach ()
    2.70 +   * @param bps the data rate at which this object operates
    2.71 +   */
    2.72 +  void SetDataRate (DataRate bps);
    2.73 +
    2.74 +  /**
    2.75 +   * Set the inteframe gap used to separate packets.  The interframe gap
    2.76 +   * defines the minimum space required between packets sent by this device.
    2.77 +   *
    2.78 +   * @param t the interframe gap time
    2.79 +   */
    2.80 +  void SetInterframeGap (Time t);
    2.81 +
    2.82 +  /**
    2.83 +   * Set a start time for the device.
    2.84 +   *
    2.85 +   * @param tStart the start time
    2.86 +   */
    2.87 +  void Start (Time tStart);
    2.88 +
    2.89 +  /**
    2.90 +   * Set a stop time for the device.
    2.91 +   *
    2.92 +   * @param tStop the stop time
    2.93 +   */
    2.94 +  void Stop (Time tStop);
    2.95 +
    2.96 +  /**
    2.97 +   * Attach a queue to the EmulatedNetDevice.
    2.98 +   *
    2.99 +   * The EmulatedNetDevice "owns" a queue that implements a queueing 
   2.100 +   * method such as DropTail or RED.  
   2.101 +   *
   2.102 +   * @see Queue
   2.103 +   * @see DropTailQueue
   2.104 +   * @param queue Ptr to the new queue.
   2.105 +   */
   2.106 +  void SetQueue (Ptr<Queue> queue);
   2.107 +
   2.108 +  /**
   2.109 +   * Receive a packet.
   2.110 +   *
   2.111 +   * The EmulatedNetDevice receives packets from its socket reader
   2.112 +   * and forwards them up the protocol stack.  This is the public method
   2.113 +   * used by the reader to indicate that a packet has arrived at the device.
   2.114 +   *
   2.115 +   * @param p Ptr to the received packet.
   2.116 +   */
   2.117 +  void Receive (Ptr<Packet> p);
   2.118 +
   2.119 +  /**
   2.120 +   * Assign a MAC address to this device.
   2.121 +   *
   2.122 +   * @see Mac48Address
   2.123 +   * @param addr The new address.
   2.124 +   */
   2.125 +  void SetAddress (Mac48Address addr);
   2.126 +
   2.127 +//
   2.128 +// Pure virtual methods inherited from NetDevice we must implement.
   2.129 +//
   2.130 +  virtual void SetName(const std::string name);
   2.131 +  virtual std::string GetName(void) const;
   2.132 +
   2.133 +  virtual void SetIfIndex(const uint32_t index);
   2.134 +  virtual uint32_t GetIfIndex(void) const;
   2.135 +
   2.136 +  virtual Ptr<Channel> GetChannel (void) const;
   2.137 +  virtual Address GetAddress (void) const;
   2.138 +
   2.139 +  virtual bool SetMtu (const uint16_t mtu);
   2.140 +  virtual uint16_t GetMtu (void) const;
   2.141 +
   2.142 +  virtual bool IsLinkUp (void) const;
   2.143 +
   2.144 +  virtual void SetLinkChangeCallback (Callback<void> callback);
   2.145 +
   2.146 +  virtual bool IsBroadcast (void) const;
   2.147 +  virtual Address GetBroadcast (void) const;
   2.148 +
   2.149 +  virtual bool IsMulticast (void) const;
   2.150 +  virtual Address GetMulticast (void) const;
   2.151 +  virtual Address MakeMulticastAddress (Ipv4Address multicastGroup) const;
   2.152 +
   2.153 +  virtual bool IsPointToPoint (void) const;
   2.154 +
   2.155 +  virtual bool Send(Ptr<Packet> packet, const Address &dest, uint16_t protocolNumber);
   2.156 +
   2.157 +  virtual bool SendFrom(Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber);
   2.158 +
   2.159 +  virtual Ptr<Node> GetNode (void) const;
   2.160 +  virtual void SetNode (Ptr<Node> node);
   2.161 +
   2.162 +  virtual bool NeedsArp (void) const;
   2.163 +
   2.164 +  virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
   2.165 +  virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb);
   2.166 +
   2.167 +  virtual bool SupportsSendFrom (void) const;
   2.168 +
   2.169 +private:
   2.170 +
   2.171 +  virtual void DoDispose (void);
   2.172 +
   2.173 +  /**
   2.174 +   * Get a copy of the attached Queue.
   2.175 +   *
   2.176 +   * This method is provided for any derived class that may need to get
   2.177 +   * direct access to the underlying queue.
   2.178 +   *
   2.179 +   * @returns Ptr to the queue.
   2.180 +   */
   2.181 +  Ptr<Queue> GetQueue(void) const; 
   2.182 +
   2.183 +  /**
   2.184 +   * Spin up the device
   2.185 +   */
   2.186 +  void StartDevice (void);
   2.187 +
   2.188 +  /**
   2.189 +   * Tear down the device
   2.190 +   */
   2.191 +  void StopDevice (void);
   2.192 +
   2.193 +  /**
   2.194 +   * Loop to read and process packets
   2.195 +   */
   2.196 +  void ReadThread (void);
   2.197 +
   2.198 +  /**
   2.199 +   * Method to handle received packets.  Synchronized with simulator via ScheduleNow from ReadThread.
   2.200 +   */
   2.201 +  void ForwardUp (uint8_t *buf, uint32_t len);
   2.202 +
   2.203 +  /**
   2.204 +   * Adds the necessary headers and trailers to a packet of data in order to
   2.205 +   * respect the protocol implemented by the agent.
   2.206 +   */
   2.207 +  void AddHeader(Ptr<Packet> p, uint16_t protocolNumber);
   2.208 +
   2.209 +  /**
   2.210 +   * Removes, from a packet of data, all headers and trailers that
   2.211 +   * relate to the protocol implemented by the agent
   2.212 +   * \return Returns true if the packet should be forwarded up the
   2.213 +   * protocol stack.
   2.214 +   */
   2.215 +  bool ProcessHeader(Ptr<Packet> p, uint16_t& param);
   2.216 +
   2.217 +  /**
   2.218 +   * Start Sending a Packet Down the Wire.
   2.219 +   *
   2.220 +   * @returns true if success, false on failure
   2.221 +   */
   2.222 +  bool TransmitStart (Ptr<Packet> p);
   2.223 +
   2.224 +  void NotifyLinkUp (void);
   2.225 +
   2.226 +  /**
   2.227 +   * The Queue which this EmulatedNetDevice uses as a packet source.
   2.228 +   * Management of this Queue has been delegated to the EmulatedNetDevice
   2.229 +   * and it has the responsibility for deletion.
   2.230 +   * @see class Queue
   2.231 +   * @see class DropTailQueue
   2.232 +   */
   2.233 +  Ptr<Queue> m_queue;
   2.234 +
   2.235 +  /**
   2.236 +   * The trace source for the packet reception events that the device can
   2.237 +   * fire.
   2.238 +   *
   2.239 +   * @see class CallBackTraceSource
   2.240 +   */
   2.241 +  TracedCallback<Ptr<const Packet> > m_rxTrace;
   2.242 +
   2.243 +  /**
   2.244 +   * The trace source for the packet drop events that the device can
   2.245 +   * fire.
   2.246 +   *
   2.247 +   * @see class CallBackTraceSource
   2.248 +   */
   2.249 +  TracedCallback<Ptr<const Packet> > m_dropTrace;
   2.250 +
   2.251 +  /**
   2.252 +   * Time to start spinning up the device
   2.253 +   */
   2.254 +  Time m_tStart;
   2.255 +
   2.256 +  /**
   2.257 +   * Time to start tearing down the device
   2.258 +   */
   2.259 +  Time m_tStop;
   2.260 +
   2.261 +  EventId m_startEvent;
   2.262 +  EventId m_stopEvent;
   2.263 +
   2.264 +  int32_t m_sock;
   2.265 +
   2.266 +  Ptr<SystemThread> m_readThread;
   2.267 +
   2.268 +  /**
   2.269 +   * The Node to which this device is attached.
   2.270 +   */
   2.271 +  Ptr<Node> m_node;
   2.272 +
   2.273 +  /**
   2.274 +   * The MAC address which has been assigned to this device.
   2.275 +   */
   2.276 +  Mac48Address m_address;
   2.277 +
   2.278 +  /**
   2.279 +   * The callback used to notify higher layers that a packet has been received.
   2.280 +   */
   2.281 +  NetDevice::ReceiveCallback m_rxCallback;
   2.282 +
   2.283 +  /**
   2.284 +   * The callback used to notify higher layers that a packet has been received in promiscuous mode.
   2.285 +   */
   2.286 +  NetDevice::PromiscReceiveCallback m_promiscRxCallback;
   2.287 +
   2.288 +  /**
   2.289 +   * The ns-3 interface index (in the sense of net device index) that has been assigned to this network device.
   2.290 +   */
   2.291 +  uint32_t m_ifIndex;
   2.292 +
   2.293 +  /**
   2.294 +   * The Unix interface index that we got from the system and which corresponds to the interface (e.g., "eth1")
   2.295 +   * we are using to talk to the network.  Valid when m_sock is valid.
   2.296 +   */
   2.297 +  int32_t m_sll_ifindex;
   2.298 +
   2.299 +  /**
   2.300 +   * The human readable name of this device.
   2.301 +   */
   2.302 +  std::string m_name;
   2.303 +
   2.304 +  /**
   2.305 +   * Flag indicating whether or not the link is up.  In this case,
   2.306 +   * whether or not the device is connected to a channel.
   2.307 +   */
   2.308 +  bool m_linkUp;
   2.309 +
   2.310 +  /**
   2.311 +   * Callback to fire if the link changes state (up or down).
   2.312 +   */
   2.313 +  Callback<void> m_linkChangeCallback;
   2.314 +
   2.315 +  /**
   2.316 +   * The unix/linux name of the underlying device (e.g., eth0)
   2.317 +   */
   2.318 +  std::string m_deviceName;
   2.319 +};
   2.320 +
   2.321 +} // namespace ns3
   2.322 +
   2.323 +#endif // EMULATED_NET_DEVICE_H
   2.324 +
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/devices/emulated/emulated.h	Mon Oct 27 22:01:24 2008 -0700
     3.3 @@ -0,0 +1,10 @@
     3.4 +/**
     3.5 + * \ingroup devices
     3.6 + * \defgroup Emulated Emulated Net Device Model
     3.7 + *
     3.8 + * \section Emulated Net Device Model
     3.9 + *
    3.10 + * This is a description of the emulated network device model.
    3.11 + *
    3.12 + * It is very detailed and comprehensive and answers all possible questions.
    3.13 + */
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/devices/emulated/waf	Mon Oct 27 22:01:24 2008 -0700
     4.3 @@ -0,0 +1,1 @@
     4.4 +exec "`dirname "$0"`"/../../../waf "$@"
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/src/devices/emulated/wscript	Mon Oct 27 22:01:24 2008 -0700
     5.3 @@ -0,0 +1,14 @@
     5.4 +## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
     5.5 +
     5.6 +
     5.7 +def build(bld):
     5.8 +    module = bld.create_ns3_module('emulated', ['node'])
     5.9 +    module.source = [
    5.10 +        'emulated-net-device.cc',
    5.11 +        ]
    5.12 +    headers = bld.create_obj('ns3header')
    5.13 +    headers.module = 'emulated'
    5.14 +    headers.source = [
    5.15 +        'emulated-net-device.h',
    5.16 +        ]
    5.17 +
     6.1 --- a/src/devices/emutap/host-tap-net-device.cc	Mon Oct 27 13:01:28 2008 -0700
     6.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.3 @@ -1,194 +0,0 @@
     6.4 -/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
     6.5 -/*
     6.6 - * Copyright (c) 2008 INRIA
     6.7 - *
     6.8 - * This program is free software; you can redistribute it and/or modify
     6.9 - * it under the terms of the GNU General Public License version 2 as
    6.10 - * published by the Free Software Foundation;
    6.11 - *
    6.12 - * This program is distributed in the hope that it will be useful,
    6.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
    6.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    6.15 - * GNU General Public License for more details.
    6.16 - *
    6.17 - * You should have received a copy of the GNU General Public License
    6.18 - * along with this program; if not, write to the Free Software
    6.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    6.20 - *
    6.21 - * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
    6.22 - */
    6.23 -#include "host-tap-net-device.h"
    6.24 -#include "ns3/node.h"
    6.25 -#include "ns3/tap-channel.h"
    6.26 -#include "ns3/log.h"
    6.27 -
    6.28 -NS_LOG_COMPONENT_DEFINE ("HostTapNetDevice");
    6.29 -
    6.30 -namespace ns3 {
    6.31 -
    6.32 -TypeId 
    6.33 -HostTapNetDevice::GetTypeId (void)
    6.34 -{
    6.35 -  static TypeId tid = TypeId ("ns3::HostTapNetDevice")
    6.36 -    .SetParent<NetDevice> ()
    6.37 -    .AddConstructor<HostTapNetDevice> ()
    6.38 -    ;
    6.39 -  return tid;
    6.40 -}
    6.41 -
    6.42 -HostTapNetDevice::HostTapNetDevice ()
    6.43 -  : m_node (0),
    6.44 -    m_mtu (0xffff),
    6.45 -    m_name (""),
    6.46 -    m_ifIndex (0)
    6.47 -{
    6.48 -  NS_LOG_FUNCTION (this);
    6.49 -}
    6.50 -
    6.51 -void 
    6.52 -HostTapNetDevice::SetChannel (Ptr<TapChannel> channel)
    6.53 -{
    6.54 -  m_channel = channel;
    6.55 -  m_channel->SetHostDevice (this);
    6.56 -}
    6.57 -
    6.58 -void 
    6.59 -HostTapNetDevice::SetAddress (Mac48Address address)
    6.60 -{
    6.61 -  m_address = address;
    6.62 -}
    6.63 -
    6.64 -Mac48Address 
    6.65 -HostTapNetDevice::GetMacAddress (void) const
    6.66 -{
    6.67 -  return m_address;
    6.68 -}
    6.69 -
    6.70 -void 
    6.71 -HostTapNetDevice::SetName(const std::string name)
    6.72 -{
    6.73 -  m_name = name;
    6.74 -}
    6.75 -std::string 
    6.76 -HostTapNetDevice::GetName(void) const
    6.77 -{
    6.78 -  return m_name;
    6.79 -}
    6.80 -void 
    6.81 -HostTapNetDevice::SetIfIndex(const uint32_t index)
    6.82 -{
    6.83 -  m_ifIndex = index;
    6.84 -}
    6.85 -uint32_t 
    6.86 -HostTapNetDevice::GetIfIndex(void) const
    6.87 -{
    6.88 -  return m_ifIndex;
    6.89 -}
    6.90 -Ptr<Channel> 
    6.91 -HostTapNetDevice::GetChannel (void) const
    6.92 -{
    6.93 -  return m_channel;
    6.94 -}
    6.95 -Address 
    6.96 -HostTapNetDevice::GetAddress (void) const
    6.97 -{
    6.98 -  return m_address;
    6.99 -}
   6.100 -bool 
   6.101 -HostTapNetDevice::SetMtu (const uint16_t mtu)
   6.102 -{
   6.103 -  m_mtu = mtu;
   6.104 -  return true;
   6.105 -}
   6.106 -uint16_t 
   6.107 -HostTapNetDevice::GetMtu (void) const
   6.108 -{
   6.109 -  return m_mtu;
   6.110 -}
   6.111 -bool 
   6.112 -HostTapNetDevice::IsLinkUp (void) const
   6.113 -{
   6.114 -  return true;
   6.115 -}
   6.116 -void 
   6.117 -HostTapNetDevice::SetLinkChangeCallback (Callback<void> callback)
   6.118 -{}
   6.119 -bool 
   6.120 -HostTapNetDevice::IsBroadcast (void) const
   6.121 -{
   6.122 -  return true;
   6.123 -}
   6.124 -Address
   6.125 -HostTapNetDevice::GetBroadcast (void) const
   6.126 -{
   6.127 -  return Mac48Address ("ff:ff:ff:ff:ff:ff");
   6.128 -}
   6.129 -bool 
   6.130 -HostTapNetDevice::IsMulticast (void) const
   6.131 -{
   6.132 -  return true;
   6.133 -}
   6.134 -Address 
   6.135 -HostTapNetDevice::GetMulticast (void) const
   6.136 -{
   6.137 -  return Mac48Address::GetMulticastPrefix ();
   6.138 -}
   6.139 -Address 
   6.140 -HostTapNetDevice::MakeMulticastAddress (Ipv4Address multicastGroup) const
   6.141 -{
   6.142 -  return Mac48Address::GetMulticast (multicastGroup);
   6.143 -}
   6.144 -bool 
   6.145 -HostTapNetDevice::IsPointToPoint (void) const
   6.146 -{
   6.147 -  return false;
   6.148 -}
   6.149 -bool 
   6.150 -HostTapNetDevice::Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
   6.151 -{
   6.152 -  return false;
   6.153 -}
   6.154 -bool 
   6.155 -HostTapNetDevice::SendFrom(Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber)
   6.156 -{
   6.157 -  return false;
   6.158 -}
   6.159 -Ptr<Node> 
   6.160 -HostTapNetDevice::GetNode (void) const
   6.161 -{
   6.162 -  return m_node;
   6.163 -}
   6.164 -void 
   6.165 -HostTapNetDevice::SetNode (Ptr<Node> node)
   6.166 -{
   6.167 -  m_node = node;
   6.168 -}
   6.169 -bool 
   6.170 -HostTapNetDevice::NeedsArp (void) const
   6.171 -{
   6.172 -  return false;
   6.173 -}
   6.174 -void 
   6.175 -HostTapNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb)
   6.176 -{}
   6.177 -
   6.178 -void
   6.179 -HostTapNetDevice::DoDispose (void)
   6.180 -{
   6.181 -  NS_LOG_FUNCTION (this);
   6.182 -  m_node = 0;
   6.183 -  m_channel = 0;
   6.184 -  NetDevice::DoDispose ();
   6.185 -}
   6.186 -
   6.187 -void
   6.188 -HostTapNetDevice::SetPromiscReceiveCallback (PromiscReceiveCallback cb)
   6.189 -{}
   6.190 -
   6.191 -bool
   6.192 -HostTapNetDevice::SupportsSendFrom (void) const
   6.193 -{
   6.194 -  return false;
   6.195 -}
   6.196 -
   6.197 -} // namespace ns3
     7.1 --- a/src/devices/emutap/host-tap-net-device.h	Mon Oct 27 13:01:28 2008 -0700
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,90 +0,0 @@
     7.4 -/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
     7.5 -/*
     7.6 - * Copyright (c) 2008 INRIA
     7.7 - *
     7.8 - * This program is free software; you can redistribute it and/or modify
     7.9 - * it under the terms of the GNU General Public License version 2 as
    7.10 - * published by the Free Software Foundation;
    7.11 - *
    7.12 - * This program is distributed in the hope that it will be useful,
    7.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
    7.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    7.15 - * GNU General Public License for more details.
    7.16 - *
    7.17 - * You should have received a copy of the GNU General Public License
    7.18 - * along with this program; if not, write to the Free Software
    7.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    7.20 - *
    7.21 - * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
    7.22 - */
    7.23 -#ifndef HOST_TAP_NET_DEVICE_H
    7.24 -#define HOST_TAP_NET_DEVICE_H
    7.25 -
    7.26 -#include "ns3/net-device.h"
    7.27 -#include "ns3/mac48-address.h"
    7.28 -#include "ns3/traced-callback.h"
    7.29 -#include <stdint.h>
    7.30 -#include <string>
    7.31 -
    7.32 -namespace ns3 {
    7.33 -
    7.34 -class Node;
    7.35 -class TapChannel;
    7.36 -
    7.37 -
    7.38 -/**
    7.39 - * \ingroup netdevice
    7.40 - * 
    7.41 - * \brief a NetDevice to get packets to and from a host tap device.
    7.42 - */
    7.43 -class HostTapNetDevice : public NetDevice
    7.44 -{
    7.45 -public:
    7.46 -  static TypeId GetTypeId (void);
    7.47 -  HostTapNetDevice ();
    7.48 -
    7.49 -  void SetAddress (Mac48Address address);
    7.50 -  void SetChannel (Ptr<TapChannel> channel);
    7.51 -
    7.52 -  Mac48Address GetMacAddress (void) const;
    7.53 -
    7.54 -  // inherited from NetDevice base class.
    7.55 -  virtual void SetName(const std::string name);
    7.56 -  virtual std::string GetName(void) const;
    7.57 -  virtual void SetIfIndex(const uint32_t index);
    7.58 -  virtual uint32_t GetIfIndex(void) const;
    7.59 -  virtual Ptr<Channel> GetChannel (void) const;
    7.60 -  virtual Address GetAddress (void) const;
    7.61 -  virtual bool SetMtu (const uint16_t mtu);
    7.62 -  virtual uint16_t GetMtu (void) const;
    7.63 -  virtual bool IsLinkUp (void) const;
    7.64 -  virtual void SetLinkChangeCallback (Callback<void> callback);
    7.65 -  virtual bool IsBroadcast (void) const;
    7.66 -  virtual Address GetBroadcast (void) const;
    7.67 -  virtual bool IsMulticast (void) const;
    7.68 -  virtual Address GetMulticast (void) const;
    7.69 -  virtual Address MakeMulticastAddress (Ipv4Address multicastGroup) const;
    7.70 -  virtual bool IsPointToPoint (void) const;
    7.71 -  virtual bool Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber);
    7.72 -  virtual bool SendFrom(Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber);
    7.73 -  virtual Ptr<Node> GetNode (void) const;
    7.74 -  virtual void SetNode (Ptr<Node> node);
    7.75 -  virtual bool NeedsArp (void) const;
    7.76 -  virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
    7.77 -  virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb);
    7.78 -  virtual bool SupportsSendFrom (void) const;
    7.79 -
    7.80 -protected:
    7.81 -  virtual void DoDispose (void);
    7.82 -private:
    7.83 -  Ptr<Node> m_node;
    7.84 -  uint16_t m_mtu;
    7.85 -  std::string m_name;
    7.86 -  uint32_t m_ifIndex;
    7.87 -  Mac48Address m_address;
    7.88 -  Ptr<TapChannel> m_channel;
    7.89 -};
    7.90 -
    7.91 -} // namespace ns3
    7.92 -
    7.93 -#endif /* HOST_TAP_NET_DEVICE_H */
     8.1 --- a/src/devices/emutap/tap-channel.cc	Mon Oct 27 13:01:28 2008 -0700
     8.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.3 @@ -1,61 +0,0 @@
     8.4 -#include "tap-channel.h"
     8.5 -#include "host-tap-net-device.h"
     8.6 -#include "tap-net-device.h"
     8.7 -
     8.8 -namespace ns3 {
     8.9 -
    8.10 -
    8.11 -TapChannel::TapChannel ()
    8.12 -  : m_hostDevice (0),
    8.13 -    m_device (0)
    8.14 -{}
    8.15 -
    8.16 -void
    8.17 -TapChannel::DoDispose (void)
    8.18 -{
    8.19 -  m_device = 0;
    8.20 -  m_hostDevice = 0;
    8.21 -  Channel::DoDispose ();
    8.22 -}
    8.23 -
    8.24 -void
    8.25 -TapChannel::SetDevice (Ptr<TapNetDevice> device)
    8.26 -{
    8.27 -  m_device = device;
    8.28 -}
    8.29 -
    8.30 -void
    8.31 -TapChannel::SetHostDevice (Ptr<HostTapNetDevice> device)
    8.32 -{
    8.33 -  m_hostDevice = device;
    8.34 -}
    8.35 -
    8.36 -Ptr<HostTapNetDevice> 
    8.37 -TapChannel::GetHostDevice (void) const
    8.38 -{
    8.39 -  return m_hostDevice;
    8.40 -}
    8.41 -
    8.42 -uint32_t 
    8.43 -TapChannel::GetNDevices (void) const
    8.44 -{
    8.45 -  return 2;
    8.46 -}
    8.47 -Ptr<NetDevice> 
    8.48 -TapChannel::GetDevice (uint32_t i) const
    8.49 -{
    8.50 -  if (i == 0)
    8.51 -    {
    8.52 -      return m_device;
    8.53 -    }
    8.54 -  else if (i == 1)
    8.55 -    {
    8.56 -      return m_hostDevice;
    8.57 -    }
    8.58 -  else
    8.59 -    {
    8.60 -      return 0;
    8.61 -    }
    8.62 -}
    8.63 -
    8.64 -} // namespace ns3
     9.1 --- a/src/devices/emutap/tap-channel.h	Mon Oct 27 13:01:28 2008 -0700
     9.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.3 @@ -1,36 +0,0 @@
     9.4 -#ifndef TAP_CHANNEL_H
     9.5 -#define TAP_CHANNEL_H
     9.6 -
     9.7 -#include "ns3/channel.h"
     9.8 -
     9.9 -namespace ns3 {
    9.10 -
    9.11 -class HostTapNetDevice;
    9.12 -class TapNetDevice;
    9.13 -class NetDevice;
    9.14 -
    9.15 -
    9.16 -class TapChannel : public Channel
    9.17 -{
    9.18 -public:
    9.19 -  TapChannel ();
    9.20 -
    9.21 -  void SetHostDevice (Ptr<HostTapNetDevice> device);
    9.22 -  void SetDevice (Ptr<TapNetDevice> device);
    9.23 -
    9.24 -  Ptr<HostTapNetDevice> GetHostDevice (void) const;
    9.25 -
    9.26 -  // overriden from Channel base class
    9.27 -  virtual uint32_t GetNDevices (void) const;
    9.28 -  virtual Ptr<NetDevice> GetDevice (uint32_t i) const;
    9.29 -
    9.30 -private:
    9.31 -  virtual void DoDispose (void);
    9.32 -
    9.33 -  Ptr<HostTapNetDevice> m_hostDevice;
    9.34 -  Ptr<TapNetDevice> m_device;
    9.35 -};
    9.36 -
    9.37 -} // namespace ns3
    9.38 -
    9.39 -#endif /* TAP_CHANNEL_H */
    10.1 --- a/src/devices/emutap/tap-manager-client.cc	Mon Oct 27 13:01:28 2008 -0700
    10.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.3 @@ -1,180 +0,0 @@
    10.4 -#include "tap-manager-client.h"
    10.5 -#include "ns3/log.h"
    10.6 -#include <sys/socket.h>
    10.7 -#include <sys/wait.h>
    10.8 -#include <sys/stat.h>
    10.9 -#include <linux/un.h>
   10.10 -#include <errno.h>
   10.11 -#include <string.h>
   10.12 -#include <iomanip>
   10.13 -#include <iostream>
   10.14 -#include <list>
   10.15 -
   10.16 -
   10.17 -NS_LOG_COMPONENT_DEFINE("TapManagerClient");
   10.18 -
   10.19 -#define TAP_MANAGER "ns3-tap-manager"
   10.20 -
   10.21 -namespace ns3 {
   10.22 -
   10.23 -static std::string
   10.24 -EncodeAsString (struct sockaddr_un un, int len)
   10.25 -{
   10.26 -  uint8_t *buffer = (uint8_t *)&un;
   10.27 -  std::ostringstream oss;
   10.28 -  oss.setf (std::ios::hex, std::ios::basefield);
   10.29 -  oss.fill('0');
   10.30 -  for (uint8_t i = 0; i < len; i++)
   10.31 -    {
   10.32 -      oss << ":" << std::setw (2) << (uint32_t)buffer[i];
   10.33 -    }
   10.34 -  return oss.str ();
   10.35 -}
   10.36 -
   10.37 -bool
   10.38 -TapManagerClient::Exists (std::string filename) const
   10.39 -{
   10.40 -  struct stat st;
   10.41 -  int retval = ::stat (filename.c_str (), &st);
   10.42 -  return retval == 0;
   10.43 -}
   10.44 -
   10.45 -std::string
   10.46 -TapManagerClient::FindManager (void) const
   10.47 -{
   10.48 -  std::list<std::string> locations;
   10.49 -  locations.push_back ("./src/devices/tap");
   10.50 -  locations.push_back ("./build/debug/src/devices/tap");
   10.51 -  locations.push_back ("./build/optimized/src/devices/tap");
   10.52 -  for (std::list<std::string>::const_iterator i = locations.begin (); i != locations.end (); ++i)
   10.53 -    {
   10.54 -      if (Exists (*i + "/" + TAP_MANAGER))
   10.55 -	{
   10.56 -	  return *i + "/" + TAP_MANAGER;
   10.57 -	}
   10.58 -    }
   10.59 -  NS_FATAL_ERROR ("Could not find manager");
   10.60 -  return ""; // quiet compiler
   10.61 -}
   10.62 -
   10.63 -int
   10.64 -TapManagerClient::AllocateTap (Mac48Address host, Ipv4Address ad, Ipv4Mask mask, Ipv4Address gateway)
   10.65 -{
   10.66 -  NS_LOG_FUNCTION (host << ad << mask << gateway);
   10.67 -  // create a socket to get information back from the tap manager.
   10.68 -  int sock = socket (PF_UNIX, SOCK_DGRAM, 0);
   10.69 -  if (sock == -1)
   10.70 -    {
   10.71 -      NS_FATAL_ERROR ("Socket creation, errno=" << strerror (errno));
   10.72 -    }
   10.73 -
   10.74 -  struct sockaddr_un un;
   10.75 -  memset (&un, 0, sizeof (un));
   10.76 -  un.sun_family = AF_UNIX;
   10.77 -  int status = bind (sock, (struct sockaddr*)&un, sizeof (sa_family_t)); // let the kernel allocate an endpoint for us.
   10.78 -  if (status == -1)
   10.79 -    {
   10.80 -      NS_FATAL_ERROR ("Could not bind: errno=" << strerror (errno));
   10.81 -    }
   10.82 -  socklen_t len = sizeof (un);
   10.83 -  status = getsockname (sock, (struct sockaddr*)&un, &len);
   10.84 -  if (status == -1)
   10.85 -    {
   10.86 -      NS_FATAL_ERROR ("Could not get socket address: errno=" << strerror (errno));
   10.87 -    }
   10.88 -  NS_LOG_DEBUG ("Allocated enpoint=" << EncodeAsString (un, len) << ", len=" << len);
   10.89 -
   10.90 -  pid_t pid = ::fork ();
   10.91 -  if (pid == 0)
   10.92 -    {
   10.93 -      // child.
   10.94 -      NS_LOG_DEBUG ("Child");
   10.95 -
   10.96 -      std::ostringstream oss;
   10.97 -      oss << "--path=" << EncodeAsString (un, len);
   10.98 -      std::string pathArg = oss.str ();
   10.99 -      oss.str ("");
  10.100 -      oss << "--mac-addr=" << host;
  10.101 -      std::string hostArg = oss.str ();
  10.102 -      oss.str ("");
  10.103 -      oss << "--ip-addr=" << ad;
  10.104 -      std::string ipArg = oss.str ();
  10.105 -      oss.str ("");
  10.106 -      oss << "--ip-gw=" << gateway;
  10.107 -      std::string ipGw = oss.str ();
  10.108 -      oss.str ("");
  10.109 -      oss << "--ip-netmask=" << mask;
  10.110 -      std::string ipMask = oss.str ();
  10.111 -      oss.str ("");
  10.112 -      status = ::execl (FindManager ().c_str (), 
  10.113 -			TAP_MANAGER, 
  10.114 -			pathArg.c_str (),
  10.115 -			hostArg.c_str (),
  10.116 -			ipArg.c_str (),
  10.117 -			ipGw.c_str (),
  10.118 -			ipMask.c_str (),
  10.119 -			(char *)NULL);
  10.120 -      if (status == -1)
  10.121 -	{
  10.122 -	  NS_LOG_ERROR ("Cannot execl tap-manager, errno=" << ::strerror (errno));
  10.123 -	}
  10.124 -      ::_exit (-1);
  10.125 -    }
  10.126 -  else
  10.127 -    {
  10.128 -      // parent
  10.129 -      NS_LOG_DEBUG ("Parent");
  10.130 -      int st;
  10.131 -      pid_t waited = waitpid (pid, &st, 0);
  10.132 -      if (waited == -1)
  10.133 -	{
  10.134 -	  NS_FATAL_ERROR ("Cannot wait for tap-manager, errno=" << strerror (errno));
  10.135 -	}
  10.136 -      NS_ASSERT (pid == waited);
  10.137 -      if (!WIFEXITED (st))
  10.138 -	{
  10.139 -	  // tap manager did not complete successfully
  10.140 -	  NS_FATAL_ERROR ("tap-manager did not exit correctly");
  10.141 -	}
  10.142 -      else if (WEXITSTATUS (st) != 0)
  10.143 -	{
  10.144 -	  NS_FATAL_ERROR ("tap-manager did not complete successfully, err=" << WEXITSTATUS (st));
  10.145 -	}
  10.146 -      // the tap fd should be available on our unix socket now.
  10.147 -      size_t msg_size = sizeof(int);
  10.148 -      char control[CMSG_SPACE(msg_size)];
  10.149 -      struct cmsghdr *cmsg;
  10.150 -      uint8_t buffer;
  10.151 -      struct iovec iov;
  10.152 -      iov.iov_base = &buffer;
  10.153 -      iov.iov_len = 1;
  10.154 -      struct msghdr msg;
  10.155 -      msg.msg_name = 0;
  10.156 -      msg.msg_namelen = 0;
  10.157 -      msg.msg_iov = &iov;
  10.158 -      msg.msg_iovlen = 1;
  10.159 -      msg.msg_control = control;
  10.160 -      msg.msg_controllen = sizeof (control);
  10.161 -      msg.msg_flags = 0;
  10.162 -      ssize_t bytesRead = recvmsg (sock, &msg, 0);
  10.163 -      if (bytesRead != 1)
  10.164 -	{
  10.165 -	  NS_FATAL_ERROR ("Did not get byte from tap-manager");
  10.166 -	}
  10.167 -      NS_LOG_ERROR ("read bytes=" << bytesRead);
  10.168 -      for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) 
  10.169 -	{
  10.170 -	  if (cmsg->cmsg_level == SOL_SOCKET &&
  10.171 -	      cmsg->cmsg_type == SCM_RIGHTS)
  10.172 -	    {
  10.173 -	      int *fd = (int*)CMSG_DATA (cmsg);
  10.174 -	      NS_LOG_ERROR ("got tap fd=" << *fd);
  10.175 -	      return *fd;
  10.176 -	    }
  10.177 -	}
  10.178 -      NS_FATAL_ERROR ("Did not get SCM_RIGHTS from tap-manager");
  10.179 -    }
  10.180 -  return -1;
  10.181 -}
  10.182 -
  10.183 -} // namespace ns3
    11.1 --- a/src/devices/emutap/tap-manager-client.h	Mon Oct 27 13:01:28 2008 -0700
    11.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.3 @@ -1,21 +0,0 @@
    11.4 -#ifndef TAP_MANAGER_CLIENT_H
    11.5 -#define TAP_MANAGER_CLIENT_H
    11.6 -
    11.7 -#include "ns3/mac48-address.h"
    11.8 -#include "ns3/ipv4-address.h"
    11.9 -#include <string>
   11.10 -
   11.11 -namespace ns3 {
   11.12 -
   11.13 -class TapManagerClient
   11.14 -{
   11.15 -public:
   11.16 -  int AllocateTap (Mac48Address host, Ipv4Address ad, Ipv4Mask mask, Ipv4Address gateway);
   11.17 -private:
   11.18 -  std::string FindManager (void) const;
   11.19 -  bool Exists (std::string filename) const;
   11.20 -};
   11.21 -
   11.22 -} // namespace ns3
   11.23 -
   11.24 -#endif /* TAP_MANAGER_CLIENT_H */
    12.1 --- a/src/devices/emutap/tap-manager.cc	Mon Oct 27 13:01:28 2008 -0700
    12.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.3 @@ -1,339 +0,0 @@
    12.4 -#include <fcntl.h>
    12.5 -#include <sys/ioctl.h>
    12.6 -#include <sys/types.h>
    12.7 -#include <sys/socket.h>
    12.8 -#include <linux/un.h>
    12.9 -#include <linux/if.h>
   12.10 -#include <linux/if_tun.h>
   12.11 -#include <linux/route.h>
   12.12 -#include <netinet/in.h>
   12.13 -#include <stdint.h>
   12.14 -#include <iostream>
   12.15 -#include <sstream>
   12.16 -#include <iomanip>
   12.17 -#include <string.h>
   12.18 -#include <errno.h>
   12.19 -#include <stdlib.h>
   12.20 -
   12.21 -#define noENABLE_LOG
   12.22 -
   12.23 -#define EXIT_ERROR(x, err)						\
   12.24 -  std::cout << __FILE__ << ":" << __LINE__ << ": Unrecoverable Error: " << x; \
   12.25 -  std::cout << " errno=" << strerror (errno) << std::endl;		\
   12.26 -  exit (err)
   12.27 -#ifdef ENABLE_LOG
   12.28 -#define LOG(x) \
   12.29 -  std::cout << x << std::endl;
   12.30 -#else
   12.31 -#define LOG(x)
   12.32 -#endif
   12.33 -
   12.34 -
   12.35 -#define CHECK_ARG(el,var) \
   12.36 -  {						\
   12.37 -    char start[] = "--"  el  "=";		     \
   12.38 -    if (strncmp (*argv, start, strlen (start)) == 0) \
   12.39 -      {						     \
   12.40 -	var = *argv + strlen (start);		     \
   12.41 -	LOG ("--" << el << "=" << var);		     \
   12.42 -      }						     \
   12.43 -  }
   12.44 -
   12.45 -#define ASCII_DOT (0x2e)
   12.46 -#define ASCII_ZERO (0x30)
   12.47 -#define ASCII_a (0x41)
   12.48 -#define ASCII_z (0x5a)
   12.49 -#define ASCII_A (0x61)
   12.50 -#define ASCII_Z (0x7a)
   12.51 -#define ASCII_COLON (0x3a)
   12.52 -#define ASCII_ZERO (0x30)
   12.53 -static char
   12.54 -AsciiToLowCase (char c)
   12.55 -{
   12.56 -  if (c >= ASCII_a && c <= ASCII_z) {
   12.57 -    return c;
   12.58 -  } else if (c >= ASCII_A && c <= ASCII_Z) {
   12.59 -    return c + (ASCII_a - ASCII_A);
   12.60 -  } else {
   12.61 -    return c;
   12.62 -  }
   12.63 -}
   12.64 -static uint32_t 
   12.65 -AsciiToIpv4 (const char *address)
   12.66 -{
   12.67 -  uint32_t host = 0;
   12.68 -  while (true) {
   12.69 -    uint8_t byte = 0;
   12.70 -    while (*address != ASCII_DOT &&
   12.71 -           *address != 0) {
   12.72 -      byte *= 10;
   12.73 -      byte += *address - ASCII_ZERO;
   12.74 -      address++;
   12.75 -    }
   12.76 -    host <<= 8;
   12.77 -    host |= byte;
   12.78 -    if (*address == 0) {
   12.79 -      break;
   12.80 -    }
   12.81 -    address++;
   12.82 -  }
   12.83 -  return host;
   12.84 -}
   12.85 -
   12.86 -static void 
   12.87 -AsciiToMac48 (const char *str, uint8_t addr[6])
   12.88 -{
   12.89 -  int i = 0;
   12.90 -  while (*str != 0 && i < 6) 
   12.91 -    {
   12.92 -      uint8_t byte = 0;
   12.93 -      while (*str != ASCII_COLON && *str != 0) 
   12.94 -	{
   12.95 -	  byte <<= 4;
   12.96 -	  char low = AsciiToLowCase (*str);
   12.97 -	  if (low >= ASCII_a) 
   12.98 -	    {
   12.99 -	      byte |= low - ASCII_a + 10;
  12.100 -	    } 
  12.101 -	  else 
  12.102 -	    {
  12.103 -	      byte |= low - ASCII_ZERO;
  12.104 -	    }
  12.105 -	  str++;
  12.106 -	}
  12.107 -      addr[i] = byte;
  12.108 -      i++;
  12.109 -      if (*str == 0) 
  12.110 -	{
  12.111 -	  break;
  12.112 -	}
  12.113 -      str++;
  12.114 -    }
  12.115 -}
  12.116 -
  12.117 -static void
  12.118 -SetInetAddress (sockaddr *ad, uint32_t networkOrder)
  12.119 -{
  12.120 -  struct sockaddr_in *sin = (struct sockaddr_in*)ad;
  12.121 -  sin->sin_family = AF_INET;
  12.122 -  sin->sin_port = 0; // unused
  12.123 -  sin->sin_addr.s_addr = htonl (networkOrder);
  12.124 -}
  12.125 -
  12.126 -
  12.127 -static int
  12.128 -CreateTap (const char *mac_addr, const char *ip, 
  12.129 -	   const char *gw, const char *netmask)
  12.130 -{
  12.131 -  // opening the tun device usually requires root privs
  12.132 -  int tap = open ("/dev/net/tun", O_RDWR);
  12.133 -  if (tap == -1)
  12.134 -    {
  12.135 -      EXIT_ERROR ("Could not open /dev/net/tun", 1);
  12.136 -    }
  12.137 -  // now, crate a tap device.
  12.138 -  struct ifreq ifr;
  12.139 -  // make sure that the tap device will not send us the tun_pi header.
  12.140 -  ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
  12.141 -  ifr.ifr_name[0] = 0; // allow the kernel to pick a device name.
  12.142 -  int status = ioctl (tap, TUNSETIFF, (void *) &ifr);
  12.143 -  if (status == -1)
  12.144 -    {
  12.145 -      EXIT_ERROR ("Could not allocate a tap device", 2);
  12.146 -    }
  12.147 -  std::string tapDeviceName = (char *)ifr.ifr_name;
  12.148 -  LOG ("Allocated TAP device=" << tapDeviceName);
  12.149 -
  12.150 -  // set its hardware address to something we know will be unique within the simulation
  12.151 -  ifr.ifr_hwaddr.sa_family = 1; // this is ARPHRD_ETHER from if_arp.h
  12.152 -  AsciiToMac48 (mac_addr, (uint8_t*)ifr.ifr_hwaddr.sa_data);
  12.153 -  status = ioctl (tap, SIOCSIFHWADDR, &ifr);
  12.154 -  if (status == -1)
  12.155 -    {
  12.156 -      EXIT_ERROR ("Could not set hardware address=" << mac_addr << " for=" << (char *)ifr.ifr_name, 3);
  12.157 -    }
  12.158 -  LOG ("device=" << (char *)ifr.ifr_name << " addr=" << mac_addr);
  12.159 -
  12.160 -
  12.161 -  // The ip address must be set using an AF_INET socket.
  12.162 -  int fd = socket (AF_INET, SOCK_DGRAM, 0);
  12.163 -
  12.164 -  // set interface up.
  12.165 -  status = ioctl (fd, SIOCGIFFLAGS, &ifr);
  12.166 -  if (status == -1)
  12.167 -    {
  12.168 -      EXIT_ERROR ("Could not get flags for interface=" << (char *)ifr.ifr_name, 4);
  12.169 -    }
  12.170 -  ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
  12.171 -  status = ioctl (fd, SIOCSIFFLAGS, &ifr);
  12.172 -  if (status == -1)
  12.173 -    {
  12.174 -      EXIT_ERROR ("Could not bring interface " << (char *)ifr.ifr_name << " up", 5);
  12.175 -    }
  12.176 -  LOG ("device=" << (char *)ifr.ifr_name << " is up");
  12.177 -
  12.178 -
  12.179 -  // set its ip address.
  12.180 -  SetInetAddress (&ifr.ifr_addr, AsciiToIpv4 (ip));
  12.181 -  status = ioctl (fd, SIOCSIFADDR, &ifr);
  12.182 -  if (status == -1)
  12.183 -    {
  12.184 -      EXIT_ERROR ("Could not set ip address=" << ip << " for=" <<  (char *)ifr.ifr_name, 6);
  12.185 -    }
  12.186 -  LOG ("device=" << (char *)ifr.ifr_name << " addr=" << ip);
  12.187 -
  12.188 -  // set its ip mask to be /32
  12.189 -  SetInetAddress (&ifr.ifr_netmask, 0xffffffff);
  12.190 -  status = ioctl (fd, SIOCSIFNETMASK, &ifr);
  12.191 -  if (status == -1)
  12.192 -    {
  12.193 -      EXIT_ERROR ("Could not set ip mask=" << netmask << " for=" <<  (char *)ifr.ifr_name, 7);
  12.194 -    }
  12.195 -  LOG ("device=" << (char *)ifr.ifr_name << " mask=" << netmask); 
  12.196 -
  12.197 -  // add routing entry for gateway.
  12.198 -  struct rtentry rt;
  12.199 -  SetInetAddress (&rt.rt_dst, AsciiToIpv4 (gw));
  12.200 -  SetInetAddress (&rt.rt_genmask, 0xffffffff);
  12.201 -  rt.rt_flags = RTF_UP;
  12.202 -  rt.rt_metric = 2;
  12.203 -  rt.rt_dev = (char*)tapDeviceName.c_str ();
  12.204 -  status = ioctl (fd, SIOCADDRT, &rt);
  12.205 -  if (status == -1)
  12.206 -    {
  12.207 -      EXIT_ERROR ("Could not add routing table entry", 8);
  12.208 -    }
  12.209 -  LOG ("added routing table entry for gw.");
  12.210 -
  12.211 -  // add routing entry for subnet through gateway.
  12.212 -  uint32_t network = AsciiToIpv4 (ip) & AsciiToIpv4 (netmask);
  12.213 -  SetInetAddress (&rt.rt_dst, network);
  12.214 -  SetInetAddress (&rt.rt_gateway, AsciiToIpv4 (gw));
  12.215 -  SetInetAddress (&rt.rt_genmask, AsciiToIpv4 (netmask));
  12.216 -  rt.rt_flags = RTF_UP | RTF_GATEWAY;
  12.217 -  rt.rt_metric = 2;
  12.218 -  rt.rt_dev = (char*)tapDeviceName.c_str ();
  12.219 -  status = ioctl (fd, SIOCADDRT, &rt);
  12.220 -  if (status == -1)
  12.221 -    {
  12.222 -      EXIT_ERROR ("Could not add routing table entry", 9);
  12.223 -    }
  12.224 -  LOG ("added routing table entry for subnet.");
  12.225 -
  12.226 -  return tap;
  12.227 -}
  12.228 -
  12.229 -static struct sockaddr_un
  12.230 -DecodeFromString (const char *path, socklen_t *len)
  12.231 -{
  12.232 -  sockaddr_un un;
  12.233 -  uint8_t *buffer = (uint8_t *)&un;
  12.234 -  std::istringstream iss;
  12.235 -  iss.str (path);
  12.236 -  uint8_t n = 0;
  12.237 -  while (!iss.bad () && !iss.eof () && !iss.fail ())
  12.238 -    {
  12.239 -      char c;
  12.240 -      iss.read (&c, 1);
  12.241 -      uint32_t tmp;
  12.242 -      iss >> std::hex >> tmp;
  12.243 -      //LOG (std::hex << tmp);
  12.244 -      buffer[n] = tmp;
  12.245 -      n++;
  12.246 -    }
  12.247 -  *len = n;
  12.248 -  return un;
  12.249 -}
  12.250 -
  12.251 -static void
  12.252 -SendFd (const char *path, int fd)
  12.253 -{
  12.254 -  // send back configuration to caller.
  12.255 -  int sock = socket (PF_UNIX, SOCK_DGRAM, 0);
  12.256 -  if (sock == -1)
  12.257 -    {
  12.258 -      EXIT_ERROR ("Socket creation", 10);
  12.259 -    }
  12.260 -  LOG ("Socket Created");
  12.261 -  
  12.262 -  socklen_t local_len;
  12.263 -  struct sockaddr_un local = DecodeFromString (path, &local_len);
  12.264 -  LOG ("len=" << local_len);
  12.265 -  int status = connect (sock, (struct sockaddr*)&local, local_len);
  12.266 -  if (status == -1)
  12.267 -    {
  12.268 -      EXIT_ERROR ("Could not connect to caller", 11);
  12.269 -    }
  12.270 -  LOG ("Socket Connected");
  12.271 -
  12.272 -  // we send a single byte whose content is meaningless.
  12.273 -  // we also return as ancillary data the tap file descriptor
  12.274 -  struct cmsghdr *cmsg;
  12.275 -  size_t msg_size = sizeof(int);
  12.276 -  char control[CMSG_SPACE(msg_size)];
  12.277 -  struct iovec iov;
  12.278 -  struct msghdr msg;
  12.279 -  char buffer = 0;
  12.280 -  iov.iov_base = &buffer;
  12.281 -  iov.iov_len = 1;
  12.282 -  msg.msg_name = 0;
  12.283 -  msg.msg_namelen = 0;
  12.284 -  msg.msg_iov = &iov;
  12.285 -  msg.msg_iovlen = 1;
  12.286 -  msg.msg_control = control;
  12.287 -  msg.msg_controllen = sizeof (control);
  12.288 -  msg.msg_flags = 0;
  12.289 -
  12.290 -  cmsg = CMSG_FIRSTHDR(&msg);
  12.291 -  cmsg->cmsg_level = SOL_SOCKET;
  12.292 -  cmsg->cmsg_type = SCM_RIGHTS;
  12.293 -  cmsg->cmsg_len = CMSG_LEN(msg_size);
  12.294 -  msg.msg_controllen = cmsg->cmsg_len;
  12.295 -
  12.296 -  int *fdptr = (int*) (CMSG_DATA(cmsg));
  12.297 -  *fdptr = fd;
  12.298 -
  12.299 -  ssize_t len = sendmsg(sock, &msg, 0);
  12.300 -  if (len == -1)
  12.301 -    {
  12.302 -      EXIT_ERROR ("Could not send SCM_RIGHTS", 12);
  12.303 -    }
  12.304 -  LOG ("Sent SCM_RIGHTS");
  12.305 -}
  12.306 -
  12.307 -
  12.308 -
  12.309 -
  12.310 -int main (int argc, char *argv[])
  12.311 -{
  12.312 -  char *path = 0;
  12.313 -  char *mac_addr = 0;
  12.314 -  char *ip_addr = 0;
  12.315 -  char *ip_gw = 0;
  12.316 -  char *ip_netmask = 0;
  12.317 -  char *stop = 0;
  12.318 -  argv++;
  12.319 -  argc--;
  12.320 -  while (argc > 0)
  12.321 -    {
  12.322 -      CHECK_ARG("path", path);
  12.323 -      CHECK_ARG("mac-addr", mac_addr);
  12.324 -      CHECK_ARG("ip-addr", ip_addr);
  12.325 -      CHECK_ARG("ip-gw", ip_gw);
  12.326 -      CHECK_ARG("ip-netmask", ip_netmask);
  12.327 -      CHECK_ARG("stop", stop);
  12.328 -      argv++;
  12.329 -      argc--;
  12.330 -    }
  12.331 -  
  12.332 -  int tap = CreateTap (mac_addr, ip_addr, ip_gw, ip_netmask);
  12.333 -
  12.334 -  if (stop)
  12.335 -    {
  12.336 -      while (1) {}
  12.337 -    }
  12.338 -
  12.339 -  SendFd (path, tap);
  12.340 -
  12.341 -  return 0;
  12.342 -}
    13.1 --- a/src/devices/emutap/tap-net-device.cc	Mon Oct 27 13:01:28 2008 -0700
    13.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.3 @@ -1,323 +0,0 @@
    13.4 -/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
    13.5 -/*
    13.6 - * Copyright (c) 2008 INRIA
    13.7 - *
    13.8 - * This program is free software; you can redistribute it and/or modify
    13.9 - * it under the terms of the GNU General Public License version 2 as
   13.10 - * published by the Free Software Foundation;
   13.11 - *
   13.12 - * This program is distributed in the hope that it will be useful,
   13.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   13.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13.15 - * GNU General Public License for more details.
   13.16 - *
   13.17 - * You should have received a copy of the GNU General Public License
   13.18 - * along with this program; if not, write to the Free Software
   13.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   13.20 - *
   13.21 - * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
   13.22 - */
   13.23 -#include "tap-net-device.h"
   13.24 -#include "tap-manager-client.h"
   13.25 -#include "ns3/node.h"
   13.26 -#include "ns3/channel.h"
   13.27 -#include "ns3/packet.h"
   13.28 -#include "ns3/log.h"
   13.29 -#include "ns3/system-thread.h"
   13.30 -#include "ns3/realtime-simulator-impl.h"
   13.31 -#include "ns3/make-event.h"
   13.32 -#include "ns3/simulator.h"
   13.33 -#include "ns3/ethernet-header.h"
   13.34 -#include "ns3/trace-source-accessor.h"
   13.35 -#include "host-tap-net-device.h"
   13.36 -#include "tap-channel.h"
   13.37 -#include <errno.h>
   13.38 -#include <stdlib.h>
   13.39 -
   13.40 -NS_LOG_COMPONENT_DEFINE ("TapNetDevice");
   13.41 -
   13.42 -namespace ns3 {
   13.43 -
   13.44 -TypeId 
   13.45 -TapNetDevice::GetTypeId (void)
   13.46 -{
   13.47 -  static TypeId tid = TypeId ("ns3::TapNetDevice")
   13.48 -    .SetParent<NetDevice> ()
   13.49 -    .AddConstructor<TapNetDevice> ()
   13.50 -    .AddTraceSource ("Rx", "A packet has been received",
   13.51 -                     MakeTraceSourceAccessor (&TapNetDevice::m_rxTrace))
   13.52 -    .AddTraceSource ("Tx", "A packet has been sent",
   13.53 -                     MakeTraceSourceAccessor (&TapNetDevice::m_txTrace))
   13.54 -    .AddTraceSource ("Drop", "A packet has been dropped",
   13.55 -                     MakeTraceSourceAccessor (&TapNetDevice::m_dropTrace))
   13.56 -    ;
   13.57 -  return tid;
   13.58 -}
   13.59 -
   13.60 -TapNetDevice::TapNetDevice ()
   13.61 -  : m_node (0),
   13.62 -    m_mtu (0xffff),
   13.63 -    m_name (""),
   13.64 -    m_ifIndex (0),
   13.65 -    m_tap (-1)
   13.66 -{
   13.67 -  NS_LOG_FUNCTION (this);
   13.68 -}
   13.69 -
   13.70 -void 
   13.71 -TapNetDevice::SetChannel (Ptr<TapChannel> channel)
   13.72 -{
   13.73 -  m_channel = channel;
   13.74 -  m_channel->SetDevice (this);
   13.75 -}
   13.76 -
   13.77 -void 
   13.78 -TapNetDevice::SetupHost (Ipv4Address ad, Ipv4Mask mask, Ipv4Address gateway)
   13.79 -{
   13.80 -  NS_LOG_FUNCTION (this << ad << mask << gateway);
   13.81 -  NS_ASSERT (m_tap == -1);
   13.82 -
   13.83 -  Mac48Address hostMacAddress = m_channel->GetHostDevice ()->GetMacAddress ();
   13.84 -
   13.85 -  TapManagerClient manager;
   13.86 -  m_tap = manager.AllocateTap (hostMacAddress, ad, mask, gateway);
   13.87 -
   13.88 -  m_thread = Create<SystemThread> (MakeCallback (&TapNetDevice::ReadThread, this));
   13.89 -  m_thread->Start ();
   13.90 -}
   13.91 -
   13.92 -
   13.93 -void
   13.94 -TapNetDevice::ReadThread (void)
   13.95 -{
   13.96 -  NS_LOG_FUNCTION (this);
   13.97 -
   13.98 -  while (1)
   13.99 -    {
  13.100 -      uint8_t *buffer = (uint8_t *)malloc (0xffff);
  13.101 -      ssize_t bytesRead = read (m_tap, buffer, 0xffff);
  13.102 -      if (bytesRead == -1)
  13.103 -        {
  13.104 -          if (errno == EBADF || errno == EINTR)
  13.105 -            {
  13.106 -              // the device was closed from under us by ::DoDispose
  13.107 -              return;
  13.108 -            }
  13.109 -          NS_FATAL_ERROR ("Error reading from tap device: errno=" << strerror (errno));
  13.110 -        }
  13.111 -      // Note: we purposedly don't use a smart pointer to manage this packet
  13.112 -      // because the want to hand over ownership of this packet to the ForwardUp
  13.113 -      // method.
  13.114 -      DynamicCast<RealtimeSimulatorImpl> (Simulator::GetImplementation ())->
  13.115 -        ScheduleRealtimeNow (MakeEvent (&TapNetDevice::ForwardUp, this, buffer, (uint32_t)bytesRead));
  13.116 -    }
  13.117 -}
  13.118 -
  13.119 -void
  13.120 -TapNetDevice::ForwardUp (uint8_t *buffer, uint32_t size)
  13.121 -{
  13.122 -  NS_LOG_FUNCTION (this << buffer << size);
  13.123 -
  13.124 -  // swallow packet reference in smart pointer.
  13.125 -  Ptr<Packet> packet = Create<Packet> (buffer, size);
  13.126 -  free (buffer);
  13.127 -  Ptr<Packet> copy = packet->Copy ();
  13.128 -
  13.129 -  EthernetHeader header = EthernetHeader (false);
  13.130 -  packet->RemoveHeader (header);
  13.131 -
  13.132 -  uint16_t protocol = header.GetLengthType ();
  13.133 -  Mac48Address to = header.GetDestination ();
  13.134 -  Mac48Address from = header.GetSource ();
  13.135 -  
  13.136 -  NetDevice::PacketType packetType;
  13.137 -  if (to == m_address)
  13.138 -    {
  13.139 -      packetType = NetDevice::PACKET_HOST;
  13.140 -    }
  13.141 -  else if (to.IsBroadcast ())
  13.142 -    {
  13.143 -      packetType = NetDevice::PACKET_HOST;
  13.144 -    }
  13.145 -  else if (to.IsMulticast ())
  13.146 -    {
  13.147 -      packetType = NetDevice::PACKET_MULTICAST;
  13.148 -    }
  13.149 -  else 
  13.150 -    {
  13.151 -      packetType = NetDevice::PACKET_OTHERHOST;
  13.152 -    }
  13.153 -  m_rxTrace (copy, from, to);
  13.154 -  if (packetType != NetDevice::PACKET_OTHERHOST)
  13.155 -    {
  13.156 -      m_rxCallback (this, packet, protocol, from);
  13.157 -    }
  13.158 -  if (!m_promiscCallback.IsNull ())
  13.159 -    {
  13.160 -      m_promiscCallback (this, packet, protocol, from, to, packetType);
  13.161 -    }
  13.162 -}
  13.163 -
  13.164 -void 
  13.165 -TapNetDevice::SetAddress (Mac48Address address)
  13.166 -{
  13.167 -  m_address = address;
  13.168 -}
  13.169 -
  13.170 -void 
  13.171 -TapNetDevice::SetName(const std::string name)
  13.172 -{
  13.173 -  m_name = name;
  13.174 -}
  13.175 -std::string 
  13.176 -TapNetDevice::GetName(void) const
  13.177 -{
  13.178 -  return m_name;
  13.179 -}
  13.180 -void 
  13.181 -TapNetDevice::SetIfIndex(const uint32_t index)
  13.182 -{
  13.183 -  m_ifIndex = index;
  13.184 -}
  13.185 -uint32_t 
  13.186 -TapNetDevice::GetIfIndex(void) const
  13.187 -{
  13.188 -  return m_ifIndex;
  13.189 -}
  13.190 -Ptr<Channel> 
  13.191 -TapNetDevice::GetChannel (void) const
  13.192 -{
  13.193 -  return m_channel;
  13.194 -}
  13.195 -Address 
  13.196 -TapNetDevice::GetAddress (void) const
  13.197 -{
  13.198 -  return m_address;
  13.199 -}
  13.200 -bool 
  13.201 -TapNetDevice::SetMtu (const uint16_t mtu)
  13.202 -{
  13.203 -  m_mtu = mtu;
  13.204 -  return true;
  13.205 -}
  13.206 -uint16_t 
  13.207 -TapNetDevice::GetMtu (void) const
  13.208 -{
  13.209 -  return m_mtu;
  13.210 -}
  13.211 -bool 
  13.212 -TapNetDevice::IsLinkUp (void) const
  13.213 -{
  13.214 -  return true;
  13.215 -}
  13.216 -void 
  13.217 -TapNetDevice::SetLinkChangeCallback (Callback<void> callback)
  13.218 -{}
  13.219 -bool 
  13.220 -TapNetDevice::IsBroadcast (void) const
  13.221 -{
  13.222 -  return true;
  13.223 -}
  13.224 -Address
  13.225 -TapNetDevice::GetBroadcast (void) const
  13.226 -{
  13.227 -  return Mac48Address ("ff:ff:ff:ff:ff:ff");
  13.228 -}
  13.229 -bool 
  13.230 -TapNetDevice::IsMulticast (void) const
  13.231 -{
  13.232 -  return true;
  13.233 -}
  13.234 -Address 
  13.235 -TapNetDevice::GetMulticast (void) const
  13.236 -{
  13.237 -  return Mac48Address::GetMulticastPrefix ();
  13.238 -}
  13.239 -Address 
  13.240 -TapNetDevice::MakeMulticastAddress (Ipv4Address multicastGroup) const
  13.241 -{
  13.242 -  return Mac48Address::GetMulticast (multicastGroup);
  13.243 -}
  13.244 -bool 
  13.245 -TapNetDevice::IsPointToPoint (void) const
  13.246 -{
  13.247 -  return false;
  13.248 -}
  13.249 -bool 
  13.250 -TapNetDevice::Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
  13.251 -{
  13.252 -  NS_LOG_FUNCTION (this << packet << dest << protocolNumber);
  13.253 -  return SendFrom (packet, m_address, dest, protocolNumber);
  13.254 -}
  13.255 -bool 
  13.256 -TapNetDevice::SendFrom(Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber)
  13.257 -{
  13.258 -  NS_LOG_FUNCTION (this << packet << source << dest << protocolNumber);
  13.259 -  Mac48Address to = Mac48Address::ConvertFrom (dest);
  13.260 -  Mac48Address from = Mac48Address::ConvertFrom (source);
  13.261 -
  13.262 -  EthernetHeader header = EthernetHeader (false);
  13.263 -  header.SetSource (from);
  13.264 -  header.SetDestination (to);
  13.265 -  header.SetLengthType (protocolNumber);
  13.266 -  packet->AddHeader (header);
  13.267 -
  13.268 -  ssize_t written = write (m_tap, packet->PeekData (), packet->GetSize ());
  13.269 -  if (written == -1 || written != (ssize_t)packet->GetSize ())
  13.270 -    {
  13.271 -      m_dropTrace (packet, from, to);
  13.272 -      return false;
  13.273 -    }
  13.274 -
  13.275 -  m_txTrace (packet, from, to);
  13.276 -  
  13.277 -  return true;
  13.278 -}
  13.279 -
  13.280 -Ptr<Node> 
  13.281 -TapNetDevice::GetNode (void) const
  13.282 -{
  13.283 -  return m_node;
  13.284 -}
  13.285 -void 
  13.286 -TapNetDevice::SetNode (Ptr<Node> node)
  13.287 -{
  13.288 -  m_node = node;
  13.289 -}
  13.290 -bool 
  13.291 -TapNetDevice::NeedsArp (void) const
  13.292 -{
  13.293 -  return true;
  13.294 -}
  13.295 -void 
  13.296 -TapNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb)
  13.297 -{
  13.298 -  m_rxCallback = cb;
  13.299 -}
  13.300 -
  13.301 -void
  13.302 -TapNetDevice::DoDispose (void)
  13.303 -{
  13.304 -  NS_LOG_FUNCTION (this);
  13.305 -  close (m_tap);
  13.306 -  m_thread->Join ();
  13.307 -  m_thread = 0;
  13.308 -  m_node = 0;
  13.309 -  m_channel = 0;
  13.310 -  NetDevice::DoDispose ();
  13.311 -}
  13.312 -
  13.313 -
  13.314 -void
  13.315 -TapNetDevice::SetPromiscReceiveCallback (PromiscReceiveCallback cb)
  13.316 -{
  13.317 -  m_promiscCallback = cb;
  13.318 -}
  13.319 -
  13.320 -bool
  13.321 -TapNetDevice::SupportsSendFrom (void) const
  13.322 -{
  13.323 -  return true;
  13.324 -}
  13.325 -
  13.326 -} // namespace ns3
    14.1 --- a/src/devices/emutap/tap-net-device.h	Mon Oct 27 13:01:28 2008 -0700
    14.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.3 @@ -1,103 +0,0 @@
    14.4 -/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
    14.5 -/*
    14.6 - * Copyright (c) 2008 INRIA
    14.7 - *
    14.8 - * This program is free software; you can redistribute it and/or modify
    14.9 - * it under the terms of the GNU General Public License version 2 as
   14.10 - * published by the Free Software Foundation;
   14.11 - *
   14.12 - * This program is distributed in the hope that it will be useful,
   14.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   14.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14.15 - * GNU General Public License for more details.
   14.16 - *
   14.17 - * You should have received a copy of the GNU General Public License
   14.18 - * along with this program; if not, write to the Free Software
   14.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   14.20 - *
   14.21 - * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
   14.22 - */
   14.23 -#ifndef TAP_NET_DEVICE_H
   14.24 -#define TAP_NET_DEVICE_H
   14.25 -
   14.26 -#include "ns3/net-device.h"
   14.27 -#include "ns3/mac48-address.h"
   14.28 -#include "ns3/traced-callback.h"
   14.29 -#include <stdint.h>
   14.30 -#include <string>
   14.31 -
   14.32 -namespace ns3 {
   14.33 -
   14.34 -class Node;
   14.35 -class SystemThread;
   14.36 -class TapChannel;
   14.37 -
   14.38 -/**
   14.39 - * \ingroup netdevice
   14.40 - * 
   14.41 - * \brief a NetDevice to get packets to and from a host tap device.
   14.42 - */
   14.43 -class TapNetDevice : public NetDevice
   14.44 -{
   14.45 -public:
   14.46 -  static TypeId GetTypeId (void);
   14.47 -  TapNetDevice ();
   14.48 -
   14.49 -  void SetAddress (Mac48Address address);
   14.50 -
   14.51 -  void SetChannel (Ptr<TapChannel> channel);
   14.52 -
   14.53 -  void SetupHost (Ipv4Address ad, Ipv4Mask mask, Ipv4Address gateway);
   14.54 -
   14.55 -  // inherited from NetDevice base class.
   14.56 -  virtual void SetName(const std::string name);
   14.57 -  virtual std::string GetName(void) const;
   14.58 -  virtual void SetIfIndex(const uint32_t index);
   14.59 -  virtual uint32_t GetIfIndex(void) const;
   14.60 -  virtual Ptr<Channel> GetChannel (void) const;
   14.61 -  virtual Address GetAddress (void) const;
   14.62 -  virtual bool SetMtu (const uint16_t mtu);
   14.63 -  virtual uint16_t GetMtu (void) const;
   14.64 -  virtual bool IsLinkUp (void) const;
   14.65 -  virtual void SetLinkChangeCallback (Callback<void> callback);
   14.66 -  virtual bool IsBroadcast (void) const;
   14.67 -  virtual Address GetBroadcast (void) const;
   14.68 -  virtual bool IsMulticast (void) const;
   14.69 -  virtual Address GetMulticast (void) const;
   14.70 -  virtual Address MakeMulticastAddress (Ipv4Address multicastGroup) const;
   14.71 -  virtual bool IsPointToPoint (void) const;
   14.72 -  virtual bool Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber);
   14.73 -  virtual bool SendFrom(Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber);
   14.74 -  virtual Ptr<Node> GetNode (void) const;
   14.75 -  virtual void SetNode (Ptr<Node> node);
   14.76 -  virtual bool NeedsArp (void) const;
   14.77 -  virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
   14.78 -  virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb);
   14.79 -  virtual bool SupportsSendFrom (void) const;
   14.80 -
   14.81 -protected:
   14.82 -  virtual void DoDispose (void);
   14.83 -private:
   14.84 -  void Receive (Ptr<Packet> packet, uint16_t protocol, 
   14.85 -                Mac48Address to, Mac48Address from);
   14.86 -  void ForwardUp (uint8_t *buffer, uint32_t size);
   14.87 -  void ReadThread (void);
   14.88 -
   14.89 -  NetDevice::ReceiveCallback m_rxCallback;
   14.90 -  NetDevice::PromiscReceiveCallback m_promiscCallback;
   14.91 -  Ptr<Node> m_node;
   14.92 -  uint16_t m_mtu;
   14.93 -  std::string m_name;
   14.94 -  uint32_t m_ifIndex;
   14.95 -  Mac48Address m_address;
   14.96 -  int m_tap;
   14.97 -  Ptr<SystemThread> m_thread;
   14.98 -  TracedCallback<Ptr<const Packet>,Mac48Address,Mac48Address> m_rxTrace;
   14.99 -  TracedCallback<Ptr<const Packet>,Mac48Address,Mac48Address> m_txTrace;
  14.100 -  TracedCallback<Ptr<const Packet>,Mac48Address,Mac48Address> m_dropTrace;
  14.101 -  Ptr<TapChannel> m_channel;
  14.102 -};
  14.103 -
  14.104 -} // namespace ns3
  14.105 -
  14.106 -#endif /* TAP_NET_DEVICE_H */
    15.1 --- a/src/devices/emutap/wscript	Mon Oct 27 13:01:28 2008 -0700
    15.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.3 @@ -1,26 +0,0 @@
    15.4 -## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
    15.5 -
    15.6 -
    15.7 -def build(bld):
    15.8 -    obj = bld.create_suid_program('ns3-tap-manager')
    15.9 -    obj.source = [
   15.10 -       'tap-manager.cc',
   15.11 -       ]
   15.12 -
   15.13 -    module = bld.create_ns3_module('emutap', ['node'])
   15.14 -    module.uselib = 'CAP'
   15.15 -    module.source = [
   15.16 -    'tap-net-device.cc',
   15.17 -    'tap-manager-client.cc',
   15.18 -    'tap-channel.cc',
   15.19 -    'host-tap-net-device.cc',
   15.20 -    ]
   15.21 -    headers = bld.create_obj('ns3header')
   15.22 -    headers.module = 'emutap'
   15.23 -    headers.source = [
   15.24 -    'tap-net-device.h',
   15.25 -    'host-tap-net-device.h',
   15.26 -    'tap-channel.h',
   15.27 -    ]
   15.28 -
   15.29 -
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/src/devices/tap/host-tap-net-device.cc	Mon Oct 27 22:01:24 2008 -0700
    16.3 @@ -0,0 +1,194 @@
    16.4 +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
    16.5 +/*
    16.6 + * Copyright (c) 2008 INRIA
    16.7 + *
    16.8 + * This program is free software; you can redistribute it and/or modify
    16.9 + * it under the terms of the GNU General Public License version 2 as
   16.10 + * published by the Free Software Foundation;
   16.11 + *
   16.12 + * This program is distributed in the hope that it will be useful,
   16.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   16.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16.15 + * GNU General Public License for more details.
   16.16 + *
   16.17 + * You should have received a copy of the GNU General Public License
   16.18 + * along with this program; if not, write to the Free Software
   16.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   16.20 + *
   16.21 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
   16.22 + */
   16.23 +#include "host-tap-net-device.h"
   16.24 +#include "ns3/node.h"
   16.25 +#include "ns3/tap-channel.h"
   16.26 +#include "ns3/log.h"
   16.27 +
   16.28 +NS_LOG_COMPONENT_DEFINE ("HostTapNetDevice");
   16.29 +
   16.30 +namespace ns3 {
   16.31 +
   16.32 +TypeId 
   16.33 +HostTapNetDevice::GetTypeId (void)
   16.34 +{
   16.35 +  static TypeId tid = TypeId ("ns3::HostTapNetDevice")
   16.36 +    .SetParent<NetDevice> ()
   16.37 +    .AddConstructor<HostTapNetDevice> ()
   16.38 +    ;
   16.39 +  return tid;
   16.40 +}
   16.41 +
   16.42 +HostTapNetDevice::HostTapNetDevice ()
   16.43 +  : m_node (0),
   16.44 +    m_mtu (0xffff),
   16.45 +    m_name (""),
   16.46 +    m_ifIndex (0)
   16.47 +{
   16.48 +  NS_LOG_FUNCTION (this);
   16.49 +}
   16.50 +
   16.51 +void 
   16.52 +HostTapNetDevice::SetChannel (Ptr<TapChannel> channel)
   16.53 +{
   16.54 +  m_channel = channel;
   16.55 +  m_channel->SetHostDevice (this);
   16.56 +}
   16.57 +
   16.58 +void 
   16.59 +HostTapNetDevice::SetAddress (Mac48Address address)
   16.60 +{
   16.61 +  m_address = address;
   16.62 +}
   16.63 +
   16.64 +Mac48Address 
   16.65 +HostTapNetDevice::GetMacAddress (void) const
   16.66 +{
   16.67 +  return m_address;
   16.68 +}
   16.69 +
   16.70 +void 
   16.71 +HostTapNetDevice::SetName(const std::string name)
   16.72 +{
   16.73 +  m_name = name;
   16.74 +}
   16.75 +std::string 
   16.76 +HostTapNetDevice::GetName(void) const
   16.77 +{
   16.78 +  return m_name;
   16.79 +}
   16.80 +void 
   16.81 +HostTapNetDevice::SetIfIndex(const uint32_t index)
   16.82 +{
   16.83 +  m_ifIndex = index;
   16.84 +}
   16.85 +uint32_t 
   16.86 +HostTapNetDevice::GetIfIndex(void) const
   16.87 +{
   16.88 +  return m_ifIndex;
   16.89 +}
   16.90 +Ptr<Channel> 
   16.91 +HostTapNetDevice::GetChannel (void) const
   16.92 +{
   16.93 +  return m_channel;
   16.94 +}
   16.95 +Address 
   16.96 +HostTapNetDevice::GetAddress (void) const
   16.97 +{
   16.98 +  return m_address;
   16.99 +}
  16.100 +bool 
  16.101 +HostTapNetDevice::SetMtu (const uint16_t mtu)
  16.102 +{
  16.103 +  m_mtu = mtu;
  16.104 +  return true;
  16.105 +}
  16.106 +uint16_t 
  16.107 +HostTapNetDevice::GetMtu (void) const
  16.108 +{
  16.109 +  return m_mtu;
  16.110 +}
  16.111 +bool 
  16.112 +HostTapNetDevice::IsLinkUp (void) const
  16.113 +{
  16.114 +  return true;
  16.115 +}
  16.116 +void 
  16.117 +HostTapNetDevice::SetLinkChangeCallback (Callback<void> callback)
  16.118 +{}
  16.119 +bool 
  16.120 +HostTapNetDevice::IsBroadcast (void) const
  16.121 +{
  16.122 +  return true;
  16.123 +}
  16.124 +Address
  16.125 +HostTapNetDevice::GetBroadcast (void) const
  16.126 +{
  16.127 +  return Mac48Address ("ff:ff:ff:ff:ff:ff");
  16.128 +}
  16.129 +bool 
  16.130 +HostTapNetDevice::IsMulticast (void) const
  16.131 +{
  16.132 +  return true;
  16.133 +}
  16.134 +Address 
  16.135 +HostTapNetDevice::GetMulticast (void) const
  16.136 +{
  16.137 +  return Mac48Address::GetMulticastPrefix ();
  16.138 +}
  16.139 +Address 
  16.140 +HostTapNetDevice::MakeMulticastAddress (Ipv4Address multicastGroup) const
  16.141 +{
  16.142 +  return Mac48Address::GetMulticast (multicastGroup);
  16.143 +}
  16.144 +bool 
  16.145 +HostTapNetDevice::IsPointToPoint (void) const
  16.146 +{
  16.147 +  return false;
  16.148 +}
  16.149 +bool 
  16.150 +HostTapNetDevice::Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
  16.151 +{
  16.152 +  return false;
  16.153 +}
  16.154 +bool 
  16.155 +HostTapNetDevice::SendFrom(Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber)
  16.156 +{
  16.157 +  return false;
  16.158 +}
  16.159 +Ptr<Node> 
  16.160 +HostTapNetDevice::GetNode (void) const
  16.161 +{
  16.162 +  return m_node;
  16.163 +}
  16.164 +void 
  16.165 +HostTapNetDevice::SetNode (Ptr<Node> node)
  16.166 +{
  16.167 +  m_node = node;
  16.168 +}
  16.169 +bool 
  16.170 +HostTapNetDevice::NeedsArp (void) const
  16.171 +{
  16.172 +  return false;
  16.173 +}
  16.174 +void 
  16.175 +HostTapNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb)
  16.176 +{}
  16.177 +
  16.178 +void
  16.179 +HostTapNetDevice::DoDispose (void)
  16.180 +{
  16.181 +  NS_LOG_FUNCTION (this);
  16.182 +  m_node = 0;
  16.183 +  m_channel = 0;
  16.184 +  NetDevice::DoDispose ();
  16.185 +}
  16.186 +
  16.187 +void
  16.188 +HostTapNetDevice::SetPromiscReceiveCallback (PromiscReceiveCallback cb)
  16.189 +{}
  16.190 +
  16.191 +bool
  16.192 +HostTapNetDevice::SupportsSendFrom (void) const
  16.193 +{
  16.194 +  return false;
  16.195 +}
  16.196 +
  16.197 +} // namespace ns3
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/src/devices/tap/host-tap-net-device.h	Mon Oct 27 22:01:24 2008 -0700
    17.3 @@ -0,0 +1,90 @@
    17.4 +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
    17.5 +/*
    17.6 + * Copyright (c) 2008 INRIA
    17.7 + *
    17.8 + * This program is free software; you can redistribute it and/or modify
    17.9 + * it under the terms of the GNU General Public License version 2 as
   17.10 + * published by the Free Software Foundation;
   17.11 + *
   17.12 + * This program is distributed in the hope that it will be useful,
   17.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   17.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   17.15 + * GNU General Public License for more details.
   17.16 + *
   17.17 + * You should have received a copy of the GNU General Public License
   17.18 + * along with this program; if not, write to the Free Software
   17.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   17.20 + *
   17.21 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
   17.22 + */
   17.23 +#ifndef HOST_TAP_NET_DEVICE_H
   17.24 +#define HOST_TAP_NET_DEVICE_H
   17.25 +
   17.26 +#include "ns3/net-device.h"
   17.27 +#include "ns3/mac48-address.h"
   17.28 +#include "ns3/traced-callback.h"
   17.29 +#include <stdint.h>
   17.30 +#include <string>
   17.31 +
   17.32 +namespace ns3 {
   17.33 +
   17.34 +class Node;
   17.35 +class TapChannel;
   17.36 +
   17.37 +
   17.38 +/**
   17.39 + * \ingroup netdevice
   17.40 + * 
   17.41 + * \brief a NetDevice to get packets to and from a host tap device.
   17.42 + */
   17.43 +class HostTapNetDevice : public NetDevice
   17.44 +{
   17.45 +public:
   17.46 +  static TypeId GetTypeId (void);
   17.47 +  HostTapNetDevice ();
   17.48 +
   17.49 +  void SetAddress (Mac48Address address);
   17.50 +  void SetChannel (Ptr<TapChannel> channel);
   17.51 +
   17.52 +  Mac48Address GetMacAddress (void) const;
   17.53 +
   17.54 +  // inherited from NetDevice base class.
   17.55 +  virtual void SetName(const std::string name);
   17.56 +  virtual std::string GetName(void) const;
   17.57 +  virtual void SetIfIndex(const uint32_t index);
   17.58 +  virtual uint32_t GetIfIndex(void) const;
   17.59 +  virtual Ptr<Channel> GetChannel (void) const;
   17.60 +  virtual Address GetAddress (void) const;
   17.61 +  virtual bool SetMtu (const uint16_t mtu);
   17.62 +  virtual uint16_t GetMtu (void) const;
   17.63 +  virtual bool IsLinkUp (void) const;
   17.64 +  virtual void SetLinkChangeCallback (Callback<void> callback);
   17.65 +  virtual bool IsBroadcast (void) const;
   17.66 +  virtual Address GetBroadcast (void) const;
   17.67 +  virtual bool IsMulticast (void) const;
   17.68 +  virtual Address GetMulticast (void) const;
   17.69 +  virtual Address MakeMulticastAddress (Ipv4Address multicastGroup) const;
   17.70 +  virtual bool IsPointToPoint (void) const;
   17.71 +  virtual bool Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber);
   17.72 +  virtual bool SendFrom(Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber);
   17.73 +  virtual Ptr<Node> GetNode (void) const;
   17.74 +  virtual void SetNode (Ptr<Node> node);
   17.75 +  virtual bool NeedsArp (void) const;
   17.76 +  virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
   17.77 +  virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb);
   17.78 +  virtual bool SupportsSendFrom (void) const;
   17.79 +
   17.80 +protected:
   17.81 +  virtual void DoDispose (void);
   17.82 +private:
   17.83 +  Ptr<Node> m_node;
   17.84 +  uint16_t m_mtu;
   17.85 +  std::string m_name;
   17.86 +  uint32_t m_ifIndex;
   17.87 +  Mac48Address m_address;
   17.88 +  Ptr<TapChannel> m_channel;
   17.89 +};
   17.90 +
   17.91 +} // namespace ns3
   17.92 +
   17.93 +#endif /* HOST_TAP_NET_DEVICE_H */
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/src/devices/tap/tap-channel.cc	Mon Oct 27 22:01:24 2008 -0700
    18.3 @@ -0,0 +1,61 @@
    18.4 +#include "tap-channel.h"
    18.5 +#include "host-tap-net-device.h"
    18.6 +#include "tap-net-device.h"
    18.7 +
    18.8 +namespace ns3 {
    18.9 +
   18.10 +
   18.11 +TapChannel::TapChannel ()
   18.12 +  : m_hostDevice (0),
   18.13 +    m_device (0)
   18.14 +{}
   18.15 +
   18.16 +void
   18.17 +TapChannel::DoDispose (void)
   18.18 +{
   18.19 +  m_device = 0;
   18.20 +  m_hostDevice = 0;
   18.21 +  Channel::DoDispose ();
   18.22 +}
   18.23 +
   18.24 +void
   18.25 +TapChannel::SetDevice (Ptr<TapNetDevice> device)
   18.26 +{
   18.27 +  m_device = device;
   18.28 +}
   18.29 +
   18.30 +void
   18.31 +TapChannel::SetHostDevice (Ptr<HostTapNetDevice> device)
   18.32 +{
   18.33 +  m_hostDevice = device;
   18.34 +}
   18.35 +
   18.36 +Ptr<HostTapNetDevice> 
   18.37 +TapChannel::GetHostDevice (void) const
   18.38 +{
   18.39 +  return m_hostDevice;
   18.40 +}
   18.41 +
   18.42 +uint32_t 
   18.43 +TapChannel::GetNDevices (void) const
   18.44 +{
   18.45 +  return 2;
   18.46 +}
   18.47 +Ptr<NetDevice> 
   18.48 +TapChannel::GetDevice (uint32_t i) const
   18.49 +{
   18.50 +  if (i == 0)
   18.51 +    {
   18.52 +      return m_device;
   18.53 +    }
   18.54 +  else if (i == 1)
   18.55 +    {
   18.56 +      return m_hostDevice;
   18.57 +    }
   18.58 +  else
   18.59 +    {
   18.60 +      return 0;
   18.61 +    }
   18.62 +}
   18.63 +
   18.64 +} // namespace ns3
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/src/devices/tap/tap-channel.h	Mon Oct 27 22:01:24 2008 -0700
    19.3 @@ -0,0 +1,36 @@
    19.4 +#ifndef TAP_CHANNEL_H
    19.5 +#define TAP_CHANNEL_H
    19.6 +
    19.7 +#include "ns3/channel.h"
    19.8 +
    19.9 +namespace ns3 {
   19.10 +
   19.11 +class HostTapNetDevice;
   19.12 +class TapNetDevice;
   19.13 +class NetDevice;
   19.14 +
   19.15 +
   19.16 +class TapChannel : public Channel
   19.17 +{
   19.18 +public:
   19.19 +  TapChannel ();
   19.20 +
   19.21 +  void SetHostDevice (Ptr<HostTapNetDevice> device);
   19.22 +  void SetDevice (Ptr<TapNetDevice> device);
   19.23 +
   19.24 +  Ptr<HostTapNetDevice> GetHostDevice (void) const;
   19.25 +
   19.26 +  // overriden from Channel base class
   19.27 +  virtual uint32_t GetNDevices (void) const;
   19.28 +  virtual Ptr<NetDevice> GetDevice (uint32_t i) const;
   19.29 +
   19.30 +private:
   19.31 +  virtual void DoDispose (void);
   19.32 +
   19.33 +  Ptr<HostTapNetDevice> m_hostDevice;
   19.34 +  Ptr<TapNetDevice> m_device;
   19.35 +};
   19.36 +
   19.37 +} // namespace ns3
   19.38 +
   19.39 +#endif /* TAP_CHANNEL_H */
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/src/devices/tap/tap-manager-client.cc	Mon Oct 27 22:01:24 2008 -0700
    20.3 @@ -0,0 +1,180 @@
    20.4 +#include "tap-manager-client.h"
    20.5 +#include "ns3/log.h"
    20.6 +#include <sys/socket.h>
    20.7 +#include <sys/wait.h>
    20.8 +#include <sys/stat.h>
    20.9 +#include <linux/un.h>
   20.10 +#include <errno.h>
   20.11 +#include <string.h>
   20.12 +#include <iomanip>
   20.13 +#include <iostream>
   20.14 +#include <list>
   20.15 +
   20.16 +
   20.17 +NS_LOG_COMPONENT_DEFINE("TapManagerClient");
   20.18 +
   20.19 +#define TAP_MANAGER "ns3-tap-manager"
   20.20 +
   20.21 +namespace ns3 {
   20.22 +
   20.23 +static std::string
   20.24 +EncodeAsString (struct sockaddr_un un, int len)
   20.25 +{
   20.26 +  uint8_t *buffer = (uint8_t *)&un;
   20.27 +  std::ostringstream oss;
   20.28 +  oss.setf (std::ios::hex, std::ios::basefield);
   20.29 +  oss.fill('0');
   20.30 +  for (uint8_t i = 0; i < len; i++)
   20.31 +    {
   20.32 +      oss << ":" << std::setw (2) << (uint32_t)buffer[i];
   20.33 +    }
   20.34 +  return oss.str ();
   20.35 +}
   20.36 +
   20.37 +bool
   20.38 +TapManagerClient::Exists (std::string filename) const
   20.39 +{
   20.40 +  struct stat st;
   20.41 +  int retval = ::stat (filename.c_str (), &st);
   20.42 +  return retval == 0;
   20.43 +}
   20.44 +
   20.45 +std::string
   20.46 +TapManagerClient::FindManager (void) const
   20.47 +{
   20.48 +  std::list<std::string> locations;
   20.49 +  locations.push_back ("./src/devices/tap");
   20.50 +  locations.push_back ("./build/debug/src/devices/tap");
   20.51 +  locations.push_back ("./build/optimized/src/devices/tap");
   20.52 +  for (std::list<std::string>::const_iterator i = locations.begin (); i != locations.end (); ++i)
   20.53 +    {
   20.54 +      if (Exists (*i + "/" + TAP_MANAGER))
   20.55 +	{
   20.56 +	  return *i + "/" + TAP_MANAGER;
   20.57 +	}
   20.58 +    }
   20.59 +  NS_FATAL_ERROR ("Could not find manager");
   20.60 +  return ""; // quiet compiler
   20.61 +}
   20.62 +
   20.63 +int
   20.64 +TapManagerClient::AllocateTap (Mac48Address host, Ipv4Address ad, Ipv4Mask mask, Ipv4Address gateway)
   20.65 +{
   20.66 +  NS_LOG_FUNCTION (host << ad << mask << gateway);
   20.67 +  // create a socket to get information back from the tap manager.
   20.68 +  int sock = socket (PF_UNIX, SOCK_DGRAM, 0);
   20.69 +  if (sock == -1)
   20.70 +    {
   20.71 +      NS_FATAL_ERROR ("Socket creation, errno=" << strerror (errno));
   20.72 +    }
   20.73 +
   20.74 +  struct sockaddr_un un;
   20.75 +  memset (&un, 0, sizeof (un));
   20.76 +  un.sun_family = AF_UNIX;
   20.77 +  int status = bind (sock, (struct sockaddr*)&un, sizeof (sa_family_t)); // let the kernel allocate an endpoint for us.
   20.78 +  if (status == -1)
   20.79 +    {
   20.80 +      NS_FATAL_ERROR ("Could not bind: errno=" << strerror (errno));
   20.81 +    }
   20.82 +  socklen_t len = sizeof (un);
   20.83 +  status = getsockname (sock, (struct sockaddr*)&un, &len);
   20.84 +  if (status == -1)
   20.85 +    {
   20.86 +      NS_FATAL_ERROR ("Could not get socket address: errno=" << strerror (errno));
   20.87 +    }
   20.88 +  NS_LOG_DEBUG ("Allocated enpoint=" << EncodeAsString (un, len) << ", len=" << len);
   20.89 +
   20.90 +  pid_t pid = ::fork ();
   20.91 +  if (pid == 0)
   20.92 +    {
   20.93 +      // child.
   20.94 +      NS_LOG_DEBUG ("Child");
   20.95 +
   20.96 +      std::ostringstream oss;
   20.97 +      oss << "--path=" << EncodeAsString (un, len);
   20.98 +      std::string pathArg = oss.str ();
   20.99 +      oss.str ("");
  20.100 +      oss << "--mac-addr=" << host;
  20.101 +      std::string hostArg = oss.str ();
  20.102 +      oss.str ("");
  20.103 +      oss << "--ip-addr=" << ad;
  20.104 +      std::string ipArg = oss.str ();
  20.105 +      oss.str ("");
  20.106 +      oss << "--ip-gw=" << gateway;
  20.107 +      std::string ipGw = oss.str ();
  20.108 +      oss.str ("");
  20.109 +      oss << "--ip-netmask=" << mask;
  20.110 +      std::string ipMask = oss.str ();
  20.111 +      oss.str ("");
  20.112 +      status = ::execl (FindManager ().c_str (), 
  20.113 +			TAP_MANAGER, 
  20.114 +			pathArg.c_str (),
  20.115 +			hostArg.c_str (),
  20.116 +			ipArg.c_str (),
  20.117 +			ipGw.c_str (),
  20.118 +			ipMask.c_str (),
  20.119 +			(char *)NULL);
  20.120 +      if (status == -1)
  20.121 +	{
  20.122 +	  NS_LOG_ERROR ("Cannot execl tap-manager, errno=" << ::strerror (errno));
  20.123 +	}
  20.124 +      ::_exit (-1);
  20.125 +    }
  20.126 +  else
  20.127 +    {
  20.128 +      // parent
  20.129 +      NS_LOG_DEBUG ("Parent");
  20.130 +      int st;
  20.131 +      pid_t waited = waitpid (pid, &st, 0);
  20.132 +      if (waited == -1)
  20.133 +	{
  20.134 +	  NS_FATAL_ERROR ("Cannot wait for tap-manager, errno=" << strerror (errno));
  20.135 +	}
  20.136 +      NS_ASSERT (pid == waited);
  20.137 +      if (!WIFEXITED (st))
  20.138 +	{
  20.139 +	  // tap manager did not complete successfully
  20.140 +	  NS_FATAL_ERROR ("tap-manager did not exit correctly");
  20.141 +	}
  20.142 +      else if (WEXITSTATUS (st) != 0)
  20.143 +	{
  20.144 +	  NS_FATAL_ERROR ("tap-manager did not complete successfully, err=" << WEXITSTATUS (st));
  20.145 +	}
  20.146 +      // the tap fd should be available on our unix socket now.
  20.147 +      size_t msg_size = sizeof(int);
  20.148 +      char control[CMSG_SPACE(msg_size)];
  20.149 +      struct cmsghdr *cmsg;
  20.150 +      uint8_t buffer;
  20.151 +      struct iovec iov;
  20.152 +      iov.iov_base = &buffer;
  20.153 +      iov.iov_len = 1;
  20.154 +      struct msghdr msg;
  20.155 +      msg.msg_name = 0;
  20.156 +      msg.msg_namelen = 0;
  20.157 +      msg.msg_iov = &iov;
  20.158 +      msg.msg_iovlen = 1;
  20.159 +      msg.msg_control = control;
  20.160 +      msg.msg_controllen = sizeof (control);
  20.161 +      msg.msg_flags = 0;
  20.162 +      ssize_t bytesRead = recvmsg (sock, &msg, 0);
  20.163 +      if (bytesRead != 1)
  20.164 +	{
  20.165 +	  NS_FATAL_ERROR ("Did not get byte from tap-manager");
  20.166 +	}
  20.167 +      NS_LOG_ERROR ("read bytes=" << bytesRead);
  20.168 +      for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) 
  20.169 +	{
  20.170 +	  if (cmsg->cmsg_level == SOL_SOCKET &&
  20.171 +	      cmsg->cmsg_type == SCM_RIGHTS)
  20.172 +	    {
  20.173 +	      int *fd = (int*)CMSG_DATA (cmsg);
  20.174 +	      NS_LOG_ERROR ("got tap fd=" << *fd);
  20.175 +	      return *fd;
  20.176 +	    }
  20.177 +	}
  20.178 +      NS_FATAL_ERROR ("Did not get SCM_RIGHTS from tap-manager");
  20.179 +    }
  20.180 +  return -1;
  20.181 +}
  20.182 +
  20.183 +} // namespace ns3
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/src/devices/tap/tap-manager-client.h	Mon Oct 27 22:01:24 2008 -0700
    21.3 @@ -0,0 +1,21 @@
    21.4 +#ifndef TAP_MANAGER_CLIENT_H
    21.5 +#define TAP_MANAGER_CLIENT_H
    21.6 +
    21.7 +#include "ns3/mac48-address.h"
    21.8 +#include "ns3/ipv4-address.h"
    21.9 +#include <string>
   21.10 +
   21.11 +namespace ns3 {
   21.12 +
   21.13 +class TapManagerClient
   21.14 +{
   21.15 +public:
   21.16 +  int AllocateTap (Mac48Address host, Ipv4Address ad, Ipv4Mask mask, Ipv4Address gateway);
   21.17 +private:
   21.18 +  std::string FindManager (void) const;
   21.19 +  bool Exists (std::string filename) const;
   21.20 +};
   21.21 +
   21.22 +} // namespace ns3
   21.23 +
   21.24 +#endif /* TAP_MANAGER_CLIENT_H */
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/src/devices/tap/tap-manager.cc	Mon Oct 27 22:01:24 2008 -0700
    22.3 @@ -0,0 +1,362 @@
    22.4 +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
    22.5 +/*
    22.6 + * Copyright (c) 2008 INRIA
    22.7 + *
    22.8 + * This program is free software; you can redistribute it and/or modify
    22.9 + * it under the terms of the GNU General Public License version 2 as
   22.10 + * published by the Free Software Foundation;
   22.11 + *
   22.12 + * This program is distributed in the hope that it will be useful,
   22.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   22.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   22.15 + * GNU General Public License for more details.
   22.16 + *
   22.17 + * You should have received a copy of the GNU General Public License
   22.18 + * along with this program; if not, write to the Free Software
   22.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   22.20 + *
   22.21 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
   22.22 + */
   22.23 +
   22.24 +#include <fcntl.h>
   22.25 +#include <sys/ioctl.h>
   22.26 +#include <sys/types.h>
   22.27 +#include <sys/socket.h>
   22.28 +#include <linux/un.h>
   22.29 +#include <linux/if.h>
   22.30 +#include <linux/if_tun.h>
   22.31 +#include <linux/route.h>
   22.32 +#include <netinet/in.h>
   22.33 +#include <stdint.h>
   22.34 +#include <iostream>
   22.35 +#include <sstream>
   22.36 +#include <iomanip>
   22.37 +#include <string.h>
   22.38 +#include <errno.h>
   22.39 +#include <stdlib.h>
   22.40 +
   22.41 +#define noENABLE_LOG
   22.42 +
   22.43 +#define EXIT_ERROR(x, err)						\
   22.44 +  std::cout << __FILE__ << ":" << __LINE__ << ": Unrecoverable Error: " << x; \
   22.45 +  std::cout << " errno=" << strerror (errno) << std::endl;		\
   22.46 +  exit (err)
   22.47 +
   22.48 +#ifdef ENABLE_LOG
   22.49 +#define LOG(x) \
   22.50 +  std::cout << x << std::endl;
   22.51 +#else
   22.52 +#define LOG(x)
   22.53 +#endif
   22.54 +
   22.55 +
   22.56 +#define CHECK_ARG(el,var) \
   22.57 +  {							\
   22.58 +    char start[] = "--"  el  "=";		     	\
   22.59 +    if (strncmp (*argv, start, strlen (start)) == 0) 	\
   22.60 +      {						     	\
   22.61 +	var = *argv + strlen (start);		     	\
   22.62 +	LOG ("--" << el << "=" << var);		     	\
   22.63 +      }						     	\
   22.64 +  }
   22.65 +
   22.66 +#define ASCII_DOT (0x2e)
   22.67 +#define ASCII_ZERO (0x30)
   22.68 +#define ASCII_a (0x41)
   22.69 +#define ASCII_z (0x5a)
   22.70 +#define ASCII_A (0x61)
   22.71 +#define ASCII_Z (0x7a)
   22.72 +#define ASCII_COLON (0x3a)
   22.73 +#define ASCII_ZERO (0x30)
   22.74 +
   22.75 +static char
   22.76 +AsciiToLowCase (char c)
   22.77 +{
   22.78 +  if (c >= ASCII_a && c <= ASCII_z) {
   22.79 +    return c;
   22.80 +  } else if (c >= ASCII_A && c <= ASCII_Z) {
   22.81 +    return c + (ASCII_a - ASCII_A);
   22.82 +  } else {
   22.83 +    return c;
   22.84 +  }
   22.85 +}
   22.86 +
   22.87 +static uint32_t 
   22.88 +AsciiToIpv4 (const char *address)
   22.89 +{
   22.90 +  uint32_t host = 0;
   22.91 +  while (true) {
   22.92 +    uint8_t byte = 0;
   22.93 +    while (*address != ASCII_DOT &&
   22.94 +           *address != 0) {
   22.95 +      byte *= 10;
   22.96 +      byte += *address - ASCII_ZERO;
   22.97 +      address++;
   22.98 +    }
   22.99 +    host <<= 8;
  22.100 +    host |= byte;
  22.101 +    if (*address == 0) {
  22.102 +      break;
  22.103 +    }
  22.104 +    address++;
  22.105 +  }
  22.106 +  return host;
  22.107 +}
  22.108 +
  22.109 +static void 
  22.110 +AsciiToMac48 (const char *str, uint8_t addr[6])
  22.111 +{
  22.112 +  int i = 0;
  22.113 +  while (*str != 0 && i < 6) 
  22.114 +    {
  22.115 +      uint8_t byte = 0;
  22.116 +      while (*str != ASCII_COLON && *str != 0) 
  22.117 +	{
  22.118 +	  byte <<= 4;
  22.119 +	  char low = AsciiToLowCase (*str);
  22.120 +	  if (low >= ASCII_a) 
  22.121 +	    {
  22.122 +	      byte |= low - ASCII_a + 10;
  22.123 +	    } 
  22.124 +	  else 
  22.125 +	    {
  22.126 +	      byte |= low - ASCII_ZERO;
  22.127 +	    }
  22.128 +	  str++;
  22.129 +	}
  22.130 +      addr[i] = byte;
  22.131 +      i++;
  22.132 +      if (*str == 0) 
  22.133 +	{
  22.134 +	  break;
  22.135 +	}
  22.136 +      str++;
  22.137 +    }
  22.138 +}
  22.139 +
  22.140 +static void
  22.141 +SetInetAddress (sockaddr *ad, uint32_t networkOrder)
  22.142 +{
  22.143 +  struct sockaddr_in *sin = (struct sockaddr_in*)ad;
  22.144 +  sin->sin_family = AF_INET;
  22.145 +  sin->sin_port = 0; // unused
  22.146 +  sin->sin_addr.s_addr = htonl (networkOrder);
  22.147 +}
  22.148 +
  22.149 +
  22.150 +static int
  22.151 +CreateTap (const char *mac_addr, const char *ip, 
  22.152 +	   const char *gw, const char *netmask)
  22.153 +{
  22.154 +  // opening the tun device usually requires root privs
  22.155 +  int tap = open ("/dev/net/tun", O_RDWR);
  22.156 +  if (tap == -1)
  22.157 +    {
  22.158 +      EXIT_ERROR ("Could not open /dev/net/tun", 1);
  22.159 +    }
  22.160 +  // now, crate a tap device.
  22.161 +  struct ifreq ifr;
  22.162 +  // make sure that the tap device will not send us the tun_pi header.
  22.163 +  ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
  22.164 +  ifr.ifr_name[0] = 0; // allow the kernel to pick a device name.
  22.165 +  int status = ioctl (tap, TUNSETIFF, (void *) &ifr);
  22.166 +  if (status == -1)
  22.167 +    {
  22.168 +      EXIT_ERROR ("Could not allocate a tap device", 2);
  22.169 +    }
  22.170 +  std::string tapDeviceName = (char *)ifr.ifr_name;
  22.171 +  LOG ("Allocated TAP device=" << tapDeviceName);
  22.172 +
  22.173 +  // set its hardware address to something we know will be unique within the simulation
  22.174 +  ifr.ifr_hwaddr.sa_family = 1; // this is ARPHRD_ETHER from if_arp.h
  22.175 +  AsciiToMac48 (mac_addr, (uint8_t*)ifr.ifr_hwaddr.sa_data);
  22.176 +  status = ioctl (tap, SIOCSIFHWADDR, &ifr);
  22.177 +  if (status == -1)
  22.178 +    {
  22.179 +      EXIT_ERROR ("Could not set hardware address=" << mac_addr << " for=" << (char *)ifr.ifr_name, 3);
  22.180 +    }
  22.181 +  LOG ("device=" << (char *)ifr.ifr_name << " addr=" << mac_addr);
  22.182 +
  22.183 +
  22.184 +  // The ip address must be set using an AF_INET socket.
  22.185 +  int fd = socket (AF_INET, SOCK_DGRAM, 0);
  22.186 +
  22.187 +  // set interface up.
  22.188 +  status = ioctl (fd, SIOCGIFFLAGS, &ifr);
  22.189 +  if (status == -1)
  22.190 +    {
  22.191 +      EXIT_ERROR ("Could not get flags for interface=" << (char *)ifr.ifr_name, 4);
  22.192 +    }
  22.193 +  ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
  22.194 +  status = ioctl (fd, SIOCSIFFLAGS, &ifr);
  22.195 +  if (status == -1)
  22.196 +    {
  22.197 +      EXIT_ERROR ("Could not bring interface " << (char *)ifr.ifr_name << " up", 5);
  22.198 +    }
  22.199 +  LOG ("device=" << (char *)ifr.ifr_name << " is up");
  22.200 +
  22.201 +
  22.202 +  // set its ip address.
  22.203 +  SetInetAddress (&ifr.ifr_addr, AsciiToIpv4 (ip));
  22.204 +  status = ioctl (fd, SIOCSIFADDR, &ifr);
  22.205 +  if (status == -1)
  22.206 +    {
  22.207 +      EXIT_ERROR ("Could not set ip address=" << ip << " for=" <<  (char *)ifr.ifr_name, 6);
  22.208 +    }
  22.209 +  LOG ("device=" << (char *)ifr.ifr_name << " addr=" << ip);
  22.210 +
  22.211 +  // set its ip mask to be /32
  22.212 +  SetInetAddress (&ifr.ifr_netmask, 0xffffffff);
  22.213 +  status = ioctl (fd, SIOCSIFNETMASK, &ifr);
  22.214 +  if (status == -1)
  22.215 +    {
  22.216 +      EXIT_ERROR ("Could not set ip mask=" << netmask << " for=" <<  (char *)ifr.ifr_name, 7);
  22.217 +    }
  22.218 +  LOG ("device=" << (char *)ifr.ifr_name << " mask=" << netmask); 
  22.219 +
  22.220 +  // add routing entry for gateway.
  22.221 +  struct rtentry rt;
  22.222 +  SetInetAddress (&rt.rt_dst, AsciiToIpv4 (gw));
  22.223 +  SetInetAddress (&rt.rt_genmask, 0xffffffff);
  22.224 +  rt.rt_flags = RTF_UP;
  22.225 +  rt.rt_metric = 2;
  22.226 +  rt.rt_dev = (char*)tapDeviceName.c_str ();
  22.227 +  status = ioctl (fd, SIOCADDRT, &rt);
  22.228 +  if (status == -1)
  22.229 +    {
  22.230 +      EXIT_ERROR ("Could not add routing table entry", 8);
  22.231 +    }
  22.232 +  LOG ("added routing table entry for gw.");
  22.233 +
  22.234 +  // add routing entry for subnet through gateway.
  22.235 +  uint32_t network = AsciiToIpv4 (ip) & AsciiToIpv4 (netmask);
  22.236 +  SetInetAddress (&rt.rt_dst, network);
  22.237 +  SetInetAddress (&rt.rt_gateway, AsciiToIpv4 (gw));
  22.238 +  SetInetAddress (&rt.rt_genmask, AsciiToIpv4 (netmask));
  22.239 +  rt.rt_flags = RTF_UP | RTF_GATEWAY;
  22.240 +  rt.rt_metric = 2;
  22.241 +  rt.rt_dev = (char*)tapDeviceName.c_str ();
  22.242 +  status = ioctl (fd, SIOCADDRT, &rt);
  22.243 +  if (status == -1)
  22.244 +    {
  22.245 +      EXIT_ERROR ("Could not add routing table entry", 9);
  22.246 +    }
  22.247 +  LOG ("added routing table entry for subnet.");
  22.248 +
  22.249 +  return tap;
  22.250 +}
  22.251 +
  22.252 +static struct sockaddr_un
  22.253 +DecodeFromString (const char *path, socklen_t *len)
  22.254 +{
  22.255 +  sockaddr_un un;
  22.256 +  uint8_t *buffer = (uint8_t *)&un;
  22.257 +  std::istringstream iss;
  22.258 +  iss.str (path);
  22.259 +  uint8_t n = 0;
  22.260 +  while (!iss.bad () && !iss.eof () && !iss.fail ())
  22.261 +    {
  22.262 +      char c;
  22.263 +      iss.read (&c, 1);
  22.264 +      uint32_t tmp;
  22.265 +      iss >> std::hex >> tmp;
  22.266 +      //LOG (std::hex << tmp);
  22.267 +      buffer[n] = tmp;
  22.268 +      n++;
  22.269 +    }
  22.270 +  *len = n;
  22.271 +  return un;
  22.272 +}
  22.273 +
  22.274 +static void
  22.275 +SendFd (const char *path, int fd)
  22.276 +{
  22.277 +  // send back configuration to caller.
  22.278 +  int sock = socket (PF_UNIX, SOCK_DGRAM, 0);
  22.279 +  if (sock == -1)
  22.280 +    {
  22.281 +      EXIT_ERROR ("Socket creation", 10);
  22.282 +    }
  22.283 +  LOG ("Socket Created");
  22.284 +  
  22.285 +  socklen_t local_len;
  22.286 +  struct sockaddr_un local = DecodeFromString (path, &local_len);
  22.287 +  LOG ("len=" << local_len);
  22.288 +  int status = connect (sock, (struct sockaddr*)&local, local_len);
  22.289 +  if (status == -1)
  22.290 +    {
  22.291 +      EXIT_ERROR ("Could not connect to caller", 11);
  22.292 +    }
  22.293 +  LOG ("Socket Connected");
  22.294 +
  22.295 +  // we send a single byte whose content is meaningless.
  22.296 +  // we also return as ancillary data the tap file descriptor
  22.297 +  struct cmsghdr *cmsg;
  22.298 +  size_t msg_size = sizeof(int);
  22.299 +  char control[CMSG_SPACE(msg_size)];
  22.300 +  struct iovec iov;
  22.301 +  struct msghdr msg;
  22.302 +  char buffer = 0;
  22.303 +  iov.iov_base = &buffer;
  22.304 +  iov.iov_len = 1;
  22.305 +  msg.msg_name = 0;
  22.306 +  msg.msg_namelen = 0;
  22.307 +  msg.msg_iov = &iov;
  22.308 +  msg.msg_iovlen = 1;
  22.309 +  msg.msg_control = control;
  22.310 +  msg.msg_controllen = sizeof (control);
  22.311 +  msg.msg_flags = 0;
  22.312 +
  22.313 +  cmsg = CMSG_FIRSTHDR(&msg);
  22.314 +  cmsg->cmsg_level = SOL_SOCKET;
  22.315 +  cmsg->cmsg_type = SCM_RIGHTS;
  22.316 +  cmsg->cmsg_len = CMSG_LEN(msg_size);
  22.317 +  msg.msg_controllen = cmsg->cmsg_len;
  22.318 +
  22.319 +  int *fdptr = (int*) (CMSG_DATA(cmsg));
  22.320 +  *fdptr = fd;
  22.321 +
  22.322 +  ssize_t len = sendmsg(sock, &msg, 0);
  22.323 +  if (len == -1)
  22.324 +    {
  22.325 +      EXIT_ERROR ("Could not send SCM_RIGHTS", 12);
  22.326 +    }
  22.327 +  LOG ("Sent SCM_RIGHTS");
  22.328 +}
  22.329 +
  22.330 +
  22.331 +
  22.332 +
  22.333 +int main (int argc, char *argv[])
  22.334 +{
  22.335 +  char *path = 0;
  22.336 +  char *mac_addr = 0;
  22.337 +  char *ip_addr = 0;
  22.338 +  char *ip_gw = 0;
  22.339 +  char *ip_netmask = 0;
  22.340 +  char *stop = 0;
  22.341 +  argv++;
  22.342 +  argc--;
  22.343 +  while (argc > 0)
  22.344 +    {
  22.345 +      CHECK_ARG("path", path);
  22.346 +      CHECK_ARG("mac-addr", mac_addr);
  22.347 +      CHECK_ARG("ip-addr", ip_addr);
  22.348 +      CHECK_ARG("ip-gw", ip_gw);
  22.349 +      CHECK_ARG("ip-netmask", ip_netmask);
  22.350 +      CHECK_ARG("stop", stop);
  22.351 +      argv++;
  22.352 +      argc--;
  22.353 +    }
  22.354 +  
  22.355 +  int tap = CreateTap (mac_addr, ip_addr, ip_gw, ip_netmask);
  22.356 +
  22.357 +  if (stop)
  22.358 +    {
  22.359 +      while (1) {}
  22.360 +    }
  22.361 +
  22.362 +  SendFd (path, tap);
  22.363 +
  22.364 +  return 0;
  22.365 +}
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/src/devices/tap/tap-net-device.cc	Mon Oct 27 22:01:24 2008 -0700
    23.3 @@ -0,0 +1,323 @@
    23.4 +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
    23.5 +/*
    23.6 + * Copyright (c) 2008 INRIA
    23.7 + *
    23.8 + * This program is free software; you can redistribute it and/or modify
    23.9 + * it under the terms of the GNU General Public License version 2 as
   23.10 + * published by the Free Software Foundation;
   23.11 + *
   23.12 + * This program is distributed in the hope that it will be useful,
   23.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   23.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   23.15 + * GNU General Public License for more details.
   23.16 + *
   23.17 + * You should have received a copy of the GNU General Public License
   23.18 + * along with this program; if not, write to the Free Software
   23.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   23.20 + *
   23.21 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
   23.22 + */
   23.23 +#include "tap-net-device.h"
   23.24 +#include "tap-manager-client.h"
   23.25 +#include "ns3/node.h"
   23.26 +#include "ns3/channel.h"
   23.27 +#include "ns3/packet.h"
   23.28 +#include "ns3/log.h"
   23.29 +#include "ns3/system-thread.h"
   23.30 +#include "ns3/realtime-simulator-impl.h"
   23.31 +#include "ns3/make-event.h"
   23.32 +#include "ns3/simulator.h"
   23.33 +#include "ns3/ethernet-header.h"
   23.34 +#include "ns3/trace-source-accessor.h"
   23.35 +#include "host-tap-net-device.h"
   23.36 +#include "tap-channel.h"
   23.37 +#include <errno.h>
   23.38 +#include <stdlib.h>
   23.39 +
   23.40 +NS_LOG_COMPONENT_DEFINE ("TapNetDevice");
   23.41 +
   23.42 +namespace ns3 {
   23.43 +
   23.44 +TypeId 
   23.45 +TapNetDevice::GetTypeId (void)
   23.46 +{
   23.47 +  static TypeId tid = TypeId ("ns3::TapNetDevice")
   23.48 +    .SetParent<NetDevice> ()
   23.49 +    .AddConstructor<TapNetDevice> ()
   23.50 +    .AddTraceSource ("Rx", "A packet has been received",
   23.51 +                     MakeTraceSourceAccessor (&TapNetDevice::m_rxTrace))
   23.52 +    .AddTraceSource ("Tx", "A packet has been sent",
   23.53 +                     MakeTraceSourceAccessor (&TapNetDevice::m_txTrace))
   23.54 +    .AddTraceSource ("Drop", "A packet has been dropped",
   23.55 +                     MakeTraceSourceAccessor (&TapNetDevice::m_dropTrace))
   23.56 +    ;
   23.57 +  return tid;
   23.58 +}
   23.59 +
   23.60 +TapNetDevice::TapNetDevice ()
   23.61 +  : m_node (0),
   23.62 +    m_mtu (0xffff),
   23.63 +    m_name (""),
   23.64 +    m_ifIndex (0),
   23.65 +    m_tap (-1)
   23.66 +{
   23.67 +  NS_LOG_FUNCTION (this);
   23.68 +}
   23.69 +
   23.70 +void 
   23.71 +TapNetDevice::SetChannel (Ptr<TapChannel> channel)
   23.72 +{
   23.73 +  m_channel = channel;
   23.74 +  m_channel->SetDevice (this);
   23.75 +}
   23.76 +
   23.77 +void 
   23.78 +TapNetDevice::SetupHost (Ipv4Address ad, Ipv4Mask mask, Ipv4Address gateway)
   23.79 +{
   23.80 +  NS_LOG_FUNCTION (this << ad << mask << gateway);
   23.81 +  NS_ASSERT (m_tap == -1);
   23.82 +
   23.83 +  Mac48Address hostMacAddress = m_channel->GetHostDevice ()->GetMacAddress ();
   23.84 +
   23.85 +  TapManagerClient manager;
   23.86 +  m_tap = manager.AllocateTap (hostMacAddress, ad, mask, gateway);
   23.87 +
   23.88 +  m_thread = Create<SystemThread> (MakeCallback (&TapNetDevice::ReadThread, this));
   23.89 +  m_thread->Start ();
   23.90 +}
   23.91 +
   23.92 +
   23.93 +void
   23.94 +TapNetDevice::ReadThread (void)
   23.95 +{
   23.96 +  NS_LOG_FUNCTION (this);
   23.97 +
   23.98 +  while (1)
   23.99 +    {
  23.100 +      uint8_t *buffer = (uint8_t *)malloc (0xffff);
  23.101 +      ssize_t bytesRead = read (m_tap, buffer, 0xffff);
  23.102 +      if (bytesRead == -1)
  23.103 +        {
  23.104 +          if (errno == EBADF || errno == EINTR)
  23.105 +            {
  23.106 +              // the device was closed from under us by ::DoDispose
  23.107 +              return;
  23.108 +            }
  23.109 +          NS_FATAL_ERROR ("Error reading from tap device: errno=" << strerror (errno));
  23.110 +        }
  23.111 +      // Note: we purposedly don't use a smart pointer to manage this packet
  23.112 +      // because the want to hand over ownership of this packet to the ForwardUp
  23.113 +      // method.
  23.114 +      DynamicCast<RealtimeSimulatorImpl> (Simulator::GetImplementation ())->
  23.115 +        ScheduleRealtimeNow (MakeEvent (&TapNetDevice::ForwardUp, this, buffer, (uint32_t)bytesRead));
  23.116 +    }
  23.117 +}
  23.118 +
  23.119 +void
  23.120 +TapNetDevice::ForwardUp (uint8_t *buffer, uint32_t size)
  23.121 +{
  23.122 +  NS_LOG_FUNCTION (this << buffer << size);
  23.123 +
  23.124 +  // swallow packet reference in smart pointer.
  23.125 +  Ptr<Packet> packet = Create<Packet> (buffer, size);
  23.126 +  free (buffer);
  23.127 +  Ptr<Packet> copy = packet->Copy ();
  23.128 +
  23.129 +  EthernetHeader header = EthernetHeader (false);
  23.130 +  packet->RemoveHeader (header);
  23.131 +
  23.132 +  uint16_t protocol = header.GetLengthType ();
  23.133 +  Mac48Address to = header.GetDestination ();
  23.134 +  Mac48Address from = header.GetSource ();
  23.135 +  
  23.136 +  NetDevice::PacketType packetType;
  23.137 +  if (to == m_address)
  23.138 +    {
  23.139 +      packetType = NetDevice::PACKET_HOST;
  23.140 +    }
  23.141 +  else if (to.IsBroadcast ())
  23.142 +    {
  23.143 +      packetType = NetDevice::PACKET_HOST;
  23.144 +    }
  23.145 +  else if (to.IsMulticast ())
  23.146 +    {
  23.147 +      packetType = NetDevice::PACKET_MULTICAST;
  23.148 +    }
  23.149 +  else 
  23.150 +    {
  23.151 +      packetType = NetDevice::PACKET_OTHERHOST;
  23.152 +    }
  23.153 +  m_rxTrace (copy, from, to);
  23.154 +  if (packetType != NetDevice::PACKET_OTHERHOST)
  23.155 +    {
  23.156 +      m_rxCallback (this, packet, protocol, from);
  23.157 +    }
  23.158 +  if (!m_promiscCallback.IsNull ())
  23.159 +    {
  23.160 +      m_promiscCallback (this, packet, protocol, from, to, packetType);
  23.161 +    }
  23.162 +}
  23.163 +
  23.164 +void 
  23.165 +TapNetDevice::SetAddress (Mac48Address address)
  23.166 +{
  23.167 +  m_address = address;
  23.168 +}
  23.169 +
  23.170 +void 
  23.171 +TapNetDevice::SetName(const std::string name)
  23.172 +{
  23.173 +  m_name = name;
  23.174 +}
  23.175 +std::string 
  23.176 +TapNetDevice::GetName(void) const
  23.177 +{
  23.178 +  return m_name;
  23.179 +}
  23.180 +void 
  23.181 +TapNetDevice::SetIfIndex(const uint32_t index)
  23.182 +{
  23.183 +  m_ifIndex = index;
  23.184 +}
  23.185 +uint32_t 
  23.186 +TapNetDevice::GetIfIndex(void) const
  23.187 +{
  23.188 +  return m_ifIndex;
  23.189 +}
  23.190 +Ptr<Channel> 
  23.191 +TapNetDevice::GetChannel (void) const
  23.192 +{
  23.193 +  return m_channel;
  23.194 +}
  23.195 +Address 
  23.196 +TapNetDevice::GetAddress (void) const
  23.197 +{
  23.198 +  return m_address;
  23.199 +}
  23.200 +bool 
  23.201 +TapNetDevice::SetMtu (const uint16_t mtu)
  23.202 +{
  23.203 +  m_mtu = mtu;
  23.204 +  return true;
  23.205 +}
  23.206 +uint16_t 
  23.207 +TapNetDevice::GetMtu (void) const
  23.208 +{
  23.209 +  return m_mtu;
  23.210 +}
  23.211 +bool 
  23.212 +TapNetDevice::IsLinkUp (void) const
  23.213 +{
  23.214 +  return true;
  23.215 +}
  23.216 +void 
  23.217 +TapNetDevice::SetLinkChangeCallback (Callback<void> callback)
  23.218 +{}
  23.219 +bool 
  23.220 +TapNetDevice::IsBroadcast (void) const
  23.221 +{
  23.222 +  return true;
  23.223 +}
  23.224 +Address
  23.225 +TapNetDevice::GetBroadcast (void) const
  23.226 +{
  23.227 +  return Mac48Address ("ff:ff:ff:ff:ff:ff");
  23.228 +}
  23.229 +bool 
  23.230 +TapNetDevice::IsMulticast (void) const
  23.231 +{
  23.232 +  return true;
  23.233 +}
  23.234 +Address 
  23.235 +TapNetDevice::GetMulticast (void) const
  23.236 +{
  23.237 +  return Mac48Address::GetMulticastPrefix ();
  23.238 +}
  23.239 +Address 
  23.240 +TapNetDevice::MakeMulticastAddress (Ipv4Address multicastGroup) const
  23.241 +{
  23.242 +  return Mac48Address::GetMulticast (multicastGroup);
  23.243 +}
  23.244 +bool 
  23.245 +TapNetDevice::IsPointToPoint (void) const
  23.246 +{
  23.247 +  return false;
  23.248 +}
  23.249 +bool 
  23.250 +TapNetDevice::Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
  23.251 +{
  23.252 +  NS_LOG_FUNCTION (this << packet << dest << protocolNumber);
  23.253 +  return SendFrom (packet, m_address, dest, protocolNumber);
  23.254 +}
  23.255 +bool 
  23.256 +TapNetDevice::SendFrom(Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber)
  23.257 +{
  23.258 +  NS_LOG_FUNCTION (this << packet << source << dest << protocolNumber);
  23.259 +  Mac48Address to = Mac48Address::ConvertFrom (dest);
  23.260 +  Mac48Address from = Mac48Address::ConvertFrom (source);
  23.261 +
  23.262 +  EthernetHeader header = EthernetHeader (false);
  23.263 +  header.SetSource (from);
  23.264 +  header.SetDestination (to);
  23.265 +  header.SetLengthType (protocolNumber);
  23.266 +  packet->AddHeader (header);
  23.267 +
  23.268 +  ssize_t written = write (m_tap, packet->PeekData (), packet->GetSize ());
  23.269 +  if (written == -1 || written != (ssize_t)packet->GetSize ())
  23.270 +    {
  23.271 +      m_dropTrace (packet, from, to);
  23.272 +      return false;
  23.273 +    }
  23.274 +
  23.275 +  m_txTrace (packet, from, to);
  23.276 +  
  23.277 +  return true;
  23.278 +}
  23.279 +
  23.280 +Ptr<Node> 
  23.281 +TapNetDevice::GetNode (void) const
  23.282 +{
  23.283 +  return m_node;
  23.284 +}
  23.285 +void 
  23.286 +TapNetDevice::SetNode (Ptr<Node> node)
  23.287 +{
  23.288 +  m_node = node;
  23.289 +}
  23.290 +bool 
  23.291 +TapNetDevice::NeedsArp (void) const
  23.292 +{
  23.293 +  return true;
  23.294 +}
  23.295 +void 
  23.296 +TapNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb)
  23.297 +{
  23.298 +  m_rxCallback = cb;
  23.299 +}
  23.300 +
  23.301 +void
  23.302 +TapNetDevice::DoDispose (void)
  23.303 +{
  23.304 +  NS_LOG_FUNCTION (this);
  23.305 +  close (m_tap);
  23.306 +  m_thread->Join ();
  23.307 +  m_thread = 0;
  23.308 +  m_node = 0;
  23.309 +  m_channel = 0;
  23.310 +  NetDevice::DoDispose ();
  23.311 +}
  23.312 +
  23.313 +
  23.314 +void
  23.315 +TapNetDevice::SetPromiscReceiveCallback (PromiscReceiveCallback cb)
  23.316 +{
  23.317 +  m_promiscCallback = cb;
  23.318 +}
  23.319 +
  23.320 +bool
  23.321 +TapNetDevice::SupportsSendFrom (void) const
  23.322 +{
  23.323 +  return true;
  23.324 +}
  23.325 +
  23.326 +} // namespace ns3
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/src/devices/tap/tap-net-device.h	Mon Oct 27 22:01:24 2008 -0700
    24.3 @@ -0,0 +1,103 @@
    24.4 +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
    24.5 +/*
    24.6 + * Copyright (c) 2008 INRIA
    24.7 + *
    24.8 + * This program is free software; you can redistribute it and/or modify
    24.9 + * it under the terms of the GNU General Public License version 2 as
   24.10 + * published by the Free Software Foundation;
   24.11 + *
   24.12 + * This program is distributed in the hope that it will be useful,
   24.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   24.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   24.15 + * GNU General Public License for more details.
   24.16 + *
   24.17 + * You should have received a copy of the GNU General Public License
   24.18 + * along with this program; if not, write to the Free Software
   24.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   24.20 + *
   24.21 + * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
   24.22 + */
   24.23 +#ifndef TAP_NET_DEVICE_H
   24.24 +#define TAP_NET_DEVICE_H
   24.25 +
   24.26 +#include "ns3/net-device.h"
   24.27 +#include "ns3/mac48-address.h"
   24.28 +#include "ns3/traced-callback.h"
   24.29 +#include <stdint.h>
   24.30 +#include <string>
   24.31 +
   24.32 +namespace ns3 {
   24.33 +
   24.34 +class Node;
   24.35 +class SystemThread;
   24.36 +class TapChannel;
   24.37 +
   24.38 +/**
   24.39 + * \ingroup netdevice
   24.40 + * 
   24.41 + * \brief a NetDevice to get packets to and from a host tap device.
   24.42 + */
   24.43 +class TapNetDevice : public NetDevice
   24.44 +{
   24.45 +public:
   24.46 +  static TypeId GetTypeId (void);
   24.47 +  TapNetDevice ();
   24.48 +
   24.49 +  void SetAddress (Mac48Address address);
   24.50 +
   24.51 +  void SetChannel (Ptr<TapChannel> channel);
   24.52 +
   24.53 +  void SetupHost (Ipv4Address ad, Ipv4Mask mask, Ipv4Address gateway);
   24.54 +
   24.55 +  // inherited from NetDevice base class.
   24.56 +  virtual void SetName(const std::string name);
   24.57 +  virtual std::string GetName(void) const;
   24.58 +  virtual void SetIfIndex(const uint32_t index);
   24.59 +  virtual uint32_t GetIfIndex(void) const;
   24.60 +  virtual Ptr<Channel> GetChannel (void) const;
   24.61 +  virtual Address GetAddress (void) const;
   24.62 +  virtual bool SetMtu (const uint16_t mtu);
   24.63 +  virtual uint16_t GetMtu (void) const;
   24.64 +  virtual bool IsLinkUp (void) const;
   24.65 +  virtual void SetLinkChangeCallback (Callback<void> callback);
   24.66 +  virtual bool IsBroadcast (void) const;
   24.67 +  virtual Address GetBroadcast (void) const;
   24.68 +  virtual bool IsMulticast (void) const;
   24.69 +  virtual Address GetMulticast (void) const;
   24.70 +  virtual Address MakeMulticastAddress (Ipv4Address multicastGroup) const;
   24.71 +  virtual bool IsPointToPoint (void) const;
   24.72 +  virtual bool Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber);
   24.73 +  virtual bool SendFrom(Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber);
   24.74 +  virtual Ptr<Node> GetNode (void) const;
   24.75 +  virtual void SetNode (Ptr<Node> node);
   24.76 +  virtual bool NeedsArp (void) const;
   24.77 +  virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
   24.78 +  virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb);
   24.79 +  virtual bool SupportsSendFrom (void) const;
   24.80 +
   24.81 +protected:
   24.82 +  virtual void DoDispose (void);
   24.83 +private:
   24.84 +  void Receive (Ptr<Packet> packet, uint16_t protocol, 
   24.85 +                Mac48Address to, Mac48Address from);
   24.86 +  void ForwardUp (uint8_t *buffer, uint32_t size);
   24.87 +  void ReadThread (void);
   24.88 +
   24.89 +  NetDevice::ReceiveCallback m_rxCallback;
   24.90 +  NetDevice::PromiscReceiveCallback m_promiscCallback;
   24.91 +  Ptr<Node> m_node;
   24.92 +  uint16_t m_mtu;
   24.93 +  std::string m_name;
   24.94 +  uint32_t m_ifIndex;
   24.95 +  Mac48Address m_address;
   24.96 +  int m_tap;
   24.97 +  Ptr<SystemThread> m_thread;
   24.98 +  TracedCallback<Ptr<const Packet>,Mac48Address,Mac48Address> m_rxTrace;
   24.99 +  TracedCallback<Ptr<const Packet>,Mac48Address,Mac48Address> m_txTrace;
  24.100 +  TracedCallback<Ptr<const Packet>,Mac48Address,Mac48Address> m_dropTrace;
  24.101 +  Ptr<TapChannel> m_channel;
  24.102 +};
  24.103 +
  24.104 +} // namespace ns3
  24.105 +
  24.106 +#endif /* TAP_NET_DEVICE_H */
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/src/devices/tap/wscript	Mon Oct 27 22:01:24 2008 -0700
    25.3 @@ -0,0 +1,26 @@
    25.4 +## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
    25.5 +
    25.6 +
    25.7 +def build(bld):
    25.8 +    obj = bld.create_suid_program('ns3-tap-manager')
    25.9 +    obj.source = [
   25.10 +       'tap-manager.cc',
   25.11 +       ]
   25.12 +
   25.13 +    module = bld.create_ns3_module('tap', ['node'])
   25.14 +    module.uselib = 'CAP'
   25.15 +    module.source = [
   25.16 +    'tap-net-device.cc',
   25.17 +    'tap-manager-client.cc',
   25.18 +    'tap-channel.cc',
   25.19 +    'host-tap-net-device.cc',
   25.20 +    ]
   25.21 +    headers = bld.create_obj('ns3header')
   25.22 +    headers.module = 'tap'
   25.23 +    headers.source = [
   25.24 +    'tap-net-device.h',
   25.25 +    'host-tap-net-device.h',
   25.26 +    'tap-channel.h',
   25.27 +    ]
   25.28 +
   25.29 +
    26.1 --- a/src/node/net-device.h	Mon Oct 27 13:01:28 2008 -0700
    26.2 +++ b/src/node/net-device.h	Mon Oct 27 22:01:24 2008 -0700
    26.3 @@ -255,13 +255,23 @@
    26.4    virtual bool NeedsArp (void) const = 0;
    26.5  
    26.6  
    26.7 -  /** Packet types */
    26.8 +  /** 
    26.9 +   * Packet types are used as they are in Linux.  GCC name resolution on 
   26.10 +   * typedef enum {} PacketType is broken for the foreseeable future, so
   26.11 +   * if you need to use ns-3 PacketType in a driver that also uses the 
   26.12 +   * Linux packet types you're hosed unless we define a shadow type, 
   26.13 +   * which we do here.
   26.14 +   */
   26.15    enum PacketType
   26.16      {
   26.17 -      PACKET_HOST = 1,  /* To us                */
   26.18 -      PACKET_BROADCAST, /* To all               */
   26.19 -      PACKET_MULTICAST, /* To group             */
   26.20 -      PACKET_OTHERHOST, /* To someone else      */
   26.21 +      PACKET_HOST = 1, /**< Packet addressed oo us */
   26.22 +      NS3_PACKET_HOST = PACKET_HOST,
   26.23 +      PACKET_BROADCAST, /**< Packet addressed to all */
   26.24 +      NS3_PACKET_BROADCAST = PACKET_BROADCAST,
   26.25 +      PACKET_MULTICAST, /**< Packet addressed to multicast group */
   26.26 +      NS3_PACKET_MULTICAST = PACKET_MULTICAST,
   26.27 +      PACKET_OTHERHOST, /**< Packet addressed to someone else */
   26.28 +      NS3_PACKET_OTHERHOST = PACKET_OTHERHOST,
   26.29      };
   26.30  
   26.31    /**
    27.1 --- a/src/wscript	Mon Oct 27 13:01:28 2008 -0700
    27.2 +++ b/src/wscript	Mon Oct 27 22:01:24 2008 -0700
    27.3 @@ -20,7 +20,8 @@
    27.4      'devices/point-to-point',
    27.5      'devices/csma',
    27.6      'devices/bridge',
    27.7 -    'devices/emutap',
    27.8 +    'devices/tap',
    27.9 +    'devices/emulated',
   27.10      'applications/onoff',
   27.11      'applications/packet-sink',
   27.12      'applications/udp-echo',