Update copyright dates with scripts/update-copyrights.
[glibc.git] / sysdeps / mach / hurd / if_index.c
blob652149b4d8cf2838bb9a020281d0f28eb2297183
1 /* Find network interface names and index numbers. Hurd version.
2 Copyright (C) 2000-2015 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
19 #include <error.h>
20 #include <net/if.h>
21 #include <string.h>
22 #include <sys/ioctl.h>
23 #include <unistd.h>
25 #include <hurd.h>
26 #include <hurd/ioctl.h>
27 #include <hurd/pfinet.h>
29 /* Return the interface index corresponding to interface IFNAME.
30 On error, return 0. */
31 unsigned int
32 __if_nametoindex (const char *ifname)
34 struct ifreq ifr;
35 int fd = __opensock ();
37 if (fd < 0)
38 return 0;
40 strncpy (ifr.ifr_name, ifname, IFNAMSIZ);
41 if (__ioctl (fd, SIOCGIFINDEX, &ifr) < 0)
43 int saved_errno = errno;
44 __close (fd);
45 if (saved_errno == EINVAL || saved_errno == ENOTTY)
46 __set_errno (ENOSYS);
47 return 0;
49 __close (fd);
50 return ifr.ifr_ifindex;
52 libc_hidden_def (__if_nametoindex)
53 weak_alias (__if_nametoindex, if_nametoindex)
54 libc_hidden_weak (if_nametoindex)
56 /* Free the structure IFN returned by if_nameindex. */
57 void
58 __if_freenameindex (struct if_nameindex *ifn)
60 struct if_nameindex *ptr = ifn;
61 while (ptr->if_name || ptr->if_index)
63 free (ptr->if_name);
64 ++ptr;
66 free (ifn);
68 weak_alias (__if_freenameindex, if_freenameindex)
70 /* Return an array of if_nameindex structures, one for each network
71 interface present, plus one indicating the end of the array. On
72 error, return NULL. */
73 struct if_nameindex *
74 __if_nameindex (void)
76 error_t err = 0;
77 char data[2048];
78 file_t server;
79 int fd = __opensock ();
80 struct ifconf ifc;
81 unsigned int nifs, i;
82 struct if_nameindex *idx = NULL;
84 ifc.ifc_buf = data;
86 if (fd < 0)
87 return NULL;
89 server = _hurd_socket_server (PF_INET, 0);
90 if (server == MACH_PORT_NULL)
91 nifs = 0;
92 else
94 size_t len = sizeof data;
95 err = __pfinet_siocgifconf (server, -1, &ifc.ifc_buf, &len);
96 if (err == MACH_SEND_INVALID_DEST || err == MIG_SERVER_DIED)
98 /* On the first use of the socket server during the operation,
99 allow for the old server port dying. */
100 server = _hurd_socket_server (PF_INET, 1);
101 if (server == MACH_PORT_NULL)
102 goto out;
103 err = __pfinet_siocgifconf (server, -1, &ifc.ifc_buf, &len);
105 if (err)
106 goto out;
108 ifc.ifc_len = len;
109 nifs = len / sizeof (struct ifreq);
112 idx = malloc ((nifs + 1) * sizeof (struct if_nameindex));
113 if (idx == NULL)
115 err = ENOBUFS;
116 goto out;
119 for (i = 0; i < nifs; ++i)
121 struct ifreq *ifr = &ifc.ifc_req[i];
122 idx[i].if_name = __strdup (ifr->ifr_name);
123 if (idx[i].if_name == NULL
124 || __ioctl (fd, SIOCGIFINDEX, ifr) < 0)
126 unsigned int j;
127 err = errno;
129 for (j = 0; j < i; ++j)
130 free (idx[j].if_name);
131 free (idx);
132 idx = NULL;
134 if (err == EINVAL)
135 err = ENOSYS;
136 else if (err == ENOMEM)
137 err = ENOBUFS;
138 goto out;
140 idx[i].if_index = ifr->ifr_ifindex;
143 idx[i].if_index = 0;
144 idx[i].if_name = NULL;
146 out:
147 __close (fd);
148 if (data != ifc.ifc_buf)
149 __vm_deallocate (__mach_task_self (), (vm_address_t) ifc.ifc_buf,
150 ifc.ifc_len);
151 __set_errno (err);
152 return idx;
154 weak_alias (__if_nameindex, if_nameindex)
156 /* Store the name of the interface corresponding to index IFINDEX in
157 IFNAME (which has space for at least IFNAMSIZ characters). Return
158 IFNAME, or NULL on error. */
159 char *
160 __if_indextoname (unsigned int ifindex, char *ifname)
162 struct ifreq ifr;
163 int fd = __opensock ();
165 if (fd < 0)
166 return NULL;
168 ifr.ifr_ifindex = ifindex;
169 if (__ioctl (fd, SIOCGIFNAME, &ifr) < 0)
171 int saved_errno = errno;
172 __close (fd);
173 if (saved_errno == EINVAL || saved_errno == ENOTTY)
174 __set_errno (ENOSYS);
175 else if (saved_errno == ENODEV)
176 __set_errno (ENXIO);
177 return NULL;
179 __close (fd);
180 return strncpy (ifname, ifr.ifr_name, IFNAMSIZ);
182 weak_alias (__if_indextoname, if_indextoname)
183 libc_hidden_weak (if_indextoname)
185 #if 0
186 void
187 internal_function
188 __protocol_available (int *have_inet, int *have_inet6)
190 *have_inet = _hurd_socket_server (PF_INET, 0) != MACH_PORT_NULL;
191 *have_inet6 = _hurd_socket_server (PF_INET6, 0) != MACH_PORT_NULL;
193 #endif