PATCH: setsockopt differences for winsock/winsock2

Marcus Meissner marcus at jet.franken.de
Mon Jul 2 16:24:04 CDT 2001


Hi,

I did add IPPROTO_IP sockopt handling to enable multicast stuff.

That was the time that I spotted that the #defines for the IP_* 
stuff _differs_ between winsock and winsock2. So I had to split up
the IPPROTO_IP handling. I tried to keep code duplication to a minimum.

I am not sure whether the forwarders are good style.

Ciao, Marcus

Changelog:
	Added handling of IPPROTO_IP in (s|g)etsockopt.
	Split up *etsockopt into winsock 1 and winsock2 function,
	since there IP_* defines differ.

Index: include/winsock.h
===================================================================
RCS file: /home/wine/wine/include/winsock.h,v
retrieving revision 1.33
diff -u -r1.33 winsock.h
--- include/winsock.h	2001/05/14 19:20:30	1.33
+++ include/winsock.h	2001/07/02 21:05:49
@@ -190,6 +190,7 @@
 #define WS_SOCK_SEQPACKET  5               /* sequenced packet stream */
 
 #define WS_SOL_SOCKET		0xffff
+#define WS_IPPROTO_IP		0
 #define WS_IPPROTO_TCP		6
 
 /*
@@ -229,6 +230,19 @@
 
 /* IPPROTO_TCP options */
 #define WS_TCP_NODELAY	1		/* do not apply nagle algorithm */
+
+/* SOL_IP options */
+#define WS_SOL_IP	0
+
+#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
 
 /*
  * Socket I/O flags (supported by spec 1.1)
Index: include/winsock2.h
===================================================================
RCS file: /home/wine/wine/include/winsock2.h,v
retrieving revision 1.8
diff -u -r1.8 winsock2.h
--- include/winsock2.h	2001/04/10 21:22:34	1.8
+++ include/winsock2.h	2001/07/02 21:05:49
@@ -22,6 +22,17 @@
 #define PVD_CONFIG            0x3001
 #define SO_CONDITIONAL_ACCEPT 0x3002
 
+/* for IPPROTO_IP setsockopt */
+#define WS2_IP_OPTIONS		1
+#define WS2_IP_HDRINCL		2
+#define WS2_IP_TOS		3
+#define WS2_IP_TTL		4
+#define WS2_IP_MULTICAST_IF	9
+#define WS2_IP_MULTICAST_TTL	10
+#define WS2_IP_MULTICAST_LOOP	11
+#define WS2_IP_ADD_MEMBERSHIP	12
+#define WS2_IP_DROP_MEMBERSHIP	13
+#define WS2_IP_DONTFRAGMENT	14
 
 /* option flags per socket */
 
Index: dlls/winsock/socket.c
===================================================================
RCS file: /home/wine/wine/dlls/winsock/socket.c,v
retrieving revision 1.51
diff -u -r1.51 socket.c
--- dlls/winsock/socket.c	2001/07/02 19:59:47	1.51
+++ dlls/winsock/socket.c	2001/07/02 21:05:56
@@ -206,6 +206,97 @@
 	0
 };
 
