diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c index 78f4c582e1a..9e484b7e4c2 100644 --- a/dlls/iphlpapi/iphlpapi_main.c +++ b/dlls/iphlpapi/iphlpapi_main.c @@ -1495,6 +1495,42 @@ DWORD WINAPI GetFriendlyIfIndex(DWORD IfIndex) return IfIndex; } +/****************************************************************** + * GetIcmpStatisticsEx (IPHLPAPI.@) + * + * Get the IPv4 and IPv6 ICMP statistics for the local computer. + * + * PARAMS + * stats [Out] buffer for ICMP statistics + * family [In] specifies whether IPv4 or IPv6 statistics are returned + * + * RETURNS + * Success: NO_ERROR + * Failure: error code from winerror.h + */ +DWORD WINAPI GetIcmpStatisticsEx( MIB_ICMP_EX *stats, DWORD family ) +{ + const NPI_MODULEID *mod = ip_module_id( family ); + struct nsi_ip_icmpstats_dynamic dyn; + DWORD err; + + if (!stats || !mod) return ERROR_INVALID_PARAMETER; + memset( stats, 0, sizeof(*stats) ); + + err = NsiGetAllParameters( 1, mod, NSI_IP_ICMPSTATS_TABLE, NULL, 0, NULL, 0, + &dyn, sizeof(dyn), NULL, 0 ); + if (err) return err; + + stats->icmpInStats.dwMsgs = dyn.in_msgs; + stats->icmpInStats.dwErrors = dyn.in_errors; + memcpy( stats->icmpInStats.rgdwTypeCount, dyn.in_type_counts, sizeof( dyn.in_type_counts ) ); + stats->icmpOutStats.dwMsgs = dyn.out_msgs; + stats->icmpOutStats.dwErrors = dyn.out_errors; + memcpy( stats->icmpOutStats.rgdwTypeCount, dyn.out_type_counts, sizeof( dyn.out_type_counts ) ); + + return ERROR_SUCCESS; +} + static void if_row_fill( MIB_IFROW *row, struct nsi_ndis_ifinfo_rw *rw, struct nsi_ndis_ifinfo_dynamic *dyn, struct nsi_ndis_ifinfo_static *stat ) { diff --git a/dlls/iphlpapi/ipstats.c b/dlls/iphlpapi/ipstats.c index 7d0011a1231..ff33ed42777 100644 --- a/dlls/iphlpapi/ipstats.c +++ b/dlls/iphlpapi/ipstats.c @@ -446,181 +446,6 @@ DWORD WINAPI GetIcmpStatistics(PMIB_ICMP stats) return ret; } -/****************************************************************** - * GetIcmpStatisticsEx (IPHLPAPI.@) - * - * Get the IPv4 and IPv6 ICMP statistics for the local computer. - * - * PARAMS - * stats [Out] buffer for ICMP statistics - * family [In] specifies whether IPv4 or IPv6 statistics are returned - * - * RETURNS - * Success: NO_ERROR - * Failure: error code from winerror.h - */ -DWORD WINAPI GetIcmpStatisticsEx(PMIB_ICMP_EX stats, DWORD family) -{ - DWORD ret = ERROR_NOT_SUPPORTED; - MIB_ICMP ipv4stats; - - if (!stats) return ERROR_INVALID_PARAMETER; - if (family != WS_AF_INET && family != WS_AF_INET6) return ERROR_INVALID_PARAMETER; - memset( stats, 0, sizeof(MIB_ICMP_EX) ); - - if (family == WS_AF_INET6) - { -#ifdef __linux__ - { - FILE *fp; - - if ((fp = fopen("/proc/net/snmp6", "r"))) - { - struct icmpstatstruct{ - const char *name; - DWORD pos; - }; - static const struct icmpstatstruct icmpinstatlist[] = { - { "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 icmpstatstruct icmpoutstatlist[] = { - { "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; - - 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)) stats->icmpInStats.dwMsgs = res; - continue; - } - - if (!_strnicmp(buf, "Icmp6InErrors", -1)) - { - if (sscanf(value, "%d", &res)) stats->icmpInStats.dwErrors = res; - continue; - } - - for (i = 0; i < ARRAY_SIZE(icmpinstatlist); i++) - { - if (!_strnicmp(buf, icmpinstatlist[i].name, -1)) - { - if (sscanf(value, "%d", &res)) - stats->icmpInStats.rgdwTypeCount[icmpinstatlist[i].pos] = res; - break; - } - } - - if (!_strnicmp(buf, "Icmp6OutMsgs", -1)) - { - if (sscanf(value, "%d", &res)) stats->icmpOutStats.dwMsgs = res; - continue; - } - - if (!_strnicmp(buf, "Icmp6OutErrors", -1)) - { - if (sscanf(value, "%d", &res)) stats->icmpOutStats.dwErrors = res; - continue; - } - - for (i = 0; i < ARRAY_SIZE(icmpoutstatlist); i++) - { - if (!_strnicmp(buf, icmpoutstatlist[i].name, -1)) - { - if (sscanf(value, "%d", &res)) - stats->icmpOutStats.rgdwTypeCount[icmpoutstatlist[i].pos] = res; - break; - } - } - - } - fclose(fp); - ret = NO_ERROR; - } - } -#else - FIXME( "unimplemented for IPv6\n" ); -#endif - return ret; - } - - ret = GetIcmpStatistics(&ipv4stats); - if (!ret) - { - stats->icmpInStats.dwMsgs = ipv4stats.stats.icmpInStats.dwMsgs; - stats->icmpInStats.dwErrors = ipv4stats.stats.icmpInStats.dwErrors; - stats->icmpInStats.rgdwTypeCount[ICMP4_DST_UNREACH] = ipv4stats.stats.icmpInStats.dwDestUnreachs; - stats->icmpInStats.rgdwTypeCount[ICMP4_SOURCE_QUENCH] = ipv4stats.stats.icmpInStats.dwSrcQuenchs; - stats->icmpInStats.rgdwTypeCount[ICMP4_REDIRECT] = ipv4stats.stats.icmpInStats.dwRedirects; - stats->icmpInStats.rgdwTypeCount[ICMP4_ECHO_REQUEST] = ipv4stats.stats.icmpInStats.dwEchos; - stats->icmpInStats.rgdwTypeCount[ICMP4_ECHO_REPLY] = ipv4stats.stats.icmpInStats.dwEchoReps; - stats->icmpInStats.rgdwTypeCount[ICMP4_TIME_EXCEEDED] = ipv4stats.stats.icmpInStats.dwTimeExcds; - stats->icmpInStats.rgdwTypeCount[ICMP4_PARAM_PROB] = ipv4stats.stats.icmpInStats.dwParmProbs; - stats->icmpInStats.rgdwTypeCount[ICMP4_TIMESTAMP_REQUEST] = ipv4stats.stats.icmpInStats.dwTimestamps; - stats->icmpInStats.rgdwTypeCount[ICMP4_TIMESTAMP_REPLY] = ipv4stats.stats.icmpInStats.dwTimestampReps; - stats->icmpInStats.rgdwTypeCount[ICMP4_MASK_REQUEST] = ipv4stats.stats.icmpInStats.dwAddrMasks; - stats->icmpInStats.rgdwTypeCount[ICMP4_MASK_REPLY] = ipv4stats.stats.icmpInStats.dwAddrMaskReps; - - stats->icmpOutStats.dwMsgs = ipv4stats.stats.icmpOutStats.dwMsgs; - stats->icmpOutStats.dwErrors = ipv4stats.stats.icmpOutStats.dwErrors; - stats->icmpOutStats.rgdwTypeCount[ICMP4_DST_UNREACH] = ipv4stats.stats.icmpOutStats.dwDestUnreachs; - stats->icmpOutStats.rgdwTypeCount[ICMP4_SOURCE_QUENCH] = ipv4stats.stats.icmpOutStats.dwSrcQuenchs; - stats->icmpOutStats.rgdwTypeCount[ICMP4_REDIRECT] = ipv4stats.stats.icmpOutStats.dwRedirects; - stats->icmpOutStats.rgdwTypeCount[ICMP4_ECHO_REQUEST] = ipv4stats.stats.icmpOutStats.dwEchos; - stats->icmpOutStats.rgdwTypeCount[ICMP4_ECHO_REPLY] = ipv4stats.stats.icmpOutStats.dwEchoReps; - stats->icmpOutStats.rgdwTypeCount[ICMP4_TIME_EXCEEDED] = ipv4stats.stats.icmpOutStats.dwTimeExcds; - stats->icmpOutStats.rgdwTypeCount[ICMP4_PARAM_PROB] = ipv4stats.stats.icmpOutStats.dwParmProbs; - stats->icmpOutStats.rgdwTypeCount[ICMP4_TIMESTAMP_REQUEST] = ipv4stats.stats.icmpOutStats.dwTimestamps; - stats->icmpOutStats.rgdwTypeCount[ICMP4_TIMESTAMP_REPLY] = ipv4stats.stats.icmpOutStats.dwTimestampReps; - stats->icmpOutStats.rgdwTypeCount[ICMP4_MASK_REQUEST] = ipv4stats.stats.icmpOutStats.dwAddrMasks; - stats->icmpOutStats.rgdwTypeCount[ICMP4_MASK_REPLY] = ipv4stats.stats.icmpOutStats.dwAddrMaskReps; - } - return ret; -} - /****************************************************************** * GetTcpStatisticsEx (IPHLPAPI.@) *