Skip to content

Commit

Permalink
* sysdeps/mach/hurd/if_index.c: Redone to use new interfaces in the H…
Browse files Browse the repository at this point in the history
…urd 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>.
  • Loading branch information
Mark Kettenis committed Jul 1, 2001
1 parent f669de7 commit 5bd5e35
Show file tree
Hide file tree
Showing 2 changed files with 147 additions and 109 deletions.
16 changes: 16 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -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
Expand Down
240 changes: 131 additions & 109 deletions sysdeps/mach/hurd/if_index.c
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -17,143 +17,165 @@
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>

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;
#include <sys/ioctl.h>
#include <unistd.h>

/* 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;
#include <hurd.h>
#include <hurd/ioctl.h>
#include <hurd/pfinet.h>

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;
}
/* 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 ((*counted_initializer) (count, nameslen))
return 0;
}
if (fd < 0)
return 0;

*idxp = 0;
for (p = memchr (opts, '\0', optslen); p != 0;
p = memchr (p + 1, '\0', optslen - (p - opts)))
strncpy (ifr.ifr_name, ifname, IFNAMSIZ);
if (__ioctl (fd, SIOCGIFINDEX, &ifr) < 0)
{
++*idxp;
if (optslen - (p - opts) >= sizeof ifopt
&& !memcmp (p + 1, ifopt, sizeof ifopt - 1)
&& (*iterator) (p + sizeof ifopt))
break;
int saved_errno = errno;
__close (fd);
if (saved_errno == EINVAL || saved_errno == ENOTTY)
__set_errno (ENOSYS);
return 0;
}

if (opts != optsbuf)
__munmap (opts, optslen);

return 1;
__close (fd);
return ifr.ifr_ifindex;
}

unsigned int
if_nametoindex (const char *ifname)
/* Free the structure IFN returned by if_nameindex. */
void
if_freenameindex (struct if_nameindex *ifn)
{
unsigned int idx;
int find_name (const char *name)
struct if_nameindex *ptr = ifn;
while (ptr->if_name || ptr->if_index)
{
return !strcmp (name, ifname);
if (ptr->if_name)
free (ptr->if_name);
++ptr;
}
return map_interfaces (PF_INET, &idx, 0, &find_name) ? idx : 0;
free (ifn);
}

char *
if_indextoname (unsigned int ifindex, char *ifname)
/* 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)
{
unsigned int idx;
int find_idx (const char *name)
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
{
if (idx == ifindex)
err = __pfinet_siocgifconf (server, -1, &ifc.ifc_buf,
&ifc.ifc_len);
if (err == MACH_SEND_INVALID_DEST || err == MIG_SERVER_DIED)
{
strncpy (ifname, name, IFNAMSIZ);
return 1;
/* 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);
}
return 0;
}
return map_interfaces (PF_INET, &idx, 0, &find_idx) ? ifname : NULL;
}
if (err)
goto out;

nifs = ifc.ifc_len / sizeof (struct ifreq);
}

struct if_nameindex *
if_nameindex (void)
{
unsigned int idx;
struct if_nameindex *buf;
char *namep;
int alloc (unsigned int count, size_t nameslen)
idx = malloc ((nifs + 1) * sizeof (struct if_nameindex));
if (idx == NULL)
{
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;
err = ENOBUFS;
goto out;
}
int fill (const char *name)

for (i = 0; i < nifs; ++i)
{
buf[idx - 1].if_index = idx;
buf[idx - 1].if_name = namep;
namep = __memccpy (namep, name, '\0', IFNAMSIZ+1) ?: &namep[IFNAMSIZ+1];
return 0;
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;
}

return map_interfaces (PF_INET, &idx, &alloc, &fill) ? buf : NULL;
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;
}

void
if_freenameindex (struct if_nameindex *ifn)
/* 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)
{
free (ifn);
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
Expand Down

0 comments on commit 5bd5e35

Please sign in to comment.