Alexandre Julliard : iphlpapi: Simplify parsing of TCP stats. Only try to open /proc on Linux.

Alexandre Julliard julliard at winehq.org
Thu Mar 5 10:31:07 CST 2009


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu Mar  5 14:24:29 2009 +0100

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

---

 dlls/iphlpapi/ipstats.c |  203 ++++++++++++++++++-----------------------------
 1 files changed, 76 insertions(+), 127 deletions(-)

diff --git a/dlls/iphlpapi/ipstats.c b/dlls/iphlpapi/ipstats.c
index 6e210fa..7d31e43 100644
--- a/dlls/iphlpapi/ipstats.c
+++ b/dlls/iphlpapi/ipstats.c
@@ -508,144 +508,93 @@ DWORD WINAPI GetIpStatistics(PMIB_IPSTATS stats)
  */
 DWORD WINAPI GetTcpStatistics(PMIB_TCPSTATS stats)
 {
-#if defined(HAVE_SYS_SYSCTL_H) && defined(UDPCTL_STATS)
+    DWORD ret = ERROR_NOT_SUPPORTED;
+
+    if (!stats) return ERROR_INVALID_PARAMETER;
+    memset( stats, 0, sizeof(*stats) );
+
+#ifdef __linux__
+    {
+        FILE *fp;
+
+        if ((fp = fopen("/proc/net/snmp", "r")))
+        {
+            static const char hdr[] = "Tcp:";
+            MIB_TCPTABLE *tcp_table;
+            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",
+                            &stats->dwRtoAlgorithm,
+                            &stats->dwRtoMin,
+                            &stats->dwRtoMax,
+                            &stats->dwMaxConn,
+                            &stats->dwActiveOpens,
+                            &stats->dwPassiveOpens,
+                            &stats->dwAttemptFails,
+                            &stats->dwEstabResets,
+                            &stats->dwCurrEstab,
+                            &stats->dwInSegs,
+                            &stats->dwOutSegs,
+                            &stats->dwRetransSegs,
+                            &stats->dwInErrs,
+                            &stats->dwOutRsts );
+                    break;
+                }
+            }
+            if (!AllocateAndGetTcpTableFromStack( &tcp_table, FALSE, GetProcessHeap(), 0 ))
+            {
+                stats->dwNumConns = tcp_table->dwNumEntries;
+                HeapFree( GetProcessHeap(), 0, tcp_table );
+            }
+            fclose(fp);
+            ret = NO_ERROR;
+        }
+    }
+#elif defined(HAVE_SYS_SYSCTL_H) && defined(UDPCTL_STATS)
+    {
 #ifndef TCPTV_MIN  /* got removed in Mac OS X for some reason */
 #define TCPTV_MIN 2
 #define TCPTV_REXMTMAX 128
 #endif
-  int mib[] = {CTL_NET, PF_INET, IPPROTO_TCP, TCPCTL_STATS};
+        int mib[] = {CTL_NET, PF_INET, IPPROTO_TCP, TCPCTL_STATS};
 #define MIB_LEN (sizeof(mib) / sizeof(mib[0]))
 #define hz 1000
-  struct tcpstat tcp_stat;
-  size_t needed;
-
-  if (!stats)
-    return ERROR_INVALID_PARAMETER;
-  needed = sizeof(tcp_stat);
-
-  if(sysctl(mib, MIB_LEN, &tcp_stat, &needed, NULL, 0) == -1)
-  {
-      ERR ("failed to get tcpstat\n");
-      return ERROR_NOT_SUPPORTED;
-  }
-
-  stats->dwRtoAlgorithm = MIB_TCP_RTO_VANJ;
-  stats->dwRtoMin = TCPTV_MIN;
-  stats->dwRtoMax = TCPTV_REXMTMAX;
-  stats->dwMaxConn = -1;
-  stats->dwActiveOpens = tcp_stat.tcps_connattempt;
-  stats->dwPassiveOpens = tcp_stat.tcps_accepts;
-  stats->dwAttemptFails = tcp_stat.tcps_conndrops;
-  stats->dwEstabResets = tcp_stat.tcps_drops;
-  stats->dwCurrEstab = 0;
-  stats->dwInSegs = tcp_stat.tcps_rcvtotal;
-  stats->dwOutSegs = tcp_stat.tcps_sndtotal - tcp_stat.tcps_sndrexmitpack;
-  stats->dwRetransSegs = tcp_stat.tcps_sndrexmitpack;
-  stats->dwInErrs = tcp_stat.tcps_rcvbadsum + tcp_stat.tcps_rcvbadoff + tcp_stat.tcps_rcvmemdrop + tcp_stat.tcps_rcvshort;
-  stats->dwOutRsts = tcp_stat.tcps_sndctrl - tcp_stat.tcps_closed;
-  stats->dwNumConns = tcp_stat.tcps_connects;
-
-  return NO_ERROR;
-
-#else
-  FILE *fp;
-  MIB_TCPTABLE *tcp_table;
-
-  if (!stats)
-    return ERROR_INVALID_PARAMETER;
-
-  memset(stats, 0, sizeof(MIB_TCPSTATS));
-
-  /* get from /proc/net/snmp, no error if can't */
-  fp = fopen("/proc/net/snmp", "r");
-  if (fp) {
-    static const char hdr[] = "Tcp:";
-    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;
+        struct tcpstat tcp_stat;
+        size_t needed = sizeof(tcp_stat);
 
-        ptr += sizeof(hdr);
-        if (ptr && *ptr) {
-          stats->dwRtoAlgorithm = strtoul(ptr, &endPtr, 10);
-          ptr = endPtr;
-        }
-        if (ptr && *ptr) {
-          stats->dwRtoMin = strtoul(ptr, &endPtr, 10);
-          ptr = endPtr;
-        }
-        if (ptr && *ptr) {
-          stats->dwRtoMax = strtoul(ptr, &endPtr, 10);
-          ptr = endPtr;
-        }
-        if (ptr && *ptr) {
-          stats->dwMaxConn = strtoul(ptr, &endPtr, 10);
-          ptr = endPtr;
-        }
-        if (ptr && *ptr) {
-          stats->dwActiveOpens = strtoul(ptr, &endPtr, 10);
-          ptr = endPtr;
-        }
-        if (ptr && *ptr) {
-          stats->dwPassiveOpens = strtoul(ptr, &endPtr, 10);
-          ptr = endPtr;
-        }
-        if (ptr && *ptr) {
-          stats->dwAttemptFails = strtoul(ptr, &endPtr, 10);
-          ptr = endPtr;
-        }
-        if (ptr && *ptr) {
-          stats->dwEstabResets = strtoul(ptr, &endPtr, 10);
-          ptr = endPtr;
-        }
-        if (ptr && *ptr) {
-          stats->dwCurrEstab = strtoul(ptr, &endPtr, 10);
-          ptr = endPtr;
-        }
-        if (ptr && *ptr) {
-          stats->dwInSegs = strtoul(ptr, &endPtr, 10);
-          ptr = endPtr;
-        }
-        if (ptr && *ptr) {
-          stats->dwOutSegs = strtoul(ptr, &endPtr, 10);
-          ptr = endPtr;
-        }
-        if (ptr && *ptr) {
-          stats->dwRetransSegs = strtoul(ptr, &endPtr, 10);
-          ptr = endPtr;
-        }
-        if (ptr && *ptr) {
-          stats->dwInErrs = strtoul(ptr, &endPtr, 10);
-          ptr = endPtr;
-        }
-        if (ptr && *ptr) {
-          stats->dwOutRsts = strtoul(ptr, &endPtr, 10);
-          ptr = endPtr;
-        }
-        if (!AllocateAndGetTcpTableFromStack( &tcp_table, FALSE, GetProcessHeap(), 0 ))
+        if(sysctl(mib, MIB_LEN, &tcp_stat, &needed, NULL, 0) != -1)
         {
-            stats->dwNumConns = tcp_table->dwNumEntries;
-            HeapFree( GetProcessHeap(), 0, tcp_table );
+            stats->dwRtoAlgorithm = MIB_TCP_RTO_VANJ;
+            stats->dwRtoMin = TCPTV_MIN;
+            stats->dwRtoMax = TCPTV_REXMTMAX;
+            stats->dwMaxConn = -1;
+            stats->dwActiveOpens = tcp_stat.tcps_connattempt;
+            stats->dwPassiveOpens = tcp_stat.tcps_accepts;
+            stats->dwAttemptFails = tcp_stat.tcps_conndrops;
+            stats->dwEstabResets = tcp_stat.tcps_drops;
+            stats->dwCurrEstab = 0;
+            stats->dwInSegs = tcp_stat.tcps_rcvtotal;
+            stats->dwOutSegs = tcp_stat.tcps_sndtotal - tcp_stat.tcps_sndrexmitpack;
+            stats->dwRetransSegs = tcp_stat.tcps_sndrexmitpack;
+            stats->dwInErrs = tcp_stat.tcps_rcvbadsum + tcp_stat.tcps_rcvbadoff + tcp_stat.tcps_rcvmemdrop + tcp_stat.tcps_rcvshort;
+            stats->dwOutRsts = tcp_stat.tcps_sndctrl - tcp_stat.tcps_closed;
+            stats->dwNumConns = tcp_stat.tcps_connects;
+            ret = NO_ERROR;
         }
-      }
+        else ERR ("failed to get tcpstat\n");
     }
-    fclose(fp);
-  }
-  else
-  {
-     ERR ("unimplemented!\n");
-     return ERROR_NOT_SUPPORTED;
-  }
-
-  return NO_ERROR;
+#else
+    FIXME( "unimplemented\n" );
 #endif
+    return ret;
 }
 
 




More information about the wine-cvs mailing list