Alexandre Julliard : iphlpapi: Implemented AllocateAndGetTcpTableFromStack for Solaris.

Alexandre Julliard julliard at winehq.org
Wed Mar 11 10:04:18 CDT 2009


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Mar 10 17:05:58 2009 +0100

iphlpapi: Implemented AllocateAndGetTcpTableFromStack for Solaris.

---

 configure               |    6 +++
 configure.ac            |    3 +
 dlls/iphlpapi/ipstats.c |  112 ++++++++++++++++++++++++++++++++++++++++++++++-
 include/config.h.in     |    9 ++++
 4 files changed, 129 insertions(+), 1 deletions(-)

diff --git a/configure b/configure
index 2d77fe1..e32cb69 100755
--- a/configure
+++ b/configure
@@ -6076,6 +6076,9 @@ done
 
 
 
+
+
+
 for ac_header in \
 	AudioUnit/AudioUnit.h \
 	Carbon/Carbon.h \
@@ -6098,6 +6101,7 @@ for ac_header in \
 	getopt.h \
 	grp.h \
 	ieeefp.h \
+	inet/mib2.h \
 	io.h \
 	jack/jack.h \
 	jpeglib.h \
@@ -6146,6 +6150,7 @@ for ac_header in \
 	soundcard.h \
 	stdint.h \
 	strings.h \
+	stropts.h \
 	sys/asoundlib.h \
 	sys/cdio.h \
 	sys/elf32.h \
@@ -6180,6 +6185,7 @@ for ac_header in \
 	sys/statvfs.h \
 	sys/strtio.h \
 	sys/syscall.h \
+	sys/tihdr.h \
 	sys/time.h \
 	sys/timeout.h \
 	sys/times.h \
