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