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 )
0 commit comments