diff options
Diffstat (limited to 'src/interface.c')
-rw-r--r-- | src/interface.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/src/interface.c b/src/interface.c index 78602b0..1b6c941 100644 --- a/src/interface.c +++ b/src/interface.c @@ -25,6 +25,7 @@ #include <assert.h> #include <unistd.h> #include <sys/ioctl.h> +#include <netinet/in.h> #include <libdaemon/dlog.h> @@ -65,3 +66,41 @@ void interface_close(struct interface *i) { free(i); } + +void interface_up(struct interface *i) { + struct ifreq ifr; + assert(i && i->fd >= 0 && i->name); + + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, i->name, sizeof(ifr.ifr_name)-1); + + if (ioctl(i->fd, SIOCGIFFLAGS, &ifr) < 0) { + daemon_log(LOG_WARNING, "Warning: Could not get interface flags."); + return; + } + + if ((ifr.ifr_flags & IFF_UP) == IFF_UP) + return; + + if (ioctl(i->fd, SIOCGIFADDR, &ifr) < 0) + daemon_log(LOG_WARNING, "Warning: Could not get interface address."); + else if (ifr.ifr_addr.sa_family != AF_INET) + daemon_log(LOG_WARNING, "Warning: The interface is not IP-based."); + else { + ((struct sockaddr_in *)(&ifr.ifr_addr))->sin_addr.s_addr = INADDR_ANY; + if (ioctl(i->fd, SIOCSIFADDR, &ifr) < 0) + daemon_log(LOG_WARNING, "Warning: Could not set interface address."); + } + + if (ioctl(i->fd, SIOCGIFFLAGS, &ifr) < 0) { + daemon_log(LOG_WARNING, "Warning: Could not get interface flags."); + return; + } + + ifr.ifr_flags |= IFF_UP; + + if (ioctl(i->fd, SIOCSIFFLAGS, &ifr) < 0) + daemon_log(LOG_WARNING, "Warning: Could not set interface flags."); + + daemon_log(LOG_INFO, "Interface set to status UP."); +} |