* 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:
Corinna Vinschen 2001-02-07 22:50:50 +00:00
parent 93ac448707
commit 9182099c10
6 changed files with 263 additions and 163 deletions

View File

@ -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> Tue Feb 6 15:04:00 2001 Corinna Vinschen <corinna@vinschen.de>
* syscalls.cc (stat_worker): Add a check for the special case when * syscalls.cc (stat_worker): Add a check for the special case when

View File

@ -175,6 +175,28 @@ LoadDLLinitfunc (ws2_32)
return 0; 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) __attribute__ ((unused));
static void __stdcall static void __stdcall
dummy_autoload (void) dummy_autoload (void)
@ -313,5 +335,9 @@ LoadDLLfunc (socket, 12, wsock32)
LoadDLLinit (ws2_32) LoadDLLinit (ws2_32)
LoadDLLfuncEx (WSADuplicateSocketA, 12, ws2_32, 1) LoadDLLfuncEx (WSADuplicateSocketA, 12, ws2_32, 1)
LoadDLLfuncEx (WSASocketA, 24, ws2_32, 1) LoadDLLfuncEx (WSASocketA, 24, ws2_32, 1)
LoadDLLinit (iphlpapi)
LoadDLLfuncEx (GetIfTable, 12, iphlpapi, 1)
LoadDLLfuncEx (GetIpAddrTable, 12, iphlpapi, 1)
} }
} }

View File

