Skip to content

Commit 9d78fbc

Browse files
committed
Implement if_nameindex & if_freenameindex
1 parent 9be1b21 commit 9d78fbc

File tree

6 files changed

+188
-14
lines changed

6 files changed

+188
-14
lines changed

include/net/if.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,9 +218,18 @@ struct sockaddr_hw {
218218
unsigned char shw_addr[8]; /* address */
219219
};
220220

221+
struct if_nameindex {
222+
short if_index; /* 1, 2, ... */
223+
char* if_name; /* null terminated name: "le0", ... */
224+
};
225+
221226
/* Convert an interface name to an index, and vice versa. */
222227
extern unsigned short if_nametoindex (const char *__ifname) __THROW;
223228
extern char *if_indextoname (unsigned short __ifindex, char __ifname[IF_NAMESIZE]) __THROW;
229+
/* Return a list of all interfaces and their indices. */
230+
extern struct if_nameindex *if_nameindex (void) __THROW;
231+
/* Free the data returned from if_nameindex. */
232+
extern void if_freenameindex (struct if_nameindex *__ptr) __THROW;
224233

225234
__END_DECLS
226235

socket/SRCFILES

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ SRCFILES = \
3838
hstrerror.c \
3939
hton.c \
4040
ident_sock.c \
41+
if_freenameindex.c \
4142
if_indextoname.c \
43+
if_nameindex.c \
4244
if_nametoindex.c \
4345
inet_addr.c \
4446
inet_lnaof.c \

socket/if_freenameindex.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#include <net/if.h>
2+
#include <stdlib.h>
3+
4+
__typeof__(if_freenameindex) __if_freenameindex;
5+
6+
void
7+
__if_freenameindex(struct if_nameindex *idx)
8+
{
9+
free(idx);
10+
}
11+
12+
weak_alias (__if_freenameindex, if_freenameindex)

socket/if_indextoname.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,24 @@
77

88
__typeof__(if_indextoname) __if_indextoname;
99

10-
char *
10+
char*
1111
__if_indextoname(unsigned short index, char name[IF_NAMESIZE])
1212
{
1313
struct ifreq ifr;
1414
int fd, r;
1515

1616
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
17-
__set_errno (ENXIO);
18-
return NULL;
19-
}
17+
__set_errno (ENXIO);
18+
return NULL;
19+
}
2020
ifr.ifr_ifindex = index;
2121
r = ioctl(fd, SIOCGIFNAME_ETH, &ifr);
2222
close(fd);
23-
if(!r){
24-
return strncpy(name, ifr.ifr_name, IF_NAMESIZE);
25-
}
26-
__set_errno (ENXIO);
23+
if(!r){
24+
return strncpy(name, ifr.ifr_name, IF_NAMESIZE);
25+
}
26+
__set_errno (ENXIO);
2727
return NULL;
2828
}
29+
2930
weak_alias (__if_indextoname, if_indextoname)

