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