mirror of
https://github.com/solemnwarning/ipxwrapper
synced 2024-12-30 16:45:37 +01:00
Implemented connect function.
This commit is contained in:
parent
18fda2a86c
commit
390663ba83
@ -15,3 +15,4 @@ EXPORTS
|
||||
WSARecvEx
|
||||
ioctlsocket
|
||||
WSHEnumProtocols
|
||||
connect
|
||||
|
@ -39,6 +39,7 @@
|
||||
#define IPX_SEND (int)(1<<3)
|
||||
#define IPX_RECV (int)(1<<4)
|
||||
#define IPX_REUSE (int)(1<<6)
|
||||
#define IPX_CONNECTED (int)(1<<7)
|
||||
|
||||
#define RETURN(...) \
|
||||
unlock_sockets();\
|
||||
@ -64,11 +65,8 @@ struct ipx_socket {
|
||||
struct sockaddr_ipx addr;
|
||||
uint32_t nic_bcast;
|
||||
|
||||
/* Extra bind address, only used for receiving packets.
|
||||
* Only defined when IPX_EX_BOUND is set.
|
||||
*/
|
||||
struct ipx_interface *ex_nic;
|
||||
uint16_t ex_socket;
|
||||
/* Address used with connect call, only set when IPX_CONNECTED is */
|
||||
struct sockaddr_ipx remote_addr;
|
||||
|
||||
ipx_socket *next;
|
||||
};
|
||||
@ -131,5 +129,6 @@ int WSAAPI r_setsockopt(SOCKET,int,int,const char*,int);
|
||||
int WSAAPI r_shutdown(SOCKET,int);
|
||||
SOCKET WSAAPI r_socket(int,int,int);
|
||||
int PASCAL r_ioctlsocket(SOCKET fd, long cmd, u_long *argp);
|
||||
int PASCAL r_connect(SOCKET fd, const struct sockaddr *addr, int addrlen);
|
||||
|
||||
#endif /* !IPXWRAPPER_H */
|
||||
|
@ -31,3 +31,4 @@ r_setsockopt:4
|
||||
r_shutdown:4
|
||||
r_socket:4
|
||||
r_ioctlsocket:4
|
||||
r_connect:4
|
||||
|
46
src/router.c
46
src/router.c
@ -297,7 +297,10 @@ DWORD router_main(void *arg) {
|
||||
packet->dest_socket == ra->addr.sa_socket &&
|
||||
|
||||
/* Check source IP is within correct subnet */
|
||||
((ra->ipaddr & ra->netmask) == (addr.sin_addr.s_addr & ra->netmask) || !global_conf.filter)
|
||||
((ra->ipaddr & ra->netmask) == (addr.sin_addr.s_addr & ra->netmask) || !global_conf.filter) &&
|
||||
|
||||
/* Check source address matches remote_addr if set */
|
||||
(ra->remote_addr.sa_family == AF_UNSPEC || (memcmp(ra->remote_addr.sa_netnum, packet->src_net, 4) == 0 && memcmp(ra->remote_addr.sa_nodenum, packet->src_node, 6) == 0))
|
||||
) {
|
||||
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
|
||||
addr.sin_port = ra->local_port;
|
||||
@ -538,6 +541,18 @@ static int router_set_reuse(struct router_vars *router, SOCKET control, SOCKET s
|
||||
return 1;
|
||||
}
|
||||
|
||||
static BOOL router_set_remote(struct router_vars *router, SOCKET control, SOCKET sock, const struct sockaddr_ipx *addr) {
|
||||
EnterCriticalSection(&(router->crit_sec));
|
||||
|
||||
struct router_addr *ra = router_get(router, control, sock);
|
||||
if(ra) {
|
||||
ra->remote_addr = *addr;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&(router->crit_sec));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL router_handle_call(struct router_vars *router, int sock, struct router_call *call) {
|
||||
struct router_ret ret;
|
||||
|
||||
@ -577,6 +592,11 @@ static BOOL router_handle_call(struct router_vars *router, int sock, struct rout
|
||||
break;
|
||||
}
|
||||
|
||||
case rc_remote: {
|
||||
router_set_remote(router, sock, call->sock, &(call->arg_addr));
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
log_printf("Recieved unknown call, dropping client");
|
||||
return FALSE;
|
||||
@ -893,3 +913,27 @@ BOOL rclient_set_reuse(struct rclient *rclient, SOCKET sock, BOOL reuse) {
|
||||
WSASetLastError(WSAENETDOWN);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL rclient_set_remote(struct rclient *rclient, SOCKET sock, const struct sockaddr_ipx *addr) {
|
||||
if(rclient->sock != -1) {
|
||||
struct router_call call;
|
||||
struct router_ret ret;
|
||||
|
||||
call.call = rc_remote;
|
||||
call.sock = sock;
|
||||
call.arg_addr = *addr;
|
||||
|
||||
if(!rclient_do(rclient, &call, &ret)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}else if(rclient->router) {
|
||||
return router_set_remote(rclient->router, 0, sock, addr);
|
||||
}
|
||||
|
||||
log_printf("rclient_bind: No router?!");
|
||||
|
||||
WSASetLastError(WSAENETDOWN);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -31,7 +31,8 @@ struct router_call {
|
||||
rc_unbind,
|
||||
rc_port,
|
||||
rc_filter,
|
||||
rc_reuse
|
||||
rc_reuse,
|
||||
rc_remote
|
||||
} call;
|
||||
|
||||
SOCKET sock;
|
||||
@ -61,6 +62,9 @@ struct router_addr {
|
||||
uint32_t ipaddr;
|
||||
uint32_t netmask;
|
||||
|
||||
/* Only accept packets from this address (any if AF_UNSPEC) */
|
||||
struct sockaddr_ipx remote_addr;
|
||||
|
||||
struct router_addr *next;
|
||||
};
|
||||
|
||||
@ -114,5 +118,6 @@ BOOL rclient_unbind(struct rclient *rclient, SOCKET sock);
|
||||
BOOL rclient_set_port(struct rclient *rclient, SOCKET sock, uint16_t port);
|
||||
BOOL rclient_set_filter(struct rclient *rclient, SOCKET sock, int ptype);
|
||||
BOOL rclient_set_reuse(struct rclient *rclient, SOCKET sock, BOOL reuse);
|
||||
BOOL rclient_set_remote(struct rclient *rclient, SOCKET sock, const struct sockaddr_ipx *addr);
|
||||
|
||||
#endif /* !IPXWRAPPER_ROUTER_H */
|
||||
|
@ -741,3 +741,64 @@ int PASCAL ioctlsocket(SOCKET fd, long cmd, u_long *argp) {
|
||||
|
||||
return r_ioctlsocket(fd, cmd, argp);
|
||||
}
|
||||
|
||||
int PASCAL connect(SOCKET fd, const struct sockaddr *addr, int addrlen) {
|
||||
ipx_socket *sockptr = get_socket(fd);
|
||||
|
||||
if(sockptr) {
|
||||
if(addrlen < sizeof(struct sockaddr_ipx)) {
|
||||
RETURN_WSA(WSAEFAULT, -1);
|
||||
}
|
||||
|
||||
struct sockaddr_ipx *ipxaddr = (struct sockaddr_ipx*)addr;
|
||||
|
||||
const unsigned char z6[] = {0,0,0,0,0,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);
|
||||
}
|
||||
|
||||
struct sockaddr_ipx dc_addr;
|
||||
dc_addr.sa_family = AF_UNSPEC;
|
||||
|
||||
if(!rclient_set_remote(&g_rclient, fd, &dc_addr)) {
|
||||
RETURN(-1);
|
||||
}
|
||||
|
||||
sockptr->flags &= ~IPX_CONNECTED;
|
||||
|
||||
RETURN(0);
|
||||
}
|
||||
|
||||
if(ipxaddr->sa_family != AF_IPX) {
|
||||
RETURN_WSA(WSAEAFNOSUPPORT, -1);
|
||||
}
|
||||
|
||||
if(!(sockptr->flags & IPX_BOUND)) {
|
||||
log_printf("connect() on unbound socket, attempting implicit bind");
|
||||
|
||||
struct sockaddr_ipx bind_addr;
|
||||
|
||||
bind_addr.sa_family = AF_IPX;
|
||||
memcpy(bind_addr.sa_netnum, ipxaddr->sa_netnum, 4);
|
||||
memset(bind_addr.sa_nodenum, 0, 6);
|
||||
bind_addr.sa_socket = 0;
|
||||
|
||||
if(bind(fd, (struct sockaddr*)&bind_addr, sizeof(bind_addr)) == -1) {
|
||||
RETURN(-1);
|
||||
}
|
||||
}
|
||||
|
||||
if(!rclient_set_remote(&g_rclient, fd, ipxaddr)) {
|
||||
RETURN(-1);
|
||||
}
|
||||
|
||||
memcpy(&(sockptr->remote_addr), addr, sizeof(*ipxaddr));
|
||||
sockptr->flags |= IPX_CONNECTED;
|
||||
|
||||
RETURN(0);
|
||||
}else{
|
||||
return r_connect(fd, addr, addrlen);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
accept
|
||||
bind:0
|
||||
closesocket:0
|
||||
connect
|
||||
connect:0
|
||||
getpeername
|
||||
getsockname:0
|
||||
getsockopt:0
|
||||
|
Loading…
x
Reference in New Issue
Block a user