Mark Adams : iphlpapi: Support for non-linux platforms,
including Mac OS X.
Alexandre Julliard
julliard at wine.codeweavers.com
Fri Jan 26 07:47:02 CST 2007
Module: wine
Branch: master
Commit: 641abc997cf97df2fd22af0da1cc8eee1272e8aa
URL: http://source.winehq.org/git/wine.git/?a=commit;h=641abc997cf97df2fd22af0da1cc8eee1272e8aa
Author: Mark Adams <mark at transgaming.com>
Date: Thu Jan 25 20:16:25 2007 -0500
iphlpapi: Support for non-linux platforms, including Mac OS X.
- Add error messages when unimplemented functions are called on
non-linux platforms.
- Implement retrieving the interface list on MacOS X (and other
platforms that use NET_RT_DUMP).
---
dlls/iphlpapi/ipstats.c | 219 ++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 218 insertions(+), 1 deletions(-)
diff --git a/dlls/iphlpapi/ipstats.c b/dlls/iphlpapi/ipstats.c
index 129380c..f5b1149 100644
--- a/dlls/iphlpapi/ipstats.c
+++ b/dlls/iphlpapi/ipstats.c
@@ -20,6 +20,7 @@
#include "config.h"
#include "wine/port.h"
+#include "wine/debug.h"
#include <stdarg.h>
#include <stdio.h>
@@ -51,6 +52,14 @@
#include <netinet/tcp_fsm.h>
#endif
+#ifdef HAVE_SYS_SYSCTL_H
+#include <sys/sysctl.h>
+#endif
+
+#define ROUNDUP(a) \
+ ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
+#define ADVANCE(x, n) (x += ROUNDUP(((struct sockaddr *)n)->sa_len))
+
#include "windef.h"
#include "winbase.h"
#include "iprtrmib.h"
@@ -71,6 +80,8 @@
#define TCPS_CLOSING 11
#endif
+WINE_DEFAULT_DEBUG_CHANNEL(iphlpapi);
+
DWORD getInterfaceStatsByName(const char *name, PMIB_IFROW entry)
{
FILE *fp;
@@ -152,6 +163,9 @@ DWORD getInterfaceStatsByName(const char
}
fclose(fp);
}
+ else
+ ERR ("unimplemented!\n");
+
return NO_ERROR;
}
@@ -279,6 +293,9 @@ DWORD getICMPStats(MIB_ICMP *stats)
}
fclose(fp);
}
+ else
+ ERR ("unimplemented!\n");
+
return NO_ERROR;
}
@@ -390,6 +407,9 @@ DWORD getIPStats(PMIB_IPSTATS stats)
}
fclose(fp);
}
+ else
+ ERR ("unimplemented!\n");
+
return NO_ERROR;
}
@@ -480,6 +500,9 @@ DWORD getTCPStats(MIB_TCPSTATS *stats)
}
fclose(fp);
}
+ else
+ ERR ("unimplemented!\n");
+
return NO_ERROR;
}
@@ -533,6 +556,9 @@ DWORD getUDPStats(MIB_UDPSTATS *stats)
}
fclose(fp);
}
+ else
+ ERR ("unimplemented!\n");
+
return NO_ERROR;
}
@@ -556,12 +582,66 @@ static DWORD getNumWithOneHeader(const c
}
fclose(fp);
}
+ else
+ ERR ("Unable to open '%s' to count entries!\n", filename);
+
return ret;
}
DWORD getNumRoutes(void)
{
- return getNumWithOneHeader("/proc/net/route");
+#if defined(HAVE_SYS_SYSCTL_H) && defined(NET_RT_DUMP)
+ int mib[6] = {CTL_NET, PF_ROUTE, 0, PF_INET, NET_RT_DUMP, 0};
+ size_t needed;
+ char *buf, *lim, *next;
+ struct rt_msghdr *rtm;
+ DWORD RouteCount = 0;
+
+ if (sysctl (mib, 6, NULL, &needed, NULL, 0) < 0)
+ {
+ ERR ("sysctl 1 failed!\n");
+ return 0;
+ }
+
+ buf = HeapAlloc (GetProcessHeap (), 0, needed);
+ if (!buf)
+ {
+ ERR ("HeapAlloc of %ld failed!\n", needed);
+ return 0;
+ }
+
+ if (sysctl (mib, 6, buf, &needed, NULL, 0) < 0)
+ {
+ ERR ("sysctl 2 failed!\n");
+ HeapFree (GetProcessHeap (), 0, buf);
+ return 0;
+ }
+
+ lim = buf + needed;
+ for (next = buf; next < lim; next += rtm->rtm_msglen)
+ {
+ rtm = (struct rt_msghdr *)next;
+
+ if (rtm->rtm_type != RTM_GET)
+ {
+ WARN ("Got unexpected message type 0x%x!\n",
+ rtm->rtm_type);
+ continue;
+ }
+
+ /* Ignore all entries except for gateway routes which aren't
+ multicast */
+ if (!(rtm->rtm_flags & RTF_GATEWAY) || (rtm->rtm_flags & RTF_MULTICAST))
+ continue;
+
+ RouteCount++;
+ }
+
+ HeapFree (GetProcessHeap (), 0, buf);
+ return RouteCount;
+#else
+ return getNumWithOneHeader("/proc/net/route");
+#endif
}
DWORD getRouteTable(PMIB_IPFORWARDTABLE *ppIpForwardTable, HANDLE heap,
@@ -577,6 +657,122 @@ DWORD getRouteTable(PMIB_IPFORWARDTABLE
sizeof(MIB_IPFORWARDTABLE) + (numRoutes - 1) * sizeof(MIB_IPFORWARDROW));
if (table) {
+#if defined(HAVE_SYS_SYSCTL_H) && defined(NET_RT_DUMP)
+ int mib[6] = {CTL_NET, PF_ROUTE, 0, PF_INET, NET_RT_DUMP, 0};
+ size_t needed;
+ char *buf, *lim, *next, *addrPtr;
+ struct rt_msghdr *rtm;
+
+ if (sysctl (mib, 6, NULL, &needed, NULL, 0) < 0)
+ {
+ ERR ("sysctl 1 failed!\n");
+ HeapFree (GetProcessHeap (), 0, table);
+ return NO_ERROR;
+ }
+
+ buf = HeapAlloc (GetProcessHeap (), 0, needed);
+ if (!buf)
+ {
+ ERR ("HeapAlloc of %ld failed!\n", needed);
+ HeapFree (GetProcessHeap (), 0, table);
+ return ERROR_OUTOFMEMORY;
+ }
+
+ if (sysctl (mib, 6, buf, &needed, NULL, 0) < 0)
+ {
+ ERR ("sysctl 2 failed!\n");
+ HeapFree (GetProcessHeap (), 0, table);
+ HeapFree (GetProcessHeap (), 0, buf);
+ return NO_ERROR;
+ }
+
+ *ppIpForwardTable = table;
+ table->dwNumEntries = 0;
+
+ lim = buf + needed;
+ for (next = buf; next < lim; next += rtm->rtm_msglen)
+ {
+ int i;
+
+ rtm = (struct rt_msghdr *)next;
+
+ if (rtm->rtm_type != RTM_GET)
+ {
+ WARN ("Got unexpected message type 0x%x!\n",
+ rtm->rtm_type);
+ continue;
+ }
+
+ /* Ignore all entries except for gateway routes which aren't
+ multicast */
+ if (!(rtm->rtm_flags & RTF_GATEWAY) ||
+ (rtm->rtm_flags & RTF_MULTICAST))
+ continue;
+
+ memset (&table->table[table->dwNumEntries], 0,
+ sizeof (MIB_IPFORWARDROW));
+ table->table[table->dwNumEntries].dwForwardIfIndex = rtm->rtm_index;
+ table->table[table->dwNumEntries].dwForwardType =
+ MIB_IPROUTE_TYPE_INDIRECT;
+ table->table[table->dwNumEntries].dwForwardMetric1 =
+ rtm->rtm_rmx.rmx_hopcount;
+ table->table[table->dwNumEntries].dwForwardProto =
+ MIB_IPPROTO_LOCAL;
+
+ addrPtr = (char *)(rtm + 1);
+
+ for (i = 1; i; i <<= 1)
+ {
+ struct sockaddr *sa;
+ DWORD addr;
+
+ if (!(i & rtm->rtm_addrs))
+ continue;
+
+ sa = (struct sockaddr *)addrPtr;
+ ADVANCE (addrPtr, sa);
+
+ /* default routes are encoded by length-zero sockaddr */
+ if (sa->sa_len == 0)
+ addr = 0;
+ else if (sa->sa_family != AF_INET)
+ {
+ ERR ("Received unsupported sockaddr family 0x%x\n",
+ sa->sa_family);
+ addr = 0;
+ }
+ else
+ {
+ struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+
+ addr = sin->sin_addr.s_addr;
+ }
+
+ switch (i)
+ {
+ case RTA_DST:
+ table->table[table->dwNumEntries].dwForwardDest = addr;
+ break;
+
+ case RTA_GATEWAY:
+ table->table[table->dwNumEntries].dwForwardNextHop = addr;
+ break;
+
+ case RTA_NETMASK:
+ table->table[table->dwNumEntries].dwForwardMask = addr;
+ break;
+
+ default:
+ ERR ("Unexpected address type 0x%x\n", i);
+ }
+ }
+
+ table->dwNumEntries++;
+ }
+
+ HeapFree (GetProcessHeap (), 0, buf);
+ ret = NO_ERROR;
+#else
FILE *fp;
ret = NO_ERROR;
@@ -656,6 +852,12 @@ DWORD getRouteTable(PMIB_IPFORWARDTABLE
}
fclose(fp);
}
+ else
+ {
+ ERR ("unimplemented!\n");
+ return ERROR_INVALID_PARAMETER;
+ }
+#endif
}
else
ret = ERROR_OUTOFMEMORY;
@@ -672,6 +874,11 @@ DWORD getArpTable(PMIB_IPNETTABLE *ppIpN
{
DWORD ret;
+#if defined(HAVE_SYS_SYSCTL_H) && defined(NET_RT_DUMP)
+ ERR ("unimplemented!\n");
+ return ERROR_INVALID_PARAMETER;
+#endif
+
if (!ppIpNetTable)
ret = ERROR_INVALID_PARAMETER;
else {
@@ -765,6 +972,11 @@ DWORD getUdpTable(PMIB_UDPTABLE *ppUdpTa
{
DWORD ret;
+#if defined(HAVE_SYS_SYSCTL_H) && defined(NET_RT_DUMP)
+ ERR ("unimplemented!\n");
+ return ERROR_INVALID_PARAMETER;
+#endif
+
if (!ppUdpTable)
ret = ERROR_INVALID_PARAMETER;
else {
@@ -828,6 +1040,11 @@ DWORD getTcpTable(PMIB_TCPTABLE *ppTcpTa
{
DWORD ret;
+#if defined(HAVE_SYS_SYSCTL_H) && defined(NET_RT_DUMP)
+ ERR ("unimplemented!\n");
+ return ERROR_INVALID_PARAMETER;
+#endif
+
if (!ppTcpTable)
ret = ERROR_INVALID_PARAMETER;
else {
More information about the wine-cvs
mailing list