ws2_32: Add extended IPX protocol support.
This commit is contained in:
parent
2d4adfc49e
commit
3eb39dc08e
@ -201,6 +201,8 @@ static const INT valid_protocols[] =
|
|||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define IS_IPX_PROTO(X) ((X) >= WS_NSPROTO_IPX && (X) <= WS_NSPROTO_IPX + 255)
|
||||||
|
|
||||||
#if defined(IP_UNICAST_IF) && defined(SO_ATTACH_FILTER)
|
#if defined(IP_UNICAST_IF) && defined(SO_ATTACH_FILTER)
|
||||||
# define LINUX_BOUND_IF
|
# define LINUX_BOUND_IF
|
||||||
struct interface_filter {
|
struct interface_filter {
|
||||||
@ -1122,6 +1124,11 @@ convert_proto_w2u(int windowsproto) {
|
|||||||
for (i=0;i<sizeof(ws_proto_map)/sizeof(ws_proto_map[0]);i++)
|
for (i=0;i<sizeof(ws_proto_map)/sizeof(ws_proto_map[0]);i++)
|
||||||
if (ws_proto_map[i][0] == windowsproto)
|
if (ws_proto_map[i][0] == windowsproto)
|
||||||
return ws_proto_map[i][1];
|
return ws_proto_map[i][1];
|
||||||
|
|
||||||
|
/* check for extended IPX */
|
||||||
|
if (IS_IPX_PROTO(windowsproto))
|
||||||
|
return windowsproto;
|
||||||
|
|
||||||
FIXME("unhandled Windows socket protocol %d\n", windowsproto);
|
FIXME("unhandled Windows socket protocol %d\n", windowsproto);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -1133,6 +1140,12 @@ convert_proto_u2w(int unixproto) {
|
|||||||
for (i=0;i<sizeof(ws_proto_map)/sizeof(ws_proto_map[0]);i++)
|
for (i=0;i<sizeof(ws_proto_map)/sizeof(ws_proto_map[0]);i++)
|
||||||
if (ws_proto_map[i][1] == unixproto)
|
if (ws_proto_map[i][1] == unixproto)
|
||||||
return ws_proto_map[i][0];
|
return ws_proto_map[i][0];
|
||||||
|
|
||||||
|
/* if value is inside IPX range just return it - the kernel simply
|
||||||
|
* echoes the value used in the socket() function */
|
||||||
|
if (IS_IPX_PROTO(unixproto))
|
||||||
|
return unixproto;
|
||||||
|
|
||||||
FIXME("unhandled UNIX socket protocol %d\n", unixproto);
|
FIXME("unhandled UNIX socket protocol %d\n", unixproto);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -5976,7 +5989,7 @@ SOCKET WINAPI WSASocketW(int af, int type, int protocol,
|
|||||||
{
|
{
|
||||||
SOCKET ret;
|
SOCKET ret;
|
||||||
DWORD err;
|
DWORD err;
|
||||||
int unixaf, unixtype;
|
int unixaf, unixtype, ipxptype = -1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
FIXME: The "advanced" parameters of WSASocketW (lpProtocolInfo,
|
FIXME: The "advanced" parameters of WSASocketW (lpProtocolInfo,
|
||||||
@ -6011,13 +6024,16 @@ SOCKET WINAPI WSASocketW(int af, int type, int protocol,
|
|||||||
|
|
||||||
if (!type && (af || protocol))
|
if (!type && (af || protocol))
|
||||||
{
|
{
|
||||||
|
int autoproto = protocol;
|
||||||
WSAPROTOCOL_INFOW infow;
|
WSAPROTOCOL_INFOW infow;
|
||||||
|
|
||||||
/* default to the first valid protocol */
|
/* default to the first valid protocol */
|
||||||
if (!protocol)
|
if (!autoproto)
|
||||||
protocol = valid_protocols[0];
|
autoproto = valid_protocols[0];
|
||||||
|
else if(IS_IPX_PROTO(autoproto))
|
||||||
|
autoproto = WS_NSPROTO_IPX;
|
||||||
|
|
||||||
if (WS_EnterSingleProtocolW(protocol, &infow))
|
if (WS_EnterSingleProtocolW(autoproto, &infow))
|
||||||
{
|
{
|
||||||
type = infow.iSocketType;
|
type = infow.iSocketType;
|
||||||
|
|
||||||
@ -6028,6 +6044,14 @@ SOCKET WINAPI WSASocketW(int af, int type, int protocol,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Windows has an extension to the IPX protocol that allows to create sockets
|
||||||
|
and set the IPX packet type at the same time, to do that a caller will use
|
||||||
|
a protocol like NSPROTO_IPX + <PACKET TYPE>
|
||||||
|
*/
|
||||||
|
if (IS_IPX_PROTO(protocol))
|
||||||
|
ipxptype = protocol - WS_NSPROTO_IPX;
|
||||||
|
|
||||||
/* convert the socket family, type and protocol */
|
/* convert the socket family, type and protocol */
|
||||||
unixaf = convert_af_w2u(af);
|
unixaf = convert_af_w2u(af);
|
||||||
unixtype = convert_socktype_w2u(type);
|
unixtype = convert_socktype_w2u(type);
|
||||||
@ -6083,6 +6107,8 @@ SOCKET WINAPI WSASocketW(int af, int type, int protocol,
|
|||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
TRACE("\tcreated %04lx\n", ret );
|
TRACE("\tcreated %04lx\n", ret );
|
||||||
|
if (ipxptype > 0)
|
||||||
|
set_ipx_packettype(ret, ipxptype);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,6 +26,8 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <winternl.h>
|
#include <winternl.h>
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
|
#include <wsipx.h>
|
||||||
|
#include <wsnwlink.h>
|
||||||
#include <mswsock.h>
|
#include <mswsock.h>
|
||||||
#include <mstcpip.h>
|
#include <mstcpip.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -2088,6 +2090,73 @@ static void test_WSASocket(void)
|
|||||||
SOCK_RAW, socktype);
|
SOCK_RAW, socktype);
|
||||||
closesocket(sock);
|
closesocket(sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* IPX socket tests */
|
||||||
|
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
sock = WSASocketA(AF_IPX, SOCK_DGRAM, NSPROTO_IPX, NULL, 0, 0);
|
||||||
|
if (sock == INVALID_SOCKET)
|
||||||
|
{
|
||||||
|
err = WSAGetLastError();
|
||||||
|
ok(err == WSAEAFNOSUPPORT || broken(err == WSAEPROTONOSUPPORT), "Expected 10047, received %d\n", err);
|
||||||
|
skip("IPX is not supported\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WSAPROTOCOL_INFOA info;
|
||||||
|
closesocket(sock);
|
||||||
|
|
||||||
|
trace("IPX is supported\n");
|
||||||
|
|
||||||
|
sock = WSASocketA(0, 0, NSPROTO_IPX, NULL, 0, 0);
|
||||||
|
ok(sock != INVALID_SOCKET, "Failed to create socket: %d\n",
|
||||||
|
WSAGetLastError());
|
||||||
|
|
||||||
|
size = sizeof(socktype);
|
||||||
|
socktype = 0xdead;
|
||||||
|
err = getsockopt(sock, SOL_SOCKET, SO_TYPE, (char *) &socktype, &size);
|
||||||
|
ok(!err,"getsockopt failed with %d\n", WSAGetLastError());
|
||||||
|
ok(socktype == SOCK_DGRAM, "Wrong socket type, expected %d received %d\n",
|
||||||
|
SOCK_DGRAM, socktype);
|
||||||
|
|
||||||
|
/* check socket family, type and protocol */
|
||||||
|
size = sizeof(WSAPROTOCOL_INFOA);
|
||||||
|
err = getsockopt(sock, SOL_SOCKET, SO_PROTOCOL_INFOA, (char *) &info, &size);
|
||||||
|
ok(!err,"getsockopt failed with %d\n", WSAGetLastError());
|
||||||
|
ok(info.iProtocol == NSPROTO_IPX, "expected protocol %d, received %d\n",
|
||||||
|
NSPROTO_IPX, info.iProtocol);
|
||||||
|
ok(info.iAddressFamily == AF_IPX, "expected family %d, received %d\n",
|
||||||
|
AF_IPX, info.iProtocol);
|
||||||
|
ok(info.iSocketType == SOCK_DGRAM, "expected type %d, received %d\n",
|
||||||
|
SOCK_DGRAM, info.iSocketType);
|
||||||
|
closesocket(sock);
|
||||||
|
|
||||||
|
/* SOCK_STREAM does not support NSPROTO_IPX */
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ok(WSASocketA(AF_IPX, SOCK_STREAM, NSPROTO_IPX, NULL, 0, 0) == INVALID_SOCKET,
|
||||||
|
"WSASocketA should have failed\n");
|
||||||
|
err = WSAGetLastError();
|
||||||
|
ok(err == WSAEPROTONOSUPPORT, "Expected 10043, received %d\n", err);
|
||||||
|
|
||||||
|
/* test extended IPX support - that is adding any number between 0 and 255
|
||||||
|
* to the IPX protocol value will make it be used as IPX packet type */
|
||||||
|
for(i = 0;i <= 255;i += 17)
|
||||||
|
{
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
sock = WSASocketA(0, 0, NSPROTO_IPX + i, NULL, 0, 0);
|
||||||
|
ok(sock != INVALID_SOCKET, "Failed to create socket: %d\n",
|
||||||
|
WSAGetLastError());
|
||||||
|
|
||||||
|
size = sizeof(int);
|
||||||
|
socktype = -1;
|
||||||
|
err = getsockopt(sock, NSPROTO_IPX, IPX_PTYPE, (char *) &socktype, &size);
|
||||||
|
ok(!err, "getsockopt failed with %d\n", WSAGetLastError());
|
||||||
|
ok(socktype == i, "Wrong IPX packet type, expected %d received %d\n",
|
||||||
|
i, socktype);
|
||||||
|
|
||||||
|
closesocket(sock);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_WSADuplicateSocket(void)
|
static void test_WSADuplicateSocket(void)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user