Eric Durbin : iphlpapi: Implement getInterfaceStatsByName on FreeBSD.

Alexandre Julliard julliard at winehq.org
Thu Jun 26 06:47:59 CDT 2008


Module: wine
Branch: master
Commit: 53058e86e83b4b6c9cf3994378287e0761039732
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=53058e86e83b4b6c9cf3994378287e0761039732

Author: Eric Durbin <eadurbin at freebsd.org>
Date:   Tue Jun 24 22:42:51 2008 -0500

iphlpapi: Implement getInterfaceStatsByName on FreeBSD.

---

 dlls/iphlpapi/ipstats.c |   59 +++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 54 insertions(+), 5 deletions(-)

diff --git a/dlls/iphlpapi/ipstats.c b/dlls/iphlpapi/ipstats.c
index a7fd40d..3a537b1 100644
--- a/dlls/iphlpapi/ipstats.c
+++ b/dlls/iphlpapi/ipstats.c
@@ -43,6 +43,9 @@
 #ifdef HAVE_NET_IF_H
 #include <net/if.h>
 #endif
+#ifdef HAVE_NET_IF_TYPES_H
+#include <net/if_types.h>
+#endif
 #ifdef HAVE_NET_ROUTE_H
 #include <net/route.h>
 #endif
@@ -102,15 +105,60 @@ WINE_DEFAULT_DEBUG_CHANNEL(iphlpapi);
 
 DWORD getInterfaceStatsByName(const char *name, PMIB_IFROW entry)
 {
-  FILE *fp;
-
-  if (!name)
-    return ERROR_INVALID_PARAMETER;
-  if (!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;
 
+  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;
   fp = fopen("/proc/net/dev", "r");
   if (fp) {
     char buf[512] = { 0 }, *ptr;
@@ -188,6 +236,7 @@ DWORD getInterfaceStatsByName(const char *name, PMIB_IFROW entry)
   }
 
   return NO_ERROR;
+#endif
 }
 
 DWORD getICMPStats(MIB_ICMP *stats)




More information about the wine-cvs mailing list