* autoload.cc: Add LoadDLLinitfunc for iphlpapi.dll.
Add LoadDLLfuncEx statements for GetIfTable@12 and GetIpAddrTable@12. * fhandler_socket.cc (fhandler_socket::ioctl): Move variable definitions to the beginning of the function to allow better debugging. Add handling for SIOCGIFHWADDR, SIOCGIFMETRIC and SIOCGIFMTU. * net.cc: Include iphlpapi.h. (get_2k_ifconf): Rewritten. Uses IP Helper API now. (get_nt_ifconf): Add handling for SIOCGIFHWADDR, SIOCGIFMETRIC and SIOCGIFMTU. (get_95_ifconf): Ditto. Renamed from `get_9x_ifconf'. (get_ifconf): Name loopback `lo' instead of `lo0' as in Linux. Add handling for SIOCGIFHWADDR, SIOCGIFMETRIC and SIOCGIFMTU. Call `get_95_ifconf' only on Windows 95, `get_nt_ifconf' only on Windows NT < Service Pack 3, `get_2k_ifconf otherwise. * include/asm/socket.h: Add defines for SIOCGIFHWADDR, SIOCGIFMETRIC and SIOCGIFMTU. * include/cygwin/if.h: Add `ifr_hwaddr', `ifr_metric' and `ifr_mtu'. (struct ifreq): Add `ifru_hwaddr'.
This commit is contained in:
parent
93ac448707
commit
9182099c10
@ -1,3 +1,24 @@
|
||||
Wed Feb 7 22:22:00 2001 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* autoload.cc: Add LoadDLLinitfunc for iphlpapi.dll.
|
||||
Add LoadDLLfuncEx statements for GetIfTable@12 and GetIpAddrTable@12.
|
||||
* fhandler_socket.cc (fhandler_socket::ioctl): Move variable
|
||||
definitions to the beginning of the function to allow better debugging.
|
||||
Add handling for SIOCGIFHWADDR, SIOCGIFMETRIC and SIOCGIFMTU.
|
||||
* net.cc: Include iphlpapi.h.
|
||||
(get_2k_ifconf): Rewritten. Uses IP Helper API now.
|
||||
(get_nt_ifconf): Add handling for SIOCGIFHWADDR, SIOCGIFMETRIC
|
||||
and SIOCGIFMTU.
|
||||
(get_95_ifconf): Ditto. Renamed from `get_9x_ifconf'.
|
||||
(get_ifconf): Name loopback `lo' instead of `lo0' as in Linux.
|
||||
Add handling for SIOCGIFHWADDR, SIOCGIFMETRIC and SIOCGIFMTU.
|
||||
Call `get_95_ifconf' only on Windows 95, `get_nt_ifconf' only
|
||||
on Windows NT < Service Pack 3, `get_2k_ifconf otherwise.
|
||||
* include/asm/socket.h: Add defines for SIOCGIFHWADDR, SIOCGIFMETRIC
|
||||
and SIOCGIFMTU.
|
||||
* include/cygwin/if.h: Add `ifr_hwaddr', `ifr_metric' and `ifr_mtu'.
|
||||
(struct ifreq): Add `ifru_hwaddr'.
|
||||
|
||||
Tue Feb 6 15:04:00 2001 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* syscalls.cc (stat_worker): Add a check for the special case when
|
||||
|
@ -175,6 +175,28 @@ LoadDLLinitfunc (ws2_32)
|
||||
return 0;
|
||||
}
|
||||
|
||||
LoadDLLinitfunc (iphlpapi)
|
||||
{
|
||||
HANDLE h;
|
||||
static NO_COPY LONG here = -1L;
|
||||
|
||||
while (InterlockedIncrement (&here))
|
||||
{
|
||||
InterlockedDecrement (&here);
|
||||
Sleep (0);
|
||||
}
|
||||
|
||||
if (iphlpapi_handle)
|
||||
/* nothing to do */;
|
||||
else if ((h = LoadLibrary ("iphlpapi.dll")) != NULL)
|
||||
iphlpapi_handle = h;
|
||||
else if (!iphlpapi_handle)
|
||||
api_fatal ("could not load iphlpapi.dll, %E");
|
||||
|
||||
InterlockedDecrement (&here);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __stdcall dummy_autoload (void) __attribute__ ((unused));
|
||||
static void __stdcall
|
||||
dummy_autoload (void)
|
||||
@ -313,5 +335,9 @@ LoadDLLfunc (socket, 12, wsock32)
|
||||
LoadDLLinit (ws2_32)
|
||||
LoadDLLfuncEx (WSADuplicateSocketA, 12, ws2_32, 1)
|
||||
LoadDLLfuncEx (WSASocketA, 24, ws2_32, 1)
|
||||
|
||||
LoadDLLinit (iphlpapi)
|
||||
LoadDLLfuncEx (GetIfTable, 12, iphlpapi, 1)
|
||||
LoadDLLfuncEx (GetIpAddrTable, 12, iphlpapi, 1)
|
||||
}
|
||||
}
|
||||
|
@ -159,20 +159,20 @@ fhandler_socket::ioctl (unsigned int cmd, void *p)
|
||||
{
|
||||
extern int get_ifconf (struct ifconf *ifc, int what); /* net.cc */
|
||||
int res;
|
||||
struct ifconf *ifc;
|
||||
struct ifreq *ifr;
|
||||
struct ifconf ifc, *ifcp;
|
||||
struct ifreq *ifr, *ifrp;
|
||||
sigframe thisframe (mainthread);
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case SIOCGIFCONF:
|
||||
ifc = (struct ifconf *) p;
|
||||
if (ifc == 0)
|
||||
ifcp = (struct ifconf *) p;
|
||||
if (!ifcp)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
res = get_ifconf (ifc, cmd);
|
||||
res = get_ifconf (ifcp, cmd);
|
||||
if (res)
|
||||
debug_printf ("error in get_ifconf\n");
|
||||
break;
|
||||
@ -194,14 +194,14 @@ fhandler_socket::ioctl (unsigned int cmd, void *p)
|
||||
case SIOCGIFBRDADDR:
|
||||
case SIOCGIFNETMASK:
|
||||
case SIOCGIFADDR:
|
||||
case SIOCGIFHWADDR:
|
||||
case SIOCGIFMETRIC:
|
||||
case SIOCGIFMTU:
|
||||
{
|
||||
char buf[2048];
|
||||
struct ifconf ifc;
|
||||
ifc.ifc_len = sizeof (buf);
|
||||
ifc.ifc_buf = buf;
|
||||
struct ifreq *ifrp;
|
||||
ifc.ifc_len = 2048;
|
||||
ifc.ifc_buf = (char *) alloca (2048);
|
||||
|
||||
struct ifreq *ifr = (struct ifreq *) p;
|
||||
ifr = (struct ifreq *) p;
|
||||
if (ifr == 0)
|
||||
{
|
||||
debug_printf ("ifr == NULL\n");
|
||||
@ -235,6 +235,15 @@ fhandler_socket::ioctl (unsigned int cmd, void *p)
|
||||
case SIOCGIFNETMASK:
|
||||
ifr->ifr_netmask = ifrp->ifr_netmask;
|
||||
break;
|
||||
case SIOCGIFHWADDR:
|
||||
ifr->ifr_hwaddr = ifrp->ifr_hwaddr;
|
||||
break;
|
||||
case SIOCGIFMETRIC:
|
||||
ifr->ifr_metric = ifrp->ifr_metric;
|
||||
break;
|
||||
case SIOCGIFMTU:
|
||||
ifr->ifr_mtu = ifrp->ifr_mtu;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -23,11 +23,14 @@
|
||||
#define SIOCGLOWAT _IOR('s', 3, u_long) /* get low watermark */
|
||||
|
||||
/* Needed for if queries */
|
||||
#define SIOCGIFCONF _IOW('s', 100, struct ifconf) /* get if list */
|
||||
#define SIOCGIFFLAGS _IOW('s', 101, struct ifreq) /* Get if flags */
|
||||
#define SIOCGIFADDR _IOW('s', 102, struct ifreq) /* Get if addr */
|
||||
#define SIOCGIFCONF _IOW('s', 100, struct ifconf) /* get if list */
|
||||
#define SIOCGIFFLAGS _IOW('s', 101, struct ifreq) /* Get if flags */
|
||||
#define SIOCGIFADDR _IOW('s', 102, struct ifreq) /* Get if addr */
|
||||
#define SIOCGIFBRDADDR _IOW('s', 103, struct ifreq) /* Get if broadcastaddr */
|
||||
#define SIOCGIFNETMASK _IOW('s', 104, struct ifreq) /* Get if netmask */
|
||||
#define SIOCGIFHWADDR _IOW('s', 105, struct ifreq) /* Get hw addr */
|
||||
#define SIOCGIFMETRIC _IOW('s', 106, struct ifreq) /* get metric */
|
||||
#define SIOCGIFMTU _IOW('s', 107, struct ifreq) /* get MTU size */
|
||||
|
||||
#define SOL_SOCKET 0xffff /* options for socket level */
|
||||
|
||||
|
@ -27,6 +27,7 @@ extern "C" {
|
||||
struct ifreq
|
||||
{
|
||||
#define IFNAMSIZ 16
|
||||
#define IFHWADDRLEN 6
|
||||
union
|
||||
{
|
||||
char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */
|
||||
@ -36,6 +37,7 @@ struct ifreq
|
||||
struct sockaddr ifru_addr;
|
||||
struct sockaddr ifru_broadaddr;
|
||||
struct sockaddr ifru_netmask;
|
||||
struct sockaddr ifru_hwaddr;
|
||||
short ifru_flags;
|
||||
int ifru_metric;
|
||||
int ifru_mtu;
|
||||
@ -47,6 +49,10 @@ struct ifreq
|
||||
#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
|
||||
#define ifr_netmask ifr_ifru.ifru_netmask /* interface net mask */
|
||||
#define ifr_flags ifr_ifru.ifru_flags /* flags */
|
||||
#define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */
|
||||
#define ifr_metric ifr_ifru.ifru_metric /* metric */
|
||||
#define ifr_mtu ifr_ifru.ifru_mtu /* mtu */
|
||||
|
||||
|
||||
/*
|
||||
* Structure used in SIOCGIFCONF request.
|
||||
|
@ -17,6 +17,7 @@ details. */
|
||||
#include <errno.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <iphlpapi.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <netdb.h>
|
||||
@ -1048,159 +1049,120 @@ getdomainname (char *domain, int len)
|
||||
/* Fill out an ifconf struct. */
|
||||
|
||||
/*
|
||||
* IFCONF Windows 2000:
|
||||
* Look at HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\
|
||||
Parameters\Interfaces
|
||||
* Each subkey is an interface.
|
||||
* IFCONF 98/ME, NTSP4, W2K:
|
||||
* Use IP Helper Library
|
||||
*/
|
||||
static void
|
||||
get_2k_ifconf (struct ifconf *ifc, int what)
|
||||
{
|
||||
HKEY key;
|
||||
int cnt = 1;
|
||||
int cnt = 0;
|
||||
char eth[2] = "/", ppp[2] = "/", slp[2] = "/";
|
||||
|
||||
/* Union maps buffer to correct struct */
|
||||
struct ifreq *ifr = ifc->ifc_req;
|
||||
|
||||
if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,
|
||||
"SYSTEM\\"
|
||||
"CurrentControlSet\\"
|
||||
"Services\\"
|
||||
"Tcpip\\"
|
||||
"Parameters\\"
|
||||
"Interfaces",
|
||||
0, KEY_READ, &key) == ERROR_SUCCESS)
|
||||
DWORD if_cnt, ip_cnt, lip, lnp;
|
||||
DWORD siz_if_table = 0;
|
||||
DWORD siz_ip_table = 0;
|
||||
PMIB_IFTABLE ift;
|
||||
PMIB_IPADDRTABLE ipt;
|
||||
struct sockaddr_in *sa = NULL;
|
||||
struct sockaddr *so = NULL;
|
||||
|
||||
if (GetIfTable(NULL, &siz_if_table, TRUE) == ERROR_INSUFFICIENT_BUFFER &&
|
||||
GetIpAddrTable(NULL, &siz_ip_table, TRUE) == ERROR_INSUFFICIENT_BUFFER &&
|
||||
(ift = (PMIB_IFTABLE) alloca (siz_if_table)) &&
|
||||
(ipt = (PMIB_IPADDRTABLE) alloca (siz_ip_table)) &&
|
||||
!GetIfTable(ift, &siz_if_table, TRUE) &&
|
||||
!GetIpAddrTable(ipt, &siz_ip_table, TRUE))
|
||||
{
|
||||
HKEY ikey;
|
||||
unsigned long lip, lnp;
|
||||
struct sockaddr_in *sa = NULL;
|
||||
char name[256];
|
||||
DWORD size;
|
||||
char eth[2] = "/", ppp[2] = "/";
|
||||
|
||||
for (int idx = 0;
|
||||
RegEnumKeyEx (key, idx, name, (size = 256, &size),
|
||||
NULL, NULL, 0, NULL) == ERROR_SUCCESS;
|
||||
++idx)
|
||||
for (if_cnt = 0; if_cnt < ift->dwNumEntries; ++if_cnt)
|
||||
{
|
||||
if (RegOpenKeyEx (key, name, 0, KEY_READ, &ikey) != ERROR_SUCCESS)
|
||||
continue;
|
||||
|
||||
/* If the "NTEContextList" value not exists, the subkey
|
||||
is irrelevant. */
|
||||
if (RegQueryValueEx (ikey, "NTEContextList",
|
||||
NULL, NULL, NULL, &size) != ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey (ikey);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((caddr_t) ++ifr > ifc->ifc_buf
|
||||
+ ifc->ifc_len
|
||||
- sizeof (struct ifreq))
|
||||
{
|
||||
RegCloseKey (ikey);
|
||||
break;
|
||||
}
|
||||
|
||||
char ipaddress[256], netmask[256];
|
||||
char dhcpaddress[256], dhcpnetmask[256];
|
||||
|
||||
if (RegQueryValueEx (ikey, "IPAddress",
|
||||
NULL, NULL,
|
||||
(unsigned char *) ipaddress,
|
||||
(size = 256, &size)) == ERROR_SUCCESS
|
||||
&& RegQueryValueEx (ikey, "SubnetMask",
|
||||
NULL, NULL,
|
||||
(unsigned char *) netmask,
|
||||
(size = 256, &size)) == ERROR_SUCCESS)
|
||||
{
|
||||
/* ppp interfaces don't have the "AddressType" value. */
|
||||
if (RegQueryValueEx (ikey, "AddressType",
|
||||
NULL, NULL, NULL, &size) == ERROR_SUCCESS)
|
||||
{
|
||||
++*eth;
|
||||
strcpy (ifr->ifr_name, "eth");
|
||||
strcat (ifr->ifr_name, eth);
|
||||
}
|
||||
else
|
||||
{
|
||||
++*ppp;
|
||||
strcpy (ifr->ifr_name, "ppp");
|
||||
strcat (ifr->ifr_name, ppp);
|
||||
}
|
||||
|
||||
memset (&ifr->ifr_addr, '\0', sizeof ifr->ifr_addr);
|
||||
if (cygwin_inet_addr (ipaddress) == 0L
|
||||
&& RegQueryValueEx (ikey, "DhcpIPAddress",
|
||||
NULL, NULL,
|
||||
(unsigned char *) dhcpaddress,
|
||||
(size = 256, &size))
|
||||
== ERROR_SUCCESS
|
||||
&& RegQueryValueEx (ikey, "DhcpSubnetMask",
|
||||
NULL, NULL,
|
||||
(unsigned char *) dhcpnetmask,
|
||||
(size = 256, &size))
|
||||
== ERROR_SUCCESS)
|
||||
{
|
||||
switch (what)
|
||||
{
|
||||
case SIOCGIFCONF:
|
||||
case SIOCGIFADDR:
|
||||
sa = (struct sockaddr_in *) &ifr->ifr_addr;
|
||||
sa->sin_addr.s_addr = cygwin_inet_addr (dhcpaddress);
|
||||
break;
|
||||
case SIOCGIFBRDADDR:
|
||||
lip = cygwin_inet_addr (dhcpaddress);
|
||||
lnp = cygwin_inet_addr (dhcpnetmask);
|
||||
sa = (struct sockaddr_in *) &ifr->ifr_broadaddr;
|
||||
sa->sin_addr.s_addr = lip & lnp | ~lnp;
|
||||
break;
|
||||
case SIOCGIFNETMASK:
|
||||
sa = (struct sockaddr_in *) &ifr->ifr_netmask;
|
||||
sa->sin_addr.s_addr =
|
||||
cygwin_inet_addr (dhcpnetmask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (what)
|
||||
{
|
||||
case SIOCGIFCONF:
|
||||
case SIOCGIFADDR:
|
||||
sa = (struct sockaddr_in *) &ifr->ifr_addr;
|
||||
sa->sin_addr.s_addr = cygwin_inet_addr (ipaddress);
|
||||
break;
|
||||
case SIOCGIFBRDADDR:
|
||||
lip = cygwin_inet_addr (ipaddress);
|
||||
lnp = cygwin_inet_addr (netmask);
|
||||
sa = (struct sockaddr_in *) &ifr->ifr_broadaddr;
|
||||
sa->sin_addr.s_addr = lip & lnp | ~lnp;
|
||||
break;
|
||||
case SIOCGIFNETMASK:
|
||||
sa = (struct sockaddr_in *) &ifr->ifr_netmask;
|
||||
sa->sin_addr.s_addr = cygwin_inet_addr (netmask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
sa->sin_family = AF_INET;
|
||||
sa->sin_port = 0;
|
||||
++cnt;
|
||||
}
|
||||
|
||||
RegCloseKey (ikey);
|
||||
}
|
||||
|
||||
RegCloseKey (key);
|
||||
switch (ift->table[if_cnt].dwType)
|
||||
{
|
||||
case MIB_IF_TYPE_ETHERNET:
|
||||
++*eth;
|
||||
strcpy (ifr->ifr_name, "eth");
|
||||
strcat (ifr->ifr_name, eth);
|
||||
break;
|
||||
case MIB_IF_TYPE_PPP:
|
||||
++*ppp;
|
||||
strcpy (ifr->ifr_name, "ppp");
|
||||
strcat (ifr->ifr_name, ppp);
|
||||
break;
|
||||
case MIB_IF_TYPE_SLIP:
|
||||
++*slp;
|
||||
strcpy (ifr->ifr_name, "slp");
|
||||
strcat (ifr->ifr_name, slp);
|
||||
break;
|
||||
case MIB_IF_TYPE_LOOPBACK:
|
||||
strcpy (ifr->ifr_name, "lo");
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
for (ip_cnt = 0; ip_cnt < ipt->dwNumEntries; ++ip_cnt)
|
||||
if (ipt->table[ip_cnt].dwIndex == ift->table[if_cnt].dwIndex)
|
||||
{
|
||||
switch (what)
|
||||
{
|
||||
case SIOCGIFCONF:
|
||||
case SIOCGIFADDR:
|
||||
sa = (struct sockaddr_in *) &ifr->ifr_addr;
|
||||
sa->sin_addr.s_addr = ipt->table[ip_cnt].dwAddr;
|
||||
sa->sin_family = AF_INET;
|
||||
sa->sin_port = 0;
|
||||
break;
|
||||
case SIOCGIFBRDADDR:
|
||||
sa = (struct sockaddr_in *) &ifr->ifr_broadaddr;
|
||||
#if 0
|
||||
/* Unfortunately, the field returns only crap. */
|
||||
sa->sin_addr.s_addr = ipt->table[ip_cnt].dwBCastAddr;
|
||||
#else
|
||||
lip = ipt->table[ip_cnt].dwAddr;
|
||||
lnp = ipt->table[ip_cnt].dwMask;
|
||||
sa->sin_addr.s_addr = lip & lnp | ~lnp;
|
||||
sa->sin_family = AF_INET;
|
||||
sa->sin_port = 0;
|
||||
#endif
|
||||
break;
|
||||
case SIOCGIFNETMASK:
|
||||
sa = (struct sockaddr_in *) &ifr->ifr_netmask;
|
||||
sa->sin_addr.s_addr = ipt->table[ip_cnt].dwMask;
|
||||
sa->sin_family = AF_INET;
|
||||
sa->sin_port = 0;
|
||||
break;
|
||||
case SIOCGIFHWADDR:
|
||||
so = &ifr->ifr_hwaddr;
|
||||
for (UINT i = 0; i < IFHWADDRLEN; ++i)
|
||||
if (i >= ift->table[if_cnt].dwPhysAddrLen)
|
||||
so->sa_data[i] = '\0';
|
||||
else
|
||||
so->sa_data[i] = ift->table[if_cnt].bPhysAddr[i];
|
||||
so->sa_family = AF_INET;
|
||||
break;
|
||||
case SIOCGIFMETRIC:
|
||||
ifr->ifr_metric = 1;
|
||||
break;
|
||||
case SIOCGIFMTU:
|
||||
ifr->ifr_mtu = ift->table[if_cnt].dwMtu;
|
||||
break;
|
||||
}
|
||||
++cnt;
|
||||
if ((caddr_t) ++ifr >
|
||||
ifc->ifc_buf + ifc->ifc_len - sizeof (struct ifreq))
|
||||
goto done;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
/* Set the correct length */
|
||||
ifc->ifc_len = cnt * sizeof (struct ifreq);
|
||||
}
|
||||
|
||||
/*
|
||||
* IFCONF Windows NT:
|
||||
* IFCONF Windows NT < SP4:
|
||||
* Look at the Bind value in
|
||||
* HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Linkage\
|
||||
* This is a REG_MULTI_SZ with strings of the form:
|
||||
@ -1217,6 +1179,7 @@ get_nt_ifconf (struct ifconf *ifc, int what)
|
||||
HKEY key;
|
||||
unsigned long lip, lnp;
|
||||
struct sockaddr_in *sa = NULL;
|
||||
struct sockaddr *so = NULL;
|
||||
DWORD size;
|
||||
int cnt = 1;
|
||||
char *binding = (char *) 0;
|
||||
@ -1315,18 +1278,35 @@ get_nt_ifconf (struct ifconf *ifc, int what)
|
||||
case SIOCGIFADDR:
|
||||
sa = (struct sockaddr_in *) &ifr->ifr_addr;
|
||||
sa->sin_addr.s_addr = cygwin_inet_addr (dhcpaddress);
|
||||
sa->sin_family = AF_INET;
|
||||
sa->sin_port = 0;
|
||||
break;
|
||||
case SIOCGIFBRDADDR:
|
||||
lip = cygwin_inet_addr (dhcpaddress);
|
||||
lnp = cygwin_inet_addr (dhcpnetmask);
|
||||
sa = (struct sockaddr_in *) &ifr->ifr_broadaddr;
|
||||
sa->sin_addr.s_addr = lip & lnp | ~lnp;
|
||||
sa->sin_family = AF_INET;
|
||||
sa->sin_port = 0;
|
||||
break;
|
||||
case SIOCGIFNETMASK:
|
||||
sa = (struct sockaddr_in *) &ifr->ifr_netmask;
|
||||
sa->sin_addr.s_addr =
|
||||
cygwin_inet_addr (dhcpnetmask);
|
||||
sa->sin_family = AF_INET;
|
||||
sa->sin_port = 0;
|
||||
break;
|
||||
case SIOCGIFHWADDR:
|
||||
so = &ifr->ifr_hwaddr;
|
||||
memset (so->sa_data, 0, IFHWADDRLEN);
|
||||
so->sa_family = AF_INET;
|
||||
break;
|
||||
case SIOCGIFMETRIC:
|
||||
ifr->ifr_metric = 1;
|
||||
break;
|
||||
case SIOCGIFMTU:
|
||||
ifr->ifr_mtu = 1500;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1337,21 +1317,36 @@ get_nt_ifconf (struct ifconf *ifc, int what)
|
||||
case SIOCGIFADDR:
|
||||
sa = (struct sockaddr_in *) &ifr->ifr_addr;
|
||||
sa->sin_addr.s_addr = cygwin_inet_addr (ip);
|
||||
sa->sin_family = AF_INET;
|
||||
sa->sin_port = 0;
|
||||
break;
|
||||
case SIOCGIFBRDADDR:
|
||||
lip = cygwin_inet_addr (ip);
|
||||
lnp = cygwin_inet_addr (np);
|
||||
sa = (struct sockaddr_in *) &ifr->ifr_broadaddr;
|
||||
sa->sin_addr.s_addr = lip & lnp | ~lnp;
|
||||
sa->sin_family = AF_INET;
|
||||
sa->sin_port = 0;
|
||||
break;
|
||||
case SIOCGIFNETMASK:
|
||||
sa = (struct sockaddr_in *) &ifr->ifr_netmask;
|
||||
sa->sin_addr.s_addr = cygwin_inet_addr (np);
|
||||
sa->sin_family = AF_INET;
|
||||
sa->sin_port = 0;
|
||||
break;
|
||||
case SIOCGIFHWADDR:
|
||||
so = &ifr->ifr_hwaddr;
|
||||
memset (so->sa_data, 0, IFHWADDRLEN);
|
||||
so->sa_family = AF_INET;
|
||||
break;
|
||||
case SIOCGIFMETRIC:
|
||||
ifr->ifr_metric = 1;
|
||||
break;
|
||||
case SIOCGIFMTU:
|
||||
ifr->ifr_mtu = 1500;
|
||||
break;
|
||||
}
|
||||
}
|
||||
sa->sin_family = AF_INET;
|
||||
sa->sin_port = 0;
|
||||
++cnt;
|
||||
}
|
||||
}
|
||||
@ -1364,7 +1359,7 @@ get_nt_ifconf (struct ifconf *ifc, int what)
|
||||
}
|
||||
|
||||
/*
|
||||
* IFCONF Windows 9x:
|
||||
* IFCONF Windows 95:
|
||||
* HKLM/Enum/Network/MSTCP/"*"
|
||||
* -> Value "Driver" enthält Subkey relativ zu
|
||||
* HKLM/System/CurrentControlSet/Class/
|
||||
@ -1381,11 +1376,12 @@ get_nt_ifconf (struct ifconf *ifc, int what)
|
||||
*
|
||||
*/
|
||||
static void
|
||||
get_9x_ifconf (struct ifconf *ifc, int what)
|
||||
get_95_ifconf (struct ifconf *ifc, int what)
|
||||
{
|
||||
HKEY key;
|
||||
unsigned long lip, lnp;
|
||||
struct sockaddr_in *sa = NULL;
|
||||
struct sockaddr *so = NULL;
|
||||
FILETIME update;
|
||||
LONG res;
|
||||
DWORD size;
|
||||
@ -1455,20 +1451,35 @@ get_9x_ifconf (struct ifconf *ifc, int what)
|
||||
case SIOCGIFADDR:
|
||||
sa = (struct sockaddr_in *) &ifr->ifr_addr;
|
||||
sa->sin_addr.s_addr = cygwin_inet_addr (ip);
|
||||
sa->sin_family = AF_INET;
|
||||
sa->sin_port = 0;
|
||||
break;
|
||||
case SIOCGIFBRDADDR:
|
||||
lip = cygwin_inet_addr (ip);
|
||||
lnp = cygwin_inet_addr (np);
|
||||
sa = (struct sockaddr_in *) &ifr->ifr_broadaddr;
|
||||
sa->sin_addr.s_addr = lip & lnp | ~lnp;
|
||||
sa->sin_family = AF_INET;
|
||||
sa->sin_port = 0;
|
||||
break;
|
||||
case SIOCGIFNETMASK:
|
||||
sa = (struct sockaddr_in *) &ifr->ifr_netmask;
|
||||
sa->sin_addr.s_addr = cygwin_inet_addr (np);
|
||||
sa->sin_family = AF_INET;
|
||||
sa->sin_port = 0;
|
||||
break;
|
||||
case SIOCGIFHWADDR:
|
||||
so = &ifr->ifr_hwaddr;
|
||||
memset (so->sa_data, 0, IFHWADDRLEN);
|
||||
so->sa_family = AF_INET;
|
||||
break;
|
||||
case SIOCGIFMETRIC:
|
||||
ifr->ifr_metric = 1;
|
||||
break;
|
||||
case SIOCGIFMTU:
|
||||
ifr->ifr_mtu = 1500;
|
||||
break;
|
||||
}
|
||||
sa->sin_family = AF_INET;
|
||||
sa->sin_port = 0;
|
||||
}
|
||||
|
||||
RegCloseKey (subkey);
|
||||
@ -1554,7 +1565,7 @@ get_ifconf (struct ifconf *ifc, int what)
|
||||
}
|
||||
|
||||
/* Set up interface lo0 first */
|
||||
strcpy (ifr->ifr_name, "lo0");
|
||||
strcpy (ifr->ifr_name, "lo");
|
||||
memset (&ifr->ifr_addr, '\0', sizeof (ifr->ifr_addr));
|
||||
switch (what)
|
||||
{
|
||||
@ -1562,32 +1573,56 @@ get_ifconf (struct ifconf *ifc, int what)
|
||||
case SIOCGIFADDR:
|
||||
sa = (struct sockaddr_in *) &ifr->ifr_addr;
|
||||
sa->sin_addr.s_addr = htonl (INADDR_LOOPBACK);
|
||||
sa->sin_family = AF_INET;
|
||||
sa->sin_port = 0;
|
||||
break;
|
||||
case SIOCGIFBRDADDR:
|
||||
lip = htonl (INADDR_LOOPBACK);
|
||||
lnp = cygwin_inet_addr ("255.0.0.0");
|
||||
sa = (struct sockaddr_in *) &ifr->ifr_broadaddr;
|
||||
sa->sin_addr.s_addr = lip & lnp | ~lnp;
|
||||
sa->sin_family = AF_INET;
|
||||
sa->sin_port = 0;
|
||||
break;
|
||||
case SIOCGIFNETMASK:
|
||||
sa = (struct sockaddr_in *) &ifr->ifr_netmask;
|
||||
sa->sin_addr.s_addr = cygwin_inet_addr ("255.0.0.0");
|
||||
sa->sin_family = AF_INET;
|
||||
sa->sin_port = 0;
|
||||
break;
|
||||
case SIOCGIFHWADDR:
|
||||
ifr->ifr_hwaddr.sa_family = AF_INET;
|
||||
memset (ifr->ifr_hwaddr.sa_data, 0, IFHWADDRLEN);
|
||||
break;
|
||||
case SIOCGIFMETRIC:
|
||||
ifr->ifr_metric = 1;
|
||||
break;
|
||||
case SIOCGIFMTU:
|
||||
/* This funny value is returned by `ifconfig lo' on Linux 2.2 kernel. */
|
||||
ifr->ifr_mtu = 3924;
|
||||
break;
|
||||
default:
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
sa->sin_family = AF_INET;
|
||||
sa->sin_port = 0;
|
||||
|
||||
OSVERSIONINFO os_version_info;
|
||||
memset (&os_version_info, 0, sizeof os_version_info);
|
||||
os_version_info.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
|
||||
GetVersionEx (&os_version_info);
|
||||
if (os_version_info.dwPlatformId != VER_PLATFORM_WIN32_NT)
|
||||
get_9x_ifconf (ifc, what);
|
||||
else if (os_version_info.dwMajorVersion <= 4)
|
||||
/* We have a win95 version... */
|
||||
if (os_version_info.dwPlatformId != VER_PLATFORM_WIN32_NT
|
||||
&& (os_version_info.dwMajorVersion < 4
|
||||
|| (os_version_info.dwMajorVersion == 4
|
||||
&& os_version_info.dwMinorVersion == 0)))
|
||||
get_95_ifconf (ifc, what);
|
||||
/* ...and a NT <= SP3 version... */
|
||||
else if (os_version_info.dwPlatformId == VER_PLATFORM_WIN32_NT
|
||||
&& (os_version_info.dwMajorVersion < 4
|
||||
|| (os_version_info.dwMajorVersion == 4
|
||||
&& strcmp (os_version_info.szCSDVersion, "Service Pack 4") < 0)))
|
||||
get_nt_ifconf (ifc, what);
|
||||
/* ...and finally a "modern" version for win98/ME, NT >= SP4 and W2K! */
|
||||
else
|
||||
get_2k_ifconf (ifc, what);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user