From 72c71d35ac7e9ff91ce577257f8d9161ab7d0ee0 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 1 Jun 2020 14:50:40 +0200 Subject: [PATCH] gluon-mesh-babel: clean up link-local address handling - Rename obtain_if_addr() to get_linklocal_address() - Pass buffer of size INET6_ADDRSTRLEN instead of the oversized NI_MAXHOST - Check if an address is link-local before converting to a string - Replace an incorrect use of strncmp() with strcmp() - Return status to caller - Streamline control flow While we're at it, the function handle_neighbour(), which is one of the callers of get_linklocal_address() is slightly cleaned up as well. --- package/gluon-mesh-babel/src/respondd.c | 65 +++++++++++++------------ 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/package/gluon-mesh-babel/src/respondd.c b/package/gluon-mesh-babel/src/respondd.c index 96195d89..124500a2 100644 --- a/package/gluon-mesh-babel/src/respondd.c +++ b/package/gluon-mesh-babel/src/respondd.c @@ -62,38 +62,40 @@ static struct babelhelper_ctx bhelper_ctx = {}; -static void obtain_if_addr(const char *ifname, char *lladdr) { +static bool get_linklocal_address(const char *ifname, char lladdr[INET6_ADDRSTRLEN]) { struct ifaddrs *ifaddr, *ifa; - int family, n; + bool ret = false; if (getifaddrs(&ifaddr) == -1) { perror("getifaddrs"); - exit(EXIT_FAILURE); + return false; } - for (ifa = ifaddr, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++) { - if (ifa->ifa_addr == NULL) + for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { + if (!ifa->ifa_addr) continue; - family = ifa->ifa_addr->sa_family; + if (ifa->ifa_addr->sa_family != AF_INET6) + continue; - if ( (family == AF_INET6) && ( ! strncmp(ifname, ifa->ifa_name, strlen(ifname)) ) ) { - char lhost[INET6_ADDRSTRLEN]; - struct in6_addr *address = &((struct sockaddr_in6*)ifa->ifa_addr)->sin6_addr; - if (inet_ntop(AF_INET6, address, lhost, INET6_ADDRSTRLEN) == NULL) { - fprintf(stderr, "obtain_if_addr: could not convert ip to string\n"); - goto cleanup; - } + if (strcmp(ifname, ifa->ifa_name) != 0) + continue; - if (! strncmp("fe80:", lhost, 5) ) { - snprintf( lladdr, NI_MAXHOST, "%s", lhost ); - goto cleanup; - } + const struct in6_addr *address = &((const struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr; + if (!IN6_IS_ADDR_LINKLOCAL(address)) + continue; + + if (!inet_ntop(AF_INET6, address, lladdr, INET6_ADDRSTRLEN)) { + perror("inet_ntop"); + continue; } + + ret = true; + break; } -cleanup: freeifaddrs(ifaddr); + return ret; } @@ -164,9 +166,10 @@ static bool interface_file_exists(const char *ifname, const char *name) { static void mesh_add_if(const char *ifname, struct json_object *wireless, struct json_object *tunnel, struct json_object *other) { - char str_ip[NI_MAXHOST] = {}; + char str_ip[INET6_ADDRSTRLEN]; - obtain_if_addr(ifname, str_ip); + if (!get_linklocal_address(ifname, str_ip)) + return; struct json_object *address = json_object_new_string(str_ip); @@ -193,24 +196,26 @@ static bool handle_neighbour(char **data, void *obj) { if (data[REACH]) json_object_object_add(neigh, "reachability", json_object_new_double(strtod(data[REACH], NULL))); - struct json_object *nif = 0; - if (data[IF] && !json_object_object_get_ex(obj, data[IF], &nif)) { - char str_ip[NI_MAXHOST] = {}; - obtain_if_addr( (const char*)data[IF], str_ip ); + if (!data[IF]) + return true; + + struct json_object *nif; + if (!json_object_object_get_ex(obj, data[IF], &nif)) { + char str_ip[INET6_ADDRSTRLEN]; nif = json_object_new_object(); - json_object_object_add(nif, "ll-addr", json_object_new_string(str_ip)); + if (get_linklocal_address(data[IF], str_ip)) + json_object_object_add(nif, "ll-addr", json_object_new_string(str_ip)); + json_object_object_add(nif, "protocol", json_object_new_string("babel")); json_object_object_add(obj, data[IF], nif); - } - struct json_object *neighborcollector = 0; - if (!json_object_object_get_ex(nif, "neighbours", &neighborcollector)) { - neighborcollector = json_object_new_object(); - json_object_object_add(nif, "neighbours", neighborcollector); + json_object_object_add(nif, "neighbours", json_object_new_object()); } + struct json_object *neighborcollector; + json_object_object_get_ex(nif, "neighbours", &neighborcollector); json_object_object_add(neighborcollector, data[ADDRESS], neigh); }