Module: wine Branch: master Commit: f2626c31af9ab192b9fc5a6132848687c3da3fb9 URL: http://source.winehq.org/git/wine.git/?a=commit;h=f2626c31af9ab192b9fc5a6132...
Author: André Hentschel nerv@dawncrow.de Date: Wed Sep 19 23:48:59 2012 +0200
iphlpapi: Implement GetIpStatisticsEx on Linux.
---
dlls/iphlpapi/iphlpapi.spec | 2 +- dlls/iphlpapi/ipstats.c | 92 ++++++++++++++++++++++++++++++++++++++-- dlls/iphlpapi/tests/iphlpapi.c | 6 ++- 3 files changed, 94 insertions(+), 6 deletions(-)
diff --git a/dlls/iphlpapi/iphlpapi.spec b/dlls/iphlpapi/iphlpapi.spec index cadb247..1bf4a71 100644 --- a/dlls/iphlpapi/iphlpapi.spec +++ b/dlls/iphlpapi/iphlpapi.spec @@ -112,7 +112,7 @@ @ stub GetIpNetTableFromStack #@ stub GetIpPathEntry #@ stub GetIpPathTable -#@ stub GetIpStatisticsEx +@ stdcall GetIpStatisticsEx( ptr long ) @ stdcall GetIpStatistics( ptr ) @ stub GetIpStatsFromStack #@ stub GetMulticastIpAddressEntry diff --git a/dlls/iphlpapi/ipstats.c b/dlls/iphlpapi/ipstats.c index 7c64b41..65c070d 100644 --- a/dlls/iphlpapi/ipstats.c +++ b/dlls/iphlpapi/ipstats.c @@ -553,23 +553,25 @@ DWORD WINAPI GetIcmpStatistics(PMIB_ICMP stats)
/****************************************************************** - * GetIpStatistics (IPHLPAPI.@) + * GetIpStatisticsEx (IPHLPAPI.@) * - * Get the IP statistics for the local computer. + * Get the IPv4 and IPv6 statistics for the local computer. * * PARAMS * stats [Out] buffer for IP statistics + * family [In] specifies wether IPv4 or IPv6 statistics are returned * * RETURNS * Success: NO_ERROR * Failure: error code from winerror.h */ -DWORD WINAPI GetIpStatistics(PMIB_IPSTATS stats) +DWORD WINAPI GetIpStatisticsEx(PMIB_IPSTATS stats, DWORD family) { DWORD ret = ERROR_NOT_SUPPORTED; MIB_IPFORWARDTABLE *fwd_table;
if (!stats) return ERROR_INVALID_PARAMETER; + if (family != WS_AF_INET && family != WS_AF_INET6) return ERROR_INVALID_PARAMETER; memset( stats, 0, sizeof(*stats) );
stats->dwNumIf = stats->dwNumAddr = getNumInterfaces(); @@ -579,6 +581,72 @@ DWORD WINAPI GetIpStatistics(PMIB_IPSTATS stats) HeapFree( GetProcessHeap(), 0, fwd_table ); }
+ if (family == WS_AF_INET6) + { +#ifdef __linux__ + { + FILE *fp; + + if ((fp = fopen("/proc/net/snmp6", "r"))) + { + struct { + const char *name; + DWORD *elem; + } ipstatlist[] = { + { "Ip6InReceives", &stats->dwInReceives }, + { "Ip6InHdrErrors", &stats->dwInHdrErrors }, + { "Ip6InAddrErrors", &stats->dwInAddrErrors }, + { "Ip6OutForwDatagrams", &stats->dwForwDatagrams }, + { "Ip6InUnknownProtos", &stats->dwInUnknownProtos }, + { "Ip6InDiscards", &stats->dwInDiscards }, + { "Ip6InDelivers", &stats->dwInDelivers }, + { "Ip6OutRequests", &stats->dwOutRequests }, + { "Ip6OutDiscards", &stats->dwOutDiscards }, + { "Ip6OutNoRoutes", &stats->dwOutNoRoutes }, + { "Ip6ReasmTimeout", &stats->dwReasmTimeout }, + { "Ip6ReasmReqds", &stats->dwReasmReqds }, + { "Ip6ReasmOKs", &stats->dwReasmOks }, + { "Ip6ReasmFails", &stats->dwReasmFails }, + { "Ip6FragOKs", &stats->dwFragOks }, + { "Ip6FragFails", &stats->dwFragFails }, + { "Ip6FragCreates", &stats->dwFragCreates }, + /* hmm, no routingDiscards, defaultTTL and forwarding? */ + }; + char buf[512], *ptr, *value; + DWORD res, i; + + while ((ptr = fgets(buf, sizeof(buf), fp))) + { + if (!(value = strchr(buf, ' '))) + continue; + + /* terminate the valuename */ + ptr = value - 1; + *(ptr + 1) = '\0'; + + /* and strip leading spaces from value */ + value += 1; + while (*value==' ') value++; + if ((ptr = strchr(value, '\n'))) + *ptr='\0'; + + for (i = 0; i < sizeof(ipstatlist)/sizeof(ipstatlist[0]); i++) + if (!strcasecmp(buf, ipstatlist[i].name)) + { + if (sscanf(value, "%d", &res)) *ipstatlist[i].elem = res; + continue; + } + } + fclose(fp); + ret = NO_ERROR; + } + } +#else + FIXME( "unimplemented for IPv6\n" ); +#endif + return ret; + } + #ifdef __linux__ { FILE *fp; @@ -712,11 +780,27 @@ DWORD WINAPI GetIpStatistics(PMIB_IPSTATS stats) ret = NO_ERROR; } #else - FIXME( "unimplemented\n" ); + FIXME( "unimplemented for IPv4\n" ); #endif return ret; }
+/****************************************************************** + * GetIpStatistics (IPHLPAPI.@) + * + * Get the IP statistics for the local computer. + * + * PARAMS + * stats [Out] buffer for IP statistics + * + * RETURNS + * Success: NO_ERROR + * Failure: error code from winerror.h + */ +DWORD WINAPI GetIpStatistics(PMIB_IPSTATS stats) +{ + return GetIpStatisticsEx(stats, WS_AF_INET); +}
/****************************************************************** * GetTcpStatistics (IPHLPAPI.@) diff --git a/dlls/iphlpapi/tests/iphlpapi.c b/dlls/iphlpapi/tests/iphlpapi.c index 638d7e5..1c0e2cc 100644 --- a/dlls/iphlpapi/tests/iphlpapi.c +++ b/dlls/iphlpapi/tests/iphlpapi.c @@ -574,7 +574,7 @@ static void testGetIpStatisticsEx(void)
if (!pGetIpStatisticsEx) { - skip( "GetIpStatisticsEx not available\n" ); + win_skip( "GetIpStatisticsEx not available\n" ); return; }
@@ -582,6 +582,10 @@ static void testGetIpStatisticsEx(void) ok(apiReturn == ERROR_INVALID_PARAMETER, "GetIpStatisticsEx(NULL, AF_INET) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
+ apiReturn = pGetIpStatisticsEx(&stats, AF_BAN); + ok(apiReturn == ERROR_INVALID_PARAMETER, + "GetIpStatisticsEx(&stats, AF_BAN) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn); + apiReturn = pGetIpStatisticsEx(&stats, AF_INET); ok(apiReturn == NO_ERROR, "GetIpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn); if (apiReturn == NO_ERROR && winetest_debug > 1)