23#include "ns3/config.h" 
   24#include "ns3/fd-net-device.h" 
   27#include "ns3/object-factory.h" 
   28#include "ns3/packet.h" 
   29#include "ns3/simulator.h" 
   30#include "ns3/trace-helper.h" 
   31#include "ns3/internet-module.h" 
   38#include <linux/if_tun.h> 
   40#include <net/ethernet.h> 
   42#include <netinet/in.h> 
   43#include <netpacket/packet.h> 
   49#include <sys/socket.h> 
   61#define TAP_MAGIC 95549 
  141  device->SetFileDescriptor (fd);
 
  154  int sock = socket (PF_UNIX, SOCK_DGRAM, 0);
 
  155  NS_ABORT_MSG_IF (sock == -1, 
"TapFdNetDeviceHelper::CreateFileDescriptor(): Unix socket creation error, errno = " << strerror (errno));
 
  160  struct sockaddr_un un;
 
  161  memset (&un, 0, 
sizeof (un));
 
  162  un.sun_family = AF_UNIX;
 
  163  int status = bind (sock, (
struct sockaddr*)&un, 
sizeof (sa_family_t));
 
  164  NS_ABORT_MSG_IF (status == -1, 
"TapFdNetDeviceHelper::CreateFileDescriptor(): Could not bind(): errno = " << strerror (errno));
 
  175  socklen_t len = 
sizeof (un);
 
  176  status = getsockname (sock, (
struct sockaddr*)&un, &len);
 
  177  NS_ABORT_MSG_IF (status == -1, 
"TapFdNetDeviceHelper::CreateFileDescriptor(): Could not getsockname(): errno = " << strerror (errno));
 
  183  NS_LOG_INFO (
"Encoded Unix socket as \"" << path << 
"\"");
 
  190  pid_t pid = ::fork ();
 
  220      std::ostringstream ossDeviceName;
 
  226      std::ostringstream ossMac;
 
  229      std::ostringstream ossIp4;
 
  235      std::ostringstream ossIp6;
 
  241      std::ostringstream ossNetmask4;
 
  247      std::ostringstream ossPrefix6;
 
  250      std::ostringstream ossMode;
 
  253      std::ostringstream ossPI;
 
  259      std::ostringstream ossPath;
 
  260      ossPath << 
"-p" << path;
 
  265      status = ::execlp (TAP_DEV_CREATOR,
 
  267                         ossDeviceName.str ().c_str (),     
 
  268                         ossMac.str ().c_str (),            
 
  269                         ossIp4.str ().c_str (),            
 
  270                         ossIp6.str ().c_str (),            
 
  271                         ossNetmask4.str ().c_str (),       
 
  272                         ossPrefix6.str ().c_str (),        
 
  273                         ossMode.str ().c_str (),           
 
  274                         ossPI.str ().c_str (),             
 
  275                         ossPath.str ().c_str (),           
 
  282      NS_FATAL_ERROR (
"TapFdNetDeviceHelper::CreateFileDescriptor(): Back from execlp(), status = " <<
 
  283                      status << 
", errno = " << ::strerror (errno));
 
  293      pid_t waited = waitpid (pid, &st, 0);
 
  294      NS_ABORT_MSG_IF (waited == -1, 
"TapFdNetDeviceHelper::CreateFileDescriptor(): waitpid() fails, errno = " << strerror (errno));
 
  295      NS_ASSERT_MSG (pid == waited, 
"TapFdNetDeviceHelper::CreateFileDescriptor(): pid mismatch");
 
  304          int exitStatus = WEXITSTATUS (st);
 
  306                           "TapFdNetDeviceHelper::CreateFileDescriptor(): socket creator exited normally with status " << exitStatus);
 
  310          NS_FATAL_ERROR (
"TapFdNetDeviceHelper::CreateFileDescriptor(): socket creator exited abnormally");
 
  328      iov.iov_base = &magic;
 
  329      iov.iov_len = 
sizeof(magic);
 
  342      size_t msg_size = 
