PATCH: more ipv6 support for winsock
Marcus Meissner
meissner at suse.de
Mon Nov 14 10:29:30 CST 2005
Hi,
To do getaddrinfo() correctly I first need to add some IPV6 support to
converts and socket handlers.
The mapper functions will be used by getaddrinfo() later too, now only
2 are used.
Ciao, Marcus
Changelog:
Added mappers for adress families, socket types protocols.
Use them in WSASocketW.
Add AF_INET6 support for the sockaddr converter functions.
Index: dlls/winsock/socket.c
===================================================================
RCS file: /home/wine/wine/dlls/winsock/socket.c,v
retrieving revision 1.193
diff -u -r1.193 socket.c
--- dlls/winsock/socket.c 5 Nov 2005 10:43:27 -0000 1.193
+++ dlls/winsock/socket.c 14 Nov 2005 16:23:57 -0000
@@ -285,6 +286,34 @@
{ 0, 0 }
};
+static const int ws_af_map[][2] =
+{
+ MAP_OPTION( AF_INET ),
+ MAP_OPTION( AF_INET6 ),
+#ifdef HAVE_IPX
+ MAP_OPTION( AF_IPX ),
+#endif
+ { 0, 0 }
+};
+
+static const int ws_socktype_map[][2] =
+{
+ MAP_OPTION( SOCK_DGRAM ),
+ MAP_OPTION( SOCK_STREAM ),
+ MAP_OPTION( SOCK_RAW ),
+ { 0, 0 }
+};
+
+static const int ws_proto_map[][2] =
+{
+ MAP_OPTION( IPPROTO_TCP ),
+ MAP_OPTION( IPPROTO_UDP ),
+ MAP_OPTION( IPPROTO_ICMP ),
+ MAP_OPTION( IPPROTO_IGMP ),
+ MAP_OPTION( IPPROTO_RAW ),
+ { 0, 0 }
+};
+
inline static DWORD NtStatusToWSAError( const DWORD status )
{
/* We only need to cover the status codes set by server async request handling */
@@ -658,6 +687,73 @@
return pfd.revents;
}
+static int
+convert_af_w2u(int windowsaf) {
+ int i;
+
+ for (i=0;ws_af_map[i][0];i++)
+ if (ws_af_map[i][0] == windowsaf)
+ return ws_af_map[i][1];
+ FIXME("unhandled Windows address family %d\n", windowsaf);
+ return -1;
+}
+
+static int
+convert_af_u2w(int unixaf) {
+ int i;
+
+ for (i=0;ws_af_map[i][0];i++)
+ if (ws_af_map[i][1] == unixaf)
+ return ws_af_map[i][0];
+ FIXME("unhandled UNIX address family %d\n", unixaf);
+ return -1;
+}
+
+static int
+convert_proto_w2u(int windowsproto) {
+ int i;
+
+ for (i=0;ws_proto_map[i][0];i++)
+ if (ws_proto_map[i][0] == windowsproto)
+ return ws_proto_map[i][1];
+ FIXME("unhandled Windows socket protocol %d\n", windowsproto);
+ return -1;
+}
+
+static int
+convert_proto_u2w(int unixproto) {
+ int i;
+
+ for (i=0;ws_proto_map[i][0];i++)
+ if (ws_proto_map[i][1] == unixproto)
+ return ws_proto_map[i][0];
+ if (unixproto == 0) /* 0 is ok too as wild card */
+ return 0;
+ FIXME("unhandled UNIX socket protocol %d\n", unixproto);
+ return -1;
+}
+
+static int
+convert_socktype_w2u(int windowssocktype) {
+ int i;
+
+ for (i=0;ws_socktype_map[i][0];i++)
+ if (ws_socktype_map[i][0] == windowssocktype)
+ return ws_socktype_map[i][1];
+ FIXME("unhandled Windows socket type %d\n", windowssocktype);
+ return -1;
+}
+
+static int
+convert_socktype_u2w(int unixsocktype) {
+ int i;
+
+ for (i=0;ws_socktype_map[i][0];i++)
+ if (ws_socktype_map[i][1] == unixsocktype)
+ return ws_socktype_map[i][0];
+ FIXME("unhandled UNIX socket type %d\n", unixsocktype);
+ return -1;
+}
/* ----------------------------------- API -----
*
@@ -803,7 +899,18 @@
return (const struct sockaddr*)uipx;
}
#endif
+ case WS_AF_INET6: {
+ struct sockaddr_in6* uin6;
+
+ if (wsaddrlen<sizeof(struct WS_sockaddr_in6))
+ return NULL;
+ *uaddrlen=sizeof(struct sockaddr_in6);
+ uin6=HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *uaddrlen);
+ memcpy(uin6,wsaddr,sizeof(struct sockaddr_in6));
+ uin6->sin6_family = AF_INET6;
+ return (const struct sockaddr*)uin6;
+ }
default:
if (wsaddrlen<sizeof(struct WS_sockaddr))
return NULL;
@@ -882,9 +989,19 @@
}
break;
#endif
-
+ case AF_INET6:
+ /* layout is same on Windows and Linux, except AF is different */
+ memcpy(wsaddr,uaddr,*wsaddrlen);
+ wsaddr->sa_family = WS_AF_INET6;
+ if (*wsaddrlen<uaddrlen) {
+ res=-1;
+ } else {
+ *wsaddrlen=uaddrlen;
+ res=0;
+ }
+ break;
default:
- /* No conversion needed */
+ /* No conversion needed (for AF_INET) */
memcpy(wsaddr,uaddr,*wsaddrlen);
if (*wsaddrlen<uaddrlen) {
res=-1;
@@ -3123,35 +3366,21 @@
return ret;
}
- /* check the socket family */
- switch(af)
- {
-#ifdef HAVE_IPX
- case WS_AF_IPX: af = AF_IPX;
-#endif
- case AF_INET:
- case AF_UNSPEC:
- break;
- default:
- SetLastError(WSAEAFNOSUPPORT);
- return INVALID_SOCKET;
+ /* check and convert the socket family */
+ af = convert_af_w2u(af);
+ if (af == -1)
+ {
+ FIXME("Unsupported socket family %d!\n", af);
+ SetLastError(WSAEAFNOSUPPORT);
+ return INVALID_SOCKET;
}
/* check the socket type */
- switch(type)
+ type = convert_socktype_w2u(type);
+ if (type == -1)
{
- case WS_SOCK_STREAM:
- type=SOCK_STREAM;
- break;
- case WS_SOCK_DGRAM:
- type=SOCK_DGRAM;
- break;
- case WS_SOCK_RAW:
- type=SOCK_RAW;
- break;
- default:
- SetLastError(WSAESOCKTNOSUPPORT);
- return INVALID_SOCKET;
+ SetLastError(WSAESOCKTNOSUPPORT);
+ return INVALID_SOCKET;
}
/* check the protocol type */
More information about the wine-patches
mailing list