22 #include "ns3/abort.h" 
   23 #include "ns3/config.h" 
   24 #include "ns3/fd-net-device.h" 
   26 #include "ns3/names.h" 
   27 #include "ns3/object-factory.h" 
   28 #include "ns3/packet.h" 
   29 #include "ns3/simulator.h" 
   30 #include "ns3/trace-helper.h" 
   32 #include <arpa/inet.h> 
   37 #include <linux/if_tun.h> 
   39 #include <net/ethernet.h> 
   41 #include <netinet/in.h> 
   42 #include <netpacket/packet.h> 
   48 #include <sys/socket.h> 
   50 #include <sys/ioctl.h> 
   60 #define EMU_MAGIC 65867 
   95       NS_FATAL_ERROR (
"EmuFdNetDeviceHelper::SetFileDescriptor (): m_deviceName is not set");
 
  103   device->SetFileDescriptor (fd);
 
  109   bzero (&ifr, 
sizeof(ifr));
 
  110   strncpy ((
char *)ifr.ifr_name, 
m_deviceName.c_str (), IFNAMSIZ);
 
  113   int32_t rc = ioctl (fd, SIOCGIFINDEX, &ifr);
 
  116       NS_FATAL_ERROR (
"EmuFdNetDeviceHelper::SetFileDescriptor (): Can't get interface index");
 
  122   struct sockaddr_ll ll;
 
  123   bzero (&ll, 
sizeof(ll));
 
  125   ll.sll_family = AF_PACKET;
 
  126   ll.sll_ifindex = ifr.ifr_ifindex;
 
  127   ll.sll_protocol = htons (ETH_P_ALL);
 
  131   rc = bind (fd, (
struct sockaddr *)&ll, 
sizeof (ll));
 
  134       NS_FATAL_ERROR (
"EmuFdNetDeviceHelper::SetFileDescriptor (): Can't bind to specified interface");
 
  137   rc = ioctl (fd, SIOCGIFFLAGS, &ifr);
 
  140       NS_FATAL_ERROR (
"EmuFdNetDeviceHelper::SetFileDescriptor (): Can't get interface flags");
 
  154   if ((ifr.ifr_flags & IFF_PROMISC) == 0)
 
  159   if ((ifr.ifr_flags & IFF_BROADCAST) != IFF_BROADCAST)
 
  165       device->SetIsBroadcast (
false);
 
  168   if ((ifr.ifr_flags & IFF_MULTICAST) == IFF_MULTICAST)
 
  171       device->SetIsMulticast (
true);
 
  177   bzero (&ifr2, 
sizeof (ifr2));
 
  180   int32_t mtufd = socket (PF_INET, SOCK_DGRAM, IPPROTO_IP);
 
  182   rc = ioctl (mtufd, SIOCGIFMTU, &ifr2);
 
  185       NS_FATAL_ERROR (
"FdNetDevice::SetFileDescriptor (): Can't ioctl SIOCGIFMTU");
 
  189   device->SetMtu (ifr.ifr_mtu);
 
  206   int sock = socket (PF_UNIX, SOCK_DGRAM, 0);
 
  209       NS_FATAL_ERROR (
"EmuFdNetDeviceHelper::CreateFileDescriptor(): Unix socket creation error, errno = " << strerror (errno));
 
  215   struct sockaddr_un un;
 
  216   memset (&un, 0, 
sizeof (un));
 
  217   un.sun_family = AF_UNIX;
 
  218   int status = bind (sock, (
struct sockaddr*)&un, 
sizeof (sa_family_t));
 
  221       NS_FATAL_ERROR (
"EmuFdNetDeviceHelper::CreateFileDescriptor(): Could not bind(): errno = " << strerror (errno));
 
  234   socklen_t len = 
