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>
38 #include <net/ethernet.h>
40 #include <netinet/in.h>
41 #include <netpacket/packet.h>
45 #include <sys/ioctl.h>
46 #include <sys/socket.h>
58 #define TAP_MAGIC 95549
138 device->SetFileDescriptor(fd);
151 int sock = socket(PF_UNIX, SOCK_DGRAM, 0);
154 "TapFdNetDeviceHelper::CreateFileDescriptor(): Unix socket creation error, errno = "
160 struct sockaddr_un un;
161 memset(&un, 0,
sizeof(un));
162 un.sun_family = AF_UNIX;
163 int status = bind(sock, (
struct sockaddr*)&un,
sizeof(sa_family_t));
165 "TapFdNetDeviceHelper::CreateFileDescriptor(): Could not bind(): errno = "
177 socklen_t len =
sizeof(un);
178 status = getsockname(sock, (
struct sockaddr*)&un, &len);
181 "TapFdNetDeviceHelper::CreateFileDescriptor(): Could not getsockname(): errno = "
188 NS_LOG_INFO(
"Encoded Unix socket as \"" << path <<
"\"");
195 pid_t pid = ::fork();
225 std::ostringstream ossDeviceName;
231 std::ostringstream ossMac;
234 std::ostringstream ossIp4;
240 std::ostringstream ossIp6;
246 std::ostringstream ossNetmask4;
252 std::ostringstream ossPrefix6;
255 std::ostringstream ossMode;
258 std::ostringstream ossPI;
264 std::ostringstream ossPath;
265 ossPath <<
"-p" << path;
270 status = ::execlp(TAP_DEV_CREATOR,
272 ossDeviceName.str().c_str(),
273 ossMac.str().c_str(),
274 ossIp4.str().c_str(),
275 ossIp6.str().c_str(),
276 ossNetmask4.str().c_str(),
277 ossPrefix6.str().c_str(),
278 ossMode.str().c_str(),
280 ossPath.str().c_str(),
287 NS_FATAL_ERROR(
"TapFdNetDeviceHelper::CreateFileDescriptor(): Back from execlp(), status = "
288 << status <<
", errno = " << ::strerror(errno));
298 pid_t waited = waitpid(pid, &st, 0);
300 "TapFdNetDeviceHelper::CreateFileDescriptor(): waitpid() fails, errno = "
302 NS_ASSERT_MSG(pid == waited,
"TapFdNetDeviceHelper::CreateFileDescriptor(): pid mismatch");
311 int exitStatus = WEXITSTATUS(st);
313 "TapFdNetDeviceHelper::CreateFileDescriptor(): socket creator exited "
314 "normally with status "
320 "TapFdNetDeviceHelper::CreateFileDescriptor(): socket creator exited abnormally");
338 iov.iov_base = &magic;
339 iov.iov_len =
sizeof(magic);
352 size_t msg_size =
sizeof(int);
353 char control[CMSG_SPACE(msg_size)];
366 msg.msg_name =
nullptr;
370 msg.msg_control = control;
371 msg.msg_controllen =
sizeof(control);
378 ssize_t bytesRead = recvmsg(sock, &msg, 0);
380 bytesRead !=
sizeof(
int),
381 "TapFdNetDeviceHelper::CreateFileDescriptor(): Wrong byte count from socket creator");
388 struct cmsghdr* cmsg;
389 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg !=
nullptr; cmsg = CMSG_NXTHDR(&msg, cmsg))
391 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
400 NS_LOG_INFO(
"Got SCM_RIGHTS with correct magic " << magic);
401 int* rawSocket = (
int*)CMSG_DATA(cmsg);
402 NS_LOG_INFO(
"Got the socket from the socket creator = " << *rawSocket);
407 NS_LOG_INFO(
"Got SCM_RIGHTS, but with bad magic " << magic);
411 NS_FATAL_ERROR(
"Did not get the raw socket from the socket creator");
std::string m_deviceName
The Unix/Linux name of the underlying device (e.g., eth0)
virtual Ptr< NetDevice > InstallPriv(Ptr< Node > node) const
This method creates an ns3::FdNetDevice and associates it to a node.
a NetDevice to read/write network traffic from/into a file descriptor.
@ DIXPI
When using TAP devices, if flag IFF_NO_PI is not set on the device, IP packets will have an extra hea...
Ipv4 addresses are stored in host order in this class.
static Ipv4Address GetZero()
a class to represent an Ipv4 address mask
static Ipv4Mask GetZero()
Describes an IPv6 address.
static Ipv6Address GetZero()
Get the 0 (::) Ipv6Address.
static Mac48Address Allocate()
Allocate a new Mac48Address.
Smart pointer class similar to boost::intrusive_ptr.
int CreateFileDescriptor() const override
Call out to a separate process running as suid root in order to create a TAP device and obtain the fi...
void SetTapMacAddress(Mac48Address mac)
Set the MAC address for the TAP device.
bool m_modePi
The TAP device flag IFF_NO_PI.
void SetTapIpv6Prefix(int prefix)
Set the IPv6 network mask for the TAP device.
Ipv6Address m_tapIp6
The IPv6 address for the TAP device.
Ptr< NetDevice > InstallPriv(Ptr< Node > node) const override
This method creates an ns3::FdNetDevice attached to a virtual TAP network interface.
void SetTapIpv4Mask(Ipv4Mask mask)
Set the IPv4 network mask for the TAP device.
Ipv4Mask m_tapMask4
The network mask IPv4 for the TAP device.
Ipv4Address m_tapIp4
The IPv4 address for the TAP device.
TapFdNetDeviceHelper()
Construct a TapFdNetDeviceHelper.
Mac48Address m_tapMac
The TAP device MAC address.
int m_tapPrefix6
The network prefix IPv6 for the TAP device.
void SetTapIpv4Address(Ipv4Address address)
Set the device IPv4 address.
void SetModePi(bool pi)
Set flag IFF_NO_PI on the device.
void SetTapIpv6Address(Ipv6Address address)
Set the device IPv6 address.
void SetFileDescriptor(Ptr< FdNetDevice > device) const override
Sets a file descriptor on the FileDescriptorNetDevice.
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::string BufferToString(uint8_t *buffer, uint32_t len)
Convert a byte buffer to a string containing a hex representation of the buffer.
ns3::StringValue attribute value declarations.