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");
smart pointer class similar to boost::intrusive_ptr
#define NS_LOG_FUNCTION(parameters)
Ptr< NetDevice > InstallPriv(Ptr< Node > node) const
NS_LOG_COMPONENT_DEFINE("TapFdNetDeviceHelper")
a class to represent an Ipv4 address mask
When using TAP devices, if flag IFF_NO_PI is not set on the device, IP packets will have an extra hea...
virtual void SetFileDescriptor(Ptr< FdNetDevice > device) const
Sets a file descriptor on the FileDescriptorNetDevice.
#define NS_FATAL_ERROR(msg)
fatal error handling
void SetTapIpv4Address(Ipv4Address address)
Set the device IPv4 address.
static Mac48Address Allocate(void)
Allocate a new Mac48Address.
std::string BufferToString(uint8_t *buffer, uint32_t len)
Convert a byte buffer to a string containing a hex representation of the buffer.
void SetTapMacAddress(Mac48Address mac)
Set the MAC address for the TAP 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...
TapFdNetDeviceHelper()
Construct a TapFdNetDeviceHelper.
#define NS_LOG_LOGIC(msg)
void SetEncapsulationMode(FdNetDevice::EncapsulationMode mode)
Set the link layer encapsulation mode of this device.
void SetTapIpv4Mask(Ipv4Mask mask)
Set the IPv4 network mask for the TAP device.
#define NS_ASSERT_MSG(condition, message)
virtual Ptr< NetDevice > InstallPriv(Ptr< Node > node) const
Describes an IPv6 address.
Ipv4 addresses are stored in host order in this class.
void SetTapIpv6Prefix(int prefix)
Set the IPv6 network mask for the TAP device.
void SetTapIpv6Address(Ipv6Address address)
Set the device IPv6 address.
#define NS_LOG_DEBUG(msg)
a NetDevice to read/write network traffic from/into a file descriptor.
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if cond is true.
void SetModePi(bool pi)
Set flag IFF_NO_PI on the device.