Huw Davies : nsiproxy: Implement IPv6 icmpstats get_all_parameters on linux.

Alexandre Julliard julliard at winehq.org
Thu Aug 12 16:35:19 CDT 2021


Module: wine
Branch: master
Commit: cf434fa31346d3e362b152b045986941bf8ba53f
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=cf434fa31346d3e362b152b045986941bf8ba53f

Author: Huw Davies <huw at codeweavers.com>
Date:   Thu Aug 12 10:38:15 2021 +0100

nsiproxy: Implement IPv6 icmpstats get_all_parameters on linux.

Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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,
         {




More information about the wine-cvs mailing list