diff options
-rw-r--r-- | netlink-notify.c | 66 |
1 files changed, 39 insertions, 27 deletions
diff --git a/netlink-notify.c b/netlink-notify.c index 16403ac..b8eddc1 100644 --- a/netlink-notify.c +++ b/netlink-notify.c @@ -12,6 +12,7 @@ #include <stdlib.h> #include <string.h> +#include <arpa/inet.h> #include <ifaddrs.h> #include <linux/if.h> #include <linux/netlink.h> @@ -78,6 +79,25 @@ void free_chain(struct addresses_seen *addresses_seen) { } } +/*** init_address ***/ +void init_address(struct addresses_seen *next) { + next->address = NULL; + next->prefix = 0; + next->next = NULL; +} + +/*** add_address ***/ +void add_address(struct addresses_seen *next, char *address, unsigned char prefix) { + while (next->next != NULL) { + /* just find the last one */ + next = next->next; + } + next->address = address; + next->prefix = prefix; + next->next = malloc(sizeof(struct addresses_seen)); + init_address(next->next); +} + /*** remove_address ***/ void remove_address(struct addresses_seen *next, char *address, unsigned char prefix) { while (next->next != NULL) { @@ -91,6 +111,22 @@ void remove_address(struct addresses_seen *next, char *address, unsigned char pr } } +/*** match_address ***/ +int match_address(struct addresses_seen *next, char *address, unsigned char prefix) { + while (next->next != NULL) { + if (next->address != NULL /* next->address can be NULL if it has been removed from interface */ && + strcmp(next->address, address) == 0 && next->prefix == prefix) { +#if DEBUG + printf("%s: Matched address: %s/%d\n", program, address, prefix); +#endif + return 1; + } + next = next->next; + } + + return 0; +} + /*** newstr_link ***/ char * newstr_link(char *text, char *interface, unsigned int flags) { char *notifystr; @@ -201,8 +237,6 @@ static int msg_handler (struct sockaddr_nl *nl, struct nlmsghdr *msg) { struct rtattr *rth; int rtl; char buf[64]; - struct addresses_seen *next; - unsigned char seen; NotifyNotification *address = NULL; ifa = (struct ifaddrmsg *) NLMSG_DATA (msg); @@ -216,9 +250,7 @@ static int msg_handler (struct sockaddr_nl *nl, struct nlmsghdr *msg) { do { maxinterface++; /* there is no interface with index 0, so this is safe */ notification[maxinterface] = NULL; - addresses_seen[maxinterface].address = NULL; - addresses_seen[maxinterface].prefix = 0; - addresses_seen[maxinterface].next = NULL; + init_address(&addresses_seen[maxinterface]); name[maxinterface] = NULL; } while (maxinterface < ifi->ifi_index); } @@ -247,32 +279,12 @@ static int msg_handler (struct sockaddr_nl *nl, struct nlmsghdr *msg) { && ifa->ifa_scope == RT_SCOPE_UNIVERSE /* no IPv6 scope link */) { inet_ntop(ifa->ifa_family, RTA_DATA (rth), buf, sizeof(buf)); - next = &(addresses_seen[ifi->ifi_index]); - seen = 0; - /* check if we already notified about this address */ - while (next->next != NULL) { - if (next->address != NULL /* next->address can be NULL if it has been removed from interface */ && - strcmp(next->address, buf) == 0 && next->prefix == ifa->ifa_prefixlen) { -#if DEBUG - printf("%s: Already notified about address %s/%d, skipping.\n", program, buf, ifa->ifa_prefixlen); -#endif - seen++; - break; - } - next = next->next; - } - - if (seen) + if (match_address(&addresses_seen[ifi->ifi_index], buf, ifa->ifa_prefixlen)) break; /* add address to struct */ - next->address = strdup(buf); - next->prefix = ifa->ifa_prefixlen; - next->next = malloc(sizeof(struct addresses_seen)); - next->next->address = NULL; - next->next->prefix = 0; - next->next->next = NULL; + add_address(&addresses_seen[ifi->ifi_index], strdup(buf), ifa->ifa_prefixlen); /* display notification */ notifystr = newstr_addr(TEXT_NEWADDR, name[ifi->ifi_index], |