29 #include <sys/ioctl.h>
30 #include <sys/types.h>
31 #include <sys/socket.h>
34 #include <linux/if_tun.h>
35 #include <net/route.h>
36 #include <netinet/in.h>
40 #define TAP_MAGIC 95549
47 std::cout << __FUNCTION__ << "(): " << msg << std::endl; \
50 #define ABORT(msg, printErrno) \
51 std::cout << __FILE__ << ": fatal error at line " << __LINE__ << ": " << __FUNCTION__ << "(): " << 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)
74 #define ASCII_ZERO (0x30)
114 while (*str != 0 && i < 6)
145 struct sockaddr any_socket;
146 struct sockaddr_in si;
148 s.si.sin_family = AF_INET;
150 s.si.sin_addr.s_addr = htonl (networkOrder);
160 LOG (
"Create Unix socket");
161 int sock = socket (PF_UNIX, SOCK_DGRAM, 0);
162 ABORT_IF (sock == -1,
"Unable to open socket", 1);
171 socklen_t clientAddrLen;
172 struct sockaddr_un clientAddr;
174 LOG (
"Decode address " << path);
176 ABORT_IF (rc ==
false,
"Unable to decode path", 0);
179 int status = connect (sock, (
struct sockaddr*)&clientAddr, clientAddrLen);
180 ABORT_IF (status == -1,
"Unable to connect to tap bridge", 1);
201 iov.iov_base = &magic;
202 iov.iov_len =
sizeof(magic);
215 size_t msg_size =
sizeof(int);
216 char control[CMSG_SPACE (msg_size)];
234 msg.msg_control = control;
235 msg.msg_controllen =
sizeof (control);
249 struct cmsghdr *cmsg;
250 cmsg = CMSG_FIRSTHDR (&msg);
251 cmsg->cmsg_level = SOL_SOCKET;
252 cmsg->cmsg_type = SCM_RIGHTS;
253 cmsg->cmsg_len = CMSG_LEN (msg_size);
258 msg.msg_controllen = cmsg->cmsg_len;
264 int *fdptr = (
int*)(CMSG_DATA (cmsg));
270 ssize_t len = sendmsg (sock, &msg, 0);
271 ABORT_IF (len == -1,
"Could not send socket back to tap bridge", 1);
273 LOG (
"sendmsg complete");
277 CreateTap (
const char *dev,
const char *gw,
const char *ip,
const char *
mac,
const char *mode,
const char *netmask)
282 int tap = open (
"/dev/net/tun", O_RDWR);
283 ABORT_IF (tap == -1,
"Could not open /dev/net/tun",
true);
293 ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
294 strcpy (ifr.ifr_name, dev);
295 int status = ioctl (tap, TUNSETIFF, (
void *) &ifr);
296 ABORT_IF (status == -1,
"Could not allocate tap device",
true);
298 std::string tapDeviceName = (
char *)ifr.ifr_name;
299 LOG (
"Allocated TAP device " << tapDeviceName);
307 if (strcmp (mode,
"2") == 0 || strcmp (mode,
"3") == 0)
309 LOG (
"Returning precreated tap ");
316 ifr.ifr_hwaddr.sa_family = 1;
318 status = ioctl (tap, SIOCSIFHWADDR, &ifr);
319 ABORT_IF (status == -1,
"Could not set MAC address",
true);
320 LOG (
"Set device MAC address to " <<
mac);
322 int fd = socket (AF_INET, SOCK_DGRAM, 0);
327 status = ioctl (fd, SIOCGIFFLAGS, &ifr);
328 ABORT_IF (status == -1,
"Could not get flags for interface",
true);
329 ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
330 status = ioctl (fd, SIOCSIFFLAGS, &ifr);
331 ABORT_IF (status == -1,
"Could not bring interface up",
true);
332 LOG (
"Device is up");
338 status = ioctl (fd, SIOCSIFADDR, &ifr);
339 ABORT_IF (status == -1,
"Could not set IP address",
true);
340 LOG (
"Set device IP address to " << ip);
346 status = ioctl (fd, SIOCSIFNETMASK, &ifr);
347 ABORT_IF (status == -1,
"Could not set net mask",
true);
348 LOG (
"Set device Net Mask to " << netmask);
354 main (
int argc,
char *argv[])
357 char *dev = (
char *)
"";
361 char *netmask = NULL;
362 char *operatingMode = NULL;
367 while ((c = getopt (argc, argv,
"vd:g:i:m:n:o:p:")) != -1)
387 operatingMode = optarg;
404 LOG (
"Provided Device Name is \"" << dev <<
"\"");
411 ABORT_IF (gw == NULL,
"Gateway Address is a required argument", 0);
412 LOG (
"Provided Gateway Address is \"" << gw <<
"\"");
419 ABORT_IF (ip == NULL,
"IP Address is a required argument", 0);
420 LOG (
"Provided IP Address is \"" << ip <<
"\"");
428 ABORT_IF (
mac == NULL,
"MAC Address is a required argument", 0);
429 LOG (
"Provided MAC Address is \"" <<
mac <<
"\"");
436 ABORT_IF (netmask == NULL,
"Net Mask is a required argument", 0);
437 LOG (
"Provided Net Mask is \"" << netmask <<
"\"");
442 ABORT_IF (operatingMode == NULL,
"Operating Mode is a required argument", 0);
443 LOG (
"Provided Operating Mode is \"" << operatingMode <<
"\"");
456 ABORT_IF (path == NULL,
"path is a required argument", 0);
457 LOG (
"Provided path is \"" << path <<
"\"");
467 LOG (
"Creating Tap");
468 int sock =
CreateTap (dev, gw, ip,
mac, operatingMode, netmask);
469 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])