26#include <linux/if_tun.h> 
   29#include <netinet/in.h> 
   34#include <sys/socket.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) 
   73#define ASCII_COLON (0x3a) 
   99        while (*address != 
ASCII_DOT && *address != 0)
 
  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);
 
  366main(
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])