[PATCH 3/6] nsiproxy: Implement IPv6 icmpstats get_all_parameters on linux.
Huw Davies
huw at codeweavers.com
Thu Aug 12 04:38:15 CDT 2021
Signed-off-by: Huw Davies <huw at codeweavers.com>
---
dlls/nsi/tests/nsi.c | 1 -
dlls/nsiproxy.sys/ip.c | 135 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 135 insertions(+), 1 deletion(-)
diff --git a/dlls/nsi/tests/nsi.c b/dlls/nsi/tests/nsi.c
index 3b1e757fa23..a21ac897e2c 100644
--- a/dlls/nsi/tests/nsi.c
+++ b/dlls/nsi/tests/nsi.c
@@ -456,7 +456,6 @@ static void test_ip_icmpstats( int family )
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;
diff --git a/dlls/nsiproxy.sys/ip.c b/dlls/nsiproxy.sys/ip.c
index 8b7b41a291c..ae3e23960de 100644
--- a/dlls/nsiproxy.sys/ip.c
+++ b/dlls/nsiproxy.sys/ip.c
@@ -355,6 +355,132 @@ static NTSTATUS ipv4_icmpstats_get_all_parameters( const void *key, DWORD key_si
#endif
}
+static NTSTATUS ipv6_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__
+ {
+ struct data
+ {
+ const char *name;
+ DWORD pos;
+ };
+ static const struct data in_list[] =
+ {
+ { "Icmp6InDestUnreachs", ICMP6_DST_UNREACH },
+ { "Icmp6InPktTooBigs", ICMP6_PACKET_TOO_BIG },
+ { "Icmp6InTimeExcds", ICMP6_TIME_EXCEEDED },
+ { "Icmp6InParmProblems", ICMP6_PARAM_PROB },
+ { "Icmp6InEchos", ICMP6_ECHO_REQUEST },
+ { "Icmp6InEchoReplies", ICMP6_ECHO_REPLY },
+ { "Icmp6InGroupMembQueries", ICMP6_MEMBERSHIP_QUERY },
+ { "Icmp6InGroupMembResponses", ICMP6_MEMBERSHIP_REPORT },
+ { "Icmp6InGroupMembReductions", ICMP6_MEMBERSHIP_REDUCTION },
+ { "Icmp6InRouterSolicits", ND_ROUTER_SOLICIT },
+ { "Icmp6InRouterAdvertisements", ND_ROUTER_ADVERT },
+ { "Icmp6InNeighborSolicits", ND_NEIGHBOR_SOLICIT },
+ { "Icmp6InNeighborAdvertisements", ND_NEIGHBOR_ADVERT },
+ { "Icmp6InRedirects", ND_REDIRECT },
+ { "Icmp6InMLDv2Reports", ICMP6_V2_MEMBERSHIP_REPORT },
+ };
+ static const struct data out_list[] =
+ {
+ { "Icmp6OutDestUnreachs", ICMP6_DST_UNREACH },
+ { "Icmp6OutPktTooBigs", ICMP6_PACKET_TOO_BIG },
+ { "Icmp6OutTimeExcds", ICMP6_TIME_EXCEEDED },
+ { "Icmp6OutParmProblems", ICMP6_PARAM_PROB },
+ { "Icmp6OutEchos", ICMP6_ECHO_REQUEST },
+ { "Icmp6OutEchoReplies", ICMP6_ECHO_REPLY },
+ { "Icmp6OutGroupMembQueries", ICMP6_MEMBERSHIP_QUERY },
+ { "Icmp6OutGroupMembResponses", ICMP6_MEMBERSHIP_REPORT },
+ { "Icmp6OutGroupMembReductions", ICMP6_MEMBERSHIP_REDUCTION },
+ { "Icmp6OutRouterSolicits", ND_ROUTER_SOLICIT },
+ { "Icmp6OutRouterAdvertisements", ND_ROUTER_ADVERT },
+ { "Icmp6OutNeighborSolicits", ND_NEIGHBOR_SOLICIT },
+ { "Icmp6OutNeighborAdvertisements", ND_NEIGHBOR_ADVERT },
+ { "Icmp6OutRedirects", ND_REDIRECT },
+ { "Icmp6OutMLDv2Reports", ICMP6_V2_MEMBERSHIP_REPORT },
+ };
+ char buf[512], *ptr, *value;
+ DWORD res, 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 */
+ ptr = value - 1;
+ *(ptr + 1) = '\0';
+
+ /* and strip leading spaces from value */
+ value += 1;
+ while (*value == ' ') value++;
+ if ((ptr = strchr( value, '\n' ))) *ptr='\0';
+
+ if (!_strnicmp( buf, "Icmp6InMsgs", -1 ))
+ {
+ if (sscanf( value, "%d", &res )) dyn.in_msgs = res;
+ continue;
+ }
+
+ if (!_strnicmp( buf, "Icmp6InErrors", -1 ))
+ {
+ if (sscanf( value, "%d", &res )) dyn.in_errors = res;
+ continue;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(in_list); i++)
+ {
+ if (!_strnicmp( buf, in_list[i].name, -1 ))
+ {
+ if (sscanf( value, "%d", &res ))
+ dyn.in_type_counts[in_list[i].pos] = res;
+ break;
+ }
+ }
+
+ if (!_strnicmp( buf, "Icmp6OutMsgs", -1 ))
+ {
+ if (sscanf( value, "%d", &res )) dyn.out_msgs = res;
+ continue;
+ }
+
+ if (!_strnicmp( buf, "Icmp6OutErrors", -1 ))
+ {
+ if (sscanf( value, "%d", &res )) dyn.out_errors = res;
+ continue;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(out_list); i++)
+ {
+ if (!_strnicmp( buf, out_list[i].name, -1 ))
+ {
+ if (sscanf( value, "%d", &res ))
+ dyn.out_type_counts[out_list[i].pos] = res;
+ break;
+ }
+ }
+ }
+ fclose( fp );
+ 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 )
{
@@ -1178,6 +1304,15 @@ static struct module_table ipv6_tables[] =
NULL,
ipv6_cmpt_get_all_parameters,
},
+ {
+ NSI_IP_ICMPSTATS_TABLE,
+ {
+ 0, 0,
+ sizeof(struct nsi_ip_icmpstats_dynamic), 0
+ },
+ NULL,
+ ipv6_icmpstats_get_all_parameters,
+ },
{
NSI_IP_IPSTATS_TABLE,
{
--
2.23.0
More information about the wine-devel
mailing list