sizeof(int);
 
  343      char control[CMSG_SPACE (msg_size)];
 
  360      msg.msg_control = control;
 
  361      msg.msg_controllen = 
sizeof (control);
 
  368      ssize_t bytesRead = recvmsg (sock, &msg, 0);
 
  369      NS_ABORT_MSG_IF (bytesRead != 
sizeof(
int), 
"TapFdNetDeviceHelper::CreateFileDescriptor(): Wrong byte count from socket creator");
 
  376      struct cmsghdr *cmsg;
 
  377      for (cmsg = CMSG_FIRSTHDR (&msg); cmsg != NULL; cmsg = CMSG_NXTHDR (&msg, cmsg))
 
  379          if (cmsg->cmsg_level == SOL_SOCKET
 
  380              && cmsg->cmsg_type == SCM_RIGHTS)
 
  389                  NS_LOG_INFO (
"Got SCM_RIGHTS with correct magic " << magic);
 
  390                  int *rawSocket = (
int*)CMSG_DATA (cmsg);
 
  391                  NS_LOG_INFO (
"Got the socket from the socket creator = " << *rawSocket);
 
  396                  NS_LOG_INFO (
"Got SCM_RIGHTS, but with bad magic " << magic);
 
  400      NS_FATAL_ERROR (
"Did not get the raw socket from the socket creator");
 
std::string m_deviceName
The Unix/Linux name of the underlying device (e.g., eth0)
 
virtual Ptr< NetDevice > InstallPriv(Ptr< Node > node) const
This method creates an ns3::FdNetDevice and associates it to a node.
 
a NetDevice to read/write network traffic from/into a file descriptor.
 
@ DIXPI
When using TAP devices, if flag IFF_NO_PI is not set on the device, IP packets will have an extra hea...
 
Ipv4 addresses are stored in host order in this class.
 
static Ipv4Address GetZero(void)
 
a class to represent an Ipv4 address mask
 
static Ipv4Mask GetZero(void)
 
Describes an IPv6 address.
 
static Ipv6Address GetZero()
Get the 0 (::) Ipv6Address.
 
static Mac48Address Allocate(void)
Allocate a new Mac48Address.
 
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
 
virtual void SetFileDescriptor(Ptr< FdNetDevice > device) const
Sets a file descriptor on the FileDescriptorNetDevice.
 
Ptr< NetDevice > InstallPriv(Ptr< Node > node) const
This method creates an ns3::FdNetDevice attached to a virtual TAP network interface.
 
void SetTapMacAddress(Mac48Address mac)
Set the MAC address for the TAP device.
 
bool m_modePi
The TAP device flag IFF_NO_PI.
 
void SetTapIpv6Prefix(int prefix)
Set the IPv6 network mask for the TAP device.
 
Ipv6Address m_tapIp6
The IPv6 address for the TAP device.
 
void SetTapIpv4Mask(Ipv4Mask mask)
Set the IPv4 network mask for the TAP device.
 
Ipv4Mask m_tapMask4
The network mask IPv4 for the TAP device.
 
Ipv4Address m_tapIp4
The IPv4 address for the TAP device.
 
TapFdNetDeviceHelper()
Construct a TapFdNetDeviceHelper.
 
Mac48Address m_tapMac
The TAP device MAC address.
 
int m_tapPrefix6
The network prefix IPv6 for the TAP device.
 
void SetTapIpv4Address(Ipv4Address address)
Set the device IPv4 address.
 
void SetModePi(bool pi)
Set flag IFF_NO_PI on the device.
 
virtual int CreateFileDescriptor(void) const
Call out to a separate process running as suid root in order to create a TAP device and obtain the fi...
 
void SetTapIpv6Address(Ipv6Address address)
Set the device IPv6 address.
 
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
 
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
 
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
 
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
 
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
 
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
 
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
 
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
 
Every class exported by the ns3 library is enclosed in the ns3 namespace.
 
std::string BufferToString(uint8_t *buffer, uint32_t len)
Convert a byte buffer to a string containing a hex representation of the buffer.
 
ns3::StringValue attribute value declarations.