26 #include "ns3/abort.h"
27 #include "ns3/config.h"
28 #include "ns3/fd-net-device.h"
30 #include "ns3/names.h"
31 #include "ns3/object-factory.h"
32 #include "ns3/packet.h"
33 #include "ns3/simulator.h"
34 #include "ns3/trace-helper.h"
35 #include "ns3/internet-module.h"
37 #include <arpa/inet.h>
42 #include <linux/if_tun.h>
44 #include <net/ethernet.h>
46 #include <netinet/in.h>
47 #include <netpacket/packet.h>
53 #include <sys/socket.h>
55 #include <sys/ioctl.h>
65 #define PLANETLAB_MAGIC 75867
116 device->SetFileDescriptor (fd);
129 int sock = socket (PF_UNIX, SOCK_DGRAM, 0);
130 NS_ABORT_MSG_IF (sock == -1,
"PlanetLabFdNetDeviceHelper::CreateFileDescriptor(): Unix socket creation error, errno = " << strerror (errno));
135 struct sockaddr_un un;
136 memset (&un, 0,
sizeof (un));
137 un.sun_family = AF_UNIX;
138 int status = bind (sock, (
struct sockaddr*)&un,
sizeof (sa_family_t));
139 NS_ABORT_MSG_IF (status == -1,
"PlanetLabFdNetDeviceHelper::CreateFileDescriptor(): Could not bind(): errno = " << strerror (errno));
150 socklen_t len =
sizeof (un);
151 status = getsockname (sock, (
struct sockaddr*)&un, &len);
152 NS_ABORT_MSG_IF (status == -1,
"PlanetLabFdNetDeviceHelper::CreateFileDescriptor(): Could not getsockname(): errno = " << strerror (errno));
158 NS_LOG_INFO (
"Encoded Unix socket as \"" << path <<
"\"");
165 pid_t pid = ::fork ();
184 std::ostringstream ossIp;
187 std::ostringstream ossPrefix;
190 std::ostringstream ossMode;
193 std::ostringstream ossPath;
194 ossPath <<
"-p" << path;
199 status = ::execlp (PLANETLAB_TAP_CREATOR,
200 PLANETLAB_TAP_CREATOR,
201 ossIp.str ().c_str (),
202 ossPrefix.str ().c_str (),
203 ossMode.str ().c_str (),
204 ossPath.str ().c_str (),
211 NS_FATAL_ERROR (
"PlanetLabFdNetDeviceHelper::CreateFileDescriptor(): Back from execlp(), errno = " << ::strerror (errno));
221 pid_t waited = waitpid (pid, &st, 0);
222 NS_ABORT_MSG_IF (waited == -1,
"PlanetLabFdNetDeviceHelper::CreateFileDescriptor(): waitpid() fails, errno = " << strerror (errno));
223 NS_ASSERT_MSG (pid == waited,
"PlanetLabFdNetDeviceHelper::CreateFileDescriptor(): pid mismatch");
232 int exitStatus = WEXITSTATUS (st);
234 "PlanetLabFdNetDeviceHelper::CreateFileDescriptor(): socket creator exited normally with status " << exitStatus);
238 NS_FATAL_ERROR (
"PlanetLabFdNetDeviceHelper::CreateFileDescriptor(): socket creator exited abnormally");
256 iov.iov_base = &magic;
257 iov.iov_len =
sizeof(magic);
270 size_t msg_size =
sizeof(int);
271 char control[CMSG_SPACE (msg_size)];
288 msg.msg_control = control;
289 msg.msg_controllen =
sizeof (control);
296 ssize_t bytesRead = recvmsg (sock, &msg, 0);
297 NS_ABORT_MSG_IF (bytesRead !=
sizeof(
int),
"PlanetLabFdNetDeviceHelper::CreateFileDescriptor(): Wrong byte count from socket creator");
304 struct cmsghdr *cmsg;
305 for (cmsg = CMSG_FIRSTHDR (&msg); cmsg != NULL; cmsg = CMSG_NXTHDR (&msg, cmsg))
307 if (cmsg->cmsg_level == SOL_SOCKET
308 && cmsg->cmsg_type == SCM_RIGHTS)
317 NS_LOG_INFO (
"Got SCM_RIGHTS with correct magic " << magic);
318 int *rawSocket = (
int*)CMSG_DATA (cmsg);
319 NS_LOG_INFO (
"Got the socket from the socket creator = " << *rawSocket);
324 NS_LOG_INFO (
"Got SCM_RIGHTS, but with bad magic " << magic);
328 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)
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 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...
void SetTapMask(Ipv4Mask mask)
Set the network mask for the TAP device.
#define NS_FATAL_ERROR(msg)
fatal error handling
Ptr< NetDevice > InstallPriv(Ptr< Node > node) const
std::string BufferToString(uint8_t *buffer, uint32_t len)
Convert a byte buffer to a string containing a hex representation of the buffer.
#define NS_LOG_LOGIC(msg)
void SetEncapsulationMode(FdNetDevice::EncapsulationMode mode)
Set the link layer encapsulation mode of this device.
virtual void SetFileDescriptor(Ptr< FdNetDevice > device) const
Sets a file descriptor on the FileDescriptorNetDevice.
#define NS_ASSERT_MSG(condition, message)
virtual Ptr< NetDevice > InstallPriv(Ptr< Node > node) const
Ipv4 addresses are stored in host order in this class.
#define NS_LOG_DEBUG(msg)
NS_LOG_COMPONENT_DEFINE("PlanetLabFdNetDeviceHelper")
void SetTapIpAddress(Ipv4Address address)
Set the device IPv4 address.
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.
PlanetLabFdNetDeviceHelper()
Construct a PlanetLabFdNetDeviceHelper.
uint16_t GetPrefixLength(void) const