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"
31 #include "ns3/internet-module.h"
33 #include <arpa/inet.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>
51 #include <sys/ioctl.h>
61 #define TAP_MAGIC 95549
142 device->SetFileDescriptor (fd);
155 int sock = socket (PF_UNIX, SOCK_DGRAM, 0);
156 NS_ABORT_MSG_IF (sock == -1,
"TapFdNetDeviceHelper::CreateFileDescriptor(): Unix socket creation error, errno = " << strerror (errno));
161 struct sockaddr_un un;
162 memset (&un, 0,
sizeof (un));
163 un.sun_family = AF_UNIX;
164 int status = bind (sock, (
struct sockaddr*)&un,
sizeof (sa_family_t));
165 NS_ABORT_MSG_IF (status == -1,
"TapFdNetDeviceHelper::CreateFileDescriptor(): Could not bind(): errno = " << strerror (errno));
176 socklen_t len =
sizeof (un);
177 status = getsockname (sock, (
struct sockaddr*)&un, &len);
178 NS_ABORT_MSG_IF (status == -1,
"TapFdNetDeviceHelper::CreateFileDescriptor(): Could not getsockname(): errno = " << strerror (errno));
184 NS_LOG_INFO (
"Encoded Unix socket as \"" << path <<
"\"");
191 pid_t pid = ::fork ();
221 std::ostringstream ossDeviceName;
227 std::ostringstream ossMac;
230 std::ostringstream ossIp4;
236 std::ostringstream ossIp6;
242 std::ostringstream ossNetmask4;
248 std::ostringstream ossPrefix6;
251 std::ostringstream ossMode;
254 std::ostringstream ossPI;
260 std::ostringstream ossPath;
261 ossPath <<
"-p" << path;
266 status = ::execlp (TAP_DEV_CREATOR,
268 ossDeviceName.str ().c_str (),
269 ossMac.str ().c_str (),
270 ossIp4.str ().c_str (),
271 ossIp6.str ().c_str (),
272 ossNetmask4.str ().c_str (),
273 ossPrefix6.str ().c_str (),
274 ossMode.str ().c_str (),
275 ossPI.str ().c_str (),
276 ossPath.str ().c_str (),
283 NS_FATAL_ERROR (
"TapFdNetDeviceHelper::CreateFileDescriptor(): Back from execlp(), 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");