* net.cc (get_flags): New static function to generate interface flags
value. (get_ipv4fromreg_ipcnt): New static function to fetch number of configured IPv4 addresses for a given NIC from registry. (get_ipv4fromreg): New static function to fetch configured IPv4 addresses for a given NIC from registry. (get_friendlyname): New static function to generate friendly name. (get_hwaddr): New static function to copy hardware address. (get_xp_ifs): Restructure slightly. Add code to generate IPv4 entries entries for interfaces which are disconnected.
This commit is contained in:
parent
a02f102db2
commit
ea3923078a
|
@ -1,3 +1,16 @@
|
||||||
|
2009-06-15 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* net.cc (get_flags): New static function to generate interface flags
|
||||||
|
value.
|
||||||
|
(get_ipv4fromreg_ipcnt): New static function to fetch number of
|
||||||
|
configured IPv4 addresses for a given NIC from registry.
|
||||||
|
(get_ipv4fromreg): New static function to fetch configured IPv4
|
||||||
|
addresses for a given NIC from registry.
|
||||||
|
(get_friendlyname): New static function to generate friendly name.
|
||||||
|
(get_hwaddr): New static function to copy hardware address.
|
||||||
|
(get_xp_ifs): Restructure slightly. Add code to generate IPv4 entries
|
||||||
|
entries for interfaces which are disconnected.
|
||||||
|
|
||||||
2009-06-14 Christopher Faylor <me+cygwin@cgf.cx>
|
2009-06-14 Christopher Faylor <me+cygwin@cgf.cx>
|
||||||
|
|
||||||
* errno.cc (errmap): Add mapping for ERROR_IO_INCOMPLETE.
|
* errno.cc (errmap): Add mapping for ERROR_IO_INCOMPLETE.
|
||||||
|
|
|
@ -1587,6 +1587,149 @@ struct ifall {
|
||||||
struct ifreq_frndlyname ifa_frndlyname;
|
struct ifreq_frndlyname ifa_frndlyname;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
get_flags (PIP_ADAPTER_ADDRESSES pap)
|
||||||
|
{
|
||||||
|
unsigned int flags = IFF_UP;
|
||||||
|
if (pap->IfType == IF_TYPE_SOFTWARE_LOOPBACK)
|
||||||
|
flags |= IFF_LOOPBACK;
|
||||||
|
else if (pap->IfType == IF_TYPE_PPP)
|
||||||
|
flags |= IFF_POINTOPOINT;
|
||||||
|
if (!(pap->Flags & IP_ADAPTER_NO_MULTICAST))
|
||||||
|
flags |= IFF_MULTICAST;
|
||||||
|
if (pap->OperStatus == IfOperStatusUp
|
||||||
|
|| pap->OperStatus == IfOperStatusUnknown)
|
||||||
|
flags |= IFF_RUNNING;
|
||||||
|
if (pap->OperStatus != IfOperStatusLowerLayerDown)
|
||||||
|
flags |= IFF_LOWER_UP;
|
||||||
|
if (pap->OperStatus == IfOperStatusDormant)
|
||||||
|
flags |= IFF_DORMANT;
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG
|
||||||
|
get_ipv4fromreg_ipcnt (const char *name)
|
||||||
|
{
|
||||||
|
HKEY key;
|
||||||
|
LONG ret;
|
||||||
|
char regkey[256], *c;
|
||||||
|
ULONG ifs = 1;
|
||||||
|
DWORD dhcp, size;
|
||||||
|
|
||||||
|
c = stpcpy (regkey, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\"
|
||||||
|
"Parameters\\Interfaces\\");
|
||||||
|
stpcpy (c, name);
|
||||||
|
if ((ret = RegOpenKeyEx (HKEY_LOCAL_MACHINE, regkey, 0, KEY_READ,
|
||||||
|
&key)) != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
debug_printf ("RegOpenKeyEx(%s), win32 error %ld", ret);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* If DHCP is used, we have only one address. */
|
||||||
|
if ((ret = RegQueryValueEx (key, "EnableDHCP", NULL, NULL, (PBYTE) &dhcp,
|
||||||
|
(size = sizeof dhcp, &size))) == ERROR_SUCCESS
|
||||||
|
&& dhcp == 0
|
||||||
|
&& (ret = RegQueryValueEx (key, "IPAddress", NULL, NULL, NULL,
|
||||||
|
&size)) == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
char *ipa = (char *) alloca (size);
|
||||||
|
RegQueryValueEx (key, "IPAddress", NULL, NULL, (PBYTE) ipa, &size);
|
||||||
|
for (ifs = 0, c = ipa; *c; c += strlen (c) + 1)
|
||||||
|
ifs++;
|
||||||
|
}
|
||||||
|
RegCloseKey (key);
|
||||||
|
return ifs;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_ipv4fromreg (struct ifall *ifp, const char *name, DWORD idx)
|
||||||
|
{
|
||||||
|
HKEY key;
|
||||||
|
LONG ret;
|
||||||
|
char regkey[256], *c;
|
||||||
|
DWORD ifs;
|
||||||
|
DWORD dhcp, size;
|
||||||
|
|
||||||
|
c = stpcpy (regkey, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\"
|
||||||
|
"Parameters\\Interfaces\\");
|
||||||
|
stpcpy (c, name);
|
||||||
|
if ((ret = RegOpenKeyEx (HKEY_LOCAL_MACHINE, regkey, 0, KEY_READ, &key))
|
||||||
|
!= ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
debug_printf ("RegOpenKeyEx(%s), win32 error %ld", ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* If DHCP is used, we have only one address. */
|
||||||
|
if ((ret = RegQueryValueEx (key, "EnableDHCP", NULL, NULL, (PBYTE) &dhcp,
|
||||||
|
(size = sizeof dhcp, &size))) == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
#define addr ((struct sockaddr_in *) &ifp->ifa_addr)
|
||||||
|
#define mask ((struct sockaddr_in *) &ifp->ifa_netmask)
|
||||||
|
#define brdc ((struct sockaddr_in *) &ifp->ifa_brddstaddr)
|
||||||
|
if (dhcp)
|
||||||
|
{
|
||||||
|
if ((ret = RegQueryValueEx (key, "DhcpIPAddress", NULL, NULL,
|
||||||
|
(PBYTE) regkey, (size = 256, &size)))
|
||||||
|
== ERROR_SUCCESS)
|
||||||
|
cygwin_inet_aton (regkey, &addr->sin_addr);
|
||||||
|
if ((ret = RegQueryValueEx (key, "DhcpSubnetMask", NULL, NULL,
|
||||||
|
(PBYTE) regkey, (size = 256, &size)))
|
||||||
|
== ERROR_SUCCESS)
|
||||||
|
cygwin_inet_aton (regkey, &mask->sin_addr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((ret = RegQueryValueEx (key, "IPAddress", NULL, NULL, NULL,
|
||||||
|
&size)) == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
char *ipa = (char *) alloca (size);
|
||||||
|
RegQueryValueEx (key, "IPAddress", NULL, NULL, (PBYTE) ipa, &size);
|
||||||
|
for (ifs = 0, c = ipa; *c && ifs < idx; c += strlen (c) + 1)
|
||||||
|
ifs++;
|
||||||
|
if (*c)
|
||||||
|
cygwin_inet_aton (c, &addr->sin_addr);
|
||||||
|
}
|
||||||
|
if ((ret = RegQueryValueEx (key, "SubnetMask", NULL, NULL, NULL,
|
||||||
|
&size)) == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
char *ipa = (char *) alloca (size);
|
||||||
|
RegQueryValueEx (key, "SubnetMask", NULL, NULL, (PBYTE) ipa, &size);
|
||||||
|
for (ifs = 0, c = ipa; *c && ifs < idx; c += strlen (c) + 1)
|
||||||
|
ifs++;
|
||||||
|
if (*c)
|
||||||
|
cygwin_inet_aton (c, &mask->sin_addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ifp->ifa_ifa.ifa_flags & IFF_BROADCAST)
|
||||||
|
brdc->sin_addr.s_addr = (addr->sin_addr.s_addr
|
||||||
|
& mask->sin_addr.s_addr)
|
||||||
|
| ~mask->sin_addr.s_addr;
|
||||||
|
#undef addr
|
||||||
|
#undef mask
|
||||||
|
#undef brdc
|
||||||
|
}
|
||||||
|
RegCloseKey (key);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_friendlyname (struct ifall *ifp, PIP_ADAPTER_ADDRESSES pap)
|
||||||
|
{
|
||||||
|
struct ifreq_frndlyname *iff = (struct ifreq_frndlyname *)
|
||||||
|
&ifp->ifa_frndlyname;
|
||||||
|
iff->ifrf_len = sys_wcstombs (iff->ifrf_friendlyname,
|
||||||
|
IFRF_FRIENDLYNAMESIZ,
|
||||||
|
pap->FriendlyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
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';
|
||||||
|
else
|
||||||
|
ifp->ifa_hwaddr.sa_data[i] = pap->PhysicalAddress[i];
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Get network interfaces XP SP1 and above.
|
* Get network interfaces XP SP1 and above.
|
||||||
* Use IP Helper function GetAdaptersAddresses.
|
* Use IP Helper function GetAdaptersAddresses.
|
||||||
|
@ -1605,7 +1748,15 @@ get_xp_ifs (ULONG family)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
for (pap = pa0; pap; pap = pap->Next)
|
for (pap = pa0; pap; pap = pap->Next)
|
||||||
for (pua = pap->FirstUnicastAddress; pua; pua = pua->Next)
|
if (!pap->FirstUnicastAddress)
|
||||||
|
{
|
||||||
|
/* FirstUnicastAddress is NULL for interfaces which are disconnected.
|
||||||
|
Fetch number of configured IPva addresses from registry and
|
||||||
|
store in an unused member of the adapter addresses structure. */
|
||||||
|
pap->Ipv6IfIndex = get_ipv4fromreg_ipcnt (pap->AdapterName);
|
||||||
|
cnt += pap->Ipv6IfIndex;
|
||||||
|
}
|
||||||
|
else for (pua = pap->FirstUnicastAddress; pua; pua = pua->Next)
|
||||||
++cnt;
|
++cnt;
|
||||||
|
|
||||||
if (!(ifret = (struct ifall *) calloc (cnt, sizeof (struct ifall))))
|
if (!(ifret = (struct ifall *) calloc (cnt, sizeof (struct ifall))))
|
||||||
|
@ -1614,8 +1765,48 @@ get_xp_ifs (ULONG family)
|
||||||
|
|
||||||
for (pap = pa0; pap; pap = pap->Next)
|
for (pap = pa0; pap; pap = pap->Next)
|
||||||
{
|
{
|
||||||
int idx = 0;
|
DWORD idx = 0;
|
||||||
for (pua = pap->FirstUnicastAddress; pua; pua = pua->Next)
|
if (!pap->FirstUnicastAddress)
|
||||||
|
for (idx = 0; idx < pap->Ipv6IfIndex; ++idx)
|
||||||
|
{
|
||||||
|
/* Next in chain */
|
||||||
|
ifp->ifa_ifa.ifa_next = (struct ifaddrs *) &ifp[1].ifa_ifa;
|
||||||
|
/* Interface name */
|
||||||
|
if (idx)
|
||||||
|
__small_sprintf (ifp->ifa_name, "%s:%u", pap->AdapterName, idx);
|
||||||
|
else
|
||||||
|
strcpy (ifp->ifa_name, pap->AdapterName);
|
||||||
|
ifp->ifa_ifa.ifa_name = ifp->ifa_name;
|
||||||
|
/* Flags */
|
||||||
|
ifp->ifa_ifa.ifa_flags = get_flags (pap);
|
||||||
|
if (pap->IfType != IF_TYPE_PPP)
|
||||||
|
ifp->ifa_ifa.ifa_flags |= IFF_BROADCAST;
|
||||||
|
/* Address */
|
||||||
|
ifp->ifa_addr.ss_family = AF_INET;
|
||||||
|
ifp->ifa_ifa.ifa_addr = (struct sockaddr *) &ifp->ifa_addr;
|
||||||
|
/* Broadcast/Destination address */
|
||||||
|
ifp->ifa_brddstaddr.ss_family = AF_INET;
|
||||||
|
ifp->ifa_ifa.ifa_dstaddr = NULL;
|
||||||
|
/* Netmask */
|
||||||
|
ifp->ifa_netmask.ss_family = AF_INET;
|
||||||
|
ifp->ifa_ifa.ifa_netmask = (struct sockaddr *) &ifp->ifa_netmask;
|
||||||
|
/* Try to fetch real IPv4 address information from registry. */
|
||||||
|
get_ipv4fromreg (ifp, pap->AdapterName, idx);
|
||||||
|
/* Hardware address */
|
||||||
|
get_hwaddr (ifp, pap);
|
||||||
|
/* Metric */
|
||||||
|
ifp->ifa_metric = 1;
|
||||||
|
/* MTU */
|
||||||
|
ifp->ifa_mtu = pap->Mtu;
|
||||||
|
/* Interface index */
|
||||||
|
ifp->ifa_ifindex = pap->IfIndex;
|
||||||
|
/* Friendly name */
|
||||||
|
get_friendlyname (ifp, pap);
|
||||||
|
++ifp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
for (idx = 0, pua = pap->FirstUnicastAddress; pua;
|
||||||
|
++idx, pua = pua->Next)
|
||||||
{
|
{
|
||||||
struct sockaddr *sa = (struct sockaddr *) pua->Address.lpSockaddr;
|
struct sockaddr *sa = (struct sockaddr *) pua->Address.lpSockaddr;
|
||||||
# define sin ((struct sockaddr_in *) sa)
|
# define sin ((struct sockaddr_in *) sa)
|
||||||
|
@ -1625,29 +1816,17 @@ get_xp_ifs (ULONG family)
|
||||||
/* Next in chain */
|
/* Next in chain */
|
||||||
ifp->ifa_ifa.ifa_next = (struct ifaddrs *) &ifp[1].ifa_ifa;
|
ifp->ifa_ifa.ifa_next = (struct ifaddrs *) &ifp[1].ifa_ifa;
|
||||||
/* Interface name */
|
/* Interface name */
|
||||||
if (!idx)
|
if (idx && sa->sa_family == AF_INET)
|
||||||
strcpy (ifp->ifa_name, pap->AdapterName);
|
|
||||||
else
|
|
||||||
__small_sprintf (ifp->ifa_name, "%s:%u", pap->AdapterName, idx);
|
__small_sprintf (ifp->ifa_name, "%s:%u", pap->AdapterName, idx);
|
||||||
|
else
|
||||||
|
strcpy (ifp->ifa_name, pap->AdapterName);
|
||||||
ifp->ifa_ifa.ifa_name = ifp->ifa_name;
|
ifp->ifa_ifa.ifa_name = ifp->ifa_name;
|
||||||
++idx;
|
|
||||||
/* Flags */
|
/* Flags */
|
||||||
ifp->ifa_ifa.ifa_flags = IFF_UP;
|
ifp->ifa_ifa.ifa_flags = get_flags (pap);
|
||||||
if (pap->IfType == IF_TYPE_SOFTWARE_LOOPBACK)
|
if (sa->sa_family == AF_INET
|
||||||
ifp->ifa_ifa.ifa_flags |= IFF_LOOPBACK;
|
&& pap->IfType != IF_TYPE_SOFTWARE_LOOPBACK
|
||||||
else if (pap->IfType == IF_TYPE_PPP)
|
&& pap->IfType != IF_TYPE_PPP)
|
||||||
ifp->ifa_ifa.ifa_flags |= IFF_POINTOPOINT;
|
|
||||||
else if (sa->sa_family == AF_INET)
|
|
||||||
ifp->ifa_ifa.ifa_flags |= IFF_BROADCAST;
|
ifp->ifa_ifa.ifa_flags |= IFF_BROADCAST;
|
||||||
if (!(pap->Flags & IP_ADAPTER_NO_MULTICAST))
|
|
||||||
ifp->ifa_ifa.ifa_flags |= IFF_MULTICAST;
|
|
||||||
if (pap->OperStatus == IfOperStatusUp
|
|
||||||
|| pap->OperStatus == IfOperStatusUnknown)
|
|
||||||
ifp->ifa_ifa.ifa_flags |= IFF_RUNNING;
|
|
||||||
if (pap->OperStatus != IfOperStatusLowerLayerDown)
|
|
||||||
ifp->ifa_ifa.ifa_flags |= IFF_LOWER_UP;
|
|
||||||
if (pap->OperStatus == IfOperStatusDormant)
|
|
||||||
ifp->ifa_ifa.ifa_flags |= IFF_DORMANT;
|
|
||||||
if (sa->sa_family == AF_INET)
|
if (sa->sa_family == AF_INET)
|
||||||
{
|
{
|
||||||
ULONG hwaddr[2], hwlen = 6;
|
ULONG hwaddr[2], hwlen = 6;
|
||||||
|
@ -1698,7 +1877,8 @@ get_xp_ifs (ULONG family)
|
||||||
if_sin = (struct sockaddr_in *) &ifp->ifa_brddstaddr;
|
if_sin = (struct sockaddr_in *) &ifp->ifa_brddstaddr;
|
||||||
uint32_t mask =
|
uint32_t mask =
|
||||||
((struct sockaddr_in *) &ifp->ifa_netmask)->sin_addr.s_addr;
|
((struct sockaddr_in *) &ifp->ifa_netmask)->sin_addr.s_addr;
|
||||||
if_sin->sin_addr.s_addr = (sin->sin_addr.s_addr & mask) | ~mask;
|
if_sin->sin_addr.s_addr = (sin->sin_addr.s_addr & mask)
|
||||||
|
| ~mask;
|
||||||
if_sin->sin_family = AF_INET;
|
if_sin->sin_family = AF_INET;
|
||||||
ifp->ifa_ifa.ifa_broadaddr = (struct sockaddr *)
|
ifp->ifa_ifa.ifa_broadaddr = (struct sockaddr *)
|
||||||
&ifp->ifa_brddstaddr;
|
&ifp->ifa_brddstaddr;
|
||||||
|
@ -1707,11 +1887,7 @@ get_xp_ifs (ULONG family)
|
||||||
ifp->ifa_ifa.ifa_broadaddr = NULL;
|
ifp->ifa_ifa.ifa_broadaddr = NULL;
|
||||||
}
|
}
|
||||||
/* Hardware address */
|
/* Hardware address */
|
||||||
for (UINT i = 0; i < IFHWADDRLEN; ++i)
|
get_hwaddr (ifp, pap);
|
||||||
if (i >= pap->PhysicalAddressLength)
|
|
||||||
ifp->ifa_hwaddr.sa_data[i] = '\0';
|
|
||||||
else
|
|
||||||
ifp->ifa_hwaddr.sa_data[i] = pap->PhysicalAddress[i];
|
|
||||||
/* Metric */
|
/* Metric */
|
||||||
if (wincap.has_gaa_on_link_prefix ())
|
if (wincap.has_gaa_on_link_prefix ())
|
||||||
ifp->ifa_metric = (sa->sa_family == AF_INET
|
ifp->ifa_metric = (sa->sa_family == AF_INET
|
||||||
|
@ -1724,11 +1900,7 @@ get_xp_ifs (ULONG family)
|
||||||
/* Interface index */
|
/* Interface index */
|
||||||
ifp->ifa_ifindex = pap->IfIndex;
|
ifp->ifa_ifindex = pap->IfIndex;
|
||||||
/* Friendly name */
|
/* Friendly name */
|
||||||
struct ifreq_frndlyname *iff = (struct ifreq_frndlyname *)
|
get_friendlyname (ifp, pap);
|
||||||
&ifp->ifa_frndlyname;
|
|
||||||
iff->ifrf_len = sys_wcstombs (iff->ifrf_friendlyname,
|
|
||||||
IFRF_FRIENDLYNAMESIZ,
|
|
||||||
pap->FriendlyName);
|
|
||||||
++ifp;
|
++ifp;
|
||||||
# undef sin
|
# undef sin
|
||||||
# undef sin6
|
# undef sin6
|
||||||
|
|
Loading…
Reference in New Issue