iphlpapi: Simplify parsing of ICMP stats. Only try to open /proc on Linux.

This commit is contained in:
Alexandre Julliard 2009-03-05 14:23:21 +01:00
parent 12dac70a32
commit fc5ac51654
1 changed files with 98 additions and 181 deletions

View File

@ -299,24 +299,70 @@ DWORD getInterfaceStatsByName(const char *name, PMIB_IFROW entry)
*/
DWORD WINAPI GetIcmpStatistics(PMIB_ICMP stats)
{
#if defined(HAVE_SYS_SYSCTL_H) && defined(ICMPCTL_STATS)
DWORD ret = ERROR_NOT_SUPPORTED;
if (!stats) return ERROR_INVALID_PARAMETER;
memset( stats, 0, sizeof(MIB_ICMP) );
#ifdef __linux__
{
FILE *fp;
if ((fp = fopen("/proc/net/snmp", "r")))
{
static const char hdr[] = "Icmp:";
char buf[512], *ptr;
while ((ptr = fgets(buf, sizeof(buf), fp)))
{
if (strncasecmp(buf, hdr, sizeof(hdr) - 1)) continue;
/* last line was a header, get another */
if (!(ptr = fgets(buf, sizeof(buf), fp))) break;
if (!strncasecmp(buf, hdr, sizeof(hdr) - 1))
{
ptr += sizeof(hdr);
sscanf( ptr, "%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u",
&stats->stats.icmpInStats.dwMsgs,
&stats->stats.icmpInStats.dwErrors,
&stats->stats.icmpInStats.dwDestUnreachs,
&stats->stats.icmpInStats.dwTimeExcds,
&stats->stats.icmpInStats.dwParmProbs,
&stats->stats.icmpInStats.dwSrcQuenchs,
&stats->stats.icmpInStats.dwRedirects,
&stats->stats.icmpInStats.dwEchoReps,
&stats->stats.icmpInStats.dwTimestamps,
&stats->stats.icmpInStats.dwTimestampReps,
&stats->stats.icmpInStats.dwAddrMasks,
&stats->stats.icmpInStats.dwAddrMaskReps,
&stats->stats.icmpOutStats.dwMsgs,
&stats->stats.icmpOutStats.dwErrors,
&stats->stats.icmpOutStats.dwDestUnreachs,
&stats->stats.icmpOutStats.dwTimeExcds,
&stats->stats.icmpOutStats.dwParmProbs,
&stats->stats.icmpOutStats.dwSrcQuenchs,
&stats->stats.icmpOutStats.dwRedirects,
&stats->stats.icmpOutStats.dwEchoReps,
&stats->stats.icmpOutStats.dwTimestamps,
&stats->stats.icmpOutStats.dwTimestampReps,
&stats->stats.icmpOutStats.dwAddrMasks,
&stats->stats.icmpOutStats.dwAddrMaskReps );
break;
}
}
fclose(fp);
ret = NO_ERROR;
}
}
#elif defined(HAVE_SYS_SYSCTL_H) && defined(ICMPCTL_STATS)
{
int mib[] = {CTL_NET, PF_INET, IPPROTO_ICMP, ICMPCTL_STATS};
#define MIB_LEN (sizeof(mib) / sizeof(mib[0]))
size_t needed;
struct icmpstat icmp_stat;
size_t needed = sizeof(icmp_stat);
int i;
if (!stats)
return ERROR_INVALID_PARAMETER;
needed = sizeof(icmp_stat);
if(sysctl(mib, MIB_LEN, &icmp_stat, &needed, NULL, 0) == -1)
if(sysctl(mib, MIB_LEN, &icmp_stat, &needed, NULL, 0) != -1)
{
ERR ("failed to get icmpstat\n");
return ERROR_NOT_SUPPORTED;
}
/*in stats */
stats->stats.icmpInStats.dwMsgs = icmp_stat.icps_badcode + icmp_stat.icps_checksum + icmp_stat.icps_tooshort + icmp_stat.icps_badlen;
for(i = 0; i <= ICMP_MAXTYPE; i++)
@ -355,143 +401,14 @@ DWORD WINAPI GetIcmpStatistics(PMIB_ICMP stats)
stats->stats.icmpOutStats.dwTimestampReps = icmp_stat.icps_outhist[ICMP_TSTAMPREPLY];
stats->stats.icmpOutStats.dwAddrMasks = icmp_stat.icps_outhist[ICMP_MASKREQ];
stats->stats.icmpOutStats.dwAddrMaskReps = icmp_stat.icps_outhist[ICMP_MASKREPLY];
#else /* ICPS_OUTHIST */
memset( &stats->stats.icmpOutStats, 0, sizeof(stats->stats.icmpOutStats) );
#endif /* ICPS_OUTHIST */
return NO_ERROR;
ret = NO_ERROR;
}
}
#else /* ICMPCTL_STATS */
FILE *fp;
if (!stats)
return ERROR_INVALID_PARAMETER;
memset(stats, 0, sizeof(MIB_ICMP));
/* get most of these stats from /proc/net/snmp, no error if can't */
fp = fopen("/proc/net/snmp", "r");
if (fp) {
static const char hdr[] = "Icmp:";
char buf[512] = { 0 }, *ptr;
do {
ptr = fgets(buf, sizeof(buf), fp);
} while (ptr && strncasecmp(buf, hdr, sizeof(hdr) - 1));
if (ptr) {
/* last line was a header, get another */
ptr = fgets(buf, sizeof(buf), fp);
if (ptr && strncasecmp(buf, hdr, sizeof(hdr) - 1) == 0) {
char *endPtr;
ptr += sizeof(hdr);
if (ptr && *ptr) {
stats->stats.icmpInStats.dwMsgs = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpInStats.dwErrors = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpInStats.dwDestUnreachs = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpInStats.dwTimeExcds = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpInStats.dwParmProbs = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpInStats.dwSrcQuenchs = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpInStats.dwRedirects = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpInStats.dwEchoReps = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpInStats.dwTimestamps = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpInStats.dwTimestampReps = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpInStats.dwAddrMasks = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpInStats.dwAddrMaskReps = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpOutStats.dwMsgs = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpOutStats.dwErrors = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpOutStats.dwDestUnreachs = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpOutStats.dwTimeExcds = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpOutStats.dwParmProbs = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpOutStats.dwSrcQuenchs = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpOutStats.dwRedirects = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpOutStats.dwEchoReps = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpOutStats.dwTimestamps = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpOutStats.dwTimestampReps = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpOutStats.dwAddrMasks = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpOutStats.dwAddrMaskReps = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
}
}
fclose(fp);
}
else
{
ERR ("unimplemented!\n");
return ERROR_NOT_SUPPORTED;
}
return NO_ERROR;
FIXME( "unimplemented\n" );
#endif
return ret;
}