1. Bryan O'Sullivan
  2. netplug

Commits

Bryan O'Sullivan  committed ffe920b

Add interface handling callback.
Early days, but we're getting there.

  • Participants
  • Parent commits 718753e
  • Branches default

Comments (0)

Files changed (3)

File if_info.c

View file
 #include "netplug.h"
 
 
-static void
+void
 parse_rtattrs(struct rtattr *tb[], int max, struct rtattr *rta, int len)
 {
+    memset(tb, 0, sizeof(tb) * (max + 1));
+
     while (RTA_OK(rta, len)) {
 	if (rta->rta_type <= max)
 	    tb[rta->rta_type] = rta;
 
 int if_info_save_interface(struct nlmsghdr *hdr, void *arg)
 {
+    struct rtattr *attrs[IFLA_MAX + 1];
+    struct ifinfomsg *info = NLMSG_DATA(hdr);
+
+    parse_rtattrs(attrs, IFLA_MAX, IFLA_RTA(info), IFLA_PAYLOAD(hdr));
+
+    return if_info_update_interface(hdr, attrs) ? 0 : -1;
+}
+
+
+struct if_info *
+if_info_get_interface(struct nlmsghdr *hdr, struct rtattr *attrs[])
+{
     if (hdr->nlmsg_type != RTM_NEWLINK) {
-	return 0;
+	return NULL;
     }
 
     struct ifinfomsg *info = NLMSG_DATA(hdr);
 
     if (hdr->nlmsg_len < NLMSG_LENGTH(sizeof(info))) {
-	return -1;
+	return NULL;
     }
 
-    struct rtattr *attrs[IFLA_MAX + 1];
-
-    memset(attrs, 0, sizeof(attrs));
-    parse_rtattrs(attrs, IFLA_MAX, IFLA_RTA(info), IFLA_PAYLOAD(hdr));
-
     if (attrs[IFLA_IFNAME] == NULL) {
-	return 0;
+	return NULL;
     }
     
     int x = info->ifi_index & 0xf;
 	i->index = info->ifi_index;
 	*ip = i;
     }
+    return i;
+}
 
+
+struct if_info *
+if_info_update_interface(struct nlmsghdr *hdr, struct rtattr *attrs[])
+{
+    struct ifinfomsg *info = NLMSG_DATA(hdr);
+    struct if_info *i;
+
+    if ((i = if_info_get_interface(hdr, attrs)) == NULL) {
+	return NULL;
+    }
+    
     i->type = info->ifi_type;
     i->flags = info->ifi_flags;
 
     strcpy(i->name, RTA_DATA(attrs[IFLA_IFNAME]));
     printf("info for %s\n", i->name);
     
-    return 0;
+    return i;
 }
 
 

File main.c

View file
+#include <stdio.h>
+#include <stdlib.h>
+
 #include "netplug.h"
 
 
+int handle_interface(struct nlmsghdr *hdr, void *arg)
+{
+    if (hdr->nlmsg_type != RTM_NEWLINK && hdr->nlmsg_type != RTM_DELLINK) {
+	return 0;
+    }
+    
+    struct ifinfomsg *info = NLMSG_DATA(hdr);
+    int len = hdr->nlmsg_len - NLMSG_LENGTH(sizeof(*info));
+
+    if (len < 0) {
+	return -1;
+    }
+    
+    struct rtattr *attrs[IFLA_MAX + 1];
+
+    parse_rtattrs(attrs, IFLA_MAX, IFLA_RTA(info), len);
+
+    if (attrs[IFLA_IFNAME] == NULL) {
+	fprintf(stderr, "No interface name\n");
+	exit(1);
+    }
+    
+    struct if_info *i;
+    
+    if ((i = if_info_get_interface(hdr, attrs)) == NULL) {
+	return -1;
+    }
+
+    char *name = RTA_DATA(attrs[IFLA_IFNAME]);
+
+    printf("%s: flags 0x%08x -> 0x%08x\n", name, i->flags, info->ifi_flags);
+
+    if_info_update_interface(hdr, attrs);
+    
+    return 0;
+}
+
+
 int
 main(int argc, char *argv[])
 {
     int fd = netlink_open();
     netlink_request_dump(fd);
     netlink_receive_dump(fd, if_info_save_interface, NULL);
-    netlink_listen(fd, NULL, NULL);
+    netlink_listen(fd, handle_interface, NULL);
     return fd ? 0 : 0;
 }
 

File netplug.h

View file
 void netlink_receive_dump(int fd, netlink_callback callback, void *arg);
 void netlink_listen(int fd, netlink_callback callback, void *arg);
 
+struct if_info *if_info_get_interface(struct nlmsghdr *hdr,
+				      struct rtattr *attrs[]);
+struct if_info *if_info_update_interface(struct nlmsghdr *hdr,
+					 struct rtattr *attrs[]);
 int if_info_save_interface(struct nlmsghdr *hdr, void *arg);
+void parse_rtattrs(struct rtattr *tb[], int max, struct rtattr *rta, int len);
 
 void *xmalloc(size_t n);