Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/lib/libc/net/if_nameindex.c
39476 views
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_dl.h>
33
#include <net/if.h>
34
#include <ifaddrs.h>
35
#include <stdlib.h>
36
#include <string.h>
37
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
struct if_nameindex *
79
if_nameindex(void)
80
{
81
struct ifaddrs *ifaddrs, *ifa;
82
unsigned int ni;
83
int nbytes;
84
struct if_nameindex *ifni, *ifni2;
85
char *cp;
86
87
if (getifaddrs(&ifaddrs) < 0)
88
return(NULL);
89
90
/*
91
* First, find out how many interfaces there are, and how
92
* much space we need for the string names.
93
*/
94
ni = 0;
95
nbytes = 0;
96
for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
97
if (ifa->ifa_addr &&
98
ifa->ifa_addr->sa_family == AF_LINK) {
99
nbytes += strlen(ifa->ifa_name) + 1;
100
ni++;
101
}
102
}
103
104
/*
105
* Next, allocate a chunk of memory, use the first part
106
* for the array of structures, and the last part for
107
* the strings.
108
*/
109
cp = malloc((ni + 1) * sizeof(struct if_nameindex) + nbytes);
110
ifni = (struct if_nameindex *)cp;
111
if (ifni == NULL)
112
goto out;
113
cp += (ni + 1) * sizeof(struct if_nameindex);
114
115
/*
116
* Now just loop through the list of interfaces again,
117
* filling in the if_nameindex array and making copies
118
* of all the strings.
119
*/
120
ifni2 = ifni;
121
for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
122
if (ifa->ifa_addr &&
123
ifa->ifa_addr->sa_family == AF_LINK) {
124
ifni2->if_index =
125
LLINDEX((struct sockaddr_dl*)ifa->ifa_addr);
126
ifni2->if_name = cp;
127
strcpy(cp, ifa->ifa_name);
128
ifni2++;
129
cp += strlen(cp) + 1;
130
}
131
}
132
/*
133
* Finally, don't forget to terminate the array.
134
*/
135
ifni2->if_index = 0;
136
ifni2->if_name = NULL;
137
out:
138
freeifaddrs(ifaddrs);
139
return(ifni);
140
}
141
142
void
143
if_freenameindex(struct if_nameindex *ptr)
144
{
145
free(ptr);
146
}
147
148