nsiproxy: Implement IPv4 icmpstats get_all_parameters.
Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
2586bbb212
commit
23ee1ebea6
|
@ -446,6 +446,48 @@ err:
|
|||
winetest_pop_context();
|
||||
}
|
||||
|
||||
static void test_ip_icmpstats( int family )
|
||||
{
|
||||
const NPI_MODULEID *mod = (family == AF_INET) ? &NPI_MS_IPV4_MODULEID : &NPI_MS_IPV6_MODULEID;
|
||||
struct nsi_ip_icmpstats_dynamic nsi_stats, nsi_stats2;
|
||||
MIB_ICMP_EX table;
|
||||
DWORD err, i;
|
||||
|
||||
winetest_push_context( family == AF_INET ? "AF_INET" : "AF_INET6" );
|
||||
|
||||
err = NsiGetAllParameters( 1, mod, NSI_IP_ICMPSTATS_TABLE, NULL, 0, NULL, 0, &nsi_stats, sizeof(nsi_stats), NULL, 0 );
|
||||
todo_wine_if( family == AF_INET6)
|
||||
ok( !err, "got %d\n", err );
|
||||
if (err) goto err;
|
||||
|
||||
err = GetIcmpStatisticsEx( &table, family );
|
||||
ok( !err, "got %d\n", err );
|
||||
if (err) goto err;
|
||||
|
||||
err = NsiGetAllParameters( 1, mod, NSI_IP_ICMPSTATS_TABLE, NULL, 0, NULL, 0, &nsi_stats2, sizeof(nsi_stats2), NULL, 0 );
|
||||
ok( !err, "got %d\n", err );
|
||||
|
||||
ok( bounded( table.icmpInStats.dwMsgs, nsi_stats.in_msgs, nsi_stats2.in_msgs ),
|
||||
"%d vs [%d %d]\n", table.icmpInStats.dwMsgs, nsi_stats.in_msgs, nsi_stats2.in_msgs );
|
||||
ok( bounded( table.icmpInStats.dwErrors, nsi_stats.in_errors, nsi_stats2.in_errors ),
|
||||
"%d vs [%d %d]\n", table.icmpInStats.dwErrors, nsi_stats.in_errors, nsi_stats2.in_errors );
|
||||
ok( bounded( table.icmpOutStats.dwMsgs, nsi_stats.out_msgs, nsi_stats2.out_msgs ),
|
||||
"%d vs [%d %d]\n", table.icmpOutStats.dwMsgs, nsi_stats.out_msgs, nsi_stats2.out_msgs );
|
||||
ok( bounded( table.icmpOutStats.dwErrors, nsi_stats.out_errors, nsi_stats2.out_errors ),
|
||||
"%d vs [%d %d]\n", table.icmpOutStats.dwErrors, nsi_stats.out_errors, nsi_stats2.out_errors );
|
||||
for (i = 0; i < ARRAY_SIZE(nsi_stats.in_type_counts); i++)
|
||||
{
|
||||
winetest_push_context( "%d", i );
|
||||
ok( bounded( table.icmpInStats.rgdwTypeCount[i], nsi_stats.in_type_counts[i], nsi_stats2.in_type_counts[i] ),
|
||||
"%d vs [%d %d]\n", table.icmpInStats.rgdwTypeCount[i], nsi_stats.in_type_counts[i], nsi_stats2.in_type_counts[i] );
|
||||
ok( bounded( table.icmpOutStats.rgdwTypeCount[i], nsi_stats.out_type_counts[i], nsi_stats2.out_type_counts[i] ),
|
||||
"%d vs [%d %d]\n", table.icmpOutStats.rgdwTypeCount[i], nsi_stats.out_type_counts[i], nsi_stats2.out_type_counts[i] );
|
||||
winetest_pop_context();
|
||||
}
|
||||
err:
|
||||
winetest_pop_context();
|
||||
}
|
||||
|
||||
|
||||
static void test_ip_ipstats( int family )
|
||||
{
|
||||
|
@ -763,6 +805,8 @@ START_TEST( nsi )
|
|||
|
||||
test_ip_cmpt( AF_INET );
|
||||
test_ip_cmpt( AF_INET6 );
|
||||
test_ip_icmpstats( AF_INET );
|
||||
test_ip_icmpstats( AF_INET6 );
|
||||
test_ip_ipstats( AF_INET );
|
||||
test_ip_ipstats( AF_INET6 );
|
||||
test_ip_unicast( AF_INET );
|
||||
|
|
|
@ -41,10 +41,26 @@
|
|||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETINET_IP_H
|
||||
#include <netinet/ip.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETINET_IN_SYSTM_H
|
||||
#include <netinet/in_systm.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETINET_IP_ICMP_H
|
||||
#include <netinet/ip_icmp.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETINET_IP_VAR_H
|
||||
#include <netinet/ip_var.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETINET_ICMP_VAR_H
|
||||
#include <netinet/icmp_var.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETINET_IF_ETHER_H
|
||||
#include <netinet/if_ether.h>
|
||||
#endif
|
||||
|
@ -76,6 +92,7 @@
|
|||
#include "ws2ipdef.h"
|
||||
#include "nldef.h"
|
||||
#include "ifdef.h"
|
||||
#include "ipmib.h"
|
||||
#include "netiodef.h"
|
||||
#include "wine/heap.h"
|
||||
#include "wine/nsi.h"
|
||||
|
@ -223,6 +240,121 @@ static NTSTATUS ipv6_cmpt_get_all_parameters( const void *key, DWORD key_size, v
|
|||
dynamic_data, dynamic_size, static_data, static_size );
|
||||
}
|
||||
|
||||
static NTSTATUS ipv4_icmpstats_get_all_parameters( const void *key, DWORD key_size, void *rw_data, DWORD rw_size,
|
||||
void *dynamic_data, DWORD dynamic_size, void *static_data, DWORD static_size )
|
||||
{
|
||||
struct nsi_ip_icmpstats_dynamic dyn;
|
||||
|
||||
TRACE( "%p %d %p %d %p %d %p %d\n", key, key_size, rw_data, rw_size, dynamic_data, dynamic_size,
|
||||
static_data, static_size );
|
||||
|
||||
memset( &dyn, 0, sizeof(dyn) );
|
||||
|
||||
#ifdef __linux__
|
||||
{
|
||||
NTSTATUS status = STATUS_NOT_SUPPORTED;
|
||||
static const char hdr[] = "Icmp:";
|
||||
char buf[512], *ptr;
|
||||
FILE *fp;
|
||||
|
||||
if (!(fp = fopen( "/proc/net/snmp", "r" ))) return STATUS_NOT_SUPPORTED;
|
||||
|
||||
while ((ptr = fgets( buf, sizeof(buf), fp )))
|
||||
{
|
||||
if (_strnicmp( buf, hdr, sizeof(hdr) - 1 )) continue;
|
||||
/* last line was a header, get another */
|
||||
if (!(ptr = fgets( buf, sizeof(buf), fp ))) break;
|
||||
if (!_strnicmp( buf, hdr, sizeof(hdr) - 1 ))
|
||||
{
|
||||
ptr += sizeof(hdr);
|
||||
sscanf( ptr, "%u %u %*u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u",
|
||||
&dyn.in_msgs,
|
||||
&dyn.in_errors,
|
||||
&dyn.in_type_counts[ICMP4_DST_UNREACH],
|
||||
&dyn.in_type_counts[ICMP4_TIME_EXCEEDED],
|
||||
&dyn.in_type_counts[ICMP4_PARAM_PROB],
|
||||
&dyn.in_type_counts[ICMP4_SOURCE_QUENCH],
|
||||
&dyn.in_type_counts[ICMP4_REDIRECT],
|
||||
&dyn.in_type_counts[ICMP4_ECHO_REQUEST],
|
||||
&dyn.in_type_counts[ICMP4_ECHO_REPLY],
|
||||
&dyn.in_type_counts[ICMP4_TIMESTAMP_REQUEST],
|
||||
&dyn.in_type_counts[ICMP4_TIMESTAMP_REPLY],
|
||||
&dyn.in_type_counts[ICMP4_MASK_REQUEST],
|
||||
&dyn.in_type_counts[ICMP4_MASK_REPLY],
|
||||
&dyn.out_msgs,
|
||||
&dyn.out_errors,
|
||||
&dyn.out_type_counts[ICMP4_DST_UNREACH],
|
||||
&dyn.out_type_counts[ICMP4_TIME_EXCEEDED],
|
||||
&dyn.out_type_counts[ICMP4_PARAM_PROB],
|
||||
&dyn.out_type_counts[ICMP4_SOURCE_QUENCH],
|
||||
&dyn.out_type_counts[ICMP4_REDIRECT],
|
||||
&dyn.out_type_counts[ICMP4_ECHO_REQUEST],
|
||||
&dyn.out_type_counts[ICMP4_ECHO_REPLY],
|
||||
&dyn.out_type_counts[ICMP4_TIMESTAMP_REQUEST],
|
||||
&dyn.out_type_counts[ICMP4_TIMESTAMP_REPLY],
|
||||
&dyn.out_type_counts[ICMP4_MASK_REQUEST],
|
||||
&dyn.out_type_counts[ICMP4_MASK_REPLY] );
|
||||
status = STATUS_SUCCESS;
|
||||
if (dynamic_data) *(struct nsi_ip_icmpstats_dynamic *)dynamic_data = dyn;
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose( fp );
|
||||
return status;
|
||||
}
|
||||
#elif defined(HAVE_SYS_SYSCTL_H) && defined(ICMPCTL_STATS)
|
||||
{
|
||||
int mib[] = { CTL_NET, PF_INET, IPPROTO_ICMP, ICMPCTL_STATS };
|
||||
struct icmpstat icmp_stat;
|
||||
size_t needed = sizeof(icmp_stat);
|
||||
int i;
|
||||
|
||||
if (sysctl( mib, ARRAY_SIZE(mib), &icmp_stat, &needed, NULL, 0 ) == -1) return STATUS_NOT_SUPPORTED;
|
||||
|
||||
dyn.in_msgs = icmp_stat.icps_badcode + icmp_stat.icps_checksum + icmp_stat.icps_tooshort + icmp_stat.icps_badlen;
|
||||
for (i = 0; i <= ICMP_MAXTYPE; i++)
|
||||
dyn.in_msgs += icmp_stat.icps_inhist[i];
|
||||
|
||||
dyn.in_errors = icmp_stat.icps_badcode + icmp_stat.icps_tooshort + icmp_stat.icps_checksum + icmp_stat.icps_badlen;
|
||||
|
||||
dyn.in_type_counts[ICMP4_DST_UNREACH] = icmp_stat.icps_inhist[ICMP_UNREACH];
|
||||
dyn.in_type_counts[ICMP4_TIME_EXCEEDED] = icmp_stat.icps_inhist[ICMP_TIMXCEED];
|
||||
dyn.in_type_counts[ICMP4_PARAM_PROB] = icmp_stat.icps_inhist[ICMP_PARAMPROB];
|
||||
dyn.in_type_counts[ICMP4_SOURCE_QUENCH] = icmp_stat.icps_inhist[ICMP_SOURCEQUENCH];
|
||||
dyn.in_type_counts[ICMP4_REDIRECT] = icmp_stat.icps_inhist[ICMP_REDIRECT];
|
||||
dyn.in_type_counts[ICMP4_ECHO_REQUEST] = icmp_stat.icps_inhist[ICMP_ECHO];
|
||||
dyn.in_type_counts[ICMP4_ECHO_REPLY] = icmp_stat.icps_inhist[ICMP_ECHOREPLY];
|
||||
dyn.in_type_counts[ICMP4_TIMESTAMP_REQUEST] = icmp_stat.icps_inhist[ICMP_TSTAMP];
|
||||
dyn.in_type_counts[ICMP4_TIMESTAMP_REPLY] = icmp_stat.icps_inhist[ICMP_TSTAMPREPLY];
|
||||
dyn.in_type_counts[ICMP4_MASK_REQUEST] = icmp_stat.icps_inhist[ICMP_MASKREQ];
|
||||
dyn.in_type_counts[ICMP4_MASK_REPLY] = icmp_stat.icps_inhist[ICMP_MASKREPLY];
|
||||
|
||||
dyn.out_msgs = icmp_stat.icps_oldshort + icmp_stat.icps_oldicmp;
|
||||
for (i = 0; i <= ICMP_MAXTYPE; i++)
|
||||
dyn.out_msgs += icmp_stat.icps_outhist[i];
|
||||
|
||||
dyn.out_errors = icmp_stat.icps_oldshort + icmp_stat.icps_oldicmp;
|
||||
|
||||
dyn.out_type_counts[ICMP4_DST_UNREACH] = icmp_stat.icps_outhist[ICMP_UNREACH];
|
||||
dyn.out_type_counts[ICMP4_TIME_EXCEEDED] = icmp_stat.icps_outhist[ICMP_TIMXCEED];
|
||||
dyn.out_type_counts[ICMP4_PARAM_PROB] = icmp_stat.icps_outhist[ICMP_PARAMPROB];
|
||||
dyn.out_type_counts[ICMP4_SOURCE_QUENCH] = icmp_stat.icps_outhist[ICMP_SOURCEQUENCH];
|
||||
dyn.out_type_counts[ICMP4_REDIRECT] = icmp_stat.icps_outhist[ICMP_REDIRECT];
|
||||
dyn.out_type_counts[ICMP4_ECHO_REQUEST] = icmp_stat.icps_outhist[ICMP_ECHO];
|
||||
dyn.out_type_counts[ICMP4_ECHO_REPLY] = icmp_stat.icps_outhist[ICMP_ECHOREPLY];
|
||||
dyn.out_type_counts[ICMP4_TIMESTAMP_REQUEST] = icmp_stat.icps_outhist[ICMP_TSTAMP];
|
||||
dyn.out_type_counts[ICMP4_TIMESTAMP_REPLY] = icmp_stat.icps_outhist[ICMP_TSTAMPREPLY];
|
||||
dyn.out_type_counts[ICMP4_MASK_REQUEST] = icmp_stat.icps_outhist[ICMP_MASKREQ];
|
||||
dyn.out_type_counts[ICMP4_MASK_REPLY] = icmp_stat.icps_outhist[ICMP_MASKREPLY];
|
||||
if (dynamic_data) *(struct nsi_ip_icmpstats_dynamic *)dynamic_data = dyn;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
#else
|
||||
FIXME( "not implemented\n" );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
static NTSTATUS ipv4_ipstats_get_all_parameters( const void *key, DWORD key_size, void *rw_data, DWORD rw_size,
|
||||
void *dynamic_data, DWORD dynamic_size, void *static_data, DWORD static_size )
|
||||
{
|
||||
|
@ -981,6 +1113,15 @@ static struct module_table ipv4_tables[] =
|
|||
NULL,
|
||||
ipv4_cmpt_get_all_parameters,
|
||||
},
|
||||
{
|
||||
NSI_IP_ICMPSTATS_TABLE,
|
||||
{
|
||||
0, 0,
|
||||
sizeof(struct nsi_ip_icmpstats_dynamic), 0
|
||||
},
|
||||
NULL,
|
||||
ipv4_icmpstats_get_all_parameters,
|
||||
},
|
||||
{
|
||||
NSI_IP_IPSTATS_TABLE,
|
||||
{
|
||||
|
|
|
@ -98,6 +98,7 @@ struct nsi_ndis_ifinfo_static
|
|||
|
||||
/* Undocumented NSI IP tables */
|
||||
#define NSI_IP_COMPARTMENT_TABLE 2
|
||||
#define NSI_IP_ICMPSTATS_TABLE 3
|
||||
#define NSI_IP_IPSTATS_TABLE 6
|
||||
#define NSI_IP_UNICAST_TABLE 10
|
||||
#define NSI_IP_NEIGHBOUR_TABLE 11
|
||||
|
@ -119,6 +120,16 @@ struct nsi_ip_cmpt_dynamic
|
|||
DWORD num_addrs;
|
||||
};
|
||||
|
||||
struct nsi_ip_icmpstats_dynamic
|
||||
{
|
||||
DWORD in_msgs;
|
||||
DWORD in_errors;
|
||||
DWORD in_type_counts[256];
|
||||
DWORD out_msgs;
|
||||
DWORD out_errors;
|
||||
DWORD out_type_counts[256];
|
||||
};
|
||||
|
||||
struct nsi_ip_ipstats_dynamic
|
||||
{
|
||||
DWORD unk[4];
|
||||
|
|
Loading…
Reference in New Issue