+static INT _ws_ip_ops[] = {
+#ifdef IP_ADD_MEMBERSHIP
+	WS_IP_ADD_MEMBERSHIP,
+#endif
+#ifdef IP_DROP_MEMBERSHIP
+	WS_IP_DROP_MEMBERSHIP,
+#endif
+#ifdef IP_OPTIONS
+	WS_IP_OPTIONS,
+#endif
+#ifdef IP_MULTICAST_IF
+	WS_IP_MULTICAST_IF,
+#endif
+#ifdef IP_MULTICAST_TTL
+	WS_IP_MULTICAST_TTL,
+#endif
+#ifdef IP_MULTICAST_LOOP
+	WS_IP_MULTICAST_LOOP,
+#endif
+#ifdef IP_TTL
+	WS_IP_TTL,
+#endif
+#ifdef IP_TOS
+	WS_IP_TOS,
+#endif
+#ifdef IP_DONTFRAGMENT
+	WS_IP_DONTFRAGMENT,
+#endif
+	0
+};
+static INT _ws2_ip_ops[] = {
+#ifdef IP_ADD_MEMBERSHIP
+	WS2_IP_ADD_MEMBERSHIP,
+#endif
+#ifdef IP_DROP_MEMBERSHIP
+	WS2_IP_DROP_MEMBERSHIP,
+#endif
+#ifdef IP_OPTIONS
+	WS2_IP_OPTIONS,
+#endif
+#ifdef IP_MULTICAST_IF
+	WS2_IP_MULTICAST_IF,
+#endif
+#ifdef IP_MULTICAST_TTL
+	WS2_IP_MULTICAST_TTL,
+#endif
+#ifdef IP_MULTICAST_LOOP
+	WS2_IP_MULTICAST_LOOP,
+#endif
+#ifdef IP_TTL
+	WS2_IP_TTL,
+#endif
+#ifdef IP_TOS
+	WS2_IP_TOS,
+#endif
+#ifdef IP_DONTFRAGMENT
+	WS2_IP_DONTFRAGMENT,
+#endif
+	0
+};
+static int _px_ip_ops[] = {
+#ifdef IP_ADD_MEMBERSHIP
+	IP_ADD_MEMBERSHIP,
+#endif
+#ifdef IP_DROP_MEMBERSHIP
+	IP_DROP_MEMBERSHIP,
+#endif
+#ifdef IP_OPTIONS
+	IP_OPTIONS,
+#endif
+#ifdef IP_MULTICAST_IF
+	IP_MULTICAST_IF,
+#endif
+#ifdef IP_MULTICAST_TTL
+	IP_MULTICAST_TTL,
+#endif
+#ifdef IP_MULTICAST_LOOP
+	IP_MULTICAST_LOOP,
+#endif
+#ifdef IP_TTL
+	IP_TTL,
+#endif
+#ifdef IP_TOS
+	IP_TOS,
+#endif
+#ifdef IP_DONTFRAGMENT
+	IP_DONTFRAGMENT,
+#endif
+	0
+};
+
 /* set last error code from NT status without mapping WSA errors */
 inline static unsigned int set_error( unsigned int err )
 {
@@ -334,7 +425,7 @@
  * Converts socket flags from Windows format.
  * Return 1 if converted, 0 if not (error).
  */
-static int convert_sockopt(INT *level, INT *optname)
+static int convert_sockopt(INT *level, INT *optname, int wslevel)
 {
   int i;
   switch (*level)
@@ -359,6 +450,38 @@
 	}
         FIXME("Unknown IPPROTO_TCP optname 0x%x\n", *optname);
 	break;
+     case WS_IPPROTO_IP:
+	*level = SOL_IP;
+	switch (wslevel) {
+	case 1:
+	    for (i=0; _ws_ip_ops[i]; i++)
+		    if ( _ws_ip_ops[i] == *optname ) break;
+#ifdef IP_MULTICAST_IF
+	    if (*optname == WS_IP_MULTICAST_IF) {
+		FIXME("Need struct conversion for IP_MULTICAST_IF\n");
+	    }
+#endif
+	    break;
+	case 2:
+	    for (i=0; _ws2_ip_ops[i]; i++)
+		    if ( _ws2_ip_ops[i] == *optname ) break;
+#ifdef IP_MULTICAST_IF
+	    if (*optname == WS2_IP_MULTICAST_IF) {
+		FIXME("Need struct conversion for IP_MULTICAST_IF\n");
+	    }
+#endif
+	    break;
+	default: i=0;FIXME("no such level %d\n",wslevel);break; /* silence cc */
+	}
+        if( _ws_ip_ops[i] ) {
+	    *optname = _px_ip_ops[i];
+	    return 1;
+	}
+        FIXME("Unknown IPPROTO_IP optname 0x%x\n", *optname);
+	break;
+     default:
+        FIXME("Unknown level 0x%x, optname 0x%x\n", *level,*optname);
+	break;
   }
   return 0;
 }
@@ -1124,18 +1247,16 @@
 }
 
 
