mirror of
https://github.com/ntop/n2n.git
synced 2024-04-21 16:31:34 +00:00
Ensure that the TAP interface is up and running
This commit is contained in:
@@ -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. */
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user