20 #include "ns3/mac48-address.h"
28 #include <linux/if_tun.h>
30 #include <net/route.h>
31 #include <netinet/in.h>
35 #include <sys/ioctl.h>
36 #include <sys/socket.h>
37 #include <sys/types.h>
41 #define TAP_MAGIC 95549
48 std::cout << __FUNCTION__ << "(): " << msg << std::endl; \
51 #define ABORT(msg, printErrno) \
52 std::cout << __FILE__ << ": fatal error at line " << __LINE__ << ": " << __FUNCTION__ \
53 << "(): " << msg << std::endl; \
56 std::cout << " errno = " << errno << " (" << std::strerror(errno) << ")" << std::endl; \
60 #define ABORT_IF(cond, msg, printErrno) \
63 ABORT(msg, printErrno); \
70 struct sockaddr any_socket;
71 struct sockaddr_in si;
74 s.si.sin_family = AF_INET;
76 s.si.sin_addr.s_addr = htonl(networkOrder);
86 LOG(
"Create Unix socket");
87 int sock = socket(PF_UNIX, SOCK_DGRAM, 0);
88 ABORT_IF(sock == -1,
"Unable to open socket", 1);
97 socklen_t clientAddrLen;
98 struct sockaddr_un clientAddr;
100 LOG(
"Decode address " << path);
102 ABORT_IF(
rc ==
false,
"Unable to decode path", 0);
105 int status = connect(sock, (
struct sockaddr*)&clientAddr, clientAddrLen);
106 ABORT_IF(status == -1,
"Unable to connect to tap bridge", 1);
127 iov.iov_base = &magic;
128 iov.iov_len =
sizeof(magic);
141 size_t msg_size =
sizeof(int);
142 char control[CMSG_SPACE(msg_size)];
156 msg.msg_name =
nullptr;
160 msg.msg_control = control;
161 msg.msg_controllen =
sizeof(control);
175 struct cmsghdr* cmsg;
176 cmsg = CMSG_FIRSTHDR(&msg);
177 cmsg->cmsg_level = SOL_SOCKET;
178 cmsg->cmsg_type = SCM_RIGHTS;
179 cmsg->cmsg_len = CMSG_LEN(msg_size);
184 msg.msg_controllen = cmsg->cmsg_len;
190 int* fdptr = (
int*)(CMSG_DATA(cmsg));
196 ssize_t len = sendmsg(sock, &msg, 0);
197 ABORT_IF(len == -1,
"Could not send socket back to tap bridge", 1);
199 LOG(
"sendmsg complete");
213 int tap = open(
"/dev/net/tun", O_RDWR);
214 ABORT_IF(tap == -1,
"Could not open /dev/net/tun",
true);
224 ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
225 strcpy(ifr.ifr_name, dev);
226 int status = ioctl(tap, TUNSETIFF, (
void*)&ifr);
227 ABORT_IF(status == -1,
"Could not allocate tap device",
true);
229 std::string tapDeviceName = (
char*)ifr.ifr_name;
230 LOG(
"Allocated TAP device " << tapDeviceName);
238 if (std::string(mode) ==
"2" || std::string(mode) ==
"3")
240 LOG(
"Returning precreated tap ");
247 ifr.ifr_hwaddr.sa_family = 1;
249 status = ioctl(tap, SIOCSIFHWADDR, &ifr);
250 ABORT_IF(status == -1,
"Could not set MAC address",
true);
251 LOG(
"Set device MAC address to " <<
mac);
253 int fd = socket(AF_INET, SOCK_DGRAM, 0);
258 status = ioctl(fd, SIOCGIFFLAGS, &ifr);
259 ABORT_IF(status == -1,
"Could not get flags for interface",
true);
260 ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
261 status = ioctl(fd, SIOCSIFFLAGS, &ifr);
262 ABORT_IF(status == -1,
"Could not bring interface up",
true);
269 status = ioctl(fd, SIOCSIFADDR, &ifr);
270 ABORT_IF(status == -1,
"Could not set IP address",
true);
271 LOG(
"Set device IP address to " << ip);
277 status = ioctl(fd, SIOCSIFNETMASK, &ifr);
278 ABORT_IF(status == -1,
"Could not set net mask",
true);
279 LOG(
"Set device Net Mask to " << netmask);
285 main(
int argc,
char* argv[])
288 char* dev = (
char*)
"";
292 char* netmask =
nullptr;
293 char* operatingMode =
nullptr;
294 char* path =
nullptr;
298 while ((c = getopt(argc, argv,
"vd:g:i:m:n:o:p:")) != -1)
318 operatingMode = optarg;
335 LOG(
"Provided Device Name is \"" << dev <<
"\"");
342 ABORT_IF(gw ==
nullptr,
"Gateway Address is a required argument", 0);
343 LOG(
"Provided Gateway Address is \"" << gw <<
"\"");
350 ABORT_IF(ip ==
nullptr,
"IP Address is a required argument", 0);
351 LOG(
"Provided IP Address is \"" << ip <<
"\"");
359 ABORT_IF(
mac ==
nullptr,
"MAC Address is a required argument", 0);
360 LOG(
"Provided MAC Address is \"" <<
mac <<
"\"");
367 ABORT_IF(netmask ==
nullptr,
"Net Mask is a required argument", 0);
368 LOG(
"Provided Net Mask is \"" << netmask <<
"\"");
373 ABORT_IF(operatingMode ==
nullptr,
"Operating Mode is a required argument", 0);
374 LOG(
"Provided Operating Mode is \"" << operatingMode <<
"\"");
387 ABORT_IF(path ==
nullptr,
"path is a required argument", 0);
388 LOG(
"Provided path is \"" << path <<
"\"");
399 int sock =
CreateTap(dev, gw, ip,
mac, operatingMode, netmask);
400 ABORT_IF(sock == -1,
"main(): Unable to create tap socket", 1);
Ipv4 addresses are stored in host order in this class.
a class to represent an Ipv4 address mask
void CopyTo(uint8_t buffer[6]) const
bool TapStringToBuffer(std::string s, uint8_t *buffer, uint32_t *len)
Convert string encoded by the inverse function (TapBufferToString) back into a byte buffer.
static void SendSocket(const char *path, int fd)
static sockaddr CreateInetAddress(uint32_t networkOrder)
#define ABORT_IF(cond, msg, printErrno)
static int CreateTap(const char *dev, const char *gw, const char *ip, const char *mac, const char *mode, const char *netmask)