[PATCH 2/4] nsiproxy: Implement IPv6 ipstats get_all_parameters on linux.
Huw Davies
huw at codeweavers.com
Wed Aug 11 05:01:29 CDT 2021
Signed-off-by: Huw Davies <huw at codeweavers.com>
---
dlls/nsi/tests/nsi.c | 1 -
dlls/nsiproxy.sys/ip.c | 85 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 85 insertions(+), 1 deletion(-)
diff --git a/dlls/nsi/tests/nsi.c b/dlls/nsi/tests/nsi.c
index dd1a552cce6..feed72a1626 100644
--- a/dlls/nsi/tests/nsi.c
+++ b/dlls/nsi/tests/nsi.c
@@ -424,7 +424,6 @@ static void test_ip_ipstats( int family )
/* The table appears to consist of a single object without a key. The rw data does exist but
isn't part of GetIpStatisticsEx() and isn't yet tested */
err = NsiGetAllParameters( 1, mod, NSI_IP_IPSTATS_TABLE, NULL, 0, NULL, 0, &dyn, sizeof(dyn), &stat, sizeof(stat) );
-todo_wine_if( family == AF_INET6 )
ok( !err, "got %x\n", err );
if (err) goto err;
diff --git a/dlls/nsiproxy.sys/ip.c b/dlls/nsiproxy.sys/ip.c
index 438ae219174..7d9af08c711 100644
--- a/dlls/nsiproxy.sys/ip.c
+++ b/dlls/nsiproxy.sys/ip.c
@@ -226,6 +226,82 @@ static NTSTATUS ipv4_ipstats_get_all_parameters( const void *key, DWORD key_size
#endif
}
+static NTSTATUS ipv6_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 )
+{
+ struct nsi_ip_ipstats_dynamic dyn;
+ struct nsi_ip_ipstats_static stat;
+
+ memset( &dyn, 0, sizeof(dyn) );
+ memset( &stat, 0, sizeof(stat) );
+
+#ifdef __linux__
+ {
+ struct
+ {
+ const char *name;
+ void *elem;
+ int size;
+ } ipstatlist[] =
+ {
+#define X(x) &x, sizeof(x)
+ { "Ip6InReceives", X( dyn.in_recv ) },
+ { "Ip6InHdrErrors", X( dyn.in_hdr_errs ) },
+ { "Ip6InAddrErrors", X( dyn.in_addr_errs ) },
+ { "Ip6OutForwDatagrams", X( dyn.fwd_dgrams ) },
+ { "Ip6InUnknownProtos", X( dyn.in_unk_protos ) },
+ { "Ip6InDiscards", X( dyn.in_discards ) },
+ { "Ip6InDelivers", X( dyn.in_delivers ) },
+ { "Ip6OutRequests", X( dyn.out_reqs ) },
+ { "Ip6OutDiscards", X( dyn.out_discards ) },
+ { "Ip6OutNoRoutes", X( dyn.out_no_routes ) },
+ { "Ip6ReasmTimeout", X( stat.reasm_timeout ) },
+ { "Ip6ReasmReqds", X( dyn.reasm_reqds ) },
+ { "Ip6ReasmOKs", X( dyn.reasm_oks ) },
+ { "Ip6ReasmFails", X( dyn.reasm_fails ) },
+ { "Ip6FragOKs", X( dyn.frag_oks ) },
+ { "Ip6FragFails", X( dyn.frag_fails ) },
+ { "Ip6FragCreates", X( dyn.frag_creates ) },
+ /* no routingDiscards */
+#undef X
+ };
+ NTSTATUS status = STATUS_NOT_SUPPORTED;
+ char buf[512], *ptr, *value;
+ DWORD i;
+ FILE *fp;
+
+ if (!(fp = fopen( "/proc/net/snmp6", "r" ))) return STATUS_NOT_SUPPORTED;
+
+ while ((ptr = fgets( buf, sizeof(buf), fp )))
+ {
+ if (!(value = strchr( buf, ' ' ))) continue;
+ /* terminate the valuename */
+ *value++ = '\0';
+ /* and strip leading spaces from value */
+ while (*value == ' ') value++;
+ if ((ptr = strchr( value, '\n' ))) *ptr = '\0';
+
+ for (i = 0; i < ARRAY_SIZE(ipstatlist); i++)
+ if (!_strnicmp( buf, ipstatlist[i].name, -1 ))
+ {
+ if (ipstatlist[i].size == sizeof(long))
+ *(long *)ipstatlist[i].elem = strtoul( value, NULL, 10 );
+ else
+ *(long long *)ipstatlist[i].elem = strtoull( value, NULL, 10 );
+ status = STATUS_SUCCESS;
+ }
+ }
+ fclose( fp );
+ if (dynamic_data) *(struct nsi_ip_ipstats_dynamic *)dynamic_data = dyn;
+ if (static_data) *(struct nsi_ip_ipstats_static *)static_data = stat;
+ return status;;
+ }
+#else
+ FIXME( "not implemented\n" );
+ return STATUS_NOT_IMPLEMENTED;
+#endif
+}
+
static void unicast_fill_entry( struct ifaddrs *entry, void *key, struct nsi_ip_unicast_rw *rw,
struct nsi_ip_unicast_dynamic *dyn, struct nsi_ip_unicast_static *stat )
{
@@ -840,6 +916,15 @@ const struct module ipv4_module =
static struct module_table ipv6_tables[] =
{
+ {
+ NSI_IP_IPSTATS_TABLE,
+ {
+ 0, 0,
+ sizeof(struct nsi_ip_ipstats_dynamic), sizeof(struct nsi_ip_ipstats_static)
+ },
+ NULL,
+ ipv6_ipstats_get_all_parameters,
+ },
{
NSI_IP_UNICAST_TABLE,
{
--
2.23.0
More information about the wine-devel
mailing list