diff --git a/src/tuntap_freebsd.c b/src/tuntap_freebsd.c index d871e89..ebc5d56 100644 --- a/src/tuntap_freebsd.c +++ b/src/tuntap_freebsd.c @@ -16,118 +16,121 @@ * */ + #include "n2n.h" + #ifdef __FreeBSD__ -void tuntap_close(tuntap_dev *device); - -/* ********************************** */ #define N2N_FREEBSD_TAPDEVICE_SIZE 32 -int tuntap_open(tuntap_dev *device /* ignored */, - char *dev, - const char *address_mode, /* static or dhcp */ - char *device_ip, - char *device_mask, - const char * device_mac, - int mtu) { - int i; - char tap_device[N2N_FREEBSD_TAPDEVICE_SIZE]; - for (i = 0; i < 255; i++) { - snprintf(tap_device, sizeof(tap_device), "/dev/tap%d", i); - device->fd = open(tap_device, O_RDWR); - if(device->fd > 0) { - traceEvent(TRACE_NORMAL, "Succesfully open %s", tap_device); - break; - } - } - - if(device->fd < 0) { - traceEvent(TRACE_ERROR, "Unable to open tap device"); - return(-1); - } else { - char buf[256]; - FILE *fd; +void tuntap_close (tuntap_dev *device); - device->ip_addr = inet_addr(device_ip); - if ( device_mac && device_mac[0] != '\0' ) - { - /* FIXME - This is not tested. Might be wrong syntax for OS X */ +int tuntap_open (tuntap_dev *device /* ignored */, + char *dev, + const char *address_mode, /* static or dhcp */ + char *device_ip, + char *device_mask, + const char * device_mac, + int mtu) { - /* Set the hw address before bringing the if up. */ - snprintf(buf, sizeof(buf), "ifconfig tap%d ether %s", - i, device_mac); - system(buf); + int i; + char tap_device[N2N_FREEBSD_TAPDEVICE_SIZE]; + + for(i = 0; i < 255; i++) { + snprintf(tap_device, sizeof(tap_device), "/dev/tap%d", i); + + device->fd = open(tap_device, O_RDWR); + if(device->fd > 0) { + traceEvent(TRACE_NORMAL, "Succesfully open %s", tap_device); + break; + } } - snprintf(buf, sizeof(buf), "ifconfig tap%d %s netmask %s mtu %d up", - i, device_ip, device_mask, mtu); - system(buf); - - traceEvent(TRACE_NORMAL, "Interface tap%d up and running (%s/%s)", - i, device_ip, device_mask); - - /* Read MAC address */ - - snprintf(buf, sizeof(buf), "ifconfig tap%d |grep ether|cut -c 8-24", i); - /* traceEvent(TRACE_INFO, "%s", buf); */ - - fd = popen(buf, "r"); - if(fd < 0) { - tuntap_close(device); - return(-1); + if(device->fd < 0) { + traceEvent(TRACE_ERROR, "Unable to open tap device"); + return -1; } else { - int a, b, c, d, e, f; + char buf[256]; + FILE *fd; - buf[0] = 0; - fgets(buf, sizeof(buf), fd); - pclose(fd); - - if(buf[0] == '\0') { - traceEvent(TRACE_ERROR, "Unable to read tap%d interface MAC address"); - exit(0); - } + device->ip_addr = inet_addr(device_ip); - traceEvent(TRACE_NORMAL, "Interface tap%d mac %s", i, buf); - if(sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", &a, &b, &c, &d, &e, &f) == 6) { - device->mac_addr[0] = a, device->mac_addr[1] = b; - device->mac_addr[2] = c, device->mac_addr[3] = d; - device->mac_addr[4] = e, device->mac_addr[5] = f; - } + if(device_mac && device_mac[0] != '\0') { + // FIXME - this is not tested, might be wrong syntax for OS X + + // set the hw address before bringing the if up + snprintf(buf, sizeof(buf), "ifconfig tap%d ether %s", i, device_mac); + system(buf); + } + + snprintf(buf, sizeof(buf), "ifconfig tap%d %s netmask %s mtu %d up", i, device_ip, device_mask, mtu); + system(buf); + + traceEvent(TRACE_NORMAL, "Interface tap%d up and running (%s/%s)", i, device_ip, device_mask); + + // read MAC address + snprintf(buf, sizeof(buf), "ifconfig tap%d |grep ether|cut -c 8-24", i); + // traceEvent(TRACE_INFO, "%s", buf); + + fd = popen(buf, "r"); + if(fd < 0) { + tuntap_close(device); + return -1; + } else { + int a, b, c, d, e, f; + + buf[0] = 0; + fgets(buf, sizeof(buf), fd); + pclose(fd); + + if(buf[0] == '\0') { + traceEvent(TRACE_ERROR, "Unable to read tap%d interface MAC address"); + exit(0); + } + + traceEvent(TRACE_NORMAL, "Interface tap%d mac %s", i, buf); + if(sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", &a, &b, &c, &d, &e, &f) == 6) { + device->mac_addr[0] = a, device->mac_addr[1] = b; + device->mac_addr[2] = c, device->mac_addr[3] = d; + device->mac_addr[4] = e, device->mac_addr[5] = f; + } + } } - } - /* read_mac(dev, device->mac_addr); */ - return(device->fd); + // read_mac(dev, device->mac_addr); + + return device->fd; } -/* ********************************** */ -int tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, int len) { - return(read(tuntap->fd, buf, len)); +int tuntap_read (struct tuntap_dev *tuntap, unsigned char *buf, int len) { + + return read(tuntap->fd, buf, len); } -/* ********************************** */ -int tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, int len) { - return(write(tuntap->fd, buf, len)); +int tuntap_write (struct tuntap_dev *tuntap, unsigned char *buf, int len) { + + return write(tuntap->fd, buf, len); } -/* ********************************** */ -void tuntap_close(struct tuntap_dev *tuntap) { - close(tuntap->fd); +void tuntap_close (struct tuntap_dev *tuntap) { + + close(tuntap->fd); } -/* Fill out the ip_addr value from the interface. Called to pick up dynamic - * address changes. */ -void tuntap_get_address(struct tuntap_dev *tuntap) -{ + +// fill out the ip_addr value from the interface, called to pick up dynamic address changes +void tuntap_get_address (struct tuntap_dev *tuntap) { + + // no action } + #endif /* #ifdef __FreeBSD__ */ diff --git a/src/tuntap_linux.c b/src/tuntap_linux.c index 94b3766..99c2620 100644 --- a/src/tuntap_linux.c +++ b/src/tuntap_linux.c @@ -16,71 +16,72 @@ * */ + #ifdef __linux__ + #include "n2n.h" -/* ********************************** */ -static int setup_ifname(int fd, const char *ifname, const char *ipaddr, - const char *netmask, uint8_t *mac, int mtu) { - struct ifreq ifr; +static int setup_ifname (int fd, const char *ifname, const char *ipaddr, + const char *netmask, uint8_t *mac, int mtu) { - memset(&ifr, 0, sizeof(ifr)); + struct ifreq ifr; - strncpy(ifr.ifr_name, ifname, IFNAMSIZ); - ifr.ifr_name[IFNAMSIZ-1] = '\0'; + memset(&ifr, 0, sizeof(ifr)); - ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER; - memcpy(ifr.ifr_hwaddr.sa_data, mac, 6); + strncpy(ifr.ifr_name, ifname, IFNAMSIZ); + ifr.ifr_name[IFNAMSIZ-1] = '\0'; - if(ioctl(fd, SIOCSIFHWADDR, &ifr) == -1) { - traceEvent(TRACE_ERROR, "ioctl(SIOCSIFHWADDR) failed [%d]: %s", errno, strerror(errno)); - return(-1); - } + ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER; + memcpy(ifr.ifr_hwaddr.sa_data, mac, 6); - ifr.ifr_addr.sa_family = AF_INET; - - /* Interface Address */ - inet_pton(AF_INET, ipaddr, &((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr); - if(ioctl(fd, SIOCSIFADDR, &ifr) == -1) { - traceEvent(TRACE_ERROR, "ioctl(SIOCSIFADDR) failed [%d]: %s", errno, strerror(errno)); - return(-2); - } - - /* Netmask */ - if(netmask && (((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr.s_addr != 0)) { - inet_pton(AF_INET, netmask, &((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr); - if(ioctl(fd, SIOCSIFNETMASK, &ifr) == -1) { - traceEvent(TRACE_ERROR, "ioctl(SIOCSIFNETMASK, %s) failed [%d]: %s", netmask, errno, strerror(errno)); - return(-3); + if(ioctl(fd, SIOCSIFHWADDR, &ifr) == -1) { + traceEvent(TRACE_ERROR, "ioctl(SIOCSIFHWADDR) failed [%d]: %s", errno, strerror(errno)); + return -1; } + + ifr.ifr_addr.sa_family = AF_INET; + + // interface address + inet_pton(AF_INET, ipaddr, &((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr); + if(ioctl(fd, SIOCSIFADDR, &ifr) == -1) { + traceEvent(TRACE_ERROR, "ioctl(SIOCSIFADDR) failed [%d]: %s", errno, strerror(errno)); + return -2; } - /* MTU */ - ifr.ifr_mtu = mtu; - if(ioctl(fd, SIOCSIFMTU, &ifr) == -1) { - traceEvent(TRACE_ERROR, "ioctl(SIOCSIFMTU) failed [%d]: %s", errno, strerror(errno)); - return(-4); - } + // netmask + if(netmask && (((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr.s_addr != 0)) { + inet_pton(AF_INET, netmask, &((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr); + if(ioctl(fd, SIOCSIFNETMASK, &ifr) == -1) { + traceEvent(TRACE_ERROR, "ioctl(SIOCSIFNETMASK, %s) failed [%d]: %s", netmask, errno, strerror(errno)); + return -3; + } + } - /* Set up and running */ - if(ioctl(fd, SIOCGIFFLAGS, &ifr) == -1) { - traceEvent(TRACE_ERROR, "ioctl(SIOCGIFFLAGS) failed [%d]: %s", errno, strerror(errno)); - return(-5); - } + // MTU + ifr.ifr_mtu = mtu; + if(ioctl(fd, SIOCSIFMTU, &ifr) == -1) { + traceEvent(TRACE_ERROR, "ioctl(SIOCSIFMTU) failed [%d]: %s", errno, strerror(errno)); + return -4; + } - ifr.ifr_flags |= (IFF_UP | IFF_RUNNING); + // set up and running + if(ioctl(fd, SIOCGIFFLAGS, &ifr) == -1) { + traceEvent(TRACE_ERROR, "ioctl(SIOCGIFFLAGS) failed [%d]: %s", errno, strerror(errno)); + return -5; + } - if(ioctl(fd, SIOCSIFFLAGS, &ifr) == -1) { - traceEvent(TRACE_ERROR, "ioctl(SIOCSIFFLAGS) failed [%d]: %s", errno, strerror(errno)); - return(-6); - } + ifr.ifr_flags |= (IFF_UP | IFF_RUNNING); - return(0); + if(ioctl(fd, SIOCSIFFLAGS, &ifr) == -1) { + traceEvent(TRACE_ERROR, "ioctl(SIOCSIFFLAGS) failed [%d]: %s", errno, strerror(errno)); + return -6; + } + + return 0; } -/* ********************************** */ /** @brief Open and configure the TAP device for packet read/write. * @@ -88,7 +89,7 @@ static int setup_ifname(int fd, const char *ifname, const char *ipaddr, * configures it. * * @param device - [inout] a device info holder object - * @param dev - user-defined name for the new iface, + * @param dev - user-defined name for the new iface, * if NULL system will assign a name * @param device_ip - address of iface * @param device_mask - netmask for device_ip @@ -97,179 +98,186 @@ static int setup_ifname(int fd, const char *ifname, const char *ipaddr, * @return - negative value on error * - non-negative file-descriptor on success */ -int tuntap_open(tuntap_dev *device, - char *dev, /* user-definable interface name, eg. edge0 */ - const char *address_mode, /* static or dhcp */ - char *device_ip, - char *device_mask, - const char * device_mac, - int mtu) { - char *tuntap_device = "/dev/net/tun"; - int ioctl_fd; - struct ifreq ifr; - int rc; - int nl_fd; - char nl_buf[8192]; /* >= 8192 to avoid truncation, see "man 7 netlink" */ - struct iovec iov; - struct sockaddr_nl sa; - int up_and_running = 0; - struct msghdr msg; +int tuntap_open (tuntap_dev *device, + char *dev, /* user-definable interface name, eg. edge0 */ + const char *address_mode, /* static or dhcp */ + char *device_ip, + char *device_mask, + const char * device_mac, + int mtu) { - device->fd = open(tuntap_device, O_RDWR); - if(device->fd < 0) { - traceEvent(TRACE_ERROR, "tuntap open() error: %s[%d]. Is the tun kernel module loaded?\n", strerror(errno), errno); - return -1; - } + char *tuntap_device = "/dev/net/tun"; + int ioctl_fd; + struct ifreq ifr; + int rc; + int nl_fd; + char nl_buf[8192]; /* >= 8192 to avoid truncation, see "man 7 netlink" */ + struct iovec iov; + struct sockaddr_nl sa; + int up_and_running = 0; + struct msghdr msg; - memset(&ifr, 0, sizeof(ifr)); - ifr.ifr_flags = IFF_TAP|IFF_NO_PI; /* Want a TAP device for layer 2 frames. */ - strncpy(ifr.ifr_name, dev, IFNAMSIZ-1); - ifr.ifr_name[IFNAMSIZ-1] = '\0'; - rc = ioctl(device->fd, TUNSETIFF, (void *)&ifr); - - if(rc < 0) { - traceEvent(TRACE_ERROR, "tuntap ioctl(TUNSETIFF, IFF_TAP) error: %s[%d]\n", strerror(errno), rc); - close(device->fd); - return -1; - } - - /* Store the device name for later reuse */ - strncpy(device->dev_name, ifr.ifr_name, MIN(IFNAMSIZ, N2N_IFNAMSIZ) ); - - if(device_mac && device_mac[0]) { - /* Use the user-provided MAC */ - str2mac(device->mac_addr, device_mac); - } else { - /* Set an explicit random MAC to know the exact MAC in use. Manually - * reading the MAC address is not safe as it may change internally - * also after the TAP interface UP status has been notified. */ - int i; - - for(i = 0; i < 6; i++) - device->mac_addr[i] = n2n_rand(); - - device->mac_addr[0] &= ~0x01; /* Clear multicast bit */ - device->mac_addr[0] |= 0x02; /* Set locally-assigned bit */ - } - - /* Initialize Netlink socket */ - if((nl_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) == -1) { - traceEvent(TRACE_ERROR, "netlink socket creation failed [%d]: %s", errno, strerror(errno)); - return -1; - } - - iov.iov_base = nl_buf; - iov.iov_len = sizeof(nl_buf); - - memset(&sa, 0, sizeof(sa)); - sa.nl_family = PF_NETLINK; - sa.nl_groups = RTMGRP_LINK; - sa.nl_pid = getpid(); - - memset(&msg, 0, sizeof(msg)); - msg.msg_name = &sa; - msg.msg_namelen = sizeof(sa); - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - - /* Subscribe to interface events */ - if(bind(nl_fd, (struct sockaddr*)&sa, sizeof(sa)) == -1) { - traceEvent(TRACE_ERROR, "netlink socket bind failed [%d]: %s", errno, strerror(errno)); - return -1; - } - - if((ioctl_fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0) { - traceEvent(TRACE_ERROR, "socket creation failed [%d]: %s", errno, strerror(errno)); - close(nl_fd); - return -1; - } - - if(setup_ifname(ioctl_fd, device->dev_name, device_ip, device_mask, device->mac_addr, mtu) < 0) { - close(nl_fd); - close(ioctl_fd); - close(device->fd); - return -1; - } - - close(ioctl_fd); - - /* Wait for the up and running notification */ - traceEvent(TRACE_INFO, "Waiting for TAP interface to be up and running..."); - - while(!up_and_running) { - ssize_t len = recvmsg(nl_fd, &msg, 0); - struct nlmsghdr *nh; - - for(nh = (struct nlmsghdr *)nl_buf; NLMSG_OK(nh, len); nh = NLMSG_NEXT(nh, len)) { - if(nh->nlmsg_type == NLMSG_ERROR) { - traceEvent(TRACE_DEBUG, "nh->nlmsg_type == NLMSG_ERROR"); - break; - } - - if(nh->nlmsg_type == NLMSG_DONE) - break; - - if(nh->nlmsg_type == NETLINK_GENERIC) { - struct ifinfomsg *ifi = NLMSG_DATA(nh); - - /* NOTE: skipping interface name check, assuming it's our TAP */ - if((ifi->ifi_flags & IFF_UP) && (ifi->ifi_flags & IFF_RUNNING)) { - up_and_running = 1; - traceEvent(TRACE_INFO, "Interface is up and running"); - break; - } - } + device->fd = open(tuntap_device, O_RDWR); + if(device->fd < 0) { + traceEvent(TRACE_ERROR, "tuntap open() error: %s[%d]. Is the tun kernel module loaded?\n", strerror(errno), errno); + return -1; } - } - close(nl_fd); + memset(&ifr, 0, sizeof(ifr)); - device->ip_addr = inet_addr(device_ip); - device->device_mask = inet_addr(device_mask); - device->if_idx = if_nametoindex(dev); + // want a TAP device for layer 2 frames + ifr.ifr_flags = IFF_TAP|IFF_NO_PI; - return(device->fd); + strncpy(ifr.ifr_name, dev, IFNAMSIZ-1); + ifr.ifr_name[IFNAMSIZ-1] = '\0'; + rc = ioctl(device->fd, TUNSETIFF, (void *)&ifr); + + if(rc < 0) { + traceEvent(TRACE_ERROR, "tuntap ioctl(TUNSETIFF, IFF_TAP) error: %s[%d]\n", strerror(errno), rc); + close(device->fd); + return -1; + } + + // store the device name for later reuse + strncpy(device->dev_name, ifr.ifr_name, MIN(IFNAMSIZ, N2N_IFNAMSIZ)); + + if(device_mac && device_mac[0]) { + // use the user-provided MAC + str2mac(device->mac_addr, device_mac); + } else { + // set an explicit random MAC to know the exact MAC in use, manually + // reading the MAC address is not safe as it may change internally + // also after the TAP interface UP status has been notified + int i; + + for(i = 0; i < 6; i++) + device->mac_addr[i] = n2n_rand(); + + // clear multicast bit + device->mac_addr[0] &= ~0x01; + + // set locally-assigned bit + device->mac_addr[0] |= 0x02; + } + + // initialize netlink socket + if((nl_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) == -1) { + traceEvent(TRACE_ERROR, "netlink socket creation failed [%d]: %s", errno, strerror(errno)); + return -1; + } + + iov.iov_base = nl_buf; + iov.iov_len = sizeof(nl_buf); + + memset(&sa, 0, sizeof(sa)); + sa.nl_family = PF_NETLINK; + sa.nl_groups = RTMGRP_LINK; + sa.nl_pid = getpid(); + + memset(&msg, 0, sizeof(msg)); + msg.msg_name = &sa; + msg.msg_namelen = sizeof(sa); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + + // subscribe to interface events + if(bind(nl_fd, (struct sockaddr*)&sa, sizeof(sa)) == -1) { + traceEvent(TRACE_ERROR, "netlink socket bind failed [%d]: %s", errno, strerror(errno)); + return -1; + } + + if((ioctl_fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0) { + traceEvent(TRACE_ERROR, "socket creation failed [%d]: %s", errno, strerror(errno)); + close(nl_fd); + return -1; + } + + if(setup_ifname(ioctl_fd, device->dev_name, device_ip, device_mask, device->mac_addr, mtu) < 0) { + close(nl_fd); + close(ioctl_fd); + close(device->fd); + return -1; + } + + close(ioctl_fd); + + // wait for the up and running notification + traceEvent(TRACE_INFO, "Waiting for TAP interface to be up and running..."); + + while(!up_and_running) { + ssize_t len = recvmsg(nl_fd, &msg, 0); + struct nlmsghdr *nh; + + for(nh = (struct nlmsghdr *)nl_buf; NLMSG_OK(nh, len); nh = NLMSG_NEXT(nh, len)) { + if(nh->nlmsg_type == NLMSG_ERROR) { + traceEvent(TRACE_DEBUG, "nh->nlmsg_type == NLMSG_ERROR"); + break; + } + + if(nh->nlmsg_type == NLMSG_DONE) + break; + + if(nh->nlmsg_type == NETLINK_GENERIC) { + struct ifinfomsg *ifi = NLMSG_DATA(nh); + + // NOTE: skipping interface name check, assuming it's our TAP + if((ifi->ifi_flags & IFF_UP) && (ifi->ifi_flags & IFF_RUNNING)) { + up_and_running = 1; + traceEvent(TRACE_INFO, "Interface is up and running"); + break; + } + } + } + } + + close(nl_fd); + + device->ip_addr = inet_addr(device_ip); + device->device_mask = inet_addr(device_mask); + device->if_idx = if_nametoindex(dev); + + return device->fd; } -/* *************************************************** */ -int tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, int len) { - return(read(tuntap->fd, buf, len)); +int tuntap_read (struct tuntap_dev *tuntap, unsigned char *buf, int len) { + + return read(tuntap->fd, buf, len); } -/* *************************************************** */ -int tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, int len) { - return(write(tuntap->fd, buf, len)); +int tuntap_write (struct tuntap_dev *tuntap, unsigned char *buf, int len) { + + return write(tuntap->fd, buf, len); } -/* *************************************************** */ -void tuntap_close(struct tuntap_dev *tuntap) { - close(tuntap->fd); +void tuntap_close (struct tuntap_dev *tuntap) { + + close(tuntap->fd); } -/* *************************************************** */ -/* Fill out the ip_addr value from the interface. Called to pick up dynamic - * address changes. */ -void tuntap_get_address(struct tuntap_dev *tuntap) { - struct ifreq ifr; - int fd; +// fill out the ip_addr value from the interface, called to pick up dynamic address changes +void tuntap_get_address (struct tuntap_dev *tuntap) { - if((fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0) { - traceEvent(TRACE_ERROR, "socket creation failed [%d]: %s", errno, strerror(errno)); - return; - } + struct ifreq ifr; + int fd; - ifr.ifr_addr.sa_family = AF_INET; - strncpy(ifr.ifr_name, tuntap->dev_name, IFNAMSIZ); - ifr.ifr_name[IFNAMSIZ-1] = '\0'; + if((fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0) { + traceEvent(TRACE_ERROR, "socket creation failed [%d]: %s", errno, strerror(errno)); + return; + } - if(ioctl(fd, SIOCGIFADDR, &ifr) != -1) - tuntap->ip_addr = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr; + ifr.ifr_addr.sa_family = AF_INET; + strncpy(ifr.ifr_name, tuntap->dev_name, IFNAMSIZ); + ifr.ifr_name[IFNAMSIZ-1] = '\0'; - close(fd); + if(ioctl(fd, SIOCGIFADDR, &ifr) != -1) + tuntap->ip_addr = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr; + + close(fd); } + #endif /* #ifdef __linux__ */ diff --git a/src/tuntap_netbsd.c b/src/tuntap_netbsd.c index 617e2b2..9a1277f 100644 --- a/src/tuntap_netbsd.c +++ b/src/tuntap_netbsd.c @@ -16,130 +16,133 @@ * */ + #include "n2n.h" + #ifdef __NetBSD__ + #include #include #include -void tun_close(tuntap_dev *device); - -/* ********************************** */ #define N2N_NETBSD_TAPDEVICE_SIZE 32 -int tuntap_open(tuntap_dev *device /* ignored */, - char *dev, - const char *address_mode, /* static or dhcp */ - char *device_ip, - char *device_mask, - const char * device_mac, - int mtu) { - char tap_device[N2N_NETBSD_TAPDEVICE_SIZE]; - struct ifreq req; - if(dev) { - snprintf(tap_device, sizeof(tap_device), "/dev/%s", dev); - device->fd = open(tap_device, O_RDWR); - snprintf(tap_device, sizeof(tap_device), "%s", dev); - } - else { - device->fd = open("/dev/tap", O_RDWR); - if(device->fd >= 0) { - if(ioctl(device->fd, TAPGIFNAME, &req) == -1) { - traceEvent(TRACE_ERROR, "Unable to obtain name of tap device (%s)", strerror(errno)); - close(device->fd); - return(-1); - } - else { - snprintf(tap_device, sizeof(tap_device), req.ifr_name); - } - } - } - if(device->fd < 0) { - traceEvent(TRACE_ERROR, "Unable to open tap device (%s)", strerror(errno)); - return(-1); - } else { - char cmd[256]; - FILE *fd; +void tun_close (tuntap_dev *device); - traceEvent(TRACE_NORMAL, "Succesfully open %s", tap_device); - device->ip_addr = inet_addr(device_ip); +int tuntap_open (tuntap_dev *device /* ignored */, + char *dev, + const char *address_mode, /* static or dhcp */ + char *device_ip, + char *device_mask, + const char * device_mac, + int mtu) { - if( device_mac && device_mac[0] != '\0') { - /* Set the hw address before bringing the if up. */ - snprintf(cmd, sizeof(cmd), "ifconfig %s link %s active", - tap_device, device_mac); - system(cmd); - } + char tap_device[N2N_NETBSD_TAPDEVICE_SIZE]; + struct ifreq req; - snprintf(cmd, sizeof(cmd), "ifconfig %s %s netmask %s mtu %d up", - tap_device, device_ip, device_mask, mtu); - system(cmd); - - traceEvent(TRACE_NORMAL, "Interface %s up and running (%s/%s)", - tap_device, device_ip, device_mask); - - /* Read MAC address */ - snprintf(cmd, sizeof(cmd), "ifconfig %s |grep address|cut -c 11-28", tap_device); - /* traceEvent(TRACE_INFO, "%s", cmd); */ - - fd = popen(cmd, "r"); - if(fd < 0) { - tun_close(device); - return(-1); + if(dev) { + snprintf(tap_device, sizeof(tap_device), "/dev/%s", dev); + device->fd = open(tap_device, O_RDWR); + snprintf(tap_device, sizeof(tap_device), "%s", dev); } else { - int a, b, c, d, e, f; - char buf[256]; - - buf[0] = 0; - fgets(buf, sizeof(buf), fd); - pclose(fd); - - if(buf[0] == '\0') { - traceEvent(TRACE_ERROR, "Unable to read %s interface MAC address [%s]", tap_device, cmd); - exit(0); - } - - traceEvent(TRACE_NORMAL, "Interface %s mac %s", tap_device, buf); - if(sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", &a, &b, &c, &d, &e, &f) == 6) { - device->mac_addr[0] = a, device->mac_addr[1] = b; - device->mac_addr[2] = c, device->mac_addr[3] = d; - device->mac_addr[4] = e, device->mac_addr[5] = f; - } + device->fd = open("/dev/tap", O_RDWR); + if(device->fd >= 0) { + if(ioctl(device->fd, TAPGIFNAME, &req) == -1) { + traceEvent(TRACE_ERROR, "Unable to obtain name of tap device (%s)", strerror(errno)); + close(device->fd); + return -1; + } else { + snprintf(tap_device, sizeof(tap_device), req.ifr_name); + } + } } - } + if(device->fd < 0) { + traceEvent(TRACE_ERROR, "Unable to open tap device (%s)", strerror(errno)); + return -1; + } else { + char cmd[256]; + FILE *fd; - /* read_mac(dev, device->mac_addr); */ - return(device->fd); + traceEvent(TRACE_NORMAL, "Succesfully open %s", tap_device); + + device->ip_addr = inet_addr(device_ip); + + if(device_mac && device_mac[0] != '\0') { + // set the hw address before bringing the if up + snprintf(cmd, sizeof(cmd), "ifconfig %s link %s active", tap_device, device_mac); + system(cmd); + } + + snprintf(cmd, sizeof(cmd), "ifconfig %s %s netmask %s mtu %d up", tap_device, device_ip, device_mask, mtu); + system(cmd); + + traceEvent(TRACE_NORMAL, "Interface %s up and running (%s/%s)", tap_device, device_ip, device_mask); + + // read MAC address + snprintf(cmd, sizeof(cmd), "ifconfig %s |grep address|cut -c 11-28", tap_device); + // traceEvent(TRACE_INFO, "%s", cmd); + + fd = popen(cmd, "r"); + if(fd < 0) { + tun_close(device); + return -1; + } else { + int a, b, c, d, e, f; + char buf[256]; + + buf[0] = 0; + fgets(buf, sizeof(buf), fd); + pclose(fd); + + if(buf[0] == '\0') { + traceEvent(TRACE_ERROR, "Unable to read %s interface MAC address [%s]", tap_device, cmd); + exit(0); + } + + traceEvent(TRACE_NORMAL, "Interface %s mac %s", tap_device, buf); + if(sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", &a, &b, &c, &d, &e, &f) == 6) { + device->mac_addr[0] = a, device->mac_addr[1] = b; + device->mac_addr[2] = c, device->mac_addr[3] = d; + device->mac_addr[4] = e, device->mac_addr[5] = f; + } + } + } + + // read_mac(dev, device->mac_addr); + + return(device->fd); } -/* ********************************** */ -int tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, int len) { - return(read(tuntap->fd, buf, len)); +int tuntap_read (struct tuntap_dev *tuntap, unsigned char *buf, int len) { + + return(read(tuntap->fd, buf, len)); } -/* ********************************** */ -int tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, int len) { - return(write(tuntap->fd, buf, len)); +int tuntap_write (struct tuntap_dev *tuntap, unsigned char *buf, int len) { + + return(write(tuntap->fd, buf, len)); } -/* ********************************** */ -void tuntap_close(struct tuntap_dev *tuntap) { - close(tuntap->fd); +void tuntap_close (struct tuntap_dev *tuntap) { + + close(tuntap->fd); } -/* Fill out the ip_addr value from the interface. Called to pick up dynamic - * address changes. */ -void tuntap_get_address(struct tuntap_dev *tuntap) -{ + +// fill out the ip_addr value from the interface, called to pick up dynamic address changes +void tuntap_get_address (struct tuntap_dev *tuntap) { + + // no action } + #endif /* #ifdef __NetBSD__ */ diff --git a/src/tuntap_osx.c b/src/tuntap_osx.c index ef166ff..00cc9fd 100644 --- a/src/tuntap_osx.c +++ b/src/tuntap_osx.c @@ -16,119 +16,119 @@ * */ + #include "n2n.h" + #ifdef __APPLE__ -void tun_close(tuntap_dev *device); - -/* ********************************** */ #define N2N_OSX_TAPDEVICE_SIZE 32 -int tuntap_open(tuntap_dev *device /* ignored */, - char *dev, - const char *address_mode, /* static or dhcp */ - char *device_ip, - char *device_mask, - const char * device_mac, - int mtu) { - int i; - char tap_device[N2N_OSX_TAPDEVICE_SIZE]; - for (i = 0; i < 255; i++) { - snprintf(tap_device, sizeof(tap_device), "/dev/tap%d", i); - device->fd = open(tap_device, O_RDWR); - if(device->fd > 0) { - traceEvent(TRACE_NORMAL, "Succesfully open %s", tap_device); - break; - } - } - - if(device->fd < 0) { - traceEvent(TRACE_ERROR, "Unable to open any tap devices /dev/tap0 through /dev/tap254. Is this user properly authorized to access those descriptors?"); - traceEvent(TRACE_ERROR, "Please read https://github.com/ntop/n2n/blob/dev/doc/macOS.md"); - return(-1); - } else { - char buf[256]; - FILE *fd; +void tun_close (tuntap_dev *device); - device->ip_addr = inet_addr(device_ip); - if ( device_mac && device_mac[0] != '\0' ) - { - /* FIXME - This is not tested. Might be wrong syntax for OS X */ +int tuntap_open (tuntap_dev *device /* ignored */, + char *dev, + const char *address_mode, /* static or dhcp */ + char *device_ip, + char *device_mask, + const char * device_mac, + int mtu) { - /* Set the hw address before bringing the if up. */ - snprintf(buf, sizeof(buf), "ifconfig tap%d ether %s", - i, device_mac); - system(buf); + int i; + char tap_device[N2N_OSX_TAPDEVICE_SIZE]; + + for(i = 0; i < 255; i++) { + snprintf(tap_device, sizeof(tap_device), "/dev/tap%d", i); + + device->fd = open(tap_device, O_RDWR); + if(device->fd > 0) { + traceEvent(TRACE_NORMAL, "Succesfully open %s", tap_device); + break; + } } - snprintf(buf, sizeof(buf), "ifconfig tap%d %s netmask %s mtu %d up", - i, device_ip, device_mask, mtu); - system(buf); - - traceEvent(TRACE_NORMAL, "Interface tap%d up and running (%s/%s)", - i, device_ip, device_mask); - - /* Read MAC address */ - - snprintf(buf, sizeof(buf), "ifconfig tap%d |grep ether|cut -c 8-24", i); - /* traceEvent(TRACE_INFO, "%s", buf); */ - - fd = popen(buf, "r"); - if(fd < 0) { - tuntap_close(device); - return(-1); + if(device->fd < 0) { + traceEvent(TRACE_ERROR, "Unable to open any tap devices /dev/tap0 through /dev/tap254. Is this user properly authorized to access those descriptors?"); + traceEvent(TRACE_ERROR, "Please read https://github.com/ntop/n2n/blob/dev/doc/Building.md"); + return -1; } else { - int a, b, c, d, e, f; + char buf[256]; + FILE *fd; - buf[0] = 0; - fgets(buf, sizeof(buf), fd); - pclose(fd); - - if(buf[0] == '\0') { - traceEvent(TRACE_ERROR, "Unable to read tap%d interface MAC address"); - exit(0); - } + device->ip_addr = inet_addr(device_ip); - traceEvent(TRACE_NORMAL, "Interface tap%d [MTU %d] mac %s", i, mtu, buf); - if(sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", &a, &b, &c, &d, &e, &f) == 6) { - device->mac_addr[0] = a, device->mac_addr[1] = b; - device->mac_addr[2] = c, device->mac_addr[3] = d; - device->mac_addr[4] = e, device->mac_addr[5] = f; - } + if(device_mac && device_mac[0] != '\0') { + // FIXME - this is not tested. might be wrong syntax for OS X + // set the hw address before bringing the if up + snprintf(buf, sizeof(buf), "ifconfig tap%d ether %s", i, device_mac); + system(buf); + } + + snprintf(buf, sizeof(buf), "ifconfig tap%d %s netmask %s mtu %d up", i, device_ip, device_mask, mtu); + system(buf); + + traceEvent(TRACE_NORMAL, "Interface tap%d up and running (%s/%s)", i, device_ip, device_mask); + + // read MAC address + snprintf(buf, sizeof(buf), "ifconfig tap%d |grep ether|cut -c 8-24", i); + // traceEvent(TRACE_INFO, "%s", buf); + + fd = popen(buf, "r"); + if(fd < 0) { + tuntap_close(device); + return -1; + } else { + int a, b, c, d, e, f; + + buf[0] = 0; + fgets(buf, sizeof(buf), fd); + pclose(fd); + + if(buf[0] == '\0') { + traceEvent(TRACE_ERROR, "Unable to read tap%d interface MAC address"); + exit(0); + } + + traceEvent(TRACE_NORMAL, "Interface tap%d [MTU %d] mac %s", i, mtu, buf); + if(sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", &a, &b, &c, &d, &e, &f) == 6) { + device->mac_addr[0] = a, device->mac_addr[1] = b; + device->mac_addr[2] = c, device->mac_addr[3] = d; + device->mac_addr[4] = e, device->mac_addr[5] = f; + } + } } - } + // read_mac(dev, device->mac_addr); - /* read_mac(dev, device->mac_addr); */ - return(device->fd); + return(device->fd); } -/* ********************************** */ -int tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, int len) { - return(read(tuntap->fd, buf, len)); +int tuntap_read (struct tuntap_dev *tuntap, unsigned char *buf, int len) { + + return(read(tuntap->fd, buf, len)); } -/* ********************************** */ -int tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, int len) { - return(write(tuntap->fd, buf, len)); +int tuntap_write (struct tuntap_dev *tuntap, unsigned char *buf, int len) { + + return(write(tuntap->fd, buf, len)); } -/* ********************************** */ -void tuntap_close(struct tuntap_dev *tuntap) { - close(tuntap->fd); +void tuntap_close (struct tuntap_dev *tuntap) { + + close(tuntap->fd); } -/* Fill out the ip_addr value from the interface. Called to pick up dynamic - * address changes. */ -void tuntap_get_address(struct tuntap_dev *tuntap) -{ +// fill out the ip_addr value from the interface, called to pick up dynamic address changes +void tuntap_get_address (struct tuntap_dev *tuntap) { + + // no action } + #endif /* __APPLE__ */