24 #include "ns3/abort.h"    25 #include "ns3/config.h"    26 #include "ns3/fd-net-device.h"    28 #include "ns3/names.h"    29 #include "ns3/object-factory.h"    30 #include "ns3/packet.h"    31 #include "ns3/simulator.h"    32 #include "ns3/trace-helper.h"    33 #include "ns3/netmap-net-device.h"    34 #include "ns3/uinteger.h"    36 #include <arpa/inet.h>    42 #include <net/ethernet.h>    44 #include <netinet/in.h>    50 #include <sys/socket.h>    52 #include <sys/ioctl.h>    59 #include <net/netmap_user.h>    65 #define EMU_MAGIC 65867   102   device->AggregateObject (ndqi);
   103   netmapDevice->SetNetDeviceQueue (ndqi->GetTxQueue (0));
   114       NS_FATAL_ERROR (
"NetmapNetDeviceHelper::SetFileDescriptor (): m_deviceName is not set");
   121   int fd = socket (PF_INET, SOCK_DGRAM, 0);
   127   bzero (&ifr, 
sizeof(ifr));
   128   strncpy ((
char *)ifr.ifr_name, 
m_deviceName.c_str (), IFNAMSIZ - 1);
   131   int32_t rc = ioctl (fd, SIOCGIFINDEX, &ifr);
   134       NS_FATAL_ERROR (
"NetmapNetDeviceHelper::SetFileDescriptor (): Can't get interface index");
   137   rc = ioctl (fd, SIOCGIFFLAGS, &ifr);
   140       NS_FATAL_ERROR (
"NetmapNetDeviceHelper::SetFileDescriptor (): Can't get interface flags");
   154   if ((ifr.ifr_flags & IFF_PROMISC) == 0)
   158                       << 
" is not in promiscuous mode. Please config the interface in promiscuous "   159                       "mode before to run the simulation.");
   162   if ((ifr.ifr_flags & IFF_BROADCAST) != IFF_BROADCAST)
   168       device->SetIsBroadcast (
false);
   171   if ((ifr.ifr_flags & IFF_MULTICAST) == IFF_MULTICAST)
   174       device->SetIsMulticast (
true);
   185   rc = ioctl (fd, SIOCGIFMTU, &ifr);
   188       NS_FATAL_ERROR (
"FdNetDevice::SetFileDescriptor (): Can't ioctl SIOCGIFMTU");
   192   device->SetMtu (ifr.ifr_mtu);
   212   int sock = socket (PF_UNIX, SOCK_DGRAM, 0);
   215       NS_FATAL_ERROR (
"NetmapNetDeviceHelper::CreateFileDescriptor(): Unix socket creation error, errno = " << strerror (errno));
   221   struct sockaddr_un un;
   222   memset (&un, 0, 
sizeof (un));
   223   un.sun_family = AF_UNIX;
   224   int status = bind (sock, (
struct sockaddr*)&un, 
sizeof (sa_family_t));
   227       NS_FATAL_ERROR (
"NetmapNetDeviceHelper::CreateFileDescriptor(): Could not bind(): errno = " << strerror (errno));
   240   socklen_t len = 
