Module: wine Branch: master Commit: 641abc997cf97df2fd22af0da1cc8eee1272e8aa URL: http://source.winehq.org/git/wine.git/?a=commit;h=641abc997cf97df2fd22af0da1...
Author: Mark Adams mark@transgaming.com Date: Thu Jan 25 20:16:25 2007 -0500
iphlpapi: Support for non-linux platforms, including Mac OS X.
- Add error messages when unimplemented functions are called on non-linux platforms. - Implement retrieving the interface list on MacOS X (and other platforms that use NET_RT_DUMP).
---
dlls/iphlpapi/ipstats.c | 219 ++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 218 insertions(+), 1 deletions(-)
diff --git a/dlls/iphlpapi/ipstats.c b/dlls/iphlpapi/ipstats.c index 129380c..f5b1149 100644 --- a/dlls/iphlpapi/ipstats.c +++ b/dlls/iphlpapi/ipstats.c @@ -20,6 +20,7 @@
#include "config.h" #include "wine/port.h" +#include "wine/debug.h"
#include <stdarg.h> #include <stdio.h> @@ -51,6 +52,14 @@ #include <netinet/tcp_fsm.h> #endif
+#ifdef HAVE_SYS_SYSCTL_H +#include <sys/sysctl.h> +#endif + +#define ROUNDUP(a) \ + ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) +#define ADVANCE(x, n) (x += ROUNDUP(((struct sockaddr *)n)->sa_len)) + #include "windef.h" #include "winbase.h" #include "iprtrmib.h" @@ -71,6 +80,8 @@ #define TCPS_CLOSING 11 #endif
+WINE_DEFAULT_DEBUG_CHANNEL(iphlpapi); + DWORD getInterfaceStatsByName(const char *name, PMIB_IFROW entry) { FILE *fp; @@ -152,6 +163,9 @@ DWORD getInterfaceStatsByName(const char } fclose(fp); } + else + ERR ("unimplemented!\n"); + return NO_ERROR; }
@@ -279,6 +293,9 @@ DWORD getICMPStats(MIB_ICMP *stats) } fclose(fp); } + else + ERR ("unimplemented!\n"); + return NO_ERROR; }
@@ -390,6 +407,9 @@ DWORD getIPStats(PMIB_IPSTATS stats) } fclose(fp); } + else + ERR ("unimplemented!\n"); + return NO_ERROR; }
@@ -480,6 +500,9 @@ DWORD getTCPStats(MIB_TCPSTATS *stats) } fclose(fp); } + else + ERR ("unimplemented!\n"); + return NO_ERROR; }
@@ -533,6 +556,9 @@ DWORD getUDPStats(MIB_UDPSTATS *stats) } fclose(fp); } + else + ERR ("unimplemented!\n"); + return NO_ERROR; }
@@ -556,12 +582,66 @@ static DWORD getNumWithOneHeader(const c } fclose(fp); } + else + ERR ("Unable to open '%s' to count entries!\n", filename); + return ret; }
DWORD getNumRoutes(void) { - return getNumWithOneHeader("/proc/net/route"); +#if defined(HAVE_SYS_SYSCTL_H) && defined(NET_RT_DUMP) + int mib[6] = {CTL_NET, PF_ROUTE, 0, PF_INET, NET_RT_DUMP, 0}; + size_t needed; + char *buf, *lim, *next; + struct rt_msghdr *rtm; + DWORD RouteCount = 0; + + if (sysctl (mib, 6, NULL, &needed, NULL, 0) < 0) + { + ERR ("sysctl 1 failed!\n"); + return 0; + } + + buf = HeapAlloc (GetProcessHeap (), 0, needed); + if (!buf) + { + ERR ("HeapAlloc of %ld failed!\n", needed); + return 0; + } + + if (sysctl (mib, 6, buf, &needed, NULL, 0) < 0) + { + ERR ("sysctl 2 failed!\n"); + HeapFree (GetProcessHeap (), 0, buf); + return 0; + } + + lim = buf + needed; + for (next = buf; next < lim; next += rtm->rtm_msglen) + { + rtm = (struct rt_msghdr *)next; + + if (rtm->rtm_type != RTM_GET) + { + WARN ("Got unexpected message type 0x%x!\n", + rtm->rtm_type); + continue; + } + + /* Ignore all entries except for gateway routes which aren't + multicast */ + if (!(rtm->rtm_flags & RTF_GATEWAY) || (rtm->rtm_flags & RTF_MULTICAST)) + continue; + + RouteCount++; + } + + HeapFree (GetProcessHeap (), 0, buf); + return RouteCount; +#else + return getNumWithOneHeader("/proc/net/route"); +#endif }
DWORD getRouteTable(PMIB_IPFORWARDTABLE *ppIpForwardTable, HANDLE heap, @@ -577,6 +657,122 @@ DWORD getRouteTable(PMIB_IPFORWARDTABLE sizeof(MIB_IPFORWARDTABLE) + (numRoutes - 1) * sizeof(MIB_IPFORWARDROW));
if (table) { +#if defined(HAVE_SYS_SYSCTL_H) && defined(NET_RT_DUMP) + int mib[6] = {CTL_NET, PF_ROUTE, 0, PF_INET, NET_RT_DUMP, 0}; + size_t needed; + char *buf, *lim, *next, *addrPtr; + struct rt_msghdr *rtm; + + if (sysctl (mib, 6, NULL, &needed, NULL, 0) < 0) + { + ERR ("sysctl 1 failed!\n"); + HeapFree (GetProcessHeap (), 0, table); + return NO_ERROR; + } + + buf = HeapAlloc (GetProcessHeap (), 0, needed); + if (!buf) + { + ERR ("HeapAlloc of %ld failed!\n", needed); + HeapFree (GetProcessHeap (), 0, table); + return ERROR_OUTOFMEMORY; + } + + if (sysctl (mib, 6, buf, &needed, NULL, 0) < 0) + { + ERR ("sysctl 2 failed!\n"); + HeapFree (GetProcessHeap (), 0, table); + HeapFree (GetProcessHeap (), 0, buf); + return NO_ERROR; + } + + *ppIpForwardTable = table; + table->dwNumEntries = 0; + + lim = buf + needed; + for (next = buf; next < lim; next += rtm->rtm_msglen) + { + int i; + + rtm = (struct rt_msghdr *)next; + + if (rtm->rtm_type != RTM_GET) + { + WARN ("Got unexpected message type 0x%x!\n", + rtm->rtm_type); + continue; + } + + /* Ignore all entries except for gateway routes which aren't + multicast */ + if (!(rtm->rtm_flags & RTF_GATEWAY) || + (rtm->rtm_flags & RTF_MULTICAST)) + continue; + + memset (&table->table[table->dwNumEntries], 0, + sizeof (MIB_IPFORWARDROW)); + table->table[table->dwNumEntries].dwForwardIfIndex = rtm->rtm_index; + table->table[table->dwNumEntries].dwForwardType = + MIB_IPROUTE_TYPE_INDIRECT; + table->table[table->dwNumEntries].dwForwardMetric1 = + rtm->rtm_rmx.rmx_hopcount; + table->table[table->dwNumEntries].dwForwardProto = + MIB_IPPROTO_LOCAL; + + addrPtr = (char *)(rtm + 1); + + for (i = 1; i; i <<= 1) + { + struct sockaddr *sa; + DWORD addr; + + if (!(i & rtm->rtm_addrs)) + continue; + + sa = (struct sockaddr *)addrPtr; + ADVANCE (addrPtr, sa); + + /* default routes are encoded by length-zero sockaddr */ + if (sa->sa_len == 0) + addr = 0; + else if (sa->sa_family != AF_INET) + { + ERR ("Received unsupported sockaddr family 0x%x\n", + sa->sa_family); + addr = 0; + } + else + { + struct sockaddr_in *sin = (struct sockaddr_in *)sa; + + addr = sin->sin_addr.s_addr; + } + + switch (i) + { + case RTA_DST: + table->table[table->dwNumEntries].dwForwardDest = addr; + break; + + case RTA_GATEWAY: + table->table[table->dwNumEntries].dwForwardNextHop = addr; + break; + + case RTA_NETMASK: + table->table[table->dwNumEntries].dwForwardMask = addr; + break; + + default: + ERR ("Unexpected address type 0x%x\n", i); + } + } + + table->dwNumEntries++; + } + + HeapFree (GetProcessHeap (), 0, buf); + ret = NO_ERROR; +#else FILE *fp;
ret = NO_ERROR; @@ -656,6 +852,12 @@ DWORD getRouteTable(PMIB_IPFORWARDTABLE } fclose(fp); } + else + { + ERR ("unimplemented!\n"); + return ERROR_INVALID_PARAMETER; + } +#endif } else ret = ERROR_OUTOFMEMORY; @@ -672,6 +874,11 @@ DWORD getArpTable(PMIB_IPNETTABLE *ppIpN { DWORD ret;
+#if defined(HAVE_SYS_SYSCTL_H) && defined(NET_RT_DUMP) + ERR ("unimplemented!\n"); + return ERROR_INVALID_PARAMETER; +#endif + if (!ppIpNetTable) ret = ERROR_INVALID_PARAMETER; else { @@ -765,6 +972,11 @@ DWORD getUdpTable(PMIB_UDPTABLE *ppUdpTa { DWORD ret;
+#if defined(HAVE_SYS_SYSCTL_H) && defined(NET_RT_DUMP) + ERR ("unimplemented!\n"); + return ERROR_INVALID_PARAMETER; +#endif + if (!ppUdpTable) ret = ERROR_INVALID_PARAMETER; else { @@ -828,6 +1040,11 @@ DWORD getTcpTable(PMIB_TCPTABLE *ppTcpTa { DWORD ret;
+#if defined(HAVE_SYS_SYSCTL_H) && defined(NET_RT_DUMP) + ERR ("unimplemented!\n"); + return ERROR_INVALID_PARAMETER; +#endif + if (!ppTcpTable) ret = ERROR_INVALID_PARAMETER; else {