summaryrefslogtreecommitdiffstats
path: root/src/ifmonitor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ifmonitor.c')
-rw-r--r--src/ifmonitor.c84
1 files changed, 84 insertions, 0 deletions
diff --git a/src/ifmonitor.c b/src/ifmonitor.c
new file mode 100644
index 0000000..b1124a5
--- /dev/null
+++ b/src/ifmonitor.c
@@ -0,0 +1,84 @@
+#include <stdio.h>
+#include <sys/socket.h>
+#include <linux/types.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <linux/if.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "util.h"
+#include "nlapi.h"
+
+static int callback(struct nlmsghdr *n, void *u) {
+ int (*cb)(int b, int index, unsigned short type, const char *name) = u;
+
+ if (n->nlmsg_type == RTM_NEWLINK || n->nlmsg_type == RTM_DELLINK) {
+ struct rtattr *a;
+ struct ifinfomsg *i;
+ char ifname[IFNAMSIZ+1];
+ int la;
+
+ i = NLMSG_DATA(n);
+
+ if (n->nlmsg_len < NLMSG_LENGTH(sizeof(struct ifinfomsg))) {
+ fprintf(stderr, "NETLINK: Packet too small or truncated! (2)\n");
+ return -1;
+ }
+
+ memset(&ifname, 0, sizeof(ifname));
+
+ a = (void*) i + NLMSG_ALIGN(sizeof(struct ifinfomsg));
+ la = NLMSG_PAYLOAD(n, sizeof(struct ifinfomsg));
+
+ while (RTA_OK(a, la)) {
+
+ if(a->rta_type == IFLA_IFNAME)
+ strncpy(ifname, RTA_DATA(a), MIN(RTA_PAYLOAD(a), IFNAMSIZ));
+
+ a = RTA_NEXT(a, la);
+ }
+
+ if (cb(n->nlmsg_type == RTM_NEWLINK, i->ifi_index, i->ifi_type, ifname[0] ? ifname : NULL) < 0)
+ return -1;
+ }
+
+
+ return 0;
+}
+
+
+int ifmonitor_init(int (*cb) (int b, int index, unsigned short type, const char *name)) {
+ return nlapi_register(callback, cb);
+}
+
+#if 0
+
+int test(int b, int index, unsigned short type, const char * name) {
+ printf("CALLBACK %s %s %i %i\n", b ? "new" : "del", name, index, type);
+ return 0;
+}
+
+int main(int argc, char *argv[]) {
+ int r = 1;
+
+ if (nlapi_open(RTMGRP_LINK) < 0)
+ goto finish;
+
+ if (ifmonitor_init(test) < 0)
+ goto finish;
+
+ for (;;)
+ if (nlapi_work() < 0)
+ goto finish;
+
+ r = 0;
+
+finish:
+ nlapi_close();
+
+ return r;
+}
+
+#endif