Updated to fedora-glibc-20041110T0839
[glibc.git] / sysdeps / mach / hurd / if_index.c
blob664a3a1ef3dd54463d2edca1b7de3f87ab6d889c
1 /* Find network interface names and index numbers. Hurd version.
2 Copyright (C) 2000,01,02 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, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
20 #include <error.h>
21 #include <net/if.h>
22 #include <string.h>
23 #include <sys/ioctl.h>
24 #include <unistd.h>
26 #include <hurd.h>
27 #include <hurd/ioctl.h>
28 #include <hurd/pfinet.h>
30 /* Return the interface index corresponding to interface IFNAME.
31 On error, return 0. */
32 unsigned int
33 if_nametoindex (const char *ifname)
35 struct ifreq ifr;
36 int fd = __opensock ();
38 if (fd < 0)
39 return 0;
41 strncpy (ifr.ifr_name, ifname, IFNAMSIZ);
42 if (__ioctl (fd, SIOCGIFINDEX, &ifr) < 0)
44 int saved_errno = errno;
45 __close (fd);
46 if (saved_errno == EINVAL || saved_errno == ENOTTY)
47 __set_errno (ENOSYS);
48 return 0;
50 __close (fd);
51 return ifr.ifr_ifindex;
53 libc_hidden_def (if_nametoindex)
55 /* Free the structure IFN returned by if_nameindex. */
56 void
57 if_freenameindex (struct if_nameindex *ifn)
59 struct if_nameindex *ptr = ifn;
60 while (ptr->if_name || ptr->if_index)
62 if (ptr->if_name)
63 free (ptr->if_name);
64 ++ptr;
66 free (ifn);
69 /* Return an array of if_nameindex structures, one for each network
70 interface present, plus one indicating the end of the array. On
71 error, return NULL. */
72 struct if_nameindex *
73 if_nameindex (void)
75 error_t err = 0;
76 char data[2048];
77 file_t server;
78 int fd = __opensock ();
79 struct ifconf ifc;
80 unsigned int nifs, i;
81 struct if_nameindex *idx = NULL;
83 ifc.ifc_buf = data;
85 if (fd < 0)
86 return NULL;
88 server = _hurd_socket_server (PF_INET, 0);
89 if (server == MACH_PORT_NULL)
90 nifs = 0;
91 else
93 size_t len = sizeof data;
94 err = __pfinet_siocgifconf (server, -1, &ifc.ifc_buf, &len);
95 if (err == MACH_SEND_INVALID_DEST || err == MIG_SERVER_DIED)
97 /* On the first use of the socket server during the operation,
98 allow for the old server port dying. */
99 server = _hurd_socket_server (PF_INET, 1);
100 if (server == MACH_PORT_NULL)
101 goto out;
102 err = __pfinet_siocgifconf (server, -1, &ifc.ifc_buf, &len);
104 if (err)
105 goto out;
107 ifc.ifc_len = len;
108 nifs = len / sizeof (struct ifreq);
111 idx = malloc ((nifs + 1) * sizeof (struct if_nameindex));
112 if (idx == NULL)
114 err = ENOBUFS;
115 goto out;
118 for (i = 0; i < nifs; ++i)
120 struct ifreq *ifr = &ifc.ifc_req[i];
121 idx[i].if_name = __strdup (ifr->ifr_name);
122 if (idx[i].if_name == NULL
123 || __ioctl (fd, SIOCGIFINDEX, ifr) < 0)
125 unsigned int j;
126 err = errno;
128 for (j = 0; j < i; ++j)
129 free (idx[j].if_name);
130 free (idx);
131 idx = NULL;
133 if (err == EINVAL)
134 err = ENOSYS;
135 else if (err == ENOMEM)
136 err = ENOBUFS;
137 goto out;
139 idx[i].if_index = ifr->ifr_ifindex;
142 idx[i].if_index = 0;
143 idx[i].if_name = NULL;
145 out:
146 __close (fd);
147 if (data != ifc.ifc_buf)
148 __vm_deallocate (__mach_task_self (), (vm_address_t) ifc.ifc_buf,
149 ifc.ifc_len);
150 __set_errno (err);
151 return idx;
154 /* Store the name of the interface corresponding to index IFINDEX in
155 IFNAME (which has space for at least IFNAMSIZ characters). Return
156 IFNAME, or NULL on error. */
157 char *
158 if_indextoname (unsigned int ifindex, char *ifname)
160 struct ifreq ifr;
161 int fd = __opensock ();
163 if (fd < 0)
164 return NULL;
166 ifr.ifr_ifindex = ifindex;
167 if (__ioctl (fd, SIOCGIFNAME, &ifr) < 0)
169 int saved_errno = errno;
170 __close (fd);
171 if (saved_errno == EINVAL || saved_errno == ENOTTY)
172 __set_errno (ENOSYS);
173 else if (saved_errno == ENODEV)
174 __set_errno (ENXIO);
175 return NULL;
177 __close (fd);
178 return strncpy (ifname, ifr.ifr_name, IFNAMSIZ);
180 libc_hidden_def (if_indextoname)
182 #if 0
183 void
184 internal_function
185 __protocol_available (int *have_inet, int *have_inet6)
187 *have_inet = _hurd_socket_server (PF_INET, 0) != MACH_PORT_NULL;
188 *have_inet6 = _hurd_socket_server (PF_INET6, 0) != MACH_PORT_NULL;
190 #endif