iphlpapi: Implement GetIcmpStatisticsEx() on top of nsi.
Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
cf434fa313
commit
1cc49258f7
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -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.@)
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue