getifaddrs: Return pointer to extended interface info in ifa_data member

According to https://cygwin.com/ml/cygwin/2016-03/msg00124.html it's a
problem to collect friendlyname info using AF_INET6 sockets.  Fix problem
by exposing additional hardware info for all collected interfaces via the
pointer in the ifaddrs::ifa_data member.

	* include/ifaddrs.h (struct ifaddrs_hwdata): Define as struct of
	not yet exposed members of struct ifall, defined in net.cc.
	* net.cc (struct ifall): Replace hardware dta members with struct
	ifaddrs_hwdata.  Accommodate throughout.
	(get_ifs): Let ifaddrs ifa_data member point to ifall::ifa_hwdata
	member.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2016-03-10 18:00:00 +01:00
parent c86b2f8e93
commit 65231f415a
2 changed files with 36 additions and 22 deletions

View File

@ -38,6 +38,19 @@ struct ifaddrs {
void *ifa_data;
};
#ifdef __CYGWIN__
#include <cygwin/if.h>
/* On Cygwin the ifa_data member points to this structure, independent of
the address family. */
struct ifaddrs_hwdata {
struct sockaddr ifa_hwaddr;
int ifa_metric;
int ifa_mtu;
int ifa_ifindex;
struct ifreq_frndlyname ifa_frndlyname;
};
#endif
/*
* This may have been defined in <net/if.h>. Note that if <net/if.h> is
* to be included it must be included before this header file.

View File

@ -1950,11 +1950,7 @@ struct ifall {
struct sockaddr_storage ifa_addr;
struct sockaddr_storage ifa_brddstaddr;
struct sockaddr_storage ifa_netmask;
struct sockaddr ifa_hwaddr;
int ifa_metric;
int ifa_mtu;
int ifa_ifindex;
struct ifreq_frndlyname ifa_frndlyname;
struct ifaddrs_hwdata ifa_hwdata;
};
static unsigned int
@ -2104,7 +2100,7 @@ static void
get_friendlyname (struct ifall *ifp, PIP_ADAPTER_ADDRESSES pap)
{
struct ifreq_frndlyname *iff = (struct ifreq_frndlyname *)
&ifp->ifa_frndlyname;
&ifp->ifa_hwdata.ifa_frndlyname;
iff->ifrf_len = sys_wcstombs (iff->ifrf_friendlyname,
IFRF_FRIENDLYNAMESIZ,
pap->FriendlyName) + 1;
@ -2115,9 +2111,9 @@ get_hwaddr (struct ifall *ifp, PIP_ADAPTER_ADDRESSES pap)
{
for (UINT i = 0; i < IFHWADDRLEN; ++i)
if (i >= pap->PhysicalAddressLength)
ifp->ifa_hwaddr.sa_data[i] = '\0';
ifp->ifa_hwdata.ifa_hwaddr.sa_data[i] = '\0';
else
ifp->ifa_hwaddr.sa_data[i] = pap->PhysicalAddress[i];
ifp->ifa_hwdata.ifa_hwaddr.sa_data[i] = pap->PhysicalAddress[i];
}
/*
@ -2233,13 +2229,15 @@ get_ifs (ULONG family)
/* Hardware address */
get_hwaddr (ifp, pap);
/* Metric */
ifp->ifa_metric = 1;
ifp->ifa_hwdata.ifa_metric = 1;
/* MTU */
ifp->ifa_mtu = pap->Mtu;
ifp->ifa_hwdata.ifa_mtu = pap->Mtu;
/* Interface index */
ifp->ifa_ifindex = pap->IfIndex;
ifp->ifa_hwdata.ifa_ifindex = pap->IfIndex;
/* Friendly name */
get_friendlyname (ifp, pap);
/* Let ifa_data member point to "ifaddrs_hwdata" data. */
ifp->ifa_ifa.ifa_data = &ifp->ifa_hwdata;
++ifp;
}
else
@ -2327,17 +2325,20 @@ get_ifs (ULONG family)
get_hwaddr (ifp, pap);
/* Metric */
if (wincap.has_gaa_on_link_prefix ())
ifp->ifa_metric = (sa->sa_family == AF_INET
? ((PIP_ADAPTER_ADDRESSES_LH) pap)->Ipv4Metric
: ((PIP_ADAPTER_ADDRESSES_LH) pap)->Ipv6Metric);
ifp->ifa_hwdata.ifa_metric
= (sa->sa_family == AF_INET)
? ((PIP_ADAPTER_ADDRESSES_LH) pap)->Ipv4Metric
: ((PIP_ADAPTER_ADDRESSES_LH) pap)->Ipv6Metric;
else
ifp->ifa_metric = 1;
ifp->ifa_hwdata.ifa_metric = 1;
/* MTU */
ifp->ifa_mtu = pap->Mtu;
ifp->ifa_hwdata.ifa_mtu = pap->Mtu;
/* Interface index */
ifp->ifa_ifindex = pap->IfIndex;
ifp->ifa_hwdata.ifa_ifindex = pap->IfIndex;
/* Friendly name */
get_friendlyname (ifp, pap);
/* Let ifa_data member point to "ifaddrs_hwdata" data. */
ifp->ifa_ifa.ifa_data = &ifp->ifa_hwdata;
++ifp;
# undef sin
# undef sin6
@ -2432,20 +2433,20 @@ get_ifconf (struct ifconf *ifc, int what)
}
break;
case SIOCGIFHWADDR:
memcpy (&ifr->ifr_hwaddr, &ifp->ifa_hwaddr,
memcpy (&ifr->ifr_hwaddr, &ifp->ifa_hwdata.ifa_hwaddr,
sizeof ifr->ifr_hwaddr);
break;
case SIOCGIFMETRIC:
ifr->ifr_metric = ifp->ifa_metric;
ifr->ifr_metric = ifp->ifa_hwdata.ifa_metric;
break;
case SIOCGIFMTU:
ifr->ifr_mtu = ifp->ifa_mtu;
ifr->ifr_mtu = ifp->ifa_hwdata.ifa_mtu;
break;
case SIOCGIFINDEX:
ifr->ifr_ifindex = ifp->ifa_ifindex;
ifr->ifr_ifindex = ifp->ifa_hwdata.ifa_ifindex;
break;
case SIOCGIFFRNDLYNAM:
memcpy (ifr->ifr_frndlyname, &ifp->ifa_frndlyname,
memcpy (ifr->ifr_frndlyname, &ifp->ifa_hwdata.ifa_frndlyname,
sizeof (struct ifreq_frndlyname));
}
if ((caddr_t) ++ifr >