-/***********************************************************************
- *		getsockopt		(WS2_32.7)
- */
-INT WINAPI WSOCK32_getsockopt(SOCKET s, INT level, 
-                                  INT optname, char *optval, INT *optlen)
+static INT WINAPI _internal_getsockopt(SOCKET s, INT level, 
+                                  INT optname, char *optval, INT *optlen,
+				  int wslevel)
 {
     int fd = _get_sock_fd(s);
 
     TRACE("socket: %04x, opt 0x%x, ptr %8x, len %d\n", s, level, (int) optval, (int) *optlen);
     if (fd != -1)
     {
-	if (!convert_sockopt(&level, &optname)) {
+	if (!convert_sockopt(&level, &optname, wslevel)) {
 	    SetLastError(WSAENOPROTOOPT);	/* Unknown option */
         } else {
 	    if (getsockopt(fd, (int) level, optname, optval, optlen) == 0 )
@@ -1151,6 +1272,25 @@
 }
 
 /***********************************************************************
+ *		getsockopt		(WSOCK32.7)
+ */
+INT WINAPI WSOCK32_getsockopt1(SOCKET s, INT level, 
+                                  INT optname, char *optval, INT *optlen)
+{
+    return _internal_getsockopt(s,level,optname,optval,optlen,1);
+}
+
+/***********************************************************************
+ *		getsockopt		(WS2_32.7)
+ */
+INT WINAPI WSOCK32_getsockopt(SOCKET s, INT level, 
+                                  INT optname, char *optval, INT *optlen)
+{
+    return _internal_getsockopt(s,level,optname,optval,optlen,2);
+}
+
+
+/***********************************************************************
  *              getsockopt		(WINSOCK.7)
  */
 INT16 WINAPI WINSOCK_getsockopt16(SOCKET16 s, INT16 level,
@@ -1160,7 +1300,7 @@
     INT *p = &optlen32;
     INT retVal;
     if( optlen ) optlen32 = *optlen; else p = NULL;
-    retVal = WSOCK32_getsockopt( s, (UINT16)level, optname, optval, p );
+    retVal = WSOCK32_getsockopt1( s, (UINT16)level, optname, optval, p );
     if( optlen ) *optlen = optlen32;
     return (INT16)retVal;
 }
@@ -2004,11 +2144,8 @@
     return (INT16)WSOCK32_sendto( s, buf, len, flags, to, tolen );
 }
 
-/***********************************************************************
- *		setsockopt		(WS2_32.21)
- */
-INT WINAPI WSOCK32_setsockopt(SOCKET16 s, INT level, INT optname, 
-                                  char *optval, INT optlen)
+static INT WINAPI _internal_setsockopt(SOCKET16 s, INT level, INT optname, 
+                                  char *optval, INT optlen, int wslevel)
 {
     int fd = _get_sock_fd(s);
 
@@ -2034,7 +2171,7 @@
             optlen = sizeof(struct linger);
             level = SOL_SOCKET;
         }else{
-            if (!convert_sockopt(&level, &optname)) {
+            if (!convert_sockopt(&level, &optname, wslevel)) {
 		SetLastError(WSAENOPROTOOPT);
 		close(fd);
 		return SOCKET_ERROR;
@@ -2072,13 +2209,30 @@
 }
 
 /***********************************************************************
+ *		setsockopt		(WSOCK32.21)
+ */
+INT WINAPI WSOCK32_setsockopt1(SOCKET16 s, INT level, INT optname, 
+                                  char *optval, INT optlen) {
+    return _internal_setsockopt(s,level,optname,optval,optlen,1);
+}
+
+/***********************************************************************
+ *		setsockopt		(WS2_32.21)
+ */
+INT WINAPI WSOCK32_setsockopt(SOCKET16 s, INT level, INT optname, 
+                                  char *optval, INT optlen) {
+    return _internal_setsockopt(s,level,optname,optval,optlen,2);
+}
+
+
+/***********************************************************************
  *              setsockopt		(WINSOCK.21)
  */
 INT16 WINAPI WINSOCK_setsockopt16(SOCKET16 s, INT16 level, INT16 optname,
                                   char *optval, INT16 optlen)
 {
     if( !optval ) return SOCKET_ERROR;
-    return (INT16)WSOCK32_setsockopt( s, (UINT16)level, optname, optval, optlen );
+    return (INT16)WSOCK32_setsockopt1( s, (UINT16)level, optname, optval, optlen );
 }
 
 
Index: dlls/winsock/ws2_32.spec
===================================================================
RCS file: /home/wine/wine/dlls/winsock/ws2_32.spec,v
retrieving revision 1.10
diff -u -r1.10 ws2_32.spec
--- dlls/winsock/ws2_32.spec	2001/04/10 21:22:34	1.10
+++ dlls/winsock/ws2_32.spec	2001/07/02 21:05:56
@@ -131,3 +131,8 @@
 #  152 ~ 499  UNKNOWN
  
 500 stub     WEP
+
+
+# WINE internal forwards from wsock32.dll
+501  stdcall  setsockopt1(long long long ptr long) WSOCK32_setsockopt1
+502  stdcall  getsockopt1(long long long ptr ptr) WSOCK32_getsockopt1
Index: dlls/wsock32/wsock32.spec
===================================================================
RCS file: /home/wine/wine/dlls/wsock32/wsock32.spec,v
retrieving revision 1.6
diff -u -r1.6 wsock32.spec
--- dlls/wsock32/wsock32.spec	2001/07/02 18:01:41	1.6
+++ dlls/wsock32/wsock32.spec	2001/07/02 21:05:56
@@ -13,7 +13,7 @@
   4 forward connect ws2_32.connect
   5 forward getpeername ws2_32.getpeername
   6 forward getsockname ws2_32.getsockname
-  7 forward getsockopt ws2_32.getsockopt
+  7 forward getsockopt ws2_32.getsockopt1
   8 forward htonl ws2_32.htonl
   9 forward htons ws2_32.htons
  10 forward inet_addr ws2_32.inet_addr
@@ -27,7 +27,7 @@
  18 forward select ws2_32.select
  19 forward send ws2_32.send
  20 forward sendto ws2_32.sendto
- 21 forward setsockopt ws2_32.setsockopt
+ 21 forward setsockopt ws2_32.setsockopt1
  22 forward shutdown ws2_32.shutdown
  23 forward socket ws2_32.socket
  51 forward gethostbyaddr ws2_32.gethostbyaddr




More information about the wine-patches mailing list