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");