From 5bd5e35748407739264507f39555149a4b337248 Mon Sep 17 00:00:00 2001 From: Mark Kettenis Date: Sun, 1 Jul 2001 12:06:11 +0000 Subject: [PATCH] * sysdeps/mach/hurd/if_index.c: Redone to use new interfaces in the Hurd pfinet server, using equivalent code from the Linux version in sysdeps/unix/sysv/linux/if_index.c. In detail: Include , , , and . Don't include and anymore. (if_nametoindex): New implementation using SIOCGIFINDEX. (if_freenameindex): Straight copy of the Linux version. (if_nameindex): New implementation based on pfinet_siocgifconf and SIOCGIFINDEX. (if_indextoname): New implementation using SIOCGIFNAME. (map_interfaces): Function removed. From Marcus Brinkmann . 2001-07-01 Mark Kettenis * sysdeps/mach/hurd/if_index.c: Redone to use new interfaces in the Hurd pfinet server, using equivalent code from the Linux version in sysdeps/unix/sysv/linux/if_index.c. In detail: Include , , , and . Don't include and anymore. (if_nametoindex): New implementation using SIOCGIFINDEX. (if_freenameindex): Straight copy of the Linux version. (if_nameindex): New implementation based on pfinet_siocgifconf and SIOCGIFINDEX. (if_indextoname): New implementation using SIOCGIFNAME. (map_interfaces): Function removed. From Marcus Brinkmann . --- ChangeLog | 16 ++ sysdeps/mach/hurd/if_index.c | 356 +++++++++++++++++++++++-------------------- 2 files changed, 205 insertions(+), 167 deletions(-) rewrite sysdeps/mach/hurd/if_index.c (63%) diff --git a/ChangeLog b/ChangeLog index 884a20f3ec..f7d756e2e5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2001-07-01 Mark Kettenis + + * sysdeps/mach/hurd/if_index.c: Redone to use new interfaces in + the Hurd pfinet server, using equivalent code from the Linux + version in sysdeps/unix/sysv/linux/if_index.c. In detail: + Include , , , and + . Don't include and + anymore. + (if_nametoindex): New implementation using SIOCGIFINDEX. + (if_freenameindex): Straight copy of the Linux version. + (if_nameindex): New implementation based on pfinet_siocgifconf and + SIOCGIFINDEX. + (if_indextoname): New implementation using SIOCGIFNAME. + (map_interfaces): Function removed. + From Marcus Brinkmann . + 2001-06-30 Jakub Jelinek * sysdeps/powerpc/dl-machine.c (__elf_preferred_address): Prefer diff --git a/sysdeps/mach/hurd/if_index.c b/sysdeps/mach/hurd/if_index.c dissimilarity index 63% index 9870e44715..ca3e2d93a6 100644 --- a/sysdeps/mach/hurd/if_index.c +++ b/sysdeps/mach/hurd/if_index.c @@ -1,167 +1,189 @@ -/* Find network interface names and index numbers. Hurd version. - Copyright (C) 2000 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include -#include -#include -#include -#include - -static int -map_interfaces (int domain, - unsigned int *idxp, - int (*counted_initializer) (unsigned int count, - size_t nameslen), - int (*iterator) (const char *)) -{ - static const char ifopt[] = "--interface="; - file_t server; - char optsbuf[512], *opts = optsbuf, *p; - size_t optslen = sizeof optsbuf; - error_t err; - - /* Find the socket server for DOMAIN. */ - server = _hurd_socket_server (domain, 0); - if (server == MACH_PORT_NULL) - return 0; - - err = __file_get_fs_options (server, &opts, &optslen); - if (err == MACH_SEND_INVALID_DEST || err == MIG_SERVER_DIED) - { - /* On the first use of the socket server during the operation, - allow for the old server port dying. */ - server = _hurd_socket_server (domain, 1); - if (server == MACH_PORT_NULL) - return -1; - err = __file_get_fs_options (server, &opts, &optslen); - } - if (err) - return __hurd_fail (err), 0; - - if (counted_initializer) - { - unsigned int count = 0; - size_t nameslen = 0; - p = memchr (opts, '\0', optslen); - while (p != 0) - { - char *end = memchr (p + 1, '\0', optslen - (p - opts)); - if (end == 0) - break; - if (optslen - (p - opts) >= sizeof ifopt - && !memcmp (p + 1, ifopt, sizeof ifopt - 1)) - { - size_t len = end + 1 - (p + sizeof ifopt); - nameslen += len > IFNAMSIZ+1 ? IFNAMSIZ+1 : len; - ++count; - } - p = end; - } - - if ((*counted_initializer) (count, nameslen)) - return 0; - } - - *idxp = 0; - for (p = memchr (opts, '\0', optslen); p != 0; - p = memchr (p + 1, '\0', optslen - (p - opts))) - { - ++*idxp; - if (optslen - (p - opts) >= sizeof ifopt - && !memcmp (p + 1, ifopt, sizeof ifopt - 1) - && (*iterator) (p + sizeof ifopt)) - break; - } - - if (opts != optsbuf) - __munmap (opts, optslen); - - return 1; -} - -unsigned int -if_nametoindex (const char *ifname) -{ - unsigned int idx; - int find_name (const char *name) - { - return !strcmp (name, ifname); - } - return map_interfaces (PF_INET, &idx, 0, &find_name) ? idx : 0; -} - -char * -if_indextoname (unsigned int ifindex, char *ifname) -{ - unsigned int idx; - int find_idx (const char *name) - { - if (idx == ifindex) - { - strncpy (ifname, name, IFNAMSIZ); - return 1; - } - return 0; - } - return map_interfaces (PF_INET, &idx, 0, &find_idx) ? ifname : NULL; -} - - -struct if_nameindex * -if_nameindex (void) -{ - unsigned int idx; - struct if_nameindex *buf; - char *namep; - int alloc (unsigned int count, size_t nameslen) - { - buf = malloc ((sizeof buf[0] * (count + 1)) + nameslen); - if (buf == 0) - return 1; - buf[count].if_index = 0; - buf[count].if_name = NULL; - namep = (char *) &buf[count + 1]; - return 0; - } - int fill (const char *name) - { - buf[idx - 1].if_index = idx; - buf[idx - 1].if_name = namep; - namep = __memccpy (namep, name, '\0', IFNAMSIZ+1) ?: &namep[IFNAMSIZ+1]; - return 0; - } - - return map_interfaces (PF_INET, &idx, &alloc, &fill) ? buf : NULL; -} - -void -if_freenameindex (struct if_nameindex *ifn) -{ - free (ifn); -} - -#if 0 -void -internal_function -__protocol_available (int *have_inet, int *have_inet6) -{ - *have_inet = _hurd_socket_server (PF_INET, 0) != MACH_PORT_NULL; - *have_inet6 = _hurd_socket_server (PF_INET6, 0) != MACH_PORT_NULL; -} -#endif +/* Find network interface names and index numbers. Hurd version. + Copyright (C) 2000, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +/* Return the interface index corresponding to interface IFNAME. + On error, return 0. */ +unsigned int +if_nametoindex (const char *ifname) +{ + struct ifreq ifr; + int fd = __opensock (); + + if (fd < 0) + return 0; + + strncpy (ifr.ifr_name, ifname, IFNAMSIZ); + if (__ioctl (fd, SIOCGIFINDEX, &ifr) < 0) + { + int saved_errno = errno; + __close (fd); + if (saved_errno == EINVAL || saved_errno == ENOTTY) + __set_errno (ENOSYS); + return 0; + } + __close (fd); + return ifr.ifr_ifindex; +} + +/* Free the structure IFN returned by if_nameindex. */ +void +if_freenameindex (struct if_nameindex *ifn) +{ + struct if_nameindex *ptr = ifn; + while (ptr->if_name || ptr->if_index) + { + if (ptr->if_name) + free (ptr->if_name); + ++ptr; + } + free (ifn); +} + +/* Return an array of if_nameindex structures, one for each network + interface present, plus one indicating the end of the array. On + error, return NULL. */ +struct if_nameindex * +if_nameindex (void) +{ + error_t err = 0; + char data[2048]; + file_t server; + int fd = __opensock (); + struct ifconf ifc; + unsigned int nifs, i; + struct if_nameindex *idx = NULL; + + ifc.ifc_buf = data; + ifc.ifc_len = sizeof (data); + + if (fd < 0) + return NULL; + + server = _hurd_socket_server (PF_INET, 0); + if (server == MACH_PORT_NULL) + nifs = 0; + else + { + err = __pfinet_siocgifconf (server, -1, &ifc.ifc_buf, + &ifc.ifc_len); + if (err == MACH_SEND_INVALID_DEST || err == MIG_SERVER_DIED) + { + /* On the first use of the socket server during the operation, + allow for the old server port dying. */ + server = _hurd_socket_server (PF_INET, 1); + if (server == MACH_PORT_NULL) + goto out; + err = __pfinet_siocgifconf (server, -1, &ifc.ifc_buf, + &ifc.ifc_len); + } + if (err) + goto out; + + nifs = ifc.ifc_len / sizeof (struct ifreq); + } + + idx = malloc ((nifs + 1) * sizeof (struct if_nameindex)); + if (idx == NULL) + { + err = ENOBUFS; + goto out; + } + + for (i = 0; i < nifs; ++i) + { + struct ifreq *ifr = &ifc.ifc_req[i]; + idx[i].if_name = __strdup (ifr->ifr_name); + if (idx[i].if_name == NULL + || __ioctl (fd, SIOCGIFINDEX, ifr) < 0) + { + unsigned int j; + err = errno; + + for (j = 0; j < i; ++j) + free (idx[j].if_name); + free (idx); + idx = NULL; + + if (err == EINVAL) + err = ENOSYS; + else if (err == ENOMEM) + err = ENOBUFS; + goto out; + } + idx[i].if_index = ifr->ifr_ifindex; + } + + idx[i].if_index = 0; + idx[i].if_name = NULL; + + out: + __close (fd); + if (data != ifc.ifc_buf) + __vm_deallocate (__mach_task_self (), (vm_address_t) ifc.ifc_buf, + ifc.ifc_len); + __set_errno (err); + return idx; +} + +/* Store the name of the interface corresponding to index IFINDEX in + IFNAME (which has space for at least IFNAMSIZ characters). Return + IFNAME, or NULL on error. */ +char * +if_indextoname (unsigned int ifindex, char *ifname) +{ + struct ifreq ifr; + int fd = __opensock (); + + if (fd < 0) + return NULL; + + ifr.ifr_ifindex = ifindex; + if (__ioctl (fd, SIOCGIFNAME, &ifr) < 0) + { + int saved_errno = errno; + __close (fd); + if (saved_errno == EINVAL || saved_errno == ENOTTY) + __set_errno (ENOSYS); + else if (saved_errno == ENODEV) + __set_errno (ENXIO); + return NULL; + } + __close (fd); + return strncpy (ifname, ifr.ifr_name, IFNAMSIZ); +} + +#if 0 +void +internal_function +__protocol_available (int *have_inet, int *have_inet6) +{ + *have_inet = _hurd_socket_server (PF_INET, 0) != MACH_PORT_NULL; + *have_inet6 = _hurd_socket_server (PF_INET6, 0) != MACH_PORT_NULL; +} +#endif -- 2.11.4.GIT