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");
virtual Ptr< NetDevice > InstallPriv(Ptr< Node > node) const
This method creates an ns3::FdNetDevice and associates it to a node.
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...
Smart pointer class similar to boost::intrusive_ptr.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
NS_ASSERT_MSG(false, "Ipv4AddressGenerator::MaskToIndex(): Impossible")
ns3::StringValue attribute value declarations.
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...
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
void SetTapMask(Ipv4Mask mask)
Set the network mask for the TAP device.
virtual void SetFileDescriptor(Ptr< FdNetDevice > device) const
Sets a file descriptor on the FileDescriptorNetDevice.
std::string BufferToString(uint8_t *buffer, uint32_t len)
Convert a byte buffer to a string containing a hex representation of the buffer.
Ptr< NetDevice > InstallPriv(Ptr< Node > node) const
This method creates an ns3::FdNetDevice attached to a virtual TAP network interface.
void SetEncapsulationMode(FdNetDevice::EncapsulationMode mode)
Set the link layer encapsulation mode of this device.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
NS_LOG_LOGIC("Net device "<< nd<< " is not bridged")
Ipv4Mask m_tapMask
The network mask for the TAP device.
Ipv4 addresses are stored in host order in this class.
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
uint16_t GetPrefixLength(void) const
Ipv4Address m_tapIp
The IP address for the TAP device.
void SetTapIpAddress(Ipv4Address address)
Set the device IPv4 address.
a NetDevice to read/write network traffic from/into a file descriptor.
PlanetLabFdNetDeviceHelper()
Construct a PlanetLabFdNetDeviceHelper.