summaryrefslogtreecommitdiff
path: root/src/lib/libc/net/if_nameindex.c
diff options
context:
space:
mode:
authorclaudio <>2015-10-23 13:09:19 +0000
committerclaudio <>2015-10-23 13:09:19 +0000
commitfbbeb39659d02bb968bbfbf1dd7200def1255ebd (patch)
treec1ea5409812cdf61c97e07d7308d28642748532d /src/lib/libc/net/if_nameindex.c
parentc82806a7e5b196fb801dc058799301df205737c7 (diff)
downloadopenbsd-fbbeb39659d02bb968bbfbf1dd7200def1255ebd.tar.gz
openbsd-fbbeb39659d02bb968bbfbf1dd7200def1255ebd.tar.bz2
openbsd-fbbeb39659d02bb968bbfbf1dd7200def1255ebd.zip
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@
Diffstat (limited to 'src/lib/libc/net/if_nameindex.c')
-rw-r--r--src/lib/libc/net/if_nameindex.c93
1 files changed, 46 insertions, 47 deletions
diff --git a/src/lib/libc/net/if_nameindex.c b/src/lib/libc/net/if_nameindex.c
index c5a771869b..11c544b20e 100644
--- a/src/lib/libc/net/if_nameindex.c
+++ b/src/lib/libc/net/if_nameindex.c
@@ -1,7 +1,8 @@
1/* $OpenBSD: if_nameindex.c,v 1.10 2010/09/24 13:29:29 claudio Exp $ */ 1/* $OpenBSD: if_nameindex.c,v 1.11 2015/10/23 13:09:19 claudio Exp $ */
2/* $KAME: if_nameindex.c,v 1.7 2000/11/24 08:17:20 itojun Exp $ */ 2/* $KAME: if_nameindex.c,v 1.7 2000/11/24 08:17:20 itojun Exp $ */
3 3
4/*- 4/*-
5 * Copyright (c) 2015 Claudio Jeker <claudio@openbsd.org>
5 * Copyright (c) 1997, 2000 6 * Copyright (c) 1997, 2000
6 * Berkeley Software Design, Inc. All rights reserved. 7 * Berkeley Software Design, Inc. All rights reserved.
7 * 8 *
@@ -28,11 +29,11 @@
28 29
29#include <sys/types.h> 30#include <sys/types.h>
30#include <sys/socket.h> 31#include <sys/socket.h>
31#include <net/if_dl.h> 32#include <sys/sysctl.h>
32#include <net/if.h> 33#include <net/if.h>
33#include <ifaddrs.h>
34#include <stdlib.h> 34#include <stdlib.h>
35#include <string.h> 35#include <string.h>
36#include <errno.h>
36 37
37/* 38/*
38 * From RFC 2553: 39 * From RFC 2553:
@@ -77,66 +78,62 @@
77struct if_nameindex * 78struct if_nameindex *
78if_nameindex(void) 79if_nameindex(void)
79{ 80{
80 struct ifaddrs *ifaddrs, *ifa; 81 struct if_nameindex_msg *ifnm = NULL;
81 unsigned int ni; 82 struct if_nameindex *ifni = NULL, *ifni2;
82 size_t nbytes;
83 struct if_nameindex *ifni, *ifni2;
84 char *cp; 83 char *cp;
84 size_t nbytes, needed;
85 unsigned int ni, i;
86 int mib[6];
85 87
86 if (getifaddrs(&ifaddrs) < 0) 88 mib[0] = CTL_NET;
87 return(NULL); 89 mib[1] = PF_ROUTE;
90 mib[2] = 0; /* protocol */
91 mib[3] = 0; /* not used */
92 mib[4] = NET_RT_IFNAMES;
93 mib[5] = 0; /* no flags */
94 while (1) {
95 struct if_nameindex_msg *buf = NULL;
88 96
89 /* 97 if (sysctl(mib, 6, NULL, &needed, NULL, 0) == -1)
90 * First, find out how many interfaces there are, and how 98 goto out;
91 * much space we need for the string names. 99 if (needed == 0)
92 */ 100 break;
93 ni = 0; 101 if ((buf = realloc(ifnm, needed)) == NULL)
94 nbytes = 0; 102 goto out;
95 for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) { 103 ifnm = buf;
96 if (ifa->ifa_addr && 104 if (sysctl(mib, 6, ifnm, &needed, NULL, 0) == -1) {
97 ifa->ifa_addr->sa_family == AF_LINK) { 105 if (errno == ENOMEM)
98 nbytes += strlen(ifa->ifa_name) + 1; 106 continue;
99 ni++; 107 goto out;
100 } 108 }
109 break;
101 } 110 }
102 111
103 /* 112 /*
104 * Next, allocate a chunk of memory, use the first part 113 * Allocate a chunk of memory, use the first part for the array of
105 * for the array of structures, and the last part for 114 * structures, and the last part for the strings.
106 * the strings.
107 */ 115 */
108 cp = malloc((ni + 1) * sizeof(struct if_nameindex) + nbytes); 116 ni = needed / sizeof(*ifnm);
109 ifni = (struct if_nameindex *)cp; 117 ifni = calloc(ni + 1, sizeof(struct if_nameindex) + IF_NAMESIZE);
110 if (ifni == NULL) 118 if (ifni == NULL)
111 goto out; 119 goto out;
112 cp += (ni + 1) * sizeof(struct if_nameindex); 120 cp = (char *)(ifni + (ni + 1));
113 121
114 /*
115 * Now just loop through the list of interfaces again,
116 * filling in the if_nameindex array and making copies
117 * of all the strings.
118 */
119 ifni2 = ifni; 122 ifni2 = ifni;
120 for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) { 123 for (i = 0; i < ni; i++) {
121 if (ifa->ifa_addr && 124 ifni2->if_index = ifnm[i].if_index;
122 ifa->ifa_addr->sa_family == AF_LINK) { 125 /* don't care about truncation */
123 ifni2->if_index = 126 strlcpy(cp, ifnm[i].if_name, IF_NAMESIZE);
124 ((struct sockaddr_dl*)ifa->ifa_addr)->sdl_index; 127 ifni2->if_name = cp;
125 ifni2->if_name = cp; 128 ifni2++;
126 nbytes = strlen(ifa->ifa_name) + 1; 129 cp += IF_NAMESIZE;
127 memcpy(cp, ifa->ifa_name, nbytes);
128 ifni2++;
129 cp += nbytes;
130 }
131 } 130 }
132 /* 131 /* Finally, terminate the array. */
133 * Finally, don't forget to terminate the array.
134 */
135 ifni2->if_index = 0; 132 ifni2->if_index = 0;
136 ifni2->if_name = NULL; 133 ifni2->if_name = NULL;
137out: 134out:
138 freeifaddrs(ifaddrs); 135 free(ifnm);
139 return(ifni); 136 return ifni;
140} 137}
141 138
142void 139void
@@ -144,3 +141,5 @@ if_freenameindex(struct if_nameindex *ptr)
144{ 141{
145 free(ptr); 142 free(ptr);
146} 143}
144DEF_WEAK(if_nameindex);
145DEF_WEAK(if_freenameindex);