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 uint32_t AsciiToIpv4(const char *address)
static char AsciiToLowCase(char c)
static void SendSocket(const char *path, int fd)
static int CreateTap(const char *dev, const char *gw, const char *ip, const char *mac, const char *mode, const char *netmask)
static sockaddr CreateInetAddress(uint32_t networkOrder)
static void AsciiToMac48(const char *str, uint8_t addr[6])
#define ABORT_IF(cond, msg, printErrno)