Browse Source

Ensure that the TAP interface is up and running

pull/115/head
emanuele-f 5 years ago
parent
commit
6868ed9ccd
  1. 2
      edge.c
  2. 65
      tuntap_linux.c

2
edge.c

@ -707,7 +707,7 @@ int main(int argc, char* argv[]) {
#ifndef WIN32
if((ec.userid != 0) || (ec.groupid != 0)) {
traceEvent(TRACE_NORMAL, "Interface up. Dropping privileges to uid=%d, gid=%d",
traceEvent(TRACE_NORMAL, "Dropping privileges to uid=%d, gid=%d",
(signed int)ec.userid, (signed int)ec.groupid);
/* Finished with the need for root privileges. Drop to unprivileged user. */

65
tuntap_linux.c

@ -21,6 +21,8 @@
#ifdef __linux__
#include <net/if_arp.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
/* *************************************************** */
@ -138,6 +140,12 @@ int tuntap_open(tuntap_dev *device,
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;
device->fd = open(tuntap_device, O_RDWR);
if(device->fd < 0) {
@ -160,12 +168,38 @@ int tuntap_open(tuntap_dev *device,
/* Store the device name for later reuse */
strncpy(device->dev_name, ifr.ifr_name, MIN(IFNAMSIZ, N2N_IFNAMSIZ) );
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();
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, mtu) < 0) {
close(nl_fd);
close(ioctl_fd);
close(device->fd);
return -1;
@ -173,6 +207,37 @@ int tuntap_open(tuntap_dev *device,
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);
read_mac(dev, device->mac_addr);

Loading…
Cancel
Save