]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/unix/sysv/linux/if_index.c
Update.
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / if_index.c
1 /* Copyright (C) 1997 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
8
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public
15 License along with the GNU C Library; see the file COPYING.LIB. If
16 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
17 Cambridge, MA 02139, USA. */
18
19 #include <string.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <net/if.h>
23
24 #define IF_INET6_FILENAME "/proc/net/if_inet6"
25
26 /* /proc/net/if_inet6 contains lines that look like this:
27 *
28 * fe8000000000000000000000836fc168 0b 00 20 80 sit7
29 *
30 * | | | | | |
31 * address --' | | | | |
32 * index --------' | | | |
33 * prefix length ---' | | |
34 * scope --------------' | |
35 * flags -----------------' |
36 * name -------------------------'
37 *
38 */
39
40 static int get_one_interface(FILE *fd, char *interface, int iflen, unsigned int *index)
41 {
42 char buffer[80];
43 static char seps[] = " \012";
44 char *c = buffer;
45 char *sp;
46 if (!fgets(buffer, 80, fd))
47 return 1;
48 if (strtok_r(buffer, seps, &sp) == NULL) return 1;
49 if (c = strtok_r(NULL, seps, &sp), c == NULL) return 1;
50 *index = strtoul(c, NULL, 16);
51 if (strtok_r(NULL, seps, &sp) == NULL) return 1;
52 if (strtok_r(NULL, seps, &sp) == NULL) return 1;
53 if (strtok_r(NULL, seps, &sp) == NULL) return 1;
54 if (c = strtok_r(NULL, seps, &sp), c == NULL) return 1;
55 strncpy(interface, c, iflen);
56 return 0;
57 }
58
59 unsigned int if_nametoindex(const char *ifname)
60 {
61 FILE *fd = fopen(IF_INET6_FILENAME, "r");
62 char this_ifname[IFNAMSIZ];
63 unsigned int this_index;
64 if (!fd) return 0;
65 while (get_one_interface(fd, this_ifname, IFNAMSIZ, &this_index) == 0) {
66 if (!strcmp(this_ifname, ifname)) {
67 fclose(fd);
68 return this_index;
69 }
70 }
71 fclose(fd);
72 return 0;
73 }
74
75 char *if_indextoname(unsigned int ifindex, char *ifname)
76 {
77 FILE *fd = fopen(IF_INET6_FILENAME, "r");
78 unsigned int this_index;
79 if (!fd) return NULL;
80 while (get_one_interface(fd, ifname, IFNAMSIZ, &this_index) == 0) {
81 if (this_index == ifindex) {
82 fclose(fd);
83 return ifname;
84 }
85 }
86 fclose(fd);
87 return NULL;
88 }
89
90 void if_freenameindex(struct if_nameindex *ifn)
91 {
92 struct if_nameindex *ptr = ifn;
93 while (ptr->if_name || ptr->if_index)
94 {
95 if (ptr->if_name)
96 free(ptr->if_name);
97 ptr++;
98 }
99 free(ifn);
100 }
101
102 struct if_nameindex *if_nameindex(void)
103 {
104 FILE *fd = fopen(IF_INET6_FILENAME, "r");
105 struct if_nameindex *ifn = NULL;
106 int nifs = 0;
107 if (!fd) return NULL;
108 do
109 {
110 struct if_nameindex *newifn;
111 nifs++;
112 newifn = realloc(ifn, nifs*sizeof(struct if_nameindex));
113 if (!newifn)
114 {
115 /* We ran out of memory. */
116 if (--nifs)
117 {
118 free(ifn[nifs-1].if_name);
119 ifn[nifs-1].if_name = 0;
120 ifn[nifs-1].if_index = 0;
121 if_freenameindex(ifn);
122 }
123 return NULL;
124 }
125 ifn = newifn;
126 ifn[nifs-1].if_index = 0;
127 ifn[nifs-1].if_name = malloc(IFNAMSIZ);
128 if (ifn[nifs-1].if_name == NULL)
129 {
130 if_freenameindex(ifn);
131 return NULL;
132 }
133 }
134 while (get_one_interface(fd, ifn[nifs-1].if_name, IFNAMSIZ,
135 &ifn[nifs-1].if_index) == 0);
136 free(ifn[nifs-1].if_name);
137 ifn[nifs-1].if_name = NULL;
138 fclose(fd);
139 return ifn;
140 }