From 864f048c25c0b067398902f7efb4f016b8120bd6 Mon Sep 17 00:00:00 2001 From: claudio Date: Fri, 23 Oct 2015 13:09:19 +0000 Subject: [PATCH] Switch if_nameindex(3) to use the new NET_RT_IFNAMES sysctl to get the list of interface names. At the same time switch if_nametoindex(3) and if_indextoname(3) to use if_nameindex(3) instead of getifaddrs(3). if_nameindex(3) exposes much less then getifaddrs(3) and is allowed by pledge(2). With and OK deraadt@ --- lib/libc/hidden/net/if.h | 6 +-- lib/libc/net/if_indextoname.c | 37 ++++++-------- lib/libc/net/if_nameindex.c | 93 +++++++++++++++++------------------ lib/libc/net/if_nametoindex.c | 31 +++++------- 4 files changed, 76 insertions(+), 91 deletions(-) diff --git a/lib/libc/hidden/net/if.h b/lib/libc/hidden/net/if.h index 0c183004b8a..95f47e47183 100644 --- a/lib/libc/hidden/net/if.h +++ b/lib/libc/hidden/net/if.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if.h,v 1.1 2015/09/14 10:47:01 guenther Exp $ */ +/* $OpenBSD: if.h,v 1.2 2015/10/23 13:09:19 claudio Exp $ */ /* * Copyright (c) 2015 Philip Guenther * @@ -21,8 +21,8 @@ #include_next PROTO_NORMAL(if_indextoname); -PROTO_DEPRECATED(if_freenameindex); -PROTO_DEPRECATED(if_nameindex); +PROTO_NORMAL(if_freenameindex); +PROTO_NORMAL(if_nameindex); PROTO_NORMAL(if_nametoindex); #endif /* _LIBC_NET_IF_H_ */ diff --git a/lib/libc/net/if_indextoname.c b/lib/libc/net/if_indextoname.c index f1c65966dfd..affa42551e9 100644 --- a/lib/libc/net/if_indextoname.c +++ b/lib/libc/net/if_indextoname.c @@ -1,7 +1,8 @@ -/* $OpenBSD: if_indextoname.c,v 1.10 2015/09/14 10:47:01 guenther Exp $ */ +/* $OpenBSD: if_indextoname.c,v 1.11 2015/10/23 13:09:19 claudio Exp $ */ /* $KAME: if_indextoname.c,v 1.6 2000/11/07 22:33:25 jinmei Exp $ */ /*- + * Copyright (c) 2015 Claudio Jeker * Copyright (c) 1997, 2000 * Berkeley Software Design, Inc. All rights reserved. * @@ -28,9 +29,7 @@ #include #include -#include #include -#include #include #include #include @@ -59,29 +58,21 @@ char * if_indextoname(unsigned int ifindex, char *ifname) { - struct ifaddrs *ifaddrs, *ifa; - int error = 0; + struct if_nameindex *ifni, *ifni2; - if (getifaddrs(&ifaddrs) < 0) - return(NULL); /* getifaddrs properly set errno */ + if ((ifni = if_nameindex()) == NULL) + return NULL; - for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) { - if (ifa->ifa_addr && - ifa->ifa_addr->sa_family == AF_LINK && - ifindex == ((struct sockaddr_dl*)ifa->ifa_addr)->sdl_index) - break; + for (ifni2 = ifni; ifni2->if_index != 0; ifni2++) { + if (ifni2->if_index == ifindex) { + strlcpy(ifname, ifni2->if_name, IFNAMSIZ); + if_freenameindex(ifni); + return ifname; + } } - if (ifa == NULL) { - error = ENXIO; - ifname = NULL; - } - else - strlcpy(ifname, ifa->ifa_name, IFNAMSIZ); - - freeifaddrs(ifaddrs); - - errno = error; - return(ifname); + if_freenameindex(ifni); + errno = ENXIO; + return NULL; } DEF_WEAK(if_indextoname); diff --git a/lib/libc/net/if_nameindex.c b/lib/libc/net/if_nameindex.c index c5a771869bc..11c544b20ee 100644 --- a/lib/libc/net/if_nameindex.c +++ b/lib/libc/net/if_nameindex.c @@ -1,7 +1,8 @@ -/* $OpenBSD: if_nameindex.c,v 1.10 2010/09/24 13:29:29 claudio Exp $ */ +/* $OpenBSD: if_nameindex.c,v 1.11 2015/10/23 13:09:19 claudio Exp $ */ /* $KAME: if_nameindex.c,v 1.7 2000/11/24 08:17:20 itojun Exp $ */ /*- + * Copyright (c) 2015 Claudio Jeker * Copyright (c) 1997, 2000 * Berkeley Software Design, Inc. All rights reserved. * @@ -28,11 +29,11 @@ #include #include -#include +#include #include -#include #include #include +#include /* * From RFC 2553: @@ -77,66 +78,62 @@ struct if_nameindex * if_nameindex(void) { - struct ifaddrs *ifaddrs, *ifa; - unsigned int ni; - size_t nbytes; - struct if_nameindex *ifni, *ifni2; + struct if_nameindex_msg *ifnm = NULL; + struct if_nameindex *ifni = NULL, *ifni2; char *cp; + size_t nbytes, needed; + unsigned int ni, i; + int mib[6]; - if (getifaddrs(&ifaddrs) < 0) - return(NULL); + mib[0] = CTL_NET; + mib[1] = PF_ROUTE; + mib[2] = 0; /* protocol */ + mib[3] = 0; /* not used */ + mib[4] = NET_RT_IFNAMES; + mib[5] = 0; /* no flags */ + while (1) { + struct if_nameindex_msg *buf = NULL; - /* - * First, find out how many interfaces there are, and how - * much space we need for the string names. - */ - ni = 0; - nbytes = 0; - for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) { - if (ifa->ifa_addr && - ifa->ifa_addr->sa_family == AF_LINK) { - nbytes += strlen(ifa->ifa_name) + 1; - ni++; + if (sysctl(mib, 6, NULL, &needed, NULL, 0) == -1) + goto out; + if (needed == 0) + break; + if ((buf = realloc(ifnm, needed)) == NULL) + goto out; + ifnm = buf; + if (sysctl(mib, 6, ifnm, &needed, NULL, 0) == -1) { + if (errno == ENOMEM) + continue; + goto out; } + break; } /* - * Next, allocate a chunk of memory, use the first part - * for the array of structures, and the last part for - * the strings. + * Allocate a chunk of memory, use the first part for the array of + * structures, and the last part for the strings. */ - cp = malloc((ni + 1) * sizeof(struct if_nameindex) + nbytes); - ifni = (struct if_nameindex *)cp; + ni = needed / sizeof(*ifnm); + ifni = calloc(ni + 1, sizeof(struct if_nameindex) + IF_NAMESIZE); if (ifni == NULL) goto out; - cp += (ni + 1) * sizeof(struct if_nameindex); + cp = (char *)(ifni + (ni + 1)); - /* - * Now just loop through the list of interfaces again, - * filling in the if_nameindex array and making copies - * of all the strings. - */ ifni2 = ifni; - for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) { - if (ifa->ifa_addr && - ifa->ifa_addr->sa_family == AF_LINK) { - ifni2->if_index = - ((struct sockaddr_dl*)ifa->ifa_addr)->sdl_index; - ifni2->if_name = cp; - nbytes = strlen(ifa->ifa_name) + 1; - memcpy(cp, ifa->ifa_name, nbytes); - ifni2++; - cp += nbytes; - } + for (i = 0; i < ni; i++) { + ifni2->if_index = ifnm[i].if_index; + /* don't care about truncation */ + strlcpy(cp, ifnm[i].if_name, IF_NAMESIZE); + ifni2->if_name = cp; + ifni2++; + cp += IF_NAMESIZE; } - /* - * Finally, don't forget to terminate the array. - */ + /* Finally, terminate the array. */ ifni2->if_index = 0; ifni2->if_name = NULL; out: - freeifaddrs(ifaddrs); - return(ifni); + free(ifnm); + return ifni; } void @@ -144,3 +141,5 @@ if_freenameindex(struct if_nameindex *ptr) { free(ptr); } +DEF_WEAK(if_nameindex); +DEF_WEAK(if_freenameindex); diff --git a/lib/libc/net/if_nametoindex.c b/lib/libc/net/if_nametoindex.c index 8b2cbf743f5..7a4492e37d8 100644 --- a/lib/libc/net/if_nametoindex.c +++ b/lib/libc/net/if_nametoindex.c @@ -1,7 +1,8 @@ -/* $OpenBSD: if_nametoindex.c,v 1.9 2015/09/14 10:47:01 guenther Exp $ */ +/* $OpenBSD: if_nametoindex.c,v 1.10 2015/10/23 13:09:19 claudio Exp $ */ /* $KAME: if_nametoindex.c,v 1.5 2000/11/24 08:04:40 itojun Exp $ */ /*- + * Copyright (c) 2015 Claudio Jeker * Copyright (c) 1997, 2000 * Berkeley Software Design, Inc. All rights reserved. * @@ -29,8 +30,6 @@ #include #include #include -#include -#include #include #include #include @@ -57,26 +56,22 @@ unsigned int if_nametoindex(const char *ifname) { - struct ifaddrs *ifaddrs, *ifa; - unsigned int ni; + struct if_nameindex *ifni, *ifni2; + unsigned int index; - if (getifaddrs(&ifaddrs) < 0) + if ((ifni = if_nameindex()) == NULL) return(0); - ni = 0; - - for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) { - if (ifa->ifa_addr && - ifa->ifa_addr->sa_family == AF_LINK && - strcmp(ifa->ifa_name, ifname) == 0) { - ni = ((struct sockaddr_dl*)ifa->ifa_addr)->sdl_index; - break; + for (ifni2 = ifni; ifni2->if_index != 0; ifni2++) { + if (strcmp(ifni2->if_name, ifname) == 0) { + index = ifni2->if_index; + if_freenameindex(ifni); + return index; } } - freeifaddrs(ifaddrs); - if (!ni) - errno = ENXIO; - return(ni); + if_freenameindex(ifni); + errno = ENXIO; + return 0; } DEF_WEAK(if_nametoindex); -- 2.20.1