sizeof (un);
 
  235   status = getsockname (sock, (
struct sockaddr*)&un, &len);
 
  238       NS_FATAL_ERROR (
"EmuFdNetDeviceHelper::CreateFileDescriptor(): Could not getsockname(): errno = " << strerror (errno));
 
  245   NS_LOG_INFO (
"Encoded Unix socket as \"" << path << 
"\"");
 
  257   pid_t pid = ::fork ();
 
  267       std::ostringstream oss;
 
  269       NS_LOG_INFO (
"Parameters set to \"" << oss.str () << 
"\"");
 
  274       status = ::execlp (RAW_SOCK_CREATOR,
 
  283       NS_FATAL_ERROR (
"EmuFdNetDeviceHelper::CreateFileDescriptor(): Back from execlp(), errno = " << ::strerror (errno));
 
  293       pid_t waited = waitpid (pid, &st, 0);
 
  296           NS_FATAL_ERROR (
"EmuFdNetDeviceHelper::CreateFileDescriptor(): waitpid() fails, errno = " << strerror (errno));
 
  298       NS_ASSERT_MSG (pid == waited, 
"EmuFdNetDeviceHelper::CreateFileDescriptor(): pid mismatch");
 
  307           int exitStatus = WEXITSTATUS (st);
 
  310               NS_FATAL_ERROR (
"EmuFdNetDeviceHelper::CreateFileDescriptor(): socket creator exited normally with status " << exitStatus);
 
  315           NS_FATAL_ERROR (
"EmuFdNetDeviceHelper::CreateFileDescriptor(): socket creator exited abnormally");
 
  331       iov.iov_base = &magic;
 
  332       iov.iov_len = 
sizeof(magic);
 
  345       size_t msg_size = 
sizeof(int);
 
  346       char control[CMSG_SPACE (msg_size)];
 
  363       msg.msg_control = control;
 
  364       msg.msg_controllen = 
sizeof (control);
 
  371       ssize_t bytesRead = recvmsg (sock, &msg, 0);
 
  372       if (bytesRead != 
sizeof(
int))
 
  374           NS_FATAL_ERROR (
"EmuFdNetDeviceHelper::CreateFileDescriptor(): Wrong byte count from socket creator");
 
  382       struct cmsghdr *cmsg;
 
  383       for (cmsg = CMSG_FIRSTHDR (&msg); cmsg != NULL; cmsg = CMSG_NXTHDR (&msg, cmsg))
 
  385           if (cmsg->cmsg_level == SOL_SOCKET
 
  386               && cmsg->cmsg_type == SCM_RIGHTS)
 
  395                   NS_LOG_INFO (
"Got SCM_RIGHTS with correct magic " << magic);
 
  396                   int *rawSocket = (
int*)CMSG_DATA (cmsg);
 
  397                   NS_LOG_INFO (
"Got the socket from the socket creator = " << *rawSocket);
 
  402                   NS_LOG_INFO (
"Got SCM_RIGHTS, but with bad magic " << magic);
 
  406       NS_FATAL_ERROR (
"Did not get the raw socket from the socket creator");
 
smart pointer class similar to boost::intrusive_ptr 
 
#define NS_LOG_FUNCTION(parameters)
 
EmuFdNetDeviceHelper()
Construct a EmuFdNetDeviceHelper. 
 
NS_LOG_COMPONENT_DEFINE("EmuFdNetDeviceHelper")
 
#define NS_FATAL_ERROR(msg)
fatal error handling 
 
std::string BufferToString(uint8_t *buffer, uint32_t len)
Convert a byte buffer to a string containing a hex representation of the buffer. 
 
Ptr< NetDevice > InstallPriv(Ptr< Node > node) const 
 
virtual int CreateFileDescriptor(void) const 
Call out to a separate process running as suid root in order to get a raw socket. ...
 
#define NS_LOG_LOGIC(msg)
 
void SetDeviceName(std::string deviceName)
Set the device name of this device. 
 
#define NS_ASSERT_MSG(condition, message)
 
std::string GetDeviceName(void)
Get the device name of this device. 
 
virtual Ptr< NetDevice > InstallPriv(Ptr< Node > node) const 
 
#define NS_LOG_DEBUG(msg)
 
a NetDevice to read/write network traffic from/into a file descriptor. 
 
virtual void SetFileDescriptor(Ptr< FdNetDevice > device) const 
Sets a file descriptor on the FileDescriptorNetDevice.