Module: wine Branch: master Commit: ea73002863c3f42f8f9a9cc25985371908bd4794 URL: http://source.winehq.org/git/wine.git/?a=commit;h=ea73002863c3f42f8f9a9cc259...
Author: Alexandre Julliard julliard@winehq.org Date: Thu Mar 5 14:23:52 2009 +0100
iphlpapi: Simplify parsing of interface data. Only try to open /proc on Linux.
---
dlls/iphlpapi/ipstats.c | 203 ++++++++++++++++++----------------------------- 1 files changed, 79 insertions(+), 124 deletions(-)
diff --git a/dlls/iphlpapi/ipstats.c b/dlls/iphlpapi/ipstats.c index c9016fc..6311641 100644 --- a/dlls/iphlpapi/ipstats.c +++ b/dlls/iphlpapi/ipstats.c @@ -150,138 +150,93 @@ WINE_DEFAULT_DEBUG_CHANNEL(iphlpapi);
DWORD getInterfaceStatsByName(const char *name, PMIB_IFROW entry) { -#if defined(HAVE_SYS_SYSCTL_H) && defined(NET_RT_IFLIST) - int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_IFLIST, if_nametoindex(name)}; -#define MIB_LEN (sizeof(mib) / sizeof(mib[0])) - - size_t needed; - char *buf, *end; - struct if_msghdr *ifm; - struct if_data ifdata; - if (!name || !entry) - return ERROR_INVALID_PARAMETER; + DWORD ret = ERROR_NOT_SUPPORTED;
- if(sysctl(mib, MIB_LEN, NULL, &needed, NULL, 0) == -1) - { - ERR ("failed to get size of iflist\n"); - return ERROR_NOT_SUPPORTED; - } - buf = HeapAlloc (GetProcessHeap (), 0, needed); - if (!buf) return ERROR_NOT_SUPPORTED; - if(sysctl(mib, MIB_LEN, buf, &needed, NULL, 0) == -1) - { - ERR ("failed to get iflist\n"); - HeapFree (GetProcessHeap (), 0, buf); - return ERROR_NOT_SUPPORTED; - } - else - for ( end = buf + needed; buf < end; buf += ifm->ifm_msglen) - { - ifm = (struct if_msghdr *) buf; - if(ifm->ifm_type == RTM_IFINFO && ifm->ifm_data.ifi_type == IFT_ETHER) - { - ifdata = ifm->ifm_data; - entry->dwMtu = ifdata.ifi_mtu; - entry->dwSpeed = ifdata.ifi_baudrate; - entry->dwInOctets = ifdata.ifi_ibytes; - entry->dwInErrors = ifdata.ifi_ierrors; - entry->dwInDiscards = ifdata.ifi_iqdrops; - entry->dwInUcastPkts = ifdata.ifi_ipackets; - entry->dwInNUcastPkts = ifdata.ifi_imcasts; - entry->dwOutOctets = ifdata.ifi_obytes; - entry->dwOutUcastPkts = ifdata.ifi_opackets; - entry->dwOutErrors = ifdata.ifi_oerrors; - HeapFree (GetProcessHeap (), 0, buf); - return NO_ERROR; - } - } - HeapFree (GetProcessHeap (), 0, buf); - return ERROR_NOT_SUPPORTED; -#else - /* get interface stats from /proc/net/dev, no error if can't - no inUnknownProtos, outNUcastPkts, outQLen */ - FILE *fp; + if (!name || !entry) return ERROR_INVALID_PARAMETER;
- if (!name || !entry) - return ERROR_INVALID_PARAMETER; - fp = fopen("/proc/net/dev", "r"); - if (fp) { - char buf[512] = { 0 }, *ptr; - int nameLen = strlen(name), nameFound = 0; +#ifdef __linux__ + { + FILE *fp;
+ if ((fp = fopen("/proc/net/dev", "r"))) + { + DWORD skip; + char buf[512], *ptr; + int nameLen = strlen(name);
- ptr = fgets(buf, sizeof(buf), fp); - while (ptr && !nameFound) { - while (*ptr && isspace(*ptr)) - ptr++; - if (strncasecmp(ptr, name, nameLen) == 0 && *(ptr + nameLen) == ':') - nameFound = 1; - else - ptr = fgets(buf, sizeof(buf), fp); + while ((ptr = fgets(buf, sizeof(buf), fp))) + { + while (*ptr && isspace(*ptr)) ptr++; + if (strncasecmp(ptr, name, nameLen) == 0 && *(ptr + nameLen) == ':') + { + ptr += nameLen + 1; + sscanf( ptr, "%u %u %u %u %u %u %u %u %u %u %u %u", + &entry->dwInOctets, &entry->dwInUcastPkts, + &entry->dwInErrors, &entry->dwInDiscards, + &skip, &skip, &skip, + &entry->dwInNUcastPkts, &entry->dwOutOctets, + &entry->dwOutUcastPkts, &entry->dwOutErrors, + &entry->dwOutDiscards ); + break; + } + } + fclose(fp); + ret = NO_ERROR; + } } - if (nameFound) { - char *endPtr; +#elif defined(HAVE_SYS_SYSCTL_H) && defined(NET_RT_IFLIST) + { + int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_IFLIST, if_nametoindex(name)}; +#define MIB_LEN (sizeof(mib) / sizeof(mib[0]))
- ptr += nameLen + 1; - if (ptr && *ptr) { - entry->dwInOctets = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - entry->dwInUcastPkts = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - entry->dwInErrors = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - entry->dwInDiscards = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - strtoul(ptr, &endPtr, 10); /* skip */ - ptr = endPtr; - } - if (ptr && *ptr) { - strtoul(ptr, &endPtr, 10); /* skip */ - ptr = endPtr; - } - if (ptr && *ptr) { - strtoul(ptr, &endPtr, 10); /* skip */ - ptr = endPtr; - } - if (ptr && *ptr) { - entry->dwInNUcastPkts = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - entry->dwOutOctets = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - entry->dwOutUcastPkts = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - entry->dwOutErrors = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - if (ptr && *ptr) { - entry->dwOutDiscards = strtoul(ptr, &endPtr, 10); - ptr = endPtr; - } - } - fclose(fp); - } - else - { - ERR ("unimplemented!\n"); - return ERROR_NOT_SUPPORTED; - } + size_t needed; + char *buf = NULL, *end; + struct if_msghdr *ifm; + struct if_data ifdata;
- return NO_ERROR; + if(sysctl(mib, MIB_LEN, NULL, &needed, NULL, 0) == -1) + { + ERR ("failed to get size of iflist\n"); + goto done; + } + buf = HeapAlloc (GetProcessHeap (), 0, needed); + if (!buf) + { + ret = ERROR_OUTOFMEMORY; + goto done; + } + if(sysctl(mib, MIB_LEN, buf, &needed, NULL, 0) == -1) + { + ERR ("failed to get iflist\n"); + goto done; + } + for ( end = buf + needed; buf < end; buf += ifm->ifm_msglen) + { + ifm = (struct if_msghdr *) buf; + if(ifm->ifm_type == RTM_IFINFO && ifm->ifm_data.ifi_type == IFT_ETHER) + { + ifdata = ifm->ifm_data; + entry->dwMtu = ifdata.ifi_mtu; + entry->dwSpeed = ifdata.ifi_baudrate; + entry->dwInOctets = ifdata.ifi_ibytes; + entry->dwInErrors = ifdata.ifi_ierrors; + entry->dwInDiscards = ifdata.ifi_iqdrops; + entry->dwInUcastPkts = ifdata.ifi_ipackets; + entry->dwInNUcastPkts = ifdata.ifi_imcasts; + entry->dwOutOctets = ifdata.ifi_obytes; + entry->dwOutUcastPkts = ifdata.ifi_opackets; + entry->dwOutErrors = ifdata.ifi_oerrors; + ret = NO_ERROR; + break; + } + } + done: + HeapFree (GetProcessHeap (), 0, buf); + } +#else + FIXME( "unimplemented\n" ); #endif + return ret; }