26 #include <linux/if_tun.h>
28 #include <net/route.h>
29 #include <netinet/in.h>
33 #include <sys/ioctl.h>
34 #include <sys/socket.h>
35 #include <sys/types.h>
39 #define TAP_MAGIC 95549
46 std::cout << __FUNCTION__ << "(): " << msg << std::endl; \
49 #define ABORT(msg, printErrno) \
50 std::cout << __FILE__ << ": fatal error at line " << __LINE__ << ": " << __FUNCTION__ \
51 << "(): " << msg << std::endl; \
54 std::cout << " errno = " << errno << " (" << std::strerror(errno) << ")" << std::endl; \
58 #define ABORT_IF(cond, msg, printErrno) \
61 ABORT(msg, printErrno); \
67 #define ASCII_DOT (0x2e)
68 #define ASCII_ZERO (0x30)
69 #define ASCII_a (0x41)
70 #define ASCII_z (0x5a)
71 #define ASCII_A (0x61)
72 #define ASCII_Z (0x7a)
73 #define ASCII_COLON (0x3a)
120 while (*str != 0 && i < 6)
151 struct sockaddr any_socket;
152 struct sockaddr_in si;
155 s.si.sin_family = AF_INET;
157 s.si.sin_addr.s_addr = htonl(networkOrder);
167 LOG(
"Create Unix socket");
168 int sock = socket(PF_UNIX, SOCK_DGRAM, 0);
169 ABORT_IF(sock == -1,
"Unable to open socket", 1);
178 socklen_t clientAddrLen;
179 struct sockaddr_un clientAddr;
181 LOG(
"Decode address " <<
path);
183 ABORT_IF(
rc ==
false,
"Unable to decode path", 0);
186 int status = connect(sock, (
struct sockaddr*)&clientAddr, clientAddrLen);
187 ABORT_IF(status == -1,
"Unable to connect to tap bridge", 1);
208 iov.iov_base = &magic;
209 iov.iov_len =
sizeof(magic);
222 size_t msg_size =
sizeof(
int);
223 char control[CMSG_SPACE(msg_size)];
237 msg.msg_name =
nullptr;
241 msg.msg_control = control;
242 msg.msg_controllen =
sizeof(control);
256 struct cmsghdr* cmsg;
257 cmsg = CMSG_FIRSTHDR(&msg);
258 cmsg->cmsg_level = SOL_SOCKET;
259 cmsg->cmsg_type = SCM_RIGHTS;
260 cmsg->cmsg_len = CMSG_LEN(msg_size);
265 msg.msg_controllen = cmsg->cmsg_len;
271 int* fdptr = (
int*)(CMSG_DATA(cmsg));
277 ssize_t len = sendmsg(sock, &msg, 0);
278 ABORT_IF(len == -1,
"Could not send socket back to tap bridge", 1);
280 LOG(
"sendmsg complete");
294 int tap = open(
"/dev/net/tun", O_RDWR);
295 ABORT_IF(tap == -1,
"Could not open /dev/net/tun",
true);
305 ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
306 strcpy(ifr.ifr_name, dev);
307 int status = ioctl(tap, TUNSETIFF, (
void*)&ifr);
308 ABORT_IF(status == -1,
"Could not allocate tap device",
true);
310 std::string tapDeviceName = (
char*)ifr.ifr_name;
311 LOG(
"Allocated TAP device " << tapDeviceName);
319 if (std::string(mode) ==
"2" || std::string(mode) ==
"3")
321 LOG(
"Returning precreated tap ");
328 ifr.ifr_hwaddr.sa_family = 1;
330 status = ioctl(tap, SIOCSIFHWADDR, &ifr);
331 ABORT_IF(status == -1,
"Could not set MAC address",
true);
332 LOG(
"Set device MAC address to " <<
mac);
334 int fd = socket(AF_INET, SOCK_DGRAM, 0);
339 status = ioctl(fd, SIOCGIFFLAGS, &ifr);
340 ABORT_IF(status == -1,
"Could not get flags for interface",
true);
341 ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
342 status = ioctl(fd, SIOCSIFFLAGS, &ifr);
343 ABORT_IF(status == -1,
"Could not bring interface up",
true);
350 status = ioctl(fd, SIOCSIFADDR, &ifr);
351 ABORT_IF(status == -1,
"Could not set IP address",
true);
352 LOG(
"Set device IP address to " << ip);
358 status = ioctl(fd, SIOCSIFNETMASK, &ifr);
359 ABORT_IF(status == -1,
"Could not set net mask",
true);
360 LOG(
"Set device Net Mask to " << netmask);
366 main(
int argc,
char* argv[])
369 char* dev = (
char*)
"";
373 char* netmask =
nullptr;
374 char* operatingMode =
nullptr;
375 char*
path =
nullptr;
379 while ((c = getopt(argc, argv,
"vd:g:i:m:n:o:p:")) != -1)
399 operatingMode = optarg;
416 LOG(
"Provided Device Name is \"" << dev <<
"\"");
423 ABORT_IF(gw ==
nullptr,
"Gateway Address is a required argument", 0);
424 LOG(
"Provided Gateway Address is \"" << gw <<
"\"");
431 ABORT_IF(ip ==
nullptr,
"IP Address is a required argument", 0);
432 LOG(
"Provided IP Address is \"" << ip <<
"\"");
440 ABORT_IF(
mac ==
nullptr,
"MAC Address is a required argument", 0);
441 LOG(
"Provided MAC Address is \"" <<
mac <<
"\"");
448 ABORT_IF(netmask ==
nullptr,
"Net Mask is a required argument", 0);
449 LOG(
"Provided Net Mask is \"" << netmask <<
"\"");
454 ABORT_IF(operatingMode ==
nullptr,
"Operating Mode is a required argument", 0);
455 LOG(
"Provided Operating Mode is \"" << operatingMode <<
"\"");
468 ABORT_IF(
path ==
nullptr,
"path is a required argument", 0);
469 LOG(
"Provided path is \"" <<
path <<
"\"");
480 int sock =
CreateTap(dev, gw, ip,
mac, operatingMode, netmask);
481 ABORT_IF(sock == -1,
"main(): Unable to create tap socket", 1);
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 uint32_t AsciiToIpv4(const char *address)
static int CreateTap(const char *dev, const char *gw, const char *ip, const char *mac, const char *mode, const char *netmask)
static char AsciiToLowCase(char c)
static void AsciiToMac48(const char *str, uint8_t addr[6])