@ -159,20 +159,20 @@ fhandler_socket::ioctl (unsigned int cmd, void *p)
{ {
extern int get_ifconf (struct ifconf *ifc, int what); /* net.cc */ extern int get_ifconf (struct ifconf *ifc, int what); /* net.cc */
int res; int res;
struct ifconf *ifc; struct ifconf ifc, *ifcp;
struct ifreq *ifr; struct ifreq *ifr, *ifrp;
sigframe thisframe (mainthread); sigframe thisframe (mainthread);
switch (cmd) switch (cmd)
{ {
case SIOCGIFCONF: case SIOCGIFCONF:
ifc = (struct ifconf *) p; ifcp = (struct ifconf *) p;
if (ifc == 0) if (!ifcp)
{ {
set_errno (EINVAL); set_errno (EINVAL);
return -1; return -1;
} }
res = get_ifconf (ifc, cmd); res = get_ifconf (ifcp, cmd);
if (res) if (res)
debug_printf ("error in get_ifconf\n"); debug_printf ("error in get_ifconf\n");
break; break;
@ -194,14 +194,14 @@ fhandler_socket::ioctl (unsigned int cmd, void *p)
case SIOCGIFBRDADDR: case SIOCGIFBRDADDR:
case SIOCGIFNETMASK: case SIOCGIFNETMASK:
case SIOCGIFADDR: case SIOCGIFADDR:
case SIOCGIFHWADDR:
case SIOCGIFMETRIC:
case SIOCGIFMTU:
{ {
char buf[2048]; ifc.ifc_len = 2048;
struct ifconf ifc; ifc.ifc_buf = (char *) alloca (2048);
ifc.ifc_len = sizeof (buf);
ifc.ifc_buf = buf;
struct ifreq *ifrp;
struct ifreq *ifr = (struct ifreq *) p; ifr = (struct ifreq *) p;
if (ifr == 0) if (ifr == 0)
{ {
debug_printf ("ifr == NULL\n"); debug_printf ("ifr == NULL\n");
@ -235,6 +235,15 @@ fhandler_socket::ioctl (unsigned int cmd, void *p)
case SIOCGIFNETMASK: case SIOCGIFNETMASK:
ifr->ifr_netmask = ifrp->ifr_netmask; ifr->ifr_netmask = ifrp->ifr_netmask;
break; 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; break;
} }

View File

@ -23,11 +23,14 @@
#define SIOCGLOWAT _IOR('s', 3, u_long) /* get low watermark */ #define SIOCGLOWAT _IOR('s', 3, u_long) /* get low watermark */
/* Needed for if queries */ /* Needed for if queries */
#define SIOCGIFCONF _IOW('s', 100, struct ifconf) /* get if list */ #define SIOCGIFCONF _IOW('s', 100, struct ifconf) /* get if list */
#define SIOCGIFFLAGS _IOW('s', 101, struct ifreq) /* Get if flags */ #define SIOCGIFFLAGS _IOW('s', 101, struct ifreq) /* Get if flags */
#define SIOCGIFADDR _IOW('s', 102, struct ifreq) /* Get if addr */ #define SIOCGIFADDR _IOW('s', 102, struct ifreq) /* Get if addr */
#define SIOCGIFBRDADDR _IOW('s', 103, struct ifreq) /* Get if broadcastaddr */ #define SIOCGIFBRDADDR _IOW('s', 103, struct ifreq) /* Get if broadcastaddr */
#define SIOCGIFNETMASK _IOW('s', 104, struct ifreq) /* Get if netmask */ #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 */ #define SOL_SOCKET 0xffff /* options for socket level */

View File

@ -27,6 +27,7 @@ extern "C" {
struct ifreq struct ifreq
{ {
#define IFNAMSIZ 16 #define IFNAMSIZ 16
#define IFHWADDRLEN 6
union union
{ {
char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */ char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */
@ -36,6 +37,7 @@ struct ifreq
struct sockaddr ifru_addr; struct sockaddr ifru_addr;
struct sockaddr ifru_broadaddr; struct sockaddr ifru_broadaddr;
struct sockaddr ifru_netmask; struct sockaddr ifru_netmask;
struct sockaddr ifru_hwaddr;
short ifru_flags; short ifru_flags;
int ifru_metric; int ifru_metric;
int ifru_mtu; int ifru_mtu;
@ -47,6 +49,10 @@ struct ifreq
#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */ #define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
#define ifr_netmask ifr_ifru.ifru_netmask /* interface net mask */ #define ifr_netmask ifr_ifru.ifru_netmask /* interface net mask */
#define ifr_flags ifr_ifru.ifru_flags /* flags */ #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. * Structure used in SIOCGIFCONF request.

View File

@ -17,6 +17,7 @@ details. */
#include <errno.h> #include <errno.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/un.h> #include <sys/un.h>
#include <iphlpapi.h>
#include <unistd.h> #include <unistd.h>
#include <netdb.h> #include <netdb.h>
@ -1048,159 +1049,120 @@ getdomainname (char *domain, int len)
/* Fill out an ifconf struct. */ /* Fill out an ifconf struct. */
/* /*
* IFCONF Windows 2000: * IFCONF 98/ME, NTSP4, W2K:
* Look at HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\ * Use IP Helper Library
Parameters\Interfaces
* Each subkey is an interface.
*/ */
static void static void
get_2k_ifconf (struct ifconf *ifc, int what) get_2k_ifconf (struct ifconf *ifc, int what)
{ {
HKEY key; int cnt = 0;
int cnt = 1; char eth[2] = "/", ppp[2] = "/", slp[2] = "/";
/* Union maps buffer to correct struct */ /* Union maps buffer to correct struct */
struct ifreq *ifr = ifc->ifc_req; struct ifreq *ifr = ifc->ifc_req;
if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, DWORD if_cnt, ip_cnt, lip, lnp;
"SYSTEM\\" DWORD siz_if_table = 0;
"CurrentControlSet\\" DWORD siz_ip_table = 0;
"Services\\" PMIB_IFTABLE ift;
"Tcpip\\" PMIB_IPADDRTABLE ipt;
"Parameters\\" struct sockaddr_in *sa = NULL;
"Interfaces", struct sockaddr *so = NULL;
0, KEY_READ, &key) == ERROR_SUCCESS)
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; for (if_cnt = 0; if_cnt < ift->dwNumEntries; ++if_cnt)
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)
{ {
if (RegOpenKeyEx (key, name, 0, KEY_READ, &ikey) != ERROR_SUCCESS) switch (ift->table[if_cnt].dwType)
continue; {
case MIB_IF_TYPE_ETHERNET:
/* If the "NTEContextList" value not exists, the subkey ++*eth;
is irrelevant. */ strcpy (ifr->ifr_name, "eth");
if (RegQueryValueEx (ikey, "NTEContextList", strcat (ifr->ifr_name, eth);
NULL, NULL, NULL, &size) != ERROR_SUCCESS) break;
{ case MIB_IF_TYPE_PPP:
RegCloseKey (ikey); ++*ppp;
continue; strcpy (ifr->ifr_name, "ppp");
} strcat (ifr->ifr_name, ppp);
break;
if ((caddr_t) ++ifr > ifc->ifc_buf case MIB_IF_TYPE_SLIP:
+ ifc->ifc_len ++*slp;
- sizeof (struct ifreq)) strcpy (ifr->ifr_name, "slp");
{ strcat (ifr->ifr_name, slp);
RegCloseKey (ikey); break;
break; case MIB_IF_TYPE_LOOPBACK:
} strcpy (ifr->ifr_name, "lo");
break;
char ipaddress[256], netmask[256]; default:
char dhcpaddress[256], dhcpnetmask[256]; continue;
}
if (RegQueryValueEx (ikey, "IPAddress", for (ip_cnt = 0; ip_cnt < ipt->dwNumEntries; ++ip_cnt)
NULL, NULL, if (ipt->table[ip_cnt].dwIndex == ift->table[if_cnt].dwIndex)
(unsigned char *) ipaddress, {
(size = 256, &size)) == ERROR_SUCCESS switch (what)
&& RegQueryValueEx (ikey, "SubnetMask", {
NULL, NULL, case SIOCGIFCONF:
(unsigned char *) netmask, case SIOCGIFADDR:
(size = 256, &size)) == ERROR_SUCCESS) sa = (struct sockaddr_in *) &ifr->ifr_addr;
{ sa->sin_addr.s_addr = ipt->table[ip_cnt].dwAddr;
/* ppp interfaces don't have the "AddressType" value. */ sa->sin_family = AF_INET;
if (RegQueryValueEx (ikey, "AddressType", sa->sin_port = 0;
NULL, NULL, NULL, &size) == ERROR_SUCCESS) break;
{ case SIOCGIFBRDADDR:
++*eth; sa = (struct sockaddr_in *) &ifr->ifr_broadaddr;
strcpy (ifr->ifr_name, "eth"); #if 0
strcat (ifr->ifr_name, eth); /* Unfortunately, the field returns only crap. */
} sa->sin_addr.s_addr = ipt->table[ip_cnt].dwBCastAddr;
else #else
{ lip = ipt->table[ip_cnt].dwAddr;
++*ppp; lnp = ipt->table[ip_cnt].dwMask;
strcpy (ifr->ifr_name, "ppp"); sa->sin_addr.s_addr = lip & lnp | ~lnp;
strcat (ifr->ifr_name, ppp); sa->sin_family = AF_INET;
} sa->sin_port = 0;
#endif
memset (&ifr->ifr_addr, '\0', sizeof ifr->ifr_addr); break;
if (cygwin_inet_addr (ipaddress) == 0L case SIOCGIFNETMASK:
&& RegQueryValueEx (ikey, "DhcpIPAddress", sa = (struct sockaddr_in *) &ifr->ifr_netmask;
NULL, NULL, sa->sin_addr.s_addr = ipt->table[ip_cnt].dwMask;
(unsigned char *) dhcpaddress, sa->sin_family = AF_INET;
(size = 256, &size)) sa->sin_port = 0;
== ERROR_SUCCESS break;
&& RegQueryValueEx (ikey, "DhcpSubnetMask", case SIOCGIFHWADDR:
NULL, NULL, so = &ifr->ifr_hwaddr;
(unsigned char *) dhcpnetmask, for (UINT i = 0; i < IFHWADDRLEN; ++i)
(size = 256, &size)) if (i >= ift->table[if_cnt].dwPhysAddrLen)
== ERROR_SUCCESS) so->sa_data[i] = '\0';
{ else
switch (what) so->sa_data[i] = ift->table[if_cnt].bPhysAddr[i];
{ so->sa_family = AF_INET;
case SIOCGIFCONF: break;
case SIOCGIFADDR: case SIOCGIFMETRIC:
sa = (struct sockaddr_in *) &ifr->ifr_addr; ifr->ifr_metric = 1;
sa->sin_addr.s_addr = cygwin_inet_addr (dhcpaddress); break;
break; case SIOCGIFMTU:
case SIOCGIFBRDADDR: ifr->ifr_mtu = ift->table[if_cnt].dwMtu;
lip = cygwin_inet_addr (dhcpaddress); break;
lnp = cygwin_inet_addr (dhcpnetmask); }
sa = (struct sockaddr_in *) &ifr->ifr_broadaddr; ++cnt;
sa->sin_addr.s_addr = lip & lnp | ~lnp; if ((caddr_t) ++ifr >
break; ifc->ifc_buf + ifc->ifc_len - sizeof (struct ifreq))
case SIOCGIFNETMASK: goto done;
sa = (struct sockaddr_in *) &ifr->ifr_netmask; break;
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);
} }
done:
/* Set the correct length */ /* Set the correct length */
ifc->ifc_len = cnt * sizeof (struct ifreq); ifc->ifc_len = cnt * sizeof (struct ifreq);
} }
/* /*
* IFCONF Windows NT: * IFCONF Windows NT < SP4:
* Look at the Bind value in * Look at the Bind value in
* HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Linkage\ * HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Linkage\
* This is a REG_MULTI_SZ with strings of the form: * 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; HKEY key;
unsigned long lip, lnp; unsigned long lip, lnp;
struct sockaddr_in *sa = NULL; struct sockaddr_in *sa = NULL;
struct sockaddr *so = NULL;
DWORD size; DWORD size;
int cnt = 1; int cnt = 1;
char *binding = (char *) 0; char *binding = (char *) 0;
@ -1315,18 +1278,35 @@ get_nt_ifconf (struct ifconf *ifc, int what)
case SIOCGIFADDR: case SIOCGIFADDR:
sa = (struct sockaddr_in *) &ifr->ifr_addr; sa = (struct sockaddr_in *) &ifr->ifr_addr;
sa->sin_addr.s_addr = cygwin_inet_addr (dhcpaddress); sa->sin_addr.s_addr = cygwin_inet_addr (dhcpaddress);
sa->sin_family = AF_INET;
sa->sin_port = 0;
break; break;
case SIOCGIFBRDADDR: case SIOCGIFBRDADDR:
lip = cygwin_inet_addr (dhcpaddress); lip = cygwin_inet_addr (dhcpaddress);
lnp = cygwin_inet_addr (dhcpnetmask); lnp = cygwin_inet_addr (dhcpnetmask);
sa = (struct sockaddr_in *) &ifr->ifr_broadaddr; sa = (struct sockaddr_in *) &ifr->ifr_broadaddr;
sa->sin_addr.s_addr = lip & lnp | ~lnp; sa->sin_addr.s_addr = lip & lnp | ~lnp;
sa->sin_family = AF_INET;
sa->sin_port = 0;
break; break;
case SIOCGIFNETMASK: case SIOCGIFNETMASK:
sa = (struct sockaddr_in *) &ifr->ifr_netmask; sa = (struct sockaddr_in *) &ifr->ifr_netmask;
sa->sin_addr.s_addr = sa->sin_addr.s_addr =
cygwin_inet_addr (dhcpnetmask); cygwin_inet_addr (dhcpnetmask);
sa->sin_family = AF_INET;
sa->sin_port = 0;
break; 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 else
@ -1337,21 +1317,36 @@ get_nt_ifconf (struct ifconf *ifc, int what)
case SIOCGIFADDR: case SIOCGIFADDR:
sa = (struct sockaddr_in *) &ifr->ifr_addr; sa = (struct sockaddr_in *) &ifr->ifr_addr;
sa->sin_addr.s_addr = cygwin_inet_addr (ip); sa->sin_addr.s_addr = cygwin_inet_addr (ip);
sa->sin_family = AF_INET;
sa->sin_port = 0;
break; break;
case SIOCGIFBRDADDR: case SIOCGIFBRDADDR:
lip = cygwin_inet_addr (ip); lip = cygwin_inet_addr (ip);
lnp = cygwin_inet_addr (np); lnp = cygwin_inet_addr (np);
sa = (struct sockaddr_in *) &ifr->ifr_broadaddr; sa = (struct sockaddr_in *) &ifr->ifr_broadaddr;
sa->sin_addr.s_addr = lip & lnp | ~lnp; sa->sin_addr.s_addr = lip & lnp | ~lnp;
sa->sin_family = AF_INET;
sa->sin_port = 0;
break; break;
case SIOCGIFNETMASK: case SIOCGIFNETMASK:
sa = (struct sockaddr_in *) &ifr->ifr_netmask; sa = (struct sockaddr_in *) &ifr->ifr_netmask;
sa->sin_addr.s_addr = cygwin_inet_addr (np); sa->sin_addr.s_addr = cygwin_inet_addr (np);
sa->sin_family = AF_INET;
sa->sin_port = 0;
break; 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; ++cnt;
} }
} }
@ -1364,7 +1359,7 @@ get_nt_ifconf (struct ifconf *ifc, int what)
} }
/* /*
* IFCONF Windows 9x: * IFCONF Windows 95:
* HKLM/Enum/Network/MSTCP/"*" * HKLM/Enum/Network/MSTCP/"*"
* -> Value "Driver" enthält Subkey relativ zu * -> Value "Driver" enthält Subkey relativ zu
* HKLM/System/CurrentControlSet/Class/ * HKLM/System/CurrentControlSet/Class/
@ -1381,11 +1376,12 @@ get_nt_ifconf (struct ifconf *ifc, int what)
* *
*/ */
static void static void
get_9x_ifconf (struct ifconf *ifc, int what) get_95_ifconf (struct ifconf *ifc, int what)
{ {
HKEY key; HKEY key;
unsigned long lip, lnp; unsigned long lip, lnp;
struct sockaddr_in *sa = NULL; struct sockaddr_in *sa = NULL;
struct sockaddr *so = NULL;
FILETIME update; FILETIME update;
LONG res; LONG res;
DWORD size; DWORD size;
@ -1455,20 +1451,35 @@ get_9x_ifconf (struct ifconf *ifc, int what)
case SIOCGIFADDR: case SIOCGIFADDR:
sa = (struct sockaddr_in *) &ifr->ifr_addr; sa = (struct sockaddr_in *) &ifr->ifr_addr;
sa->sin_addr.s_addr = cygwin_inet_addr (ip); sa->sin_addr.s_addr = cygwin_inet_addr (ip);
sa->sin_family = AF_INET;
sa->sin_port = 0;
break; break;
case SIOCGIFBRDADDR: case SIOCGIFBRDADDR:
lip = cygwin_inet_addr (ip); lip = cygwin_inet_addr (ip);
lnp = cygwin_inet_addr (np); lnp = cygwin_inet_addr (np);
sa = (struct sockaddr_in *) &ifr->ifr_broadaddr; sa = (struct sockaddr_in *) &ifr->ifr_broadaddr;
sa->sin_addr.s_addr = lip & lnp | ~lnp; sa->sin_addr.s_addr = lip & lnp | ~lnp;
sa->sin_family = AF_INET;
sa->sin_port = 0;
break; break;
case SIOCGIFNETMASK: case SIOCGIFNETMASK:
sa = (struct sockaddr_in *) &ifr->ifr_netmask; sa = (struct sockaddr_in *) &ifr->ifr_netmask;
sa->sin_addr.s_addr = cygwin_inet_addr (np); sa->sin_addr.s_addr = cygwin_inet_addr (np);
sa->sin_family = AF_INET;
sa->sin_port = 0;
break; 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); RegCloseKey (subkey);
@ -1554,7 +1565,7 @@ get_ifconf (struct ifconf *ifc, int what)
} }
/* Set up interface lo0 first */ /* Set up interface lo0 first */
strcpy (ifr->ifr_name, "lo0"); strcpy (ifr->ifr_name, "lo");
memset (&ifr->ifr_addr, '\0', sizeof (ifr->ifr_addr)); memset (&ifr->ifr_addr, '\0', sizeof (ifr->ifr_addr));
switch (what) switch (what)
{ {
@ -1562,32 +1573,56 @@ get_ifconf (struct ifconf *ifc, int what)
case SIOCGIFADDR: case SIOCGIFADDR:
sa = (struct sockaddr_in *) &ifr->ifr_addr; sa = (struct sockaddr_in *) &ifr->ifr_addr;
sa->sin_addr.s_addr = htonl (INADDR_LOOPBACK); sa->sin_addr.s_addr = htonl (INADDR_LOOPBACK);
sa->sin_family = AF_INET;
sa->sin_port = 0;
break; break;
case SIOCGIFBRDADDR: case SIOCGIFBRDADDR:
lip = htonl (INADDR_LOOPBACK); lip = htonl (INADDR_LOOPBACK);
lnp = cygwin_inet_addr ("255.0.0.0"); lnp = cygwin_inet_addr ("255.0.0.0");
sa = (struct sockaddr_in *) &ifr->ifr_broadaddr; sa = (struct sockaddr_in *) &ifr->ifr_broadaddr;
sa->sin_addr.s_addr = lip & lnp | ~lnp; sa->sin_addr.s_addr = lip & lnp | ~lnp;
sa->sin_family = AF_INET;
sa->sin_port = 0;
break; break;
case SIOCGIFNETMASK: case SIOCGIFNETMASK:
sa = (struct sockaddr_in *) &ifr->ifr_netmask; sa = (struct sockaddr_in *) &ifr->ifr_netmask;
sa->sin_addr.s_addr = cygwin_inet_addr ("255.0.0.0"); 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; break;
default: default:
set_errno (EINVAL); set_errno (EINVAL);
return -1; return -1;
} }
sa->sin_family = AF_INET;
sa->sin_port = 0;
OSVERSIONINFO os_version_info; OSVERSIONINFO os_version_info;
memset (&os_version_info, 0, sizeof os_version_info); memset (&os_version_info, 0, sizeof os_version_info);
os_version_info.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); os_version_info.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
GetVersionEx (&os_version_info); GetVersionEx (&os_version_info);
if (os_version_info.dwPlatformId != VER_PLATFORM_WIN32_NT) /* We have a win95 version... */
get_9x_ifconf (ifc, what); if (os_version_info.dwPlatformId != VER_PLATFORM_WIN32_NT
else if (os_version_info.dwMajorVersion <= 4) && (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); get_nt_ifconf (ifc, what);
/* ...and finally a "modern" version for win98/ME, NT >= SP4 and W2K! */
else else
get_2k_ifconf (ifc, what); get_2k_ifconf (ifc, what);