Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2001-02-08 01:50:50 +0300
committerCorinna Vinschen <corinna@vinschen.de>2001-02-08 01:50:50 +0300
commit9182099c105321c24a12b53183f92cc58f4e0580 (patch)
treeec80e1de7965359155d6ff7c68d4d5450e1641a0
parent93ac44870753d7b4650d2575ae5d68bd0432f59e (diff)
* 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'.
-rw-r--r--winsup/cygwin/ChangeLog21
-rw-r--r--winsup/cygwin/autoload.cc26
-rw-r--r--winsup/cygwin/fhandler_socket.cc31
-rw-r--r--winsup/cygwin/include/asm/socket.h9
-rw-r--r--winsup/cygwin/include/cygwin/if.h6
-rw-r--r--winsup/cygwin/net.cc333
6 files changed, 263 insertions, 163 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index aa137bcd9..24d127736 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -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
diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc
index f7b0a62ef..00ee37b2c 100644
--- a/winsup/cygwin/autoload.cc
+++ b/winsup/cygwin/autoload.cc
@@ -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)
}
}
diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc
index 17a6ff42b..e80a7f24b 100644
--- a/winsup/cygwin/fhandler_socket.cc
+++ b/winsup/cygwin/fhandler_socket.cc
@@ -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;
}
diff --git a/winsup/cygwin/include/asm/socket.h b/winsup/cygwin/include/asm/socket.h
index 905e81505..aa1aa7535 100644
--- a/winsup/cygwin/include/asm/socket.h
+++ b/winsup/cygwin/include/asm/socket.h
@@ -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 */
diff --git a/winsup/cygwin/include/cygwin/if.h b/winsup/cygwin/include/cygwin/if.h
index fe0b8b4c1..977166ed7 100644
--- a/winsup/cygwin/include/cygwin/if.h
+++ b/winsup/cygwin/include/cygwin/if.h
@@ -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.
diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc
index 5603a215e..fcada7b7f 100644
--- a/winsup/cygwin/net.cc
+++ b/winsup/cygwin/net.cc
@@ -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);