sizeof (un);
   241   status = getsockname (sock, (
struct sockaddr*)&un, &len);
   244       NS_FATAL_ERROR (
"NetmapNetDeviceHelper::CreateFileDescriptor(): Could not getsockname(): errno = " << strerror (errno));
   251   NS_LOG_INFO (
"Encoded Unix socket as \"" << path << 
"\"");
   263   pid_t pid = ::fork ();
   273       std::ostringstream oss;
   279       NS_LOG_INFO (
"Parameters set to \"" << oss.str () << 
"\"");
   284       status = ::execlp (NETMAP_DEV_CREATOR,
   293       NS_FATAL_ERROR (
"NetmapNetDeviceHelper::CreateFileDescriptor(): Back from execlp(), status = " <<
   294                       status << 
", errno = " << ::strerror (errno));
   304       pid_t waited = waitpid (pid, &st, 0);
   307           NS_FATAL_ERROR (
"NetmapNetDeviceHelper::CreateFileDescriptor(): waitpid() fails, errno = " << strerror (errno));
   309       NS_ASSERT_MSG (pid == waited, 
"NetmapNetDeviceHelper::CreateFileDescriptor(): pid mismatch");
   318           int exitStatus = WEXITSTATUS (st);
   321               NS_FATAL_ERROR (
"NetmapNetDeviceHelper::CreateFileDescriptor(): socket creator exited normally with status " << exitStatus);
   326           NS_FATAL_ERROR (
"NetmapNetDeviceHelper::CreateFileDescriptor(): socket creator exited abnormally");
   342       iov.iov_base = &magic;
   343       iov.iov_len = 
sizeof(magic);
   356       size_t msg_size = 
sizeof(int);
   357       char control[CMSG_SPACE (msg_size)];
   374       msg.msg_control = control;
   375       msg.msg_controllen = 
sizeof (control);
   382       ssize_t bytesRead = recvmsg (sock, &msg, 0);
   383       if (bytesRead != 
sizeof(
int))
   385           NS_FATAL_ERROR (
"NetmapNetDeviceHelper::CreateFileDescriptor(): Wrong byte count from socket creator");
   393       struct cmsghdr *cmsg;
   394       for (cmsg = CMSG_FIRSTHDR (&msg); cmsg != NULL; cmsg = CMSG_NXTHDR (&msg, cmsg))
   396           if (cmsg->cmsg_level == SOL_SOCKET
   397               && cmsg->cmsg_type == SCM_RIGHTS)
   406                   NS_LOG_INFO (
"Got SCM_RIGHTS with correct magic " << magic);
   407                   int *rawSocket = (
int*)CMSG_DATA (cmsg);
   408                   NS_LOG_INFO (
"Got the socket from the socket creator = " << *rawSocket);
   413                   NS_LOG_INFO (
"Got SCM_RIGHTS, but with bad magic " << magic);
   417       NS_FATAL_ERROR (
"Did not get the raw socket from the socket creator");
   438   memset (&nmr, 0, 
sizeof (nmr));
   440   nmr.nr_version = NETMAP_API;
   446   int code = ioctl (fd, NIOCREGIF, &nmr);
   453   uint8_t *memory = (uint8_t *) mmap (0, nmr.nr_memsize, PROT_WRITE | PROT_READ,
   456   if (memory == MAP_FAILED)
   462   struct netmap_if *nifp = NETMAP_IF (memory, nmr.nr_offset);
   466       NS_FATAL_ERROR (
"Failed getting the base struct of the interface in netmap mode");
   469   device->SetNetmapInterfaceRepresentation (nifp);
   470   device->SetTxRingsInfo (nifp->ni_tx_rings, nmr.nr_tx_slots);
   471   device->SetRxRingsInfo (nifp->ni_rx_rings, nmr.nr_rx_slots);
   473   device->SetFileDescriptor (fd);
 virtual Ptr< NetDevice > InstallPriv(Ptr< Node > node) const
This method creates an ns3::FdNetDevice and associates it to a node. 
Smart pointer class similar to boost::intrusive_ptr. 
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
ns3::StringValue attribute value declarations. 
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name. 
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO. 
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate. 
std::string BufferToString(uint8_t *buffer, uint32_t len)
Convert a byte buffer to a string containing a hex representation of the buffer. 
Hold an unsigned integer type. 
std::string GetDeviceName(void)
Get the device name of this device. 
void SwitchInNetmapMode(int fd, Ptr< NetmapNetDevice > device) const
Switch the fd in netmap mode. 
  AttributeValue implementation for TypeId. 
std::string m_deviceName
The unix/linux name of the underlying device (e.g., eth0) 
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)
Use NS_LOG to output a message of level LOG_LOGIC. 
virtual void SetDeviceAttributes(Ptr< FdNetDevice > device) const
Sets device flags and MTU. 
Every class exported by the ns3 library is enclosed in the ns3 namespace. 
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
void SetTypeId(std::string type)
Set the TypeId of the Objects to be created by this helper. 
void SetDeviceName(std::string deviceName)
Set the device name of this device. 
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG. 
Ptr< NetDevice > InstallPriv(Ptr< Node > node) const
This method creates an ns3::FdNetDevice attached to a physical network interface. ...
a NetDevice to read/write network traffic from/into a file descriptor. 
static TypeId GetTypeId(void)
Get the type ID.