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