summaryrefslogtreecommitdiffstats
path: root/src/interface.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/interface.c')
-rw-r--r--src/interface.c39
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.");
+}