socket/if_nameindex.c

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
/* $KAME: if_nameindex.c,v 1.8 2000/11/24 08:20:01 itojun Exp $ */
2+
3+
/*-
4+
* SPDX-License-Identifier: BSD-1-Clause
5+
*
6+
* Copyright (c) 1997, 2000
7+
* Berkeley Software Design, Inc. All rights reserved.
8+
*
9+
* Redistribution and use in source and binary forms, with or without
10+
* modification, are permitted provided that the following conditions
11+
* are met:
12+
* 1. Redistributions of source code must retain the above copyright
13+
* notice, this list of conditions and the following disclaimer.
14+
*
15+
* THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
16+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18+
* ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
19+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21+
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22+
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23+
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24+
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25+
* SUCH DAMAGE.
26+
*
27+
* BSDI Id: if_nameindex.c,v 2.3 2000/04/17 22:38:05 dab Exp
28+
*/
29+
30+
#include <sys/types.h>
31+
#include <sys/socket.h>
32+
#include <net/if.h>
33+
#include <ifaddrs.h>
34+
#include <stdlib.h>
35+
#include <string.h>
36+
#include <stdio.h>
37+
#include <errno.h>
38+
/*
39+
* From RFC 2553:
40+
*
41+
* 4.3 Return All Interface Names and Indexes
42+
*
43+
* The if_nameindex structure holds the information about a single
44+
* interface and is defined as a result of including the <net/if.h>
45+
* header.
46+
*
47+
* struct if_nameindex {
48+
* unsigned int if_index;
49+
* char *if_name;
50+
* };
51+
*
52+
* The final function returns an array of if_nameindex structures, one
53+
* structure per interface.
54+
*
55+
* struct if_nameindex *if_nameindex(void);
56+
*
57+
* The end of the array of structures is indicated by a structure with
58+
* an if_index of 0 and an if_name of NULL. The function returns a NULL
59+
* pointer upon an error, and would set errno to the appropriate value.
60+
*
61+
* The memory used for this array of structures along with the interface
62+
* names pointed to by the if_name members is obtained dynamically.
63+
* This memory is freed by the next function.
64+
*
65+
* 4.4. Free Memory
66+
*
67+
* The following function frees the dynamic memory that was allocated by
68+
* if_nameindex().
69+
*
70+
* #include <net/if.h>
71+
*
72+
* void if_freenameindex(struct if_nameindex *ptr);
73+
*
74+
* The argument to this function must be a pointer that was returned by
75+
* if_nameindex().
76+
*/
77+
78+
__typeof__(if_nameindex) __if_nameindex;
79+
80+
struct if_nameindex*
81+
__if_nameindex (void)
82+
{
83+
struct ifaddrs *ifaddrs, *ifa;
84+
unsigned int ni;
85+
int nbytes;
86+
struct if_nameindex *ifni, *ifni2;
87+
char *cp;
88+
89+
if (getifaddrs(&ifaddrs) < 0){
90+
__set_errno (ENOBUFS);
91+
return(NULL);
92+
}
93+
/*
94+
* First, find out how many interfaces there are, and how
95+
* much space we need for the string names.
96+
*/
97+
ni = 0;
98+
nbytes = 0;
99+
100+
for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
101+
if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET) {
102+
nbytes += strlen(ifa->ifa_name) + 1;
103+
ni++;
104+
}
105+
}
106+
107+
/*
108+
* Next, allocate a chunk of memory, use the first part
109+
* for the array of structures, and the last part for
110+
* the strings.
111+
*/
112+
cp = malloc((ni + 1) * sizeof(struct if_nameindex) + nbytes);
113+
114+
ifni = (struct if_nameindex *)cp;
115+
if (ifni == NULL){
116+
__set_errno (ENOBUFS);
117+
goto out;
118+
}
119+
cp += (ni + 1) * sizeof(struct if_nameindex);
120+
/*
121+
* Now just loop through the list of interfaces again,
122+
* filling in the if_nameindex array and making copies
123+
* of all the strings.
124+
*/
125+
ifni2 = ifni;
126+
for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
127+
if (ifa->ifa_addr &&
128+
ifa->ifa_addr->sa_family == AF_INET) {
129+
130+
ifni2->if_index = if_nametoindex(ifa->ifa_name);
131+
132+
ifni2->if_name = cp;
133+
strcpy(cp, ifa->ifa_name);
134+
ifni2++;
135+
cp += strlen(cp) + 1;
136+
}
137+
}
138+
139+
/*
140+
* Finally, don't forget to terminate the array.
141+
*/
142+
ifni2->if_index = 0;
143+
ifni2->if_name = NULL;
144+
out:
145+
freeifaddrs(ifaddrs);
146+
return(ifni);
147+
}
148+
149+
weak_alias (__if_nameindex, if_nameindex)

socket/if_nametoindex.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,23 @@
88
__typeof__(if_nametoindex) __if_nametoindex;
99

1010
unsigned short
11-
if_nametoindex(const char *name)
11+
__if_nametoindex(const char *name)
1212
{
1313
struct ifreq ifr;
1414
int fd, r;
1515

1616
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
1717
__set_errno (ENODEV);
1818
return 0;
19-
}
19+
}
2020
strlcpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
2121
r = ioctl(fd, SIOCGIFINDEX, &ifr);
2222
close(fd);
23-
if(!r){
24-
return ifr.ifr_ifindex;
25-
}
26-
__set_errno (ENODEV);
23+
if(!r){
24+
return ifr.ifr_ifindex;
25+
}
26+
__set_errno (ENODEV);
2727
return 0;
2828
}
29+
2930
weak_alias (__if_nametoindex, if_nametoindex)

0 commit comments

Comments
 (0)