Switch if_nameindex(3) to use the new NET_RT_IFNAMES sysctl to get the
authorclaudio <claudio@openbsd.org>
Fri, 23 Oct 2015 13:09:19 +0000 (13:09 +0000)
committerclaudio <claudio@openbsd.org>
Fri, 23 Oct 2015 13:09:19 +0000 (13:09 +0000)
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
lib/libc/net/if_indextoname.c
lib/libc/net/if_nameindex.c
lib/libc/net/if_nametoindex.c

index 0c18300..95f47e4 100644 (file)
@@ -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 <guenther@openbsd.org>
  *
@@ -21,8 +21,8 @@
 #include_next <net/if.h>
 
 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_ */
index f1c6596..affa425 100644 (file)
@@ -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 <claudio@openbsd.org>
  * Copyright (c) 1997, 2000
  *     Berkeley Software Design, Inc.  All rights reserved.
  *
@@ -28,9 +29,7 @@
 
 #include <sys/types.h>
 #include <sys/socket.h>
-#include <net/if_dl.h>
 #include <net/if.h>
-#include <ifaddrs.h>
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
 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);
index c5a7718..11c544b 100644 (file)
@@ -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 <claudio@openbsd.org>
  * Copyright (c) 1997, 2000
  *     Berkeley Software Design, Inc.  All rights reserved.
  *
 
 #include <sys/types.h>
 #include <sys/socket.h>
-#include <net/if_dl.h>
+#include <sys/sysctl.h>
 #include <net/if.h>
-#include <ifaddrs.h>
 #include <stdlib.h>
 #include <string.h>
+#include <errno.h>
 
 /*
  * From RFC 2553:
 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);
index 8b2cbf7..7a4492e 100644 (file)
@@ -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 <claudio@openbsd.org>
  * Copyright (c) 1997, 2000
  *     Berkeley Software Design, Inc.  All rights reserved.
  *
@@ -29,8 +30,6 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <net/if.h>
-#include <net/if_dl.h>
-#include <ifaddrs.h>
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
 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);