diff --git a/configure.ac b/configure.ac
index f70222f..274d60a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -279,6 +279,7 @@ AC_CHECK_HEADERS(\
 	getopt.h \
 	grp.h \
 	ieeefp.h \
+	inet/mib2.h \
 	io.h \
 	jack/jack.h \
 	jpeglib.h \
@@ -327,6 +328,7 @@ AC_CHECK_HEADERS(\
 	soundcard.h \
 	stdint.h \
 	strings.h \
+	stropts.h \
 	sys/asoundlib.h \
 	sys/cdio.h \
 	sys/elf32.h \
@@ -361,6 +363,7 @@ AC_CHECK_HEADERS(\
 	sys/statvfs.h \
 	sys/strtio.h \
 	sys/syscall.h \
+	sys/tihdr.h \
 	sys/time.h \
 	sys/timeout.h \
 	sys/times.h \
diff --git a/dlls/iphlpapi/ipstats.c b/dlls/iphlpapi/ipstats.c
index a1b9981..c92f0e4 100644
--- a/dlls/iphlpapi/ipstats.c
+++ b/dlls/iphlpapi/ipstats.c
@@ -25,6 +25,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <errno.h>
 #include <sys/types.h>
 #ifdef HAVE_ALIAS_H
 #include <alias.h>
@@ -110,6 +111,15 @@
 #ifdef HAVE_KSTAT_H
 #include <kstat.h>
 #endif
+#ifdef HAVE_INET_MIB2_H
+#include <inet/mib2.h>
+#endif
+#ifdef HAVE_STROPTS_H
+#include <stropts.h>
+#endif
+#ifdef HAVE_SYS_TIHDR_H
+#include <sys/tihdr.h>
+#endif
 
 #ifndef ROUNDUP
 #define ROUNDUP(a) \
@@ -173,6 +183,81 @@ static ULONGLONG kstat_get_ui64( kstat_t *ksp, const char *name )
 }
 #endif
 
+#if defined(HAVE_SYS_TIHDR_H) && defined(T_OPTMGMT_ACK)
+static int open_streams_mib( const char *proto )
+{
+    int fd;
+    struct strbuf buf;
+    struct request
+    {
+        struct T_optmgmt_req req_header;
+        struct opthdr        opt_header;
+    } request;
+
+    if ((fd = open( "/dev/arp", O_RDWR )) == -1)
+    {
+        WARN( "could not open /dev/arp: %s\n", strerror(errno) );
+        return -1;
+    }
+    if (proto) ioctl( fd, I_PUSH, proto );
+
+    request.req_header.PRIM_type  = T_SVR4_OPTMGMT_REQ;
+    request.req_header.OPT_length = sizeof(request.opt_header);
+    request.req_header.OPT_offset = FIELD_OFFSET( struct request, opt_header );
+    request.req_header.MGMT_flags = T_CURRENT;
+    request.opt_header.level      = MIB2_IP;
+    request.opt_header.name       = 0;
+    request.opt_header.len        = 0;
+
+    buf.len = sizeof(request);
+    buf.buf = (caddr_t)&request;
+    if (putmsg( fd, &buf, NULL, 0 ) == -1)
+    {
+        WARN( "putmsg: %s\n", strerror(errno) );
+        close( fd );
+        fd = -1;
+    }
+    return fd;
+}
+
+static void *read_mib_entry( int fd, int level, int name, int *len )
+{
+    struct strbuf buf;
+    void *data;
+    int ret, flags = 0;
+
+    struct reply
+    {
+        struct T_optmgmt_ack ack_header;
+        struct opthdr        opt_header;
+    } reply;
+
+    for (;;)
+    {
+        buf.maxlen = sizeof(reply);
+        buf.buf = (caddr_t)&reply;
+        if ((ret = getmsg( fd, &buf, NULL, &flags )) < 0) return NULL;
+        if (!(ret & MOREDATA)) return NULL;
+        if (reply.ack_header.PRIM_type != T_OPTMGMT_ACK) return NULL;
+        if (buf.len < sizeof(reply.ack_header)) return NULL;
+        if (reply.ack_header.OPT_length < sizeof(reply.opt_header)) return NULL;
+
+        if (!(data = HeapAlloc( GetProcessHeap(), 0, reply.opt_header.len ))) return NULL;
+        buf.maxlen = reply.opt_header.len;
+        buf.buf = (caddr_t)data;
+        flags = 0;
+        if (getmsg( fd, NULL, &buf, &flags ) >= 0 &&
+            reply.opt_header.level == level &&
+            reply.opt_header.name == name)
+        {
+            *len = buf.len;
+            return data;
+        }
+        HeapFree( GetProcessHeap(), 0, data );
+    }
+}
+#endif /* HAVE_SYS_TIHDR_H && T_OPTMGMT_ACK */
+
 DWORD getInterfaceStatsByName(const char *name, PMIB_IFROW entry)
 {
     DWORD ret = ERROR_NOT_SUPPORTED;
@@ -1398,7 +1483,7 @@ static MIB_TCPTABLE *append_tcp_row( HANDLE heap, DWORD flags, MIB_TCPTABLE *tab
 
 /* Why not a lookup table? Because the TCPS_* constants are different
    on different platforms */
-static DWORD TCPStateToMIBState (int state)
+static inline DWORD TCPStateToMIBState (int state)
 {
    switch (state)
    {
@@ -1491,6 +1576,31 @@ DWORD WINAPI AllocateAndGetTcpTableFromStack( PMIB_TCPTABLE *ppTcpTable, BOOL bO
         }
         else ret = ERROR_NOT_SUPPORTED;
     }
+#elif defined(HAVE_SYS_TIHDR_H) && defined(T_OPTMGMT_ACK)
+    {
+        void *data;
+        int fd, len;
+        mib2_tcpConnEntry_t *entry;
+
+        if ((fd = open_streams_mib( "tcp" )) != -1)
+        {
+            if ((data = read_mib_entry( fd, MIB2_TCP, MIB2_TCP_CONN, &len )))
+            {
+                for (entry = data; (char *)(entry + 1) <= (char *)data + len; entry++)
+                {
+                    row.dwLocalAddr = entry->tcpConnLocalAddress;
+                    row.dwLocalPort = htons( entry->tcpConnLocalPort );
+                    row.dwRemoteAddr = entry->tcpConnRemAddress;
+                    row.dwRemotePort = htons( entry->tcpConnRemPort );
+                    row.dwState = entry->tcpConnState;
+                    if (!(table = append_tcp_row( heap, flags, table, &count, &row ))) break;
+                }
+                HeapFree( GetProcessHeap(), 0, data );
+            }
+            close( fd );
+        }
+        else ret = ERROR_NOT_SUPPORTED;
+    }
 #elif defined(HAVE_SYS_SYSCTL_H) && defined(HAVE_STRUCT_XINPGEN)
     {
         size_t Len = 0;
diff --git a/include/config.h.in b/include/config.h.in
index f3bd775..2b7c655 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -240,6 +240,9 @@
 /* Define to 1 if you have the <ieeefp.h> header file. */
 #undef HAVE_IEEEFP_H
 
+/* Define to 1 if you have the <inet/mib2.h> header file. */
+#undef HAVE_INET_MIB2_H
+
 /* Define to 1 if you have the `inet_network' function. */
 #undef HAVE_INET_NETWORK
 
@@ -708,6 +711,9 @@
 /* Define to 1 if you have the `strncasecmp' function. */
 #undef HAVE_STRNCASECMP
 
+/* Define to 1 if you have the <stropts.h> header file. */
+#undef HAVE_STROPTS_H
+
 /* Define to 1 if you have the `strtold' function. */
 #undef HAVE_STRTOLD
 
@@ -906,6 +912,9 @@
 /* Define to 1 if you have the <sys/thr.h> header file. */
 #undef HAVE_SYS_THR_H
 
+/* Define to 1 if you have the <sys/tihdr.h> header file. */
+#undef HAVE_SYS_TIHDR_H
+
 /* Define to 1 if you have the <sys/timeout.h> header file. */
 #undef HAVE_SYS_TIMEOUT_H
 




More information about the wine-cvs mailing list