dlls/ws2_32/socket.c
/* Returns the length of the converted address if successful, 0 if it was too small to
 * start with.
 */
Returns the length of the converted address if successful, 0 if it was too small to
start with.
Returns the length of the converted address if successful 0 if it was too small to start with .
static unsigned int ws_sockaddr_ws2u(const struct WS_sockaddr* wsaddr, int wsaddrlen,
                                     union generic_unix_sockaddr *uaddr)
{
    unsigned int uaddrlen = 0;
    switch (wsaddr->sa_family)
    {
#ifdef HAS_IPX
    case WS_AF_IPX:
        {
            const struct WS_sockaddr_ipx* wsipx=(const struct WS_sockaddr_ipx*)wsaddr;
            struct sockaddr_ipx* uipx = (struct sockaddr_ipx *)uaddr;
            if (wsaddrlen<sizeof(struct WS_sockaddr_ipx))
                return 0;
            uaddrlen = sizeof(struct sockaddr_ipx);
            memset( uaddr, 0, uaddrlen );
            uipx->sipx_family=AF_IPX;
            uipx->sipx_port=wsipx->sa_socket;
            memcpy(&uipx->sipx_network,wsipx->sa_netnum,sizeof(uipx->sipx_network)+sizeof(uipx->sipx_node));
#ifdef IPX_FRAME_NONE
            uipx->sipx_type=IPX_FRAME_NONE;
#endif
            break;
        }
#endif
    case WS_AF_INET6: {
        struct sockaddr_in6* uin6 = (struct sockaddr_in6 *)uaddr;
        const struct WS_sockaddr_in6* win6 = (const struct WS_sockaddr_in6*)wsaddr;
        if (wsaddrlen >= sizeof(struct WS_sockaddr_in6_old)) {
            uaddrlen = sizeof(struct sockaddr_in6);
            memset( uaddr, 0, uaddrlen );
            uin6->sin6_family   = AF_INET6;
            uin6->sin6_port     = win6->sin6_port;
            uin6->sin6_flowinfo = win6->sin6_flowinfo;
#ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID
            if (wsaddrlen >= sizeof(struct WS_sockaddr_in6)) uin6->sin6_scope_id = win6->sin6_scope_id;
#endif
            memcpy(&uin6->sin6_addr,&win6->sin6_addr,16); 
            break;
        }
        FIXME("bad size %d for WS_sockaddr_in6\n",wsaddrlen);
        return 0;
    }
    case WS_AF_INET: {
        struct sockaddr_in* uin = (struct sockaddr_in *)uaddr;
        const struct WS_sockaddr_in* win = (const struct WS_sockaddr_in*)wsaddr;
        if (wsaddrlen<sizeof(struct WS_sockaddr_in))
            return 0;
        uaddrlen = sizeof(struct sockaddr_in);
        memset( uaddr, 0, uaddrlen );
        uin->sin_family = AF_INET;
        uin->sin_port   = win->sin_port;
        memcpy(&uin->sin_addr,&win->sin_addr,4); 
        break;
    }
#ifdef HAS_IRDA
    case WS_AF_IRDA: {
        struct sockaddr_irda *uin = (struct sockaddr_irda *)uaddr;
        const SOCKADDR_IRDA *win = (const SOCKADDR_IRDA *)wsaddr;
        if (wsaddrlen < sizeof(SOCKADDR_IRDA))
            return 0;
        uaddrlen = sizeof(struct sockaddr_irda);
        memset( uaddr, 0, uaddrlen );
        uin->sir_family = AF_IRDA;
        if (!strncmp( win->irdaServiceName, "LSAP-SEL", strlen( "LSAP-SEL" ) ))
        {
            unsigned int lsap_sel = 0;
            sscanf( win->irdaServiceName, "LSAP-SEL%u", &lsap_sel );
            uin->sir_lsap_sel = lsap_sel;
        }
        else
        {
            uin->sir_lsap_sel = LSAP_ANY;
            memcpy( uin->sir_name, win->irdaServiceName, 25 );
        }
        memcpy( &uin->sir_addr, win->irdaDeviceID, sizeof(uin->sir_addr) );
        break;
    }
#endif
    case WS_AF_UNSPEC: {
        switch (wsaddrlen) {
        default: 
        case sizeof(struct WS_sockaddr_in):
            uaddrlen = sizeof(struct sockaddr_in);
            break;
#ifdef HAS_IPX
        case sizeof(struct WS_sockaddr_ipx):
            uaddrlen = sizeof(struct sockaddr_ipx);
            break;
#endif
#ifdef HAS_IRDA
        case sizeof(SOCKADDR_IRDA):
            uaddrlen = sizeof(struct sockaddr_irda);
            break;
#endif
        case sizeof(struct WS_sockaddr_in6):
        case sizeof(struct WS_sockaddr_in6_old):
            uaddrlen = sizeof(struct sockaddr_in6);
            break;
        }
        memset( uaddr, 0, uaddrlen );
        break;
    }
    default:
        FIXME("Unknown address family %d, return NULL.\n", wsaddr->sa_family);
        return 0;
    }
    return uaddrlen;
}
static unsigned int ws_sockaddr_ws2u ( const struct WS_sockaddr * wsaddr , int wsaddrlen , union generic_unix_sockaddr * uaddr ) { unsigned int uaddrlen = 0 ; switch ( wsaddr -> sa_family ) { #ifdef HAS_IPX case WS_AF_IPX : { const struct WS_sockaddr_ipx * wsipx = ( const struct WS_sockaddr_ipx * ) wsaddr ; struct sockaddr_ipx * uipx = ( struct sockaddr_ipx * ) uaddr ; if ( wsaddrlen < sizeof ( struct WS_sockaddr_ipx ) ) return 0 ; uaddrlen = sizeof ( struct sockaddr_ipx ) ; memset ( uaddr , 0 , uaddrlen ) ; uipx -> sipx_family = AF_IPX ; uipx -> sipx_port = wsipx -> sa_socket ; memcpy ( & uipx -> sipx_network , wsipx -> sa_netnum , sizeof ( uipx -> sipx_network ) + sizeof ( uipx -> sipx_node ) ) ; #ifdef IPX_FRAME_NONE uipx -> sipx_type = IPX_FRAME_NONE ; #endif break ; } #endif case WS_AF_INET6 : { struct sockaddr_in6 * uin6 = ( struct sockaddr_in6 * ) uaddr ; const struct WS_sockaddr_in6 * win6 = ( const struct WS_sockaddr_in6 * ) wsaddr ; if ( wsaddrlen >= sizeof ( struct WS_sockaddr_in6_old ) ) { uaddrlen = sizeof ( struct sockaddr_in6 ) ; memset ( uaddr , 0 , uaddrlen ) ; uin6 -> sin6_family = AF_INET6 ; uin6 -> sin6_port = win6 -> sin6_port ; uin6 -> sin6_flowinfo = win6 -> sin6_flowinfo ; #ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID if ( wsaddrlen >= sizeof ( struct WS_sockaddr_in6 ) ) uin6 -> sin6_scope_id = win6 -> sin6_scope_id ; #endif memcpy ( & uin6 -> sin6_addr , & win6 -> sin6_addr , 16 ) ; break ; } FIXME ( " \n " , wsaddrlen ) ; return 0 ; } case WS_AF_INET : { struct sockaddr_in * uin = ( struct sockaddr_in * ) uaddr ; const struct WS_sockaddr_in * win = ( const struct WS_sockaddr_in * ) wsaddr ; if ( wsaddrlen < sizeof ( struct WS_sockaddr_in ) ) return 0 ; uaddrlen = sizeof ( struct sockaddr_in ) ; memset ( uaddr , 0 , uaddrlen ) ; uin -> sin_family = AF_INET ; uin -> sin_port = win -> sin_port ; memcpy ( & uin -> sin_addr , & win -> sin_addr , 4 ) ; break ; } #ifdef HAS_IRDA case WS_AF_IRDA : { struct sockaddr_irda * uin = ( struct sockaddr_irda * ) uaddr ; const SOCKADDR_IRDA * win = ( const SOCKADDR_IRDA * ) wsaddr ; if ( wsaddrlen < sizeof ( SOCKADDR_IRDA ) ) return 0 ; uaddrlen = sizeof ( struct sockaddr_irda ) ; memset ( uaddr , 0 , uaddrlen ) ; uin -> sir_family = AF_IRDA ; if ( ! strncmp ( win -> irdaServiceName , " " , strlen ( " " ) ) ) { unsigned int lsap_sel = 0 ; sscanf ( win -> irdaServiceName , " " , & lsap_sel ) ; uin -> sir_lsap_sel = lsap_sel ; } else { uin -> sir_lsap_sel = LSAP_ANY ; memcpy ( uin -> sir_name , win -> irdaServiceName , 25 ) ; } memcpy ( & uin -> sir_addr , win -> irdaDeviceID , sizeof ( uin -> sir_addr ) ) ; break ; } #endif case WS_AF_UNSPEC : { switch ( wsaddrlen ) { default : case sizeof ( struct WS_sockaddr_in ) : uaddrlen = sizeof ( struct sockaddr_in ) ; break ; #ifdef HAS_IPX case sizeof ( struct WS_sockaddr_ipx ) : uaddrlen = sizeof ( struct sockaddr_ipx ) ; break ; #endif #ifdef HAS_IRDA case sizeof ( SOCKADDR_IRDA ) : uaddrlen = sizeof ( struct sockaddr_irda ) ; break ; #endif case sizeof ( struct WS_sockaddr_in6 ) : case sizeof ( struct WS_sockaddr_in6_old ) : uaddrlen = sizeof ( struct sockaddr_in6 ) ; break ; } memset ( uaddr , 0 , uaddrlen ) ; break ; } default : FIXME ( " \n " , wsaddr -> sa_family ) ; return 0 ; } return uaddrlen ; }
Returns the length of the converted address if successful, 0 if it was too small to
 start with.
Returns the length of the converted address if successful 0 if it was too small to start with .
/* copy sa_netnum and sa_nodenum to sipx_network and sipx_node
             * in one go
             */ /* Note: Windows has 2 versions of the sockaddr_in6 struct, one with
         * scope_id, one without.
         */ /* 16 bytes = 128 address bits */ /* 4 bytes = 32 address bits */ /* Try to determine the needed space by the passed windows sockaddr space */ /* likely a ipv4 address */