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