mirror of
git://sourceware.org/git/glibc.git
synced 2025-01-30 12:31:53 +08:00
* 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 <unistd.h>, <error.h>, <sys/ioctl.h>, <hurd/ioctl.h> and <hurd/pfinet.h>. Don't include <sys/mman.h> and <hurd/fsys.h> 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 <marcus@gnu.org>.
2001-07-01 Mark Kettenis <kettenis@gnu.org> * 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 <unistd.h>, <error.h>, <sys/ioctl.h>, <hurd/ioctl.h> and <hurd/pfinet.h>. Don't include <sys/mman.h> and <hurd/fsys.h> 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 <marcus@gnu.org>.
This commit is contained in:
parent
f669de74ea
commit
5bd5e35748
16
ChangeLog
16
ChangeLog
@ -1,3 +1,19 @@
|
||||
2001-07-01 Mark Kettenis <kettenis@gnu.org>
|
||||
|
||||
* 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 <unistd.h>, <error.h>, <sys/ioctl.h>, <hurd/ioctl.h> and
|
||||
<hurd/pfinet.h>. Don't include <sys/mman.h> and <hurd/fsys.h>
|
||||
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 <marcus@gnu.org>.
|
||||
|
||||
2001-06-30 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* sysdeps/powerpc/dl-machine.c (__elf_preferred_address): Prefer
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Find network interface names and index numbers. Hurd version.
|
||||
Copyright (C) 2000 Free Software Foundation, Inc.
|
||||
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
|
||||
@ -17,145 +17,167 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <error.h>
|
||||
#include <net/if.h>
|
||||
#include <hurd.h>
|
||||
#include <hurd/fsys.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
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;
|
||||
}
|
||||
#include <hurd.h>
|
||||
#include <hurd/ioctl.h>
|
||||
#include <hurd/pfinet.h>
|
||||
|
||||
/* Return the interface index corresponding to interface IFNAME.
|
||||
On error, return 0. */
|
||||
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;
|
||||
}
|
||||
struct ifreq ifr;
|
||||
int fd = __opensock ();
|
||||
|
||||
char *
|
||||
if_indextoname (unsigned int ifindex, char *ifname)
|
||||
{
|
||||
unsigned int idx;
|
||||
int find_idx (const char *name)
|
||||
if (fd < 0)
|
||||
return 0;
|
||||
|
||||
strncpy (ifr.ifr_name, ifname, IFNAMSIZ);
|
||||
if (__ioctl (fd, SIOCGIFINDEX, &ifr) < 0)
|
||||
{
|
||||
if (idx == ifindex)
|
||||
{
|
||||
strncpy (ifname, name, IFNAMSIZ);
|
||||
return 1;
|
||||
}
|
||||
int saved_errno = errno;
|
||||
__close (fd);
|
||||
if (saved_errno == EINVAL || saved_errno == ENOTTY)
|
||||
__set_errno (ENOSYS);
|
||||
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;
|
||||
__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
|
||||
|
Loading…
Reference in New Issue
Block a user