Commit 5e3cc410 authored by André Hentschel's avatar André Hentschel Committed by Alexandre Julliard

iphlpapi: Implement GetUdpStatisticsEx on Linux.

parent f2626c31
......@@ -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 )
......
......@@ -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 )
......
......@@ -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 );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment