From ceb86a90f8713e087ec53e65ae4e56cdf547d90b Mon Sep 17 00:00:00 2001 From: Mike Hearn Date: Fri, 4 Apr 2003 22:04:47 +0000 Subject: [PATCH] - 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. --- dlls/winsock/socket.c | 44 ++++++++++++++++++++++++++++++++++- dlls/wsock32/socket.c | 49 +++++++++++++++++++++++++++++++++++++++ dlls/wsock32/wsock32.spec | 4 ++-- include/winsock.h | 26 +++++++++++++++++++++ include/ws2tcpip.h | 24 +++++++++++++++++++ 5 files changed, 144 insertions(+), 3 deletions(-) diff --git a/dlls/winsock/socket.c b/dlls/winsock/socket.c index cea6c570b66..c380301c496 100644 --- a/dlls/winsock/socket.c +++ b/dlls/winsock/socket.c @@ -278,6 +278,34 @@ static int _px_tcp_ops[] = { 0 }; +static const 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_OPTIONS, + WS_IP_HDRINCL, + WS_IP_TOS, + WS_IP_TTL, + 0 +}; + +static const int _px_ip_ops[] = +{ + IP_MULTICAST_IF, + IP_MULTICAST_TTL, + IP_MULTICAST_LOOP, + IP_ADD_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 +510,18 @@ static int convert_sockopt(INT *level, INT *optname) } 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 +1528,7 @@ int WINAPI WS_bind(SOCKET s, const struct WS_sockaddr* name, int namelen) 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 +2764,7 @@ int WINAPI WS_setsockopt(SOCKET s, int level, int optname, 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 +2832,7 @@ int WINAPI WS_setsockopt(SOCKET s, int level, int optname, close(fd); return 0; } + TRACE("Setting socket error, %d\n", wsaErrno()); SetLastError(wsaErrno()); close(fd); } diff --git a/dlls/wsock32/socket.c b/dlls/wsock32/socket.c index 611151dd931..88e792b08e4 100644 --- a/dlls/wsock32/socket.c +++ b/dlls/wsock32/socket.c @@ -40,6 +40,9 @@ #define recv linux_recv /* */ +#define setsockopt linux_setsockopt +#define getsockopt linux_getsockopt + #include "config.h" #include @@ -85,9 +88,55 @@ extern int WINAPI closesocket(SOCKET); 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 */ +static 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) diff --git a/dlls/wsock32/wsock32.spec b/dlls/wsock32/wsock32.spec index 543524bcaf1..2426159ac4f 100644 --- a/dlls/wsock32/wsock32.spec +++ b/dlls/wsock32/wsock32.spec @@ -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 diff --git a/include/winsock.h b/include/winsock.h index 0319b63fb84..bf0ce0770e4 100644 --- a/include/winsock.h +++ b/include/winsock.h @@ -669,6 +669,32 @@ typedef struct WS(WSAData) #define WS_TCP_NODELAY 1 #endif +/* IPPROTO_IP options */ +#ifndef __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 +#endif + + /* * Socket I/O flags (supported by spec 1.1) */ diff --git a/include/ws2tcpip.h b/include/ws2tcpip.h index 3c20f327080..5b08dbba3ec 100644 --- a/include/ws2tcpip.h +++ b/include/ws2tcpip.h @@ -72,4 +72,28 @@ typedef struct _INTERFACE_INFO #define WS_IFF_MULTICAST 0x00000010 /* multicast is supported */ #endif /* USE_WS_PREFIX */ +#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 /* USE_WS_PREFIX */ + #endif /* __WS2TCPIP__ */