* inet/test-ifaddrs.c (main: addr_string): Handle null SA.
authorRoland McGrath <roland@gnu.org>
Tue, 26 Nov 2002 03:29:06 +0000 (03:29 +0000)
committerRoland McGrath <roland@gnu.org>
Tue, 26 Nov 2002 03:29:06 +0000 (03:29 +0000)
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>.

ChangeLog
inet/test-ifaddrs.c
sysdeps/generic/ifreq.h
sysdeps/gnu/ifaddrs.c

index be335e4..d95decf 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,21 @@
 
 2002-11-25  Roland McGrath  <roland@redhat.com>
 
+       * 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>.
+
        * sysdeps/mach/hurd/i386/init-first.c: Include <ldsodefs.h>
        and <fpu_control.h>.
 
index 42fb7e7..52cda73 100644 (file)
@@ -50,6 +50,9 @@ Name           Flags   Address         Netmask         Broadcast/Destination");
       char abuf[64], mbuf[64], dbuf[64];
       inline const char *addr_string (struct sockaddr *sa, char *buf)
        {
+         if (sa == NULL)
+           return "<none>";
+
          switch (sa->sa_family)
            {
            case AF_INET:
@@ -60,6 +63,10 @@ Name           Flags   Address         Netmask         Broadcast/Destination");
              return inet_ntop (AF_INET6,
                                &((struct sockaddr_in6 *) sa)->sin6_addr,
                                buf, sizeof abuf);
+#ifdef AF_LINK
+           case AF_LINK:
+             return "<link>";
+#endif
            case AF_UNSPEC:
              return "---";
            default:
index 0d975be..4871c8d 100644 (file)
 #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)
 {
index 0c1ae5b..6ecc457 100644 (file)
@@ -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.  */