Skip to content

Commit

Permalink
* inet/test-ifaddrs.c (main: addr_string): Handle null SA.
Browse files Browse the repository at this point in the history
	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>.
  • Loading branch information
Roland McGrath committed Nov 26, 2002
1 parent 14fa7a2 commit 6938e63
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 20 deletions.
15 changes: 15 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -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>.

Expand Down
7 changes: 7 additions & 0 deletions inet/test-ifaddrs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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:
Expand Down
32 changes: 23 additions & 9 deletions sysdeps/generic/ifreq.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
{
Expand Down
30 changes: 19 additions & 11 deletions sysdeps/gnu/ifaddrs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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. */

Expand Down

0 comments on commit 6938e63

Please sign in to comment.