From dba9461675f40fde0183002d9fbcdbf429a38cbc Mon Sep 17 00:00:00 2001 From: Roderick Colenbrander Date: Tue, 7 Sep 2004 20:47:03 +0000 Subject: [PATCH] - set ipx packet type - add support for retrieving some ipx info --- dlls/winsock/socket.c | 113 ++++++++++++++++++++++++++++++++++++++++++ include/Makefile.in | 1 + include/wsnwlink.h | 49 ++++++++++++++++++ 3 files changed, 163 insertions(+) create mode 100644 include/wsnwlink.h diff --git a/dlls/winsock/socket.c b/dlls/winsock/socket.c index b3ddc9c10c8..0b1c62c61ee 100644 --- a/dlls/winsock/socket.c +++ b/dlls/winsock/socket.c @@ -128,6 +128,11 @@ #include "wine/server.h" #include "wine/debug.h" +#ifdef HAVE_IPX +# include "wsnwlink.h" +#endif + + #ifdef __FreeBSD__ # define sipx_network sipx_addr.x_net # define sipx_node sipx_addr.x_host.c_host @@ -1099,6 +1104,27 @@ static int WS2_send ( int fd, struct iovec* iov, int count, WSASetLastError ( WSAEFAULT ); goto out; } + +#ifdef HAVE_IPX + if(to->sa_family == WS_AF_IPX) + { + struct sockaddr_ipx* uipx = (struct sockaddr_ipx*)hdr.msg_name; + int val=0; + int len=sizeof(int); + + /* The packet type is stored at the ipx socket level; Atleast the linux kernel seems + * to do something with it in case hdr.msg_name is NULL. Nonetheless can we use it to store + * the packet type and then we can retrieve it using getsockopt. After that we can set the + * ipx type in the sockaddr_opx structure with the stored value. + */ + if(getsockopt(fd, SOL_IPX, IPX_TYPE, &val, &len) != -1) + { + TRACE("ptype: %d (fd:%d)\n", val, fd); + uipx->sipx_type = val; + } + } +#endif + } else hdr.msg_namelen = 0; @@ -1545,6 +1571,60 @@ INT WINAPI WS_getsockopt(SOCKET s, INT level, return 0; } +#ifdef HAVE_IPX + if(level == NSPROTO_IPX) + { + struct WS_sockaddr_ipx addr; + IPX_ADDRESS_DATA *data; + int namelen; + switch(optname) + { + case IPX_PTYPE: + fd = get_sock_fd( s, 0, NULL ); + + if(getsockopt(fd, SOL_IPX, IPX_TYPE, optval, optlen) == -1) + { + return SOCKET_ERROR; + } + TRACE("ptype: %d (fd: %d)\n", *(int*)optval, fd); + release_sock_fd( s, fd ); + + return 0; + break; + case IPX_ADDRESS: + /* + * On a Win2000 system with one network card there are useally three ipx devices one with a speed of 28.8kbps, 10Mbps and 100Mbps. + * Using this call you can then retrieve info about this all. In case of Linux it is a bit different. Useally you have + * only "one" device active and further it is not possible to query things like the linkspeed. + */ + FIXME("IPX_ADDRESS\n"); + namelen = sizeof(struct WS_sockaddr); + memset(&addr, 0, sizeof(struct WS_sockaddr)); + WS_getsockname(s, (struct WS_sockaddr*)&addr, &namelen); + + data = (IPX_ADDRESS_DATA*)optval; + memcpy(data->nodenum,&addr.sa_nodenum,sizeof(data->nodenum)); + memcpy(data->netnum,&addr.sa_netnum,sizeof(data->netnum)); + data->adapternum = 0; + data->wan = FALSE; /* We are not on a wan for now .. */ + data->status = FALSE; /* Since we are not on a wan, the wan link isn't up */ + data->maxpkt = 1467; /* This value is the default one on atleast Win2k/WinXP */ + data->linkspeed = 100000; /* Set the line speed in 100bit/s to 10 Mbit; note 1MB = 1000kB in this case */ + return 0; + break; + case IPX_MAX_ADAPTER_NUM: + FIXME("IPX_MAX_ADAPTER_NUM\n"); + *(int*)optval = 1; /* As noted under IPX_ADDRESS we have just one card. */ + + return 0; + break; + default: + FIXME("IPX optname:%x\n", optname); + return SOCKET_ERROR; + } + } +#endif + fd = get_sock_fd( s, 0, NULL ); if (fd != -1) { @@ -2219,6 +2299,39 @@ int WINAPI WS_setsockopt(SOCKET s, int level, int optname, return 0; } +#ifdef HAVE_IPX + if(level == NSPROTO_IPX) + { + switch(optname) + { + case IPX_PTYPE: + fd = get_sock_fd( s, 0, NULL ); + TRACE("trying to set IPX_PTYPE: %d (fd: %d)\n", *(int*)optval, fd); + + /* We try to set the ipx type on ipx socket level. */ + if(setsockopt(fd, SOL_IPX, IPX_TYPE, optval, optlen) == -1) + { + ERR("IPX: could not set ipx option type; expect weird behaviour\n"); + return SOCKET_ERROR; + } + release_sock_fd( s, fd ); + return 0; + break; + case IPX_FILTERPTYPE: + /* Sets the receive filter packet type, at the moment we don't support it */ + FIXME("IPX_FILTERPTYPE: %x\n", *optval); + + /* Returning 0 is better for now than returning a SOCKET_ERROR */ + return 0; + break; + default: + FIXME("opt_name:%x\n", optname); + return SOCKET_ERROR; + } + return 0; + } +#endif + /* Is a privileged and useless operation, so we don't. */ if ((optname == WS_SO_DEBUG) && (level == WS_SOL_SOCKET)) { diff --git a/include/Makefile.in b/include/Makefile.in index 9384da8706f..897d5aef8e6 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -239,6 +239,7 @@ WINDOWS_INCLUDES = \ ws2tcpip.h \ wshisotp.h \ wsipx.h \ + wsnwlink.h \ xcmc.h \ zmouse.h \ $(IDL_INCLUDES) \ diff --git a/include/wsnwlink.h b/include/wsnwlink.h new file mode 100644 index 00000000000..dd6ae9297a8 --- /dev/null +++ b/include/wsnwlink.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2003,2004 Roderick Colenbrander + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _WSNWLINK_ +#define _WSNWLINK_ + +#define IPX_PTYPE 0x4000 +#define IPX_FILTERPTYPE 0x4001 +#define IPX_DSTYPE 0x4002 +#define IPX_STOPFILTERPTYPE 0x4003 +#define IPX_EXTENDED_ADDRESS 0x4004 +#define IPX_RECVHDR 0x4005 +#define IPX_MAXSIZE 0x4006 +#define IPX_ADDRESS 0x4007 +#define IPX_GETNETINFO 0x4008 +#define IPX_GETNETINFO_NORIP 0x4009 +#define IPX_SPXGETCONNECTIONSTATUS 0x400b +#define IPX_ADDRESS_NOTIFY 0x400c +#define IPX_MAX_ADAPTER_NUM 0x400d +#define IPX_RERIPNETNUMBER 0x400e +#define IPX_RECEIVE_BROADCAST 0x400f +#define IPX_IMMEDIATESPXACK 0x4010 + +typedef struct _IPX_ADDRESS_DATA { + INT adapternum; + UCHAR netnum[4]; + UCHAR nodenum[6]; + BOOLEAN wan; + BOOLEAN status; + INT maxpkt; + ULONG linkspeed; +} IPX_ADDRESS_DATA, *PIPX_ADDRESS_DATA; + +#endif /* _WSNWLINK_ */