1
0
mirror of https://github.com/solemnwarning/ipxwrapper synced 2024-12-30 16:45:37 +01:00

Cleaned up most of the winsock code and removed the RETURN/RETURN_WSA macros.

This commit is contained in:
Daniel Collins 2012-11-11 22:21:22 +00:00
parent 9046a8ba1d
commit b453669229
2 changed files with 389 additions and 250 deletions

View File

@ -42,15 +42,6 @@
#define IPX_RECV_BCAST (int)(1<<8) #define IPX_RECV_BCAST (int)(1<<8)
#define IPX_EXT_ADDR (int)(1<<9) #define IPX_EXT_ADDR (int)(1<<9)
#define RETURN(...) \
unlock_sockets();\
return __VA_ARGS__;
#define RETURN_WSA(errnum, ...) \
unlock_sockets();\
WSASetLastError(errnum);\
return __VA_ARGS__;
typedef struct ipx_socket ipx_socket; typedef struct ipx_socket ipx_socket;
typedef struct ipx_packet ipx_packet; typedef struct ipx_packet ipx_packet;

View File

@ -205,7 +205,9 @@ int WSAAPI closesocket(SOCKET sockfd)
if(ret == SOCKET_ERROR) if(ret == SOCKET_ERROR)
{ {
log_printf(LOG_ERROR, "closesocket(%d): %s", sockfd, w32_error(WSAGetLastError())); log_printf(LOG_ERROR, "closesocket(%d): %s", sockfd, w32_error(WSAGetLastError()));
RETURN(SOCKET_ERROR);
unlock_sockets();
return -1;
} }
log_printf(LOG_INFO, "IPX socket closed (fd = %d)", sockfd); log_printf(LOG_INFO, "IPX socket closed (fd = %d)", sockfd);
@ -293,7 +295,10 @@ int WSAAPI bind(SOCKET fd, const struct sockaddr *addr, int addrlen)
if(addrlen < sizeof(ipxaddr) || addr->sa_family != AF_IPX) if(addrlen < sizeof(ipxaddr) || addr->sa_family != AF_IPX)
{ {
RETURN_WSA(WSAEFAULT, -1); WSASetLastError(WSAEFAULT);
unlock_sockets();
return -1;
} }
memcpy(&ipxaddr, addr, sizeof(ipxaddr)); memcpy(&ipxaddr, addr, sizeof(ipxaddr));
@ -334,10 +339,13 @@ int WSAAPI bind(SOCKET fd, const struct sockaddr *addr, int addrlen)
{ {
/* Address has already been bound. */ /* Address has already been bound. */
log_printf(LOG_ERROR, "bind failed: address already in use");
WSASetLastError(WSAEADDRINUSE);
addr_table_unlock(); addr_table_unlock();
unlock_sockets(); unlock_sockets();
WSASetLastError(WSAEADDRINUSE);
return -1; return -1;
} }
@ -409,24 +417,38 @@ int WSAAPI bind(SOCKET fd, const struct sockaddr *addr, int addrlen)
} }
} }
int WSAAPI getsockname(SOCKET fd, struct sockaddr *addr, int *addrlen) { int WSAAPI getsockname(SOCKET fd, struct sockaddr *addr, int *addrlen)
ipx_socket *ptr = get_socket(fd); {
ipx_socket *sock = get_socket(fd);
if(ptr) { if(sock)
if(ptr->flags & IPX_BOUND) { {
if(*addrlen < sizeof(struct sockaddr_ipx)) { if(sock->flags & IPX_BOUND)
{
if(*addrlen < sizeof(struct sockaddr_ipx))
{
*addrlen = sizeof(struct sockaddr_ipx); *addrlen = sizeof(struct sockaddr_ipx);
RETURN_WSA(WSAEFAULT, -1);
WSASetLastError(WSAEFAULT);
unlock_sockets();
return -1;
} }
memcpy(addr, &(ptr->addr), sizeof(ptr->addr)); memcpy(addr, &(sock->addr), sizeof(sock->addr));
*addrlen = sizeof(struct sockaddr_ipx); *addrlen = sizeof(struct sockaddr_ipx);
RETURN(0); unlock_sockets();
}else{ return 0;
RETURN_WSA(WSAEINVAL, -1);
} }
}else{ else{
WSASetLastError(WSAEINVAL);
unlock_sockets();
return -1;
}
}
else{
return r_getsockname(fd, addr, addrlen); return r_getsockname(fd, addr, addrlen);
} }
} }
@ -598,106 +620,111 @@ int PASCAL WSARecvEx(SOCKET fd, char *buf, int len, int *flags) {
} }
} }
#define CHECK_OPTLEN(size) \ #define GETSOCKOPT_OPTLEN(size) \
if(*optlen < size) {\ if(*optlen < size) \
{\
*optlen = size;\ *optlen = size;\
RETURN_WSA(WSAEFAULT, -1);\ WSASetLastError(WSAEFAULT); \
unlock_sockets(); \
return -1; \
}\ }\
*optlen = size; *optlen = size;
int WSAAPI getsockopt(SOCKET fd, int level, int optname, char FAR *optval, int FAR *optlen) { #define RETURN_INT_OPT(val) \
int* intval = (int*)optval; GETSOCKOPT_OPTLEN(sizeof(int)); \
BOOL *bval = (BOOL*)optval; *((int*)(optval)) = (val); \
unlock_sockets(); \
return 0;
#define RETURN_BOOL_OPT(val) \
GETSOCKOPT_OPTLEN(sizeof(BOOL)); \
*((BOOL*)(optval)) = (val) ? TRUE : FALSE; \
unlock_sockets(); \
return 0;
int WSAAPI getsockopt(SOCKET fd, int level, int optname, char FAR *optval, int FAR *optlen)
{
ipx_socket *sock = get_socket(fd);
ipx_socket *ptr = get_socket(fd); if(sock)
{
if(ptr) { if(level == NSPROTO_IPX)
if(level == NSPROTO_IPX) { {
if(optname == IPX_PTYPE) { if(optname == IPX_PTYPE)
CHECK_OPTLEN(sizeof(int)); {
*intval = ptr->s_ptype; RETURN_INT_OPT(sock->s_ptype);
RETURN(0);
} }
else if(optname == IPX_FILTERPTYPE)
if(optname == IPX_FILTERPTYPE) { {
CHECK_OPTLEN(sizeof(int)); RETURN_INT_OPT(sock->f_ptype);
*intval = ptr->f_ptype;
RETURN(0);
} }
else if(optname == IPX_MAXSIZE)
if(optname == IPX_MAXSIZE) { {
CHECK_OPTLEN(sizeof(int)); RETURN_INT_OPT(MAX_DATA_SIZE);
*intval = MAX_DATA_SIZE;
RETURN(0);
} }
else if(optname == IPX_ADDRESS)
if(optname == IPX_ADDRESS) { {
CHECK_OPTLEN(sizeof(IPX_ADDRESS_DATA)); GETSOCKOPT_OPTLEN(sizeof(IPX_ADDRESS_DATA));
IPX_ADDRESS_DATA *ipxdata = (IPX_ADDRESS_DATA*)optval; IPX_ADDRESS_DATA *ipxdata = (IPX_ADDRESS_DATA*)(optval);
struct ipx_interface *nic = ipx_interface_by_index(ipxdata->adapternum); struct ipx_interface *nic = ipx_interface_by_index(ipxdata->adapternum);
if(!nic) { if(!nic)
RETURN_WSA(ERROR_NO_DATA, -1); {
WSASetLastError(ERROR_NO_DATA);
unlock_sockets();
return -1;
} }
addr32_out(ipxdata->netnum, nic->ipx_net); addr32_out(ipxdata->netnum, nic->ipx_net);
addr48_out(ipxdata->nodenum, nic->ipx_node); addr48_out(ipxdata->nodenum, nic->ipx_node);
/* TODO: LAN/WAN detection, link speed detection */ ipxdata->wan = FALSE;
ipxdata->wan = FALSE; ipxdata->status = FALSE;
ipxdata->status = FALSE; ipxdata->maxpkt = MAX_DATA_SIZE;
ipxdata->maxpkt = MAX_DATA_SIZE;
ipxdata->linkspeed = 100000; /* 10MBps */ ipxdata->linkspeed = 100000; /* 10MBps */
free_ipx_interface(nic); free_ipx_interface(nic);
RETURN(0); unlock_sockets();
return 0;
} }
else if(optname == IPX_MAX_ADAPTER_NUM)
/* NOTE: IPX_MAX_ADAPTER_NUM implies it may be the maximum index {
* for referencing an IPX interface. This behaviour makes no sense /* NOTE: IPX_MAX_ADAPTER_NUM implies it may be
* and a code example in MSDN implies it should be the number of * the maximum index for referencing an IPX
* IPX interfaces, this code follows the latter. * interface. This behaviour makes no sense and
*/ * a code example in MSDN implies it should be
if(optname == IPX_MAX_ADAPTER_NUM) { * the number of IPX interfaces, this code
CHECK_OPTLEN(sizeof(int)); * follows the latter behaviour.
*/
*intval = ipx_interface_count(); RETURN_INT_OPT(ipx_interface_count());
RETURN(0);
} }
else if(optname == IPX_EXTENDED_ADDRESS)
if(optname == IPX_EXTENDED_ADDRESS) { {
CHECK_OPTLEN(sizeof(BOOL)); RETURN_BOOL_OPT(sock->flags & IPX_EXT_ADDR);
}
*bval = (ptr->flags & IPX_EXT_ADDR ? TRUE : FALSE); else{
log_printf(LOG_ERROR, "Unknown NSPROTO_IPX socket option passed to getsockopt: %d", optname);
RETURN(0);
WSASetLastError(WSAENOPROTOOPT);
unlock_sockets();
return -1;
} }
log_printf(LOG_ERROR, "Unknown NSPROTO_IPX socket option passed to getsockopt: %d", optname);
RETURN_WSA(WSAENOPROTOOPT, -1);
} }
else if(level == SOL_SOCKET)
if(level == SOL_SOCKET) { {
if(optname == SO_BROADCAST) { if(optname == SO_BROADCAST)
CHECK_OPTLEN(sizeof(BOOL)); {
RETURN_BOOL_OPT(sock->flags & IPX_BROADCAST);
*bval = ptr->flags & IPX_BROADCAST ? TRUE : FALSE;
RETURN(0);
} }
else if(optname == SO_REUSEADDR)
if(optname == SO_REUSEADDR) { {
CHECK_OPTLEN(sizeof(BOOL)); RETURN_BOOL_OPT(sock->flags & IPX_REUSE);
*bval = ptr->flags & IPX_REUSE ? TRUE : FALSE;
RETURN(0);
} }
} }
@ -707,21 +734,36 @@ int WSAAPI getsockopt(SOCKET fd, int level, int optname, char FAR *optval, int F
return r_getsockopt(fd, level, optname, optval, optlen); return r_getsockopt(fd, level, optname, optval, optlen);
} }
#define SET_FLAG(flag, state) \ #define SETSOCKOPT_OPTLEN(s) \
if(state) { \ if(optlen < s) \
sockptr->flags |= (flag); \ { \
}else{ \ WSASetLastError(WSAEFAULT); \
sockptr->flags &= ~(flag); \ unlock_sockets(); \
return -1; \
} }
int WSAAPI setsockopt(SOCKET fd, int level, int optname, const char FAR *optval, int optlen) { #define SET_FLAG(flag) \
int *intval = (int*)optval; SETSOCKOPT_OPTLEN(sizeof(BOOL)); \
BOOL *bval = (BOOL*)optval; if(*((BOOL*)(optval))) \
{ \
sock->flags |= (flag); \
} \
else{ \
sock->flags &= ~(flag); \
} \
unlock_sockets(); \
return 0;
int WSAAPI setsockopt(SOCKET fd, int level, int optname, const char FAR *optval, int optlen)
{
int *intval = (int*)(optval);
ipx_socket *sockptr = get_socket(fd); ipx_socket *sock = get_socket(fd);
if(sockptr) { if(sock)
if(min_log_level <= LOG_DEBUG) { {
if(min_log_level <= LOG_DEBUG)
{
char opt_s[24] = ""; char opt_s[24] = "";
int i; int i;
@ -740,52 +782,60 @@ int WSAAPI setsockopt(SOCKET fd, int level, int optname, const char FAR *optval,
} }
} }
if(level == NSPROTO_IPX) { if(level == NSPROTO_IPX)
if(optname == IPX_PTYPE) { {
sockptr->s_ptype = *intval; if(optname == IPX_PTYPE)
RETURN(0); {
} SETSOCKOPT_OPTLEN(sizeof(int));
if(optname == IPX_FILTERPTYPE) {
sockptr->f_ptype = *intval;
sockptr->flags |= IPX_FILTER;
RETURN(0); sock->s_ptype = *intval;
}
if(optname == IPX_STOPFILTERPTYPE) {
sockptr->flags &= ~IPX_FILTER;
RETURN(0); unlock_sockets();
return 0;
} }
else if(optname == IPX_FILTERPTYPE)
if(optname == IPX_RECEIVE_BROADCAST) { {
SET_FLAG(IPX_RECV_BCAST, *bval); SETSOCKOPT_OPTLEN(sizeof(int));
RETURN(0); sock->f_ptype = *intval;
sock->flags |= IPX_FILTER;
unlock_sockets();
return 0;
} }
else if(optname == IPX_STOPFILTERPTYPE)
if(optname == IPX_EXTENDED_ADDRESS) { {
SET_FLAG(IPX_EXT_ADDR, *bval); sock->flags &= ~IPX_FILTER;
RETURN(0);
unlock_sockets();
return 0;
}
else if(optname == IPX_RECEIVE_BROADCAST)
{
SET_FLAG(IPX_RECV_BCAST);
}
else if(optname == IPX_EXTENDED_ADDRESS)
{
SET_FLAG(IPX_EXT_ADDR);
}
else{
log_printf(LOG_ERROR, "Unknown NSPROTO_IPX socket option passed to setsockopt: %d", optname);
WSASetLastError(WSAENOPROTOOPT);
unlock_sockets();
return -1;
} }
log_printf(LOG_ERROR, "Unknown NSPROTO_IPX socket option passed to setsockopt: %d", optname);
RETURN_WSA(WSAENOPROTOOPT, -1);
} }
else if(level == SOL_SOCKET)
if(level == SOL_SOCKET) { {
if(optname == SO_BROADCAST) { if(optname == SO_BROADCAST)
SET_FLAG(IPX_BROADCAST, *bval); {
SET_FLAG(IPX_BROADCAST);
RETURN(0);
} }
else if(optname == SO_REUSEADDR)
if(optname == SO_REUSEADDR) { {
SET_FLAG(IPX_REUSE, *bval); SET_FLAG(IPX_REUSE);
RETURN(0);
} }
} }
@ -817,21 +867,46 @@ static int send_packet(const ipx_packet *packet, int len, struct sockaddr *addr,
return (r_sendto(private_socket, (char*)packet, len, 0, addr, addrlen) == len); return (r_sendto(private_socket, (char*)packet, len, 0, addr, addrlen) == len);
} }
int WSAAPI sendto(SOCKET fd, const char *buf, int len, int flags, const struct sockaddr *addr, int addrlen) { int WSAAPI sendto(SOCKET fd, const char *buf, int len, int flags, const struct sockaddr *addr, int addrlen)
{
struct sockaddr_ipx_ext *ipxaddr = (struct sockaddr_ipx_ext*)addr; struct sockaddr_ipx_ext *ipxaddr = (struct sockaddr_ipx_ext*)addr;
ipx_socket *sockptr = get_socket(fd); ipx_socket *sock = get_socket(fd);
if(sockptr) { if(sock)
if(!addr || addrlen < sizeof(struct sockaddr_ipx)) { {
RETURN_WSA(WSAEDESTADDRREQ, -1); if(!addr)
{
/* Destination address required. */
WSASetLastError(WSAEDESTADDRREQ);
unlock_sockets();
return -1;
} }
if(!(sockptr->flags & IPX_SEND)) { if(addrlen < sizeof(struct sockaddr_ipx))
RETURN_WSA(WSAESHUTDOWN, -1); {
/* Destination address too small. */
WSASetLastError(WSAEFAULT);
unlock_sockets();
return -1;
} }
if(!(sockptr->flags & IPX_BOUND)) { if(!(sock->flags & IPX_SEND))
{
/* Socket has been shut down for sending. */
WSASetLastError(WSAESHUTDOWN);
unlock_sockets();
return -1;
}
if(!(sock->flags & IPX_BOUND))
{
log_printf(LOG_WARNING, "sendto() on unbound socket, attempting implicit bind"); log_printf(LOG_WARNING, "sendto() on unbound socket, attempting implicit bind");
struct sockaddr_ipx bind_addr; struct sockaddr_ipx bind_addr;
@ -841,29 +916,42 @@ int WSAAPI sendto(SOCKET fd, const char *buf, int len, int flags, const struct s
memset(bind_addr.sa_nodenum, 0, 6); memset(bind_addr.sa_nodenum, 0, 6);
bind_addr.sa_socket = 0; bind_addr.sa_socket = 0;
if(bind(fd, (struct sockaddr*)&bind_addr, sizeof(bind_addr)) == -1) { if(bind(fd, (struct sockaddr*)&bind_addr, sizeof(bind_addr)) == -1)
RETURN(-1); {
unlock_sockets();
return -1;
} }
} }
if(len > MAX_DATA_SIZE) { if(len > MAX_DATA_SIZE)
RETURN_WSA(WSAEMSGSIZE, -1); {
WSASetLastError(WSAEMSGSIZE);
unlock_sockets();
return -1;
} }
int psize = sizeof(ipx_packet)+len-1; int psize = sizeof(ipx_packet)+len-1;
ipx_packet *packet = malloc(psize); ipx_packet *packet = malloc(psize);
if(!packet) { if(!packet)
RETURN_WSA(ERROR_OUTOFMEMORY, -1); {
WSASetLastError(ERROR_OUTOFMEMORY);
unlock_sockets();
return -1;
} }
packet->ptype = sockptr->s_ptype; packet->ptype = sock->s_ptype;
if(sockptr->flags & IPX_EXT_ADDR) { if(sock->flags & IPX_EXT_ADDR)
if(addrlen >= 15) { {
if(addrlen >= 15)
{
packet->ptype = ipxaddr->sa_ptype; packet->ptype = ipxaddr->sa_ptype;
}else{ }
log_printf(LOG_ERROR, "IPX_EXTENDED_ADDRESS enabled, but sendto() called with addrlen %d", addrlen); else{
log_printf(LOG_DEBUG, "IPX_EXTENDED_ADDRESS enabled, sendto called with addrlen %d", addrlen);
} }
} }
@ -873,13 +961,14 @@ int WSAAPI sendto(SOCKET fd, const char *buf, int len, int flags, const struct s
unsigned char z6[] = {0,0,0,0,0,0}; unsigned char z6[] = {0,0,0,0,0,0};
if(memcmp(packet->dest_net, z6, 4) == 0) { if(memcmp(packet->dest_net, z6, 4) == 0)
memcpy(packet->dest_net, sockptr->addr.sa_netnum, 4); {
memcpy(packet->dest_net, sock->addr.sa_netnum, 4);
} }
memcpy(packet->src_net, sockptr->addr.sa_netnum, 4); memcpy(packet->src_net, sock->addr.sa_netnum, 4);
memcpy(packet->src_node, sockptr->addr.sa_nodenum, 6); memcpy(packet->src_node, sock->addr.sa_nodenum, 6);
packet->src_socket = sockptr->addr.sa_socket; packet->src_socket = sock->addr.sa_socket;
packet->size = htons(len); packet->size = htons(len);
memcpy(packet->data, buf, len); memcpy(packet->data, buf, len);
@ -948,96 +1037,130 @@ int WSAAPI sendto(SOCKET fd, const char *buf, int len, int flags, const struct s
free(packet); free(packet);
RETURN(success ? len : -1); unlock_sockets();
}else{ return (success ? len : -1);
}
else{
return r_sendto(fd, buf, len, flags, addr, addrlen); return r_sendto(fd, buf, len, flags, addr, addrlen);
} }
} }
int PASCAL shutdown(SOCKET fd, int cmd) { int PASCAL shutdown(SOCKET fd, int cmd)
ipx_socket *sockptr = get_socket(fd); {
ipx_socket *sock = get_socket(fd);
if(sockptr) { if(sock)
if(cmd == SD_RECEIVE || cmd == SD_BOTH) { {
sockptr->flags &= ~IPX_RECV; if(cmd == SD_RECEIVE || cmd == SD_BOTH)
{
sock->flags &= ~IPX_RECV;
} }
if(cmd == SD_SEND || cmd == SD_BOTH) { if(cmd == SD_SEND || cmd == SD_BOTH)
sockptr->flags &= ~IPX_SEND; {
sock->flags &= ~IPX_SEND;
} }
RETURN(0); unlock_sockets();
}else{ return 0;
}
else{
return r_shutdown(fd, cmd); return r_shutdown(fd, cmd);
} }
} }
int PASCAL ioctlsocket(SOCKET fd, long cmd, u_long *argp) { int PASCAL ioctlsocket(SOCKET fd, long cmd, u_long *argp)
ipx_socket *sockptr = get_socket(fd); {
ipx_socket *sock = get_socket(fd);
if(sockptr && cmd == FIONREAD) { if(sock)
fd_set fdset; {
struct timeval tv = {0,0};
FD_ZERO(&fdset);
FD_SET(sockptr->fd, &fdset);
int r = select(1, &fdset, NULL, NULL, &tv);
if(r == -1) {
RETURN(-1);
}else if(r == 0) {
*(unsigned long*)argp = 0;
RETURN(0);
}
char tmp_buf;
if((r = recv_packet(sockptr, &tmp_buf, 1, MSG_PEEK, NULL, 0)) == -1) {
return -1;
}
*(unsigned long*)argp = r;
return 0;
}
if(sockptr) {
log_printf(LOG_DEBUG, "ioctlsocket(%d, %d)", fd, cmd); log_printf(LOG_DEBUG, "ioctlsocket(%d, %d)", fd, cmd);
if(cmd == FIONREAD)
{
/* Test to see if data is waiting. */
fd_set fdset;
struct timeval tv = {0,0};
FD_ZERO(&fdset);
FD_SET(sock->fd, &fdset);
int r = select(1, &fdset, NULL, NULL, &tv);
if(r == -1)
{
unlock_sockets();
return -1;
}
else if(r == 0)
{
*(unsigned long*)(argp) = 0;
unlock_sockets();
return -1;
}
/* Get the size of the packet. */
char tmp_buf;
if((r = recv_packet(sock, &tmp_buf, 1, MSG_PEEK, NULL, 0)) == -1)
{
return -1;
}
*(unsigned long*)(argp) = r;
return 0;
}
unlock_sockets(); unlock_sockets();
} }
return r_ioctlsocket(fd, cmd, argp); return r_ioctlsocket(fd, cmd, argp);
} }
int PASCAL connect(SOCKET fd, const struct sockaddr *addr, int addrlen) { int PASCAL connect(SOCKET fd, const struct sockaddr *addr, int addrlen)
ipx_socket *sockptr = get_socket(fd); {
ipx_socket *sock = get_socket(fd);
if(sockptr) { if(sock)
if(addrlen < sizeof(struct sockaddr_ipx)) { {
RETURN_WSA(WSAEFAULT, -1); if(addrlen < sizeof(struct sockaddr_ipx))
{
WSASetLastError(WSAEFAULT);
unlock_sockets();
return -1;
} }
struct sockaddr_ipx *ipxaddr = (struct sockaddr_ipx*)addr; struct sockaddr_ipx *ipxaddr = (struct sockaddr_ipx*)addr;
const unsigned char z6[] = {0,0,0,0,0,0}; const unsigned char z6[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
if(ipxaddr->sa_family == AF_UNSPEC || (ipxaddr->sa_family == AF_IPX && memcmp(ipxaddr->sa_nodenum, z6, 6) == 0)) { if(ipxaddr->sa_family == AF_UNSPEC || (ipxaddr->sa_family == AF_IPX && memcmp(ipxaddr->sa_nodenum, z6, 6) == 0))
if(!(sockptr->flags & IPX_CONNECTED)) { {
RETURN(0); /* Disconnect. */
}
struct sockaddr_ipx dc_addr; sock->flags &= ~IPX_CONNECTED;
dc_addr.sa_family = AF_UNSPEC;
sockptr->flags &= ~IPX_CONNECTED; unlock_sockets();
return 0;
RETURN(0);
} }
if(ipxaddr->sa_family != AF_IPX) { if(ipxaddr->sa_family != AF_IPX)
RETURN_WSA(WSAEAFNOSUPPORT, -1); {
/* Invalid address family. */
WSASetLastError(WSAEAFNOSUPPORT);
unlock_sockets();
return -1;
} }
if(!(sockptr->flags & IPX_BOUND)) { if(!(sock->flags & IPX_BOUND))
{
log_printf(LOG_WARNING, "connect() on unbound socket, attempting implicit bind"); log_printf(LOG_WARNING, "connect() on unbound socket, attempting implicit bind");
struct sockaddr_ipx bind_addr; struct sockaddr_ipx bind_addr;
@ -1047,52 +1170,77 @@ int PASCAL connect(SOCKET fd, const struct sockaddr *addr, int addrlen) {
memset(bind_addr.sa_nodenum, 0, 6); memset(bind_addr.sa_nodenum, 0, 6);
bind_addr.sa_socket = 0; bind_addr.sa_socket = 0;
if(bind(fd, (struct sockaddr*)&bind_addr, sizeof(bind_addr)) == -1) { if(bind(fd, (struct sockaddr*)&bind_addr, sizeof(bind_addr)) == -1)
RETURN(-1); {
unlock_sockets();
return -1;
} }
} }
memcpy(&(sockptr->remote_addr), addr, sizeof(*ipxaddr)); memcpy(&(sock->remote_addr), addr, sizeof(*ipxaddr));
sockptr->flags |= IPX_CONNECTED; sock->flags |= IPX_CONNECTED;
RETURN(0); unlock_sockets();
}else{ return 0;
}
else{
return r_connect(fd, addr, addrlen); return r_connect(fd, addr, addrlen);
} }
} }
int PASCAL send(SOCKET fd, const char *buf, int len, int flags) { int PASCAL send(SOCKET fd, const char *buf, int len, int flags)
ipx_socket *sockptr = get_socket(fd); {
ipx_socket *sock = get_socket(fd);
if(sockptr) { if(sock)
if(!(sockptr->flags & IPX_CONNECTED)) { {
RETURN_WSA(WSAENOTCONN, -1); if(!(sock->flags & IPX_CONNECTED))
{
WSASetLastError(WSAENOTCONN);
unlock_sockets();
return -1;
} }
int ret = sendto(fd, buf, len, 0, (struct sockaddr*)&(sockptr->remote_addr), sizeof(struct sockaddr_ipx)); int ret = sendto(fd, buf, len, 0, (struct sockaddr*)&(sock->remote_addr), sizeof(struct sockaddr_ipx));
RETURN(ret);
}else{ unlock_sockets();
return ret;
}
else{
return r_send(fd, buf, len, flags); return r_send(fd, buf, len, flags);
} }
} }
int PASCAL getpeername(SOCKET fd, struct sockaddr *addr, int *addrlen) { int PASCAL getpeername(SOCKET fd, struct sockaddr *addr, int *addrlen)
ipx_socket *sockptr = get_socket(fd); {
ipx_socket *sock = get_socket(fd);
if(sockptr) { if(sock)
if(!(sockptr->flags & IPX_CONNECTED)) { {
RETURN_WSA(WSAENOTCONN, -1); if(!(sock->flags & IPX_CONNECTED))
{
WSASetLastError(WSAENOTCONN);
unlock_sockets();
return -1;
} }
if(*addrlen < sizeof(struct sockaddr_ipx)) { if(*addrlen < sizeof(struct sockaddr_ipx))
RETURN_WSA(WSAEFAULT, -1); {
WSASetLastError(WSAEFAULT);
unlock_sockets();
return -1;
} }
memcpy(addr, &(sockptr->remote_addr), sizeof(struct sockaddr_ipx)); memcpy(addr, &(sock->remote_addr), sizeof(struct sockaddr_ipx));
*addrlen = sizeof(struct sockaddr_ipx); *addrlen = sizeof(struct sockaddr_ipx);
RETURN(0); unlock_sockets();
}else{ return 0;
}
else{
return r_getpeername(fd, addr, addrlen); return r_getpeername(fd, addr, addrlen);
} }
} }