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

Store zero or more IPs in ipx_interface structures rather than one.

This commit is contained in:
Daniel Collins 2012-11-02 20:45:10 +00:00
parent 7fe8d74f22
commit bee68d52b9
5 changed files with 117 additions and 33 deletions

View File

@ -17,6 +17,7 @@
#include <windows.h> #include <windows.h>
#include <iphlpapi.h> #include <iphlpapi.h>
#include <utlist.h>
#include "interface.h" #include "interface.h"
#include "common.h" #include "common.h"
@ -92,23 +93,55 @@ ipx_interface_t *get_interfaces(int ifnum)
continue; continue;
} }
struct ipx_interface *nnic = malloc(sizeof(struct ipx_interface)); ipx_interface_t *iface = malloc(sizeof(ipx_interface_t));
if(!nnic) if(!iface)
{ {
log_printf(LOG_ERROR, "Couldn't allocate ipx_interface!"); log_printf(LOG_ERROR, "Couldn't allocate ipx_interface!");
free_interfaces(nics); free_ipx_interfaces(&nics);
return NULL; return NULL;
} }
nnic->ipaddr = inet_addr(ifptr->IpAddressList.IpAddress.String); iface->ipaddr = NULL;
nnic->netmask = inet_addr(ifptr->IpAddressList.IpMask.String);
nnic->bcast = nnic->ipaddr | ~nnic->netmask;
nnic->hwaddr = hwaddr; IP_ADDR_STRING *ip_ptr = &(ifptr->IpAddressList);
nnic->ipx_net = config.netnum; for(; ip_ptr; ip_ptr = ip_ptr->Next)
nnic->ipx_node = config.nodenum; {
uint32_t ipaddr = inet_addr(ip_ptr->IpAddress.String);
uint32_t netmask = inet_addr(ip_ptr->IpMask.String);
if(ipaddr == 0)
{
/* No IP address.
* Because an empty linked list would be silly.
*/
continue;
}
ipx_interface_ip_t *addr = malloc(sizeof(ipx_interface_ip_t));
if(!addr)
{
log_printf(LOG_ERROR, "Couldn't allocate ipx_interface_ip!");
free_ipx_interface(iface);
free_ipx_interfaces(&nics);
continue;
}
addr->ipaddr = ipaddr;
addr->netmask = netmask;
addr->bcast = ipaddr | (~netmask);
DL_APPEND(iface->ipaddr, addr);
}
iface->hwaddr = hwaddr;
iface->ipx_net = config.netnum;
iface->ipx_node = config.nodenum;
/* Workaround for buggy versions of Hamachi that don't initialise /* Workaround for buggy versions of Hamachi that don't initialise
* the interface hardware address correctly. * the interface hardware address correctly.
@ -116,27 +149,31 @@ ipx_interface_t *get_interfaces(int ifnum)
unsigned char hamachi_bug[] = {0x7A, 0x79, 0x00, 0x00, 0x00, 0x00}; unsigned char hamachi_bug[] = {0x7A, 0x79, 0x00, 0x00, 0x00, 0x00};
if(nnic->ipx_node == addr48_in(hamachi_bug)) if(iface->ipx_node == addr48_in(hamachi_bug) && iface->ipaddr)
{ {
log_printf(LOG_WARNING, "Invalid Hamachi interface detected, correcting node number"); log_printf(LOG_WARNING, "Invalid Hamachi interface detected, correcting node number");
addr32_out(hamachi_bug + 2, nnic->ipaddr); addr32_out(hamachi_bug + 2, iface->ipaddr->ipaddr);
nnic->ipx_node = addr48_in(hamachi_bug); iface->ipx_node = addr48_in(hamachi_bug);
} }
if(nnic->hwaddr == primary) if(iface->hwaddr == primary)
{ {
/* Primary interface, insert at the start of the list */ /* Primary interface, insert at the start of the list */
DL_PREPEND(nics, nnic); DL_PREPEND(nics, iface);
} }
else{ else{
DL_APPEND(nics, nnic); DL_APPEND(nics, iface);
} }
} }
free(ifroot); free(ifroot);
/* Delete every entry in the NIC list except the requested one */ /* Delete every entry in the NIC list except the requested one.
*
* This is done here rather than when building the list as the primary
* interface may change the indexes if it isn't the first.
*/
if(ifnum >= 0) if(ifnum >= 0)
{ {
@ -148,7 +185,7 @@ ipx_interface_t *get_interfaces(int ifnum)
if(this_ifnum++ != ifnum) if(this_ifnum++ != ifnum)
{ {
DL_DELETE(nics, iface); DL_DELETE(nics, iface);
free(iface); free_ipx_interface(iface);
} }
} }
} }
@ -156,13 +193,28 @@ ipx_interface_t *get_interfaces(int ifnum)
return nics; return nics;
} }
void free_interfaces(ipx_interface_t *list) /* Free an ipx_interface structure and any memory allocated within. */
void free_ipx_interface(ipx_interface_t *iface)
{
ipx_interface_ip_t *a, *a_tmp;
DL_FOREACH_SAFE(iface->ipaddr, a, a_tmp)
{
DL_DELETE(iface->ipaddr, a);
free(a);
}
free(iface);
}
/* Free a list of ipx_interface structures */
void free_ipx_interfaces(ipx_interface_t **list)
{ {
ipx_interface_t *iface, *tmp; ipx_interface_t *iface, *tmp;
DL_FOREACH_SAFE(list, iface, tmp) DL_FOREACH_SAFE(*list, iface, tmp)
{ {
DL_DELETE(list, iface); DL_DELETE(*list, iface);
free(iface); free_ipx_interface(iface);
} }
} }

