IP Multicast
Mike Hearn
m.hearn at signal.qinetiq.com
Tue Apr 1 06:54:16 CST 2003
Hi,
This patch adds support for IP multicast sockets to winsock. I stole
liberally from a patch from the summer of 2001 from Marcus, so thanks to
him for that:
http://www.winehq.com/hypermail/wine-patches/2001/07/0009.html
ChangeLog:
- Map winsock sockopts to the POSIX equivalents for IP multicast
- Remap winsock1 constant values to winsock2 using a forwarder function
- Change a FIXME to a TRACE, it appeared to be simply reporting progress
thanks -mike
--
Mike Hearn <m.hearn at signal.qinetiq.com>
QinetiQ - Malvern Technology Center
-------------- next part --------------
--- dlls/wsock32/socket.c 2002-08-17 01:43:18.000000000 +0100
+++ ../wine/dlls/wsock32/socket.c 2003-04-01 12:17:42.000000000 +0100
@@ -40,6 +40,9 @@
#define recv linux_recv
/* */
+#define setsockopt linux_setsockopt
+#define getsockopt linux_getsockopt
+
#include "config.h"
#include <errno.h>
@@ -85,9 +88,53 @@
extern int WINAPI ioctlsocket(SOCKET,long,u_long*);
/* */
+/* for the get/setsockopt forwarders */
+#undef setsockopt
+#undef getsockopt
+extern int WINAPI setsockopt(SOCKET s, INT level, INT optname ,char* optval, INT optlen);
+extern int WINAPI getsockopt(SOCKET s, INT level, INT optname ,char* optval, INT* optlen);
WINE_DEFAULT_DEBUG_CHANNEL(winsock);
+/* internal remapper function for the IP_ constants */
+INT _remap_optname(INT level, INT optname) {
+ TRACE("level=%d, optname=%d\n", level, optname);
+ if (level == WS_IPPROTO_IP) {
+ switch (optname) { /***** from value *****/
+ case 2: return 9; /* IP_MULTICAST_IF */
+ case 3: return 10; /* IP_MULTICAST_TTL */
+ case 4: return 11; /* IP_MULTICAST_LOOP */
+ case 5: return 12; /* IP_ADD_MEMBERSHIP */
+ case 6: return 13; /* IP_DROP_MEMBERSHIP */
+ case 7: return 4; /* IP_TTL */
+ case 8: return 3; /* IP_TOS */
+ case 9: return 14; /* IP_DONTFRAGMENT */
+ default: FIXME("Unknown optname %d, can't remap!\n", optname); return optname;
+ }
+ } else {
+ /* don't need to do anything */
+ return optname;
+ }
+}
+
+/***********************************************************************
+ * setsockopt (WSOCK32.21)
+ *
+ * We have these forwarders because, for reasons unknown to us mere mortals,
+ * the values of the IP_ constants changed between winsock.h and winsock2.h.
+ * So, we need to remap them here.
+ */
+INT WINAPI WS1_setsockopt(SOCKET s, INT level, INT optname, char *optval, INT optlen)
+{
+ return setsockopt(s, level, _remap_optname(level, optname), optval, optlen);
+}
+
+/***********************************************************************
+ * getsockopt (WSOCK32.7)
+ */
+INT WINAPI WS1_getsockopt(SOCKET s, INT level, INT optname, char *optval, INT *optlen) {
+ return getsockopt(s, level, _remap_optname(level, optname), optval, optlen);
+}
/***********************************************************************
* WsControl (WSOCK32.1001)
--- dlls/wsock32/wsock32.spec 2003-03-17 00:17:00.000000000 +0000
+++ ../wine/dlls/wsock32/wsock32.spec 2003-04-01 12:13:49.000000000 +0100
@@ -4,7 +4,7 @@
4 stdcall connect(long ptr long) ws2_32.connect
5 stdcall getpeername(long ptr ptr) ws2_32.getpeername
6 stdcall getsockname(long ptr ptr) ws2_32.getsockname
- 7 stdcall getsockopt(long long long ptr ptr) ws2_32.getsockopt
+ 7 stdcall getsockopt(long long long ptr ptr) WS1_getsockopt
8 stdcall htonl(long) ws2_32.htonl
9 stdcall htons(long) ws2_32.htons
10 stdcall inet_addr(str) ws2_32.inet_addr
@@ -18,7 +18,7 @@
18 stdcall select(long ptr ptr ptr ptr) ws2_32.select
19 stdcall send(long ptr long long) ws2_32.send
20 stdcall sendto(long ptr long long ptr long) ws2_32.sendto
- 21 stdcall setsockopt(long long long ptr long) ws2_32.setsockopt
+ 21 stdcall setsockopt(long long long ptr long) WS1_setsockopt
22 stdcall shutdown(long long) ws2_32.shutdown
23 stdcall socket(long long long) ws2_32.socket
51 stdcall gethostbyaddr(ptr long long) ws2_32.gethostbyaddr
--- dlls/winsock/socket.c 2003-03-17 04:42:11.000000000 +0000
+++ ../wine/dlls/winsock/socket.c 2003-04-01 13:41:16.000000000 +0100
@@ -278,6 +278,16 @@
0
};
+static int _ws_ip_ops[] = {
+ WS_IP_MULTICAST_IF, WS_IP_MULTICAST_TTL, WS_IP_MULTICAST_LOOP, WS_IP_ADD_MEMBERSHIP, WS_IP_DROP_MEMBERSHIP,
+ WS_IP_DROP_MEMBERSHIP, WS_IP_OPTIONS, WS_IP_HDRINCL, WS_IP_TOS, WS_IP_TTL, 0
+};
+
+static int _px_ip_ops[] = {
+ IP_MULTICAST_IF, IP_MULTICAST_TTL, IP_MULTICAST_LOOP, IP_ADD_MEMBERSHIP, IP_DROP_MEMBERSHIP,
+ IP_DROP_MEMBERSHIP, IP_OPTIONS, IP_HDRINCL, IP_TOS, IP_TTL, 0
+};
+
static DWORD opentype_tls_index = -1; /* TLS index for SO_OPENTYPE flag */
inline static DWORD NtStatusToWSAError ( const DWORD status )
@@ -482,6 +492,18 @@
}
FIXME("Unknown IPPROTO_TCP optname 0x%x\n", *optname);
break;
+ case WS_IPPROTO_IP:
+ *level = IPPROTO_IP;
+ for(i=0; _ws_ip_ops[i]; i++) {
+ if (_ws_ip_ops[i] == *optname ) break;
+ }
+ if( _ws_ip_ops[i] ) {
+ *optname = _px_ip_ops[i];
+ return 1;
+ }
+ FIXME("Unknown IPPROTO_IP optname 0x%x\n", *optname);
+ break;
+ default: FIXME("Unimplemented or unknown socket level\n");
}
return 0;
}
@@ -1488,7 +1511,7 @@
int on = 1;
/* The game GrandPrixLegends binds more than one time, but does
* not do a SO_REUSEADDR - Stevens says this is ok */
- FIXME( "Setting WS_SO_REUSEADDR on socket before we binding it\n");
+ TRACE( "Setting WS_SO_REUSEADDR on socket before we bind it\n");
WS_setsockopt( s, WS_SOL_SOCKET, WS_SO_REUSEADDR, (char*)&on, sizeof(on) );
if (bind(fd, uaddr, uaddrlen) < 0)
@@ -2724,6 +2748,7 @@
level = SOL_SOCKET;
}else{
if (!convert_sockopt(&level, &optname)) {
+ ERR("Invalid level (%d) or optname (%d)\n", level, optname);
SetLastError(WSAENOPROTOOPT);
close(fd);
return SOCKET_ERROR;
@@ -2791,6 +2816,7 @@
close(fd);
return 0;
}
+ TRACE("Setting socket error, %d\n", wsaErrno());
SetLastError(wsaErrno());
close(fd);
}
--- include/winsock.h 2003-03-17 21:22:34.000000000 +0000
+++ ../wine/include/winsock.h 2003-03-28 17:04:47.000000000 +0000
@@ -653,6 +653,56 @@
#define WS_TCP_NODELAY 1
#endif
+/* IPPROTO_IP options */
+#if !defined(__WINE_WINSOCK2__) /* WinSock2 has different values for the IP_ constants */
+# ifndef USE_WS_PREFIX
+# define IP_OPTIONS 1
+# define IP_MULTICAST_IF 2
+# define IP_MULTICAST_TTL 3
+# define IP_MULTICAST_LOOP 4
+# define IP_ADD_MEMBERSHIP 5
+# define IP_DROP_MEMBERSHIP 6
+# define IP_TTL 7
+# define IP_TOS 8
+# define IP_DONTFRAGMENT 9
+# else
+# define WS_IP_OPTIONS 1
+# define WS_IP_MULTICAST_IF 2
+# define WS_IP_MULTICAST_TTL 3
+# define WS_IP_MULTICAST_LOOP 4
+# define WS_IP_ADD_MEMBERSHIP 5
+# define WS_IP_DROP_MEMBERSHIP 6
+# define WS_IP_TTL 7
+# define WS_IP_TOS 8
+# define WS_IP_DONTFRAGMENT 9
+# endif
+#else /* start the winsock2 section */
+# ifndef USE_WS_PREFIX
+# define IP_OPTIONS 1
+# define IP_HDRINCL 2
+# define IP_TOS 3
+# define IP_TTL 4
+# define IP_MULTICAST_IF 9
+# define IP_MULTICAST_TTL 10
+# define IP_MULTICAST_LOOP 11
+# define IP_ADD_MEMBERSHIP 12
+# define IP_DROP_MEMBERSHIP 13
+# define IP_DONTFRAGMENT 14
+# else
+# define WS_IP_OPTIONS 1
+# define WS_IP_HDRINCL 2
+# define WS_IP_TOS 3
+# define WS_IP_TTL 4
+# define WS_IP_MULTICAST_IF 9
+# define WS_IP_MULTICAST_TTL 10
+# define WS_IP_MULTICAST_LOOP 11
+# define WS_IP_ADD_MEMBERSHIP 12
+# define WS_IP_DROP_MEMBERSHIP 13
+# define WS_IP_DONTFRAGMENT 14
+# endif
+#endif
+
+
/*
* Socket I/O flags (supported by spec 1.1)
*/
More information about the wine-patches
mailing list