summaryrefslogtreecommitdiff
path: root/inet
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>2002-07-24 22:56:44 +0000
committerRoland McGrath <roland@gnu.org>2002-07-24 22:56:44 +0000
commit7f1deee65e0a90d9e6699068b5d63a28d2546e12 (patch)
treeb75aefbdd5d6d8347e0d4d3f665d8e49fcf6c43b /inet
parent11d657d7278ae4f96f0f4c8655991f2818d0eeb9 (diff)
Added <ifaddrs.h> interface with functions `getifaddrs', `freeifaddrs'.
This implementation supports only IPv4. * inet/ifaddrs.h: New file. * sysdeps/generic/ifaddrs.c: New file. * sysdeps/gnu/ifaddrs.c: New file. * inet/test-ifaddrs.c: New file. * inet/Makefile (routines): Add ifaddrs. (headers): Add ifaddrs.h here. (tests): Add test-ifaddrs. * inet/Versions (GLIBC_2.3): New set, add getifaddrs and freeifaddrs. * resolv/res_hconf.c (_res_hconf_reorder_addrs): Use an explicit socket call to get an AF_INET socket, instead of using __opensock. The SIOCGIFNETMASK ioctl will work only with a PF_INET socket. * sysdeps/generic/ifreq.h (__ifreq): Take third argument SOCKFD, if not -1 use it instead of calling __opensock. * sysdeps/unix/sysv/linux/ifreq.h (__ifreq): Likewise. * sysdeps/mach/hurd/ifreq.h (__ifreq): Take new argument and ignore it. * resolv/res_hconf.c (_res_hconf_reorder_addrs): Pass new argument. * sysdeps/mach/hurd/ifreq.h: New file. * sysdeps/generic/ifreq.h (__if_freereq): Take second argument NUM_IFS. * sysdeps/unix/sysv/linux/ifreq.h (__if_freereq): Likewise. * resolv/res_hconf.c (_res_hconf_reorder_addrs): Update caller.
Diffstat (limited to 'inet')
-rw-r--r--inet/Makefile8
-rw-r--r--inet/Versions6
-rw-r--r--inet/ifaddrs.h74
-rw-r--r--inet/test-ifaddrs.c82
4 files changed, 166 insertions, 4 deletions
diff --git a/inet/Makefile b/inet/Makefile
index ab922db4b6..be588d78b0 100644
--- a/inet/Makefile
+++ b/inet/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1991-1999, 2000, 2001 Free Software Foundation, Inc.
+# Copyright (C) 1991-1999,2000,01,02 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
@@ -24,7 +24,7 @@ subdir := inet
headers := netinet/ether.h netinet/in.h netinet/in_systm.h \
netinet/if_ether.h \
netinet/tcp.h netinet/ip.h $(wildcard arpa/*.h protocols/*.h) \
- aliases.h netinet/ip6.h netinet/icmp6.h bits/in.h
+ aliases.h ifaddrs.h netinet/ip6.h netinet/icmp6.h bits/in.h
distribute := netgroup.h
@@ -45,10 +45,10 @@ routines := htonl htons \
rcmd rexec ruserpass \
getnetgrent_r getnetgrent \
getaliasent_r getaliasent getaliasname getaliasname_r \
- in6_addr getnameinfo if_index
+ in6_addr getnameinfo if_index ifaddrs
tests := htontest test_ifindex tst-ntoa tst-ether_aton tst-network \
- tst-gethnm
+ tst-gethnm test-ifaddrs
include ../Rules
diff --git a/inet/Versions b/inet/Versions
index eb3b13c9d2..0eb1e77838 100644
--- a/inet/Versions
+++ b/inet/Versions
@@ -64,6 +64,12 @@ libc {
# r*
rcmd_af; rexec_af; rresvport_af; ruserok_af;
}
+ GLIBC_2.3 {
+ # f*
+ freeifaddrs;
+ # g*
+ getifaddrs;
+ }
GLIBC_PRIVATE {
# functions used in other libraries
__internal_endnetgrent; __internal_getnetgrent_r;
diff --git a/inet/ifaddrs.h b/inet/ifaddrs.h
new file mode 100644
index 0000000000..ba6a1554b1
--- /dev/null
+++ b/inet/ifaddrs.h
@@ -0,0 +1,74 @@
+/* ifaddrs.h -- declarations for getting network interface addresses
+ Copyright (C) 2002 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 Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _IFADDRS_H
+#define _IFADDRS_H 1
+
+#include <features.h>
+#include <sys/socket.h>
+
+__BEGIN_DECLS
+
+/* The `getifaddrs' function generates a linked list of these structures.
+ Each element of the list describes one network interface. */
+struct ifaddrs
+{
+ struct ifaddrs *ifa_next; /* Pointer to the next structure. */
+
+ char *ifa_name; /* Name of this network interface. */
+ unsigned int ifa_flags; /* Flags as from SIOCGIFFLAGS ioctl. */
+
+ struct sockaddr *ifa_addr; /* Network address of this interface. */
+ struct sockaddr *ifa_netmask; /* Netmask of this interface. */
+ union
+ {
+ /* At most one of the following two is valid. If the IFF_BROADCAST
+ bit is set in `ifa_flags', then `ifa_broadaddr' is valid. If the
+ IFF_POINTOPOINT bit is set, then `ifa_dstaddr' is valid.
+ It is never the case that both these bits are set at once. */
+ struct sockaddr *ifu_broadaddr; /* Broadcast address of this interface. */
+ struct sockaddr *ifu_dstaddr; /* Point-to-point destination address. */
+ } ifa_ifu;
+ /* These very same macros are defined by <net/if.h> for `struct ifaddr'.
+ So if they are defined already, the existing definitions will be fine. */
+# ifndef ifa_broadaddr
+# define ifa_broadaddr ifa_ifu.ifu_broadaddr
+# endif
+# ifndef ifa_dstaddr
+# define ifa_dstaddr ifa_ifu.ifu_dstaddr
+# endif
+
+ void *ifa_data; /* Address-specific data (may be unused). */
+};
+
+
+/* Create a linked list of `struct ifaddrs' structures, one for each
+ network interface on the host machine. If successful, store the
+ list in *IFAP and return 0. On errors, return -1 and set `errno'.
+
+ The storage returned in *IFAP is allocated dynamically and can
+ only be properly freed by passing it to `freeifaddrs'. */
+extern int getifaddrs (struct ifaddrs **__ifap) __THROW;
+
+/* Reclaim the storage allocated by a previous `getifaddrs' call. */
+extern void freeifaddrs (struct ifaddrs *__ifa) __THROW;
+
+__END_DECLS
+
+#endif /* ifaddrs.h */
diff --git a/inet/test-ifaddrs.c b/inet/test-ifaddrs.c
new file mode 100644
index 0000000000..42fb7e75bf
--- /dev/null
+++ b/inet/test-ifaddrs.c
@@ -0,0 +1,82 @@
+/* Test listing of network interface addresses.
+ Copyright (C) 2002 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 Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ifaddrs.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+int
+main (void)
+{
+ int failures = 0;
+ struct ifaddrs *ifaces, *ifa;
+
+ if (getifaddrs (&ifaces) < 0)
+ {
+ if (errno != ENOSYS)
+ {
+ printf ("Couldn't get any interfaces: %s.\n", strerror (errno));
+ exit (1);
+ }
+ /* The function is simply not implemented. */
+ exit (0);
+ }
+
+ puts ("\
+Name Flags Address Netmask Broadcast/Destination");
+
+ for (ifa = ifaces; ifa != NULL; ifa = ifa->ifa_next)
+ {
+ char abuf[64], mbuf[64], dbuf[64];
+ inline const char *addr_string (struct sockaddr *sa, char *buf)
+ {
+ switch (sa->sa_family)
+ {
+ case AF_INET:
+ return inet_ntop (AF_INET,
+ &((struct sockaddr_in *) sa)->sin_addr,
+ buf, sizeof abuf);
+ case AF_INET6:
+ return inet_ntop (AF_INET6,
+ &((struct sockaddr_in6 *) sa)->sin6_addr,
+ buf, sizeof abuf);
+ case AF_UNSPEC:
+ return "---";
+ default:
+ ++failures;
+ printf ("sa_family=%d %08x\n", sa->sa_family,
+ *(int*)&((struct sockaddr_in *) sa)->sin_addr.s_addr);
+ return "<unexpected sockaddr family>";
+ }
+ }
+ printf ("%-15s%#.4x %-15s %-15s %-15s\n",
+ ifa->ifa_name, ifa->ifa_flags,
+ addr_string (ifa->ifa_addr, abuf),
+ addr_string (ifa->ifa_netmask, mbuf),
+ addr_string (ifa->ifa_broadaddr, dbuf));
+ }
+
+ freeifaddrs (ifaces);
+
+ return failures ? 1 : 0;
+}