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);
 
  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)
 
int CreateTap(char *deviceName, const char *mac, const int ifftap, const int iffpi, const char *ip4, const char *netmask, const char *ip6, const int netprefix)
 
char AsciiToLowCase(char c)
 
static void SendSocket(const char *path, int fd)
 
static sockaddr CreateInetAddress(uint32_t networkOrder)
 
#define ABORT_IF(cond, msg, printErrno)
 
int main(int argc, char *argv[])
 
void AsciiToMac48(const char *str, uint8_t addr[6])