aboutsummaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>2002-11-26 03:29:06 +0000
committerRoland McGrath <roland@gnu.org>2002-11-26 03:29:06 +0000
commit6938e63f714b15c377d8cbf8e97b6f15b0e1b692 (patch)
tree953d8b439443cb9e73dd8021709ddefc06786aea /sysdeps
parent14fa7a214c1ad32997db99c6560d7f93ceb254aa (diff)
downloadglibc-6938e63f714b15c377d8cbf8e97b6f15b0e1b692.tar
glibc-6938e63f714b15c377d8cbf8e97b6f15b0e1b692.tar.gz
glibc-6938e63f714b15c377d8cbf8e97b6f15b0e1b692.tar.bz2
glibc-6938e63f714b15c377d8cbf8e97b6f15b0e1b692.zip
* inet/test-ifaddrs.c (main: addr_string): Handle null SA.
Grok AF_LINK if defined. From Momchil Velikov <velco@fadata.bg>. * sysdeps/gnu/ifaddrs.c (getifaddrs): If ioctl fails for netmask, brdaddr, or dstaddr, just set those pointers to null and don't fail. Reported by Momchil Velikov <velco@fadata.bg>. * sysdeps/generic/ifreq.h (__if_nextreq) [_HAVE_SA_LEN]: If sa_len is > sizeof IFR->ifa_addr, advance past the whole longer length. (__ifreq): Count up NIFS that way too. Reported by Momchil Velikov <velco@fadata.bg>. * sysdeps/mach/hurd/lchmod.c: Include <fcntl.h>.
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/generic/ifreq.h32
-rw-r--r--sysdeps/gnu/ifaddrs.c30
2 files changed, 42 insertions, 20 deletions
diff --git a/sysdeps/generic/ifreq.h b/sysdeps/generic/ifreq.h
index 0d975be61c..4871c8d1d8 100644
--- a/sysdeps/generic/ifreq.h
+++ b/sysdeps/generic/ifreq.h
@@ -24,6 +24,15 @@
#include <sys/socket.h>
#include <sys/ioctl.h>
+static inline struct ifreq *
+__if_nextreq (struct ifreq *ifr)
+{
+#ifdef _HAVE_SA_LEN
+ if (ifr->ifa_addr > sizeof ifr->ifa_addr)
+ return (struct ifreq *) ((char *) &ifr->ifa_addr + ifr->ifa_addr.sa_len);
+#endif
+ return ifr + 1;
+}
static inline void
__ifreq (struct ifreq **ifreqs, int *num_ifs, int sockfd)
@@ -63,23 +72,28 @@ __ifreq (struct ifreq **ifreqs, int *num_ifs, int sockfd)
}
while (rq_len < sizeof (struct ifreq) + ifc.ifc_len);
- nifs = ifc.ifc_len / sizeof (struct ifreq);
-
if (fd != sockfd)
__close (fd);
+#ifdef _HAVE_SA_LEN
+ struct ifreq *ifr = ifreqs;
+ nifs = 0;
+ while ((char *) ifr < ifc.ifc_buf + ifc.ifc_len)
+ {
+ ++nifs;
+ ifr = __if_nextreq (ifr);
+ if (ifr == NULL)
+ break;
+ }
+#else
+ nifs = ifc.ifc_len / sizeof (struct ifreq);
+#endif
+
*num_ifs = nifs;
*ifreqs = realloc (ifc.ifc_buf, nifs * sizeof (struct ifreq));
}
-static inline struct ifreq *
-__if_nextreq (struct ifreq *ifr)
-{
- return ifr + 1;
-}
-
-
static inline void
__if_freereq (struct ifreq *ifreqs, int num_ifs)
{
diff --git a/sysdeps/gnu/ifaddrs.c b/sysdeps/gnu/ifaddrs.c
index 0c1ae5bf05..6ecc457e50 100644
--- a/sysdeps/gnu/ifaddrs.c
+++ b/sysdeps/gnu/ifaddrs.c
@@ -79,11 +79,9 @@ getifaddrs (struct ifaddrs **ifap)
ifr = ifreqs;
do
{
- /* Fill in all pointers to the storage we've already allocated. */
+ /* Fill in pointers to the storage we've already allocated. */
storage[i].ia.ifa_next = &storage[i + 1].ia;
storage[i].ia.ifa_addr = &storage[i].addr;
- storage[i].ia.ifa_netmask = &storage[i].netmask;
- storage[i].ia.ifa_broadaddr = &storage[i].broadaddr; /* & dstaddr */
/* Now copy the information we already have from SIOCGIFCONF. */
storage[i].ia.ifa_name = strncpy (storage[i].name, ifr->ifr_name,
@@ -100,26 +98,36 @@ getifaddrs (struct ifaddrs **ifap)
ifr->ifr_addr = storage[i].addr;
if (__ioctl (fd, SIOCGIFNETMASK, ifr) < 0)
- break;
- storage[i].netmask = ifr->ifr_netmask;
+ storage[i].ia.ifa_netmask = NULL;
+ else
+ {
+ storage[i].ia.ifa_netmask = &storage[i].netmask;
+ storage[i].netmask = ifr->ifr_netmask;
+ }
if (ifr->ifr_flags & IFF_BROADCAST)
{
ifr->ifr_addr = storage[i].addr;
if (__ioctl (fd, SIOCGIFBRDADDR, ifr) < 0)
- break;
- storage[i].broadaddr = ifr->ifr_broadaddr;
+ storage[i].ia.ifa_broadaddr = NULL;
+ {
+ storage[i].ia.ifa_broadaddr = &storage[i].broadaddr;
+ storage[i].broadaddr = ifr->ifr_broadaddr;
+ }
}
else if (ifr->ifr_flags & IFF_POINTOPOINT)
{
ifr->ifr_addr = storage[i].addr;
if (__ioctl (fd, SIOCGIFDSTADDR, ifr) < 0)
- break;
- storage[i].broadaddr = ifr->ifr_dstaddr;
+ storage[i].ia.ifa_broadaddr = NULL;
+ else
+ {
+ storage[i].ia.ifa_broadaddr = &storage[i].broadaddr;
+ storage[i].broadaddr = ifr->ifr_dstaddr;
+ }
}
else
- /* Just 'cause. */
- memset (&storage[i].broadaddr, 0, sizeof storage[i].broadaddr);
+ storage[i].ia.ifa_broadaddr = NULL;
storage[i].ia.ifa_data = NULL; /* Nothing here for now. */