Module: wine Branch: master Commit: 5e3cc410044eab23a0368389456cc32779948506 URL: http://source.winehq.org/git/wine.git/?a=commit;h=5e3cc410044eab23a036838945...
Author: André Hentschel nerv@dawncrow.de Date: Wed Sep 19 23:52:30 2012 +0200
iphlpapi: Implement GetUdpStatisticsEx on Linux.
---
dlls/iphlpapi/iphlpapi.spec | 2 +- dlls/iphlpapi/ipstats.c | 78 ++++++++++++++++++++++++++++++++++++++-- dlls/iphlpapi/tests/iphlpapi.c | 22 +++++++----- 3 files changed, 89 insertions(+), 13 deletions(-)
diff --git a/dlls/iphlpapi/iphlpapi.spec b/dlls/iphlpapi/iphlpapi.spec index 1bf4a71..d1cf196 100644 --- a/dlls/iphlpapi/iphlpapi.spec +++ b/dlls/iphlpapi/iphlpapi.spec @@ -142,7 +142,7 @@ @ stub GetTcpTableFromStack #@ stub GetTeredoPort #@ stub GetUdp6Table -#@ stub GetUdpStatisticsEx +@ stdcall GetUdpStatisticsEx( ptr long ) @ stdcall GetUdpStatistics( ptr ) @ stub GetUdpStatsFromStack @ stdcall GetUdpTable( ptr ptr long ) diff --git a/dlls/iphlpapi/ipstats.c b/dlls/iphlpapi/ipstats.c index 65c070d..f314745 100644 --- a/dlls/iphlpapi/ipstats.c +++ b/dlls/iphlpapi/ipstats.c @@ -943,22 +943,78 @@ DWORD WINAPI GetTcpStatistics(PMIB_TCPSTATS stats) /****************************************************************** * GetUdpStatistics (IPHLPAPI.@) * - * Get the UDP statistics for the local computer. + * Get the IPv4 and IPv6 UDP statistics for the local computer. * * PARAMS * stats [Out] buffer for UDP statistics + * family [In] specifies wether IPv4 or IPv6 statistics are returned * * RETURNS * Success: NO_ERROR * Failure: error code from winerror.h */ -DWORD WINAPI GetUdpStatistics(PMIB_UDPSTATS stats) +DWORD WINAPI GetUdpStatisticsEx(PMIB_UDPSTATS stats, DWORD family) { DWORD ret = ERROR_NOT_SUPPORTED;
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->dwNumAddrs = getNumInterfaces(); + + if (family == WS_AF_INET6) + { +#ifdef __linux__ + { + FILE *fp; + + if ((fp = fopen("/proc/net/snmp6", "r"))) + { + struct { + const char *name; + DWORD *elem; + } udpstatlist[] = { + { "Udp6InDatagrams", &stats->dwInDatagrams }, + { "Udp6NoPorts", &stats->dwNoPorts }, + { "Udp6InErrors", &stats->dwInErrors }, + { "Udp6OutDatagrams", &stats->dwOutDatagrams }, + }; + 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(udpstatlist)/sizeof(udpstatlist[0]); i++) + if (!strcasecmp(buf, udpstatlist[i].name)) + { + if (sscanf(value, "%d", &res)) *udpstatlist[i].elem = res; + continue; + } + } + fclose(fp); + ret = NO_ERROR; + } + } +#else + FIXME( "unimplemented for IPv6\n" ); +#endif + return ret; + } + #ifdef __linux__ { FILE *fp; @@ -1035,11 +1091,27 @@ DWORD WINAPI GetUdpStatistics(PMIB_UDPSTATS stats) else ERR ("failed to get udpstat\n"); } #else - FIXME( "unimplemented\n" ); + FIXME( "unimplemented for IPv4\n" ); #endif return ret; }
+/****************************************************************** + * GetUdpStatistics (IPHLPAPI.@) + * + * Get the UDP statistics for the local computer. + * + * PARAMS + * stats [Out] buffer for UDP statistics + * + * RETURNS + * Success: NO_ERROR + * Failure: error code from winerror.h + */ +DWORD WINAPI GetUdpStatistics(PMIB_UDPSTATS stats) +{ + return GetUdpStatisticsEx(stats, WS_AF_INET); +}
static MIB_IPFORWARDTABLE *append_ipforward_row( HANDLE heap, DWORD flags, MIB_IPFORWARDTABLE *table, DWORD *count, const MIB_IPFORWARDROW *row ) diff --git a/dlls/iphlpapi/tests/iphlpapi.c b/dlls/iphlpapi/tests/iphlpapi.c index 1c0e2cc..02a299f 100644 --- a/dlls/iphlpapi/tests/iphlpapi.c +++ b/dlls/iphlpapi/tests/iphlpapi.c @@ -546,7 +546,7 @@ static void testGetIcmpStatisticsEx(void) if (apiReturn == NO_ERROR && winetest_debug > 1) { INT i; - trace( "ICMP Ex stats: %8s %8s\n", "in", "out" ); + trace( "ICMP IPv4 Ex stats: %8s %8s\n", "in", "out" ); trace( " dwMsgs: %8u %8u\n", stats.icmpInStats.dwMsgs, stats.icmpOutStats.dwMsgs ); trace( " dwErrors: %8u %8u\n", stats.icmpInStats.dwErrors, stats.icmpOutStats.dwErrors ); for (i = 0; i < 256; i++) @@ -559,7 +559,7 @@ static void testGetIcmpStatisticsEx(void) if (apiReturn == NO_ERROR && winetest_debug > 1) { INT i; - trace( "ICMP Ex stats: %8s %8s\n", "in", "out" ); + trace( "ICMP IPv6 Ex stats: %8s %8s\n", "in", "out" ); trace( " dwMsgs: %8u %8u\n", stats.icmpInStats.dwMsgs, stats.icmpOutStats.dwMsgs ); trace( " dwErrors: %8u %8u\n", stats.icmpInStats.dwErrors, stats.icmpOutStats.dwErrors ); for (i = 0; i < 256; i++) @@ -590,7 +590,7 @@ static void testGetIpStatisticsEx(void) ok(apiReturn == NO_ERROR, "GetIpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn); if (apiReturn == NO_ERROR && winetest_debug > 1) { - trace( "IP Ex stats:\n" ); + trace( "IP IPv4 Ex stats:\n" ); trace( " dwForwarding: %u\n", U(stats).dwForwarding ); trace( " dwDefaultTTL: %u\n", stats.dwDefaultTTL ); trace( " dwInReceives: %u\n", stats.dwInReceives ); @@ -621,7 +621,7 @@ static void testGetIpStatisticsEx(void) "GetIpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn); if (apiReturn == NO_ERROR && winetest_debug > 1) { - trace( "IP Ex stats:\n" ); + trace( "IP IPv6 Ex stats:\n" ); trace( " dwForwarding: %u\n", U(stats).dwForwarding ); trace( " dwDefaultTTL: %u\n", stats.dwDefaultTTL ); trace( " dwInReceives: %u\n", stats.dwInReceives ); @@ -667,7 +667,7 @@ static void testGetTcpStatisticsEx(void) ok(apiReturn == NO_ERROR, "GetTcpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn); if (apiReturn == NO_ERROR && winetest_debug > 1) { - trace( "TCP stats:\n" ); + trace( "TCP IPv4 Ex stats:\n" ); trace( " dwRtoAlgorithm: %u\n", U(stats).dwRtoAlgorithm ); trace( " dwRtoMin: %u\n", stats.dwRtoMin ); trace( " dwRtoMax: %u\n", stats.dwRtoMax ); @@ -690,7 +690,7 @@ static void testGetTcpStatisticsEx(void) "GetTcpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn); if (apiReturn == NO_ERROR && winetest_debug > 1) { - trace( "TCP stats:\n" ); + trace( "TCP IPv6 Ex stats:\n" ); trace( " dwRtoAlgorithm: %u\n", U(stats).dwRtoAlgorithm ); trace( " dwRtoMin: %u\n", stats.dwRtoMin ); trace( " dwRtoMax: %u\n", stats.dwRtoMax ); @@ -716,7 +716,7 @@ static void testGetUdpStatisticsEx(void)
if (!pGetUdpStatisticsEx) { - skip( "GetUdpStatisticsEx not available\n" ); + win_skip( "GetUdpStatisticsEx not available\n" ); return; }
@@ -724,11 +724,15 @@ static void testGetUdpStatisticsEx(void) ok(apiReturn == ERROR_INVALID_PARAMETER, "GetUdpStatisticsEx(NULL, AF_INET); returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn);
+ apiReturn = pGetUdpStatisticsEx(&stats, AF_BAN); + ok(apiReturn == ERROR_INVALID_PARAMETER || apiReturn == ERROR_NOT_SUPPORTED, + "GetUdpStatisticsEx(&stats, AF_BAN) returned %d, expected ERROR_INVALID_PARAMETER\n", apiReturn); + apiReturn = pGetUdpStatisticsEx(&stats, AF_INET); ok(apiReturn == NO_ERROR, "GetUdpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn); if (apiReturn == NO_ERROR && winetest_debug > 1) { - trace( "UDP stats:\n" ); + trace( "UDP IPv4 Ex stats:\n" ); trace( " dwInDatagrams: %u\n", stats.dwInDatagrams ); trace( " dwNoPorts: %u\n", stats.dwNoPorts ); trace( " dwInErrors: %u\n", stats.dwInErrors ); @@ -741,7 +745,7 @@ static void testGetUdpStatisticsEx(void) "GetUdpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn); if (apiReturn == NO_ERROR && winetest_debug > 1) { - trace( "UDP stats:\n" ); + trace( "UDP IPv6 Ex stats:\n" ); trace( " dwInDatagrams: %u\n", stats.dwInDatagrams ); trace( " dwNoPorts: %u\n", stats.dwNoPorts ); trace( " dwInErrors: %u\n", stats.dwInErrors );