View File

@ -23,23 +23,44 @@
#include "common.h" #include "common.h"
typedef struct ipx_interface ipx_interface_t; #ifdef __cplusplus
extern "C" {
#endif
struct ipx_interface { typedef struct ipx_interface_ip ipx_interface_ip_t;
struct ipx_interface_ip {
uint32_t ipaddr; uint32_t ipaddr;
uint32_t netmask; uint32_t netmask;
uint32_t bcast; uint32_t bcast;
ipx_interface_ip_t *prev;
ipx_interface_ip_t *next;
};
typedef struct ipx_interface ipx_interface_t;
struct ipx_interface {
addr48_t hwaddr; addr48_t hwaddr;
addr32_t ipx_net; addr32_t ipx_net;
addr48_t ipx_node; addr48_t ipx_node;
ipx_interface_ip_t *ipaddr;
ipx_interface_t *prev; ipx_interface_t *prev;
ipx_interface_t *next; ipx_interface_t *next;
}; };
IP_ADAPTER_INFO *get_sys_interfaces(void);
ipx_interface_t *get_interfaces(int ifnum); ipx_interface_t *get_interfaces(int ifnum);
void free_interfaces(ipx_interface_t *iface);
void free_ipx_interface(ipx_interface_t *iface);
void free_ipx_interfaces(ipx_interface_t **list);
#ifdef __cplusplus
}
#endif
#endif /* !IPXWRAPPER_INTERFACE_H */ #endif /* !IPXWRAPPER_INTERFACE_H */

View File

@ -196,20 +196,26 @@ BOOL ip_is_local(uint32_t ipaddr) {
struct ipx_interface *i = ifaces; struct ipx_interface *i = ifaces;
while(i) { while(i) {
/* TODO: Rewrite. */
if(!i->ipaddr)
{
continue;
}
struct ipaddr_list *nn = malloc(sizeof(struct ipaddr_list)); struct ipaddr_list *nn = malloc(sizeof(struct ipaddr_list));
if(!nn) { if(!nn) {
log_printf(LOG_ERROR, "Out of memory! Can't allocate ipaddr_list structure!"); log_printf(LOG_ERROR, "Out of memory! Can't allocate ipaddr_list structure!");
break; break;
} }
nn->ipaddr = i->ipaddr; nn->ipaddr = i->ipaddr->ipaddr;
nn->next = local_addrs; nn->next = local_addrs;
local_addrs = nn; local_addrs = nn;
i = i->next; i = i->next;
} }
free_interfaces(ifaces); free_ipx_interfaces(&ifaces);
local_updated = time(NULL); local_updated = time(NULL);
} }

View File

@ -345,6 +345,9 @@ static int router_bind(struct router_vars *router, SOCKET control, SOCKET sock,
if( if(
(sa_netnum == iface->ipx_net || sa_netnum == 0) (sa_netnum == iface->ipx_net || sa_netnum == 0)
&& (sa_nodenum == iface->ipx_node || sa_nodenum == 0) && (sa_nodenum == iface->ipx_node || sa_nodenum == 0)
/* TODO: Remove this check. */
&& iface->ipaddr
) { ) {
break; break;
} }
@ -353,7 +356,7 @@ static int router_bind(struct router_vars *router, SOCKET control, SOCKET sock,
if(!iface) { if(!iface) {
log_printf(LOG_ERROR, "bind failed: no such address"); log_printf(LOG_ERROR, "bind failed: no such address");
free_interfaces(ifaces); free_ipx_interfaces(&ifaces);
WSASetLastError(WSAEADDRNOTAVAIL); WSASetLastError(WSAEADDRNOTAVAIL);
return -1; return -1;
@ -362,12 +365,14 @@ static int router_bind(struct router_vars *router, SOCKET control, SOCKET sock,
addr32_out(addr->sa_netnum, iface->ipx_net); addr32_out(addr->sa_netnum, iface->ipx_net);
addr48_out(addr->sa_nodenum, iface->ipx_node); addr48_out(addr->sa_nodenum, iface->ipx_node);
*nic_bcast = iface->bcast; /* TODO: Don't store the IP stuff here. */
uint32_t iface_ipaddr = iface->ipaddr; *nic_bcast = iface->ipaddr->bcast;
uint32_t iface_netmask = iface->netmask;
free_interfaces(ifaces); uint32_t iface_ipaddr = iface->ipaddr->ipaddr;
uint32_t iface_netmask = iface->ipaddr->netmask;
free_ipx_interfaces(&ifaces);
EnterCriticalSection(&(router->crit_sec)); EnterCriticalSection(&(router->crit_sec));

View File

@ -539,7 +539,7 @@ int WSAAPI getsockopt(SOCKET fd, int level, int optname, char FAR *optval, int F
ipxdata->maxpkt = MAX_DATA_SIZE; ipxdata->maxpkt = MAX_DATA_SIZE;
ipxdata->linkspeed = 100000; /* 10MBps */ ipxdata->linkspeed = 100000; /* 10MBps */
free_interfaces(nic); free_ipx_interface(nic);
RETURN(0); RETURN(0);
} }
@ -561,7 +561,7 @@ int WSAAPI getsockopt(SOCKET fd, int level, int optname, char FAR *optval, int F
nic = nic->next; nic = nic->next;
} }
free_interfaces(ifaces); free_ipx_interfaces(&ifaces);
RETURN(0); RETURN(0);
} }