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 <iphlpapi.h>
#include <utlist.h>
#include "interface.h"
#include "common.h"
@ -92,23 +93,55 @@ ipx_interface_t *get_interfaces(int ifnum)
continue;
}
struct ipx_interface *nnic = malloc(sizeof(struct ipx_interface));
if(!nnic)
ipx_interface_t *iface = malloc(sizeof(ipx_interface_t));
if(!iface)
{
log_printf(LOG_ERROR, "Couldn't allocate ipx_interface!");
free_interfaces(nics);
free_ipx_interfaces(&nics);
return NULL;
}
nnic->ipaddr = inet_addr(ifptr->IpAddressList.IpAddress.String);
nnic->netmask = inet_addr(ifptr->IpAddressList.IpMask.String);
nnic->bcast = nnic->ipaddr | ~nnic->netmask;
iface->ipaddr = NULL;
nnic->hwaddr = hwaddr;
IP_ADDR_STRING *ip_ptr = &(ifptr->IpAddressList);
nnic->ipx_net = config.netnum;
nnic->ipx_node = config.nodenum;
for(; ip_ptr; ip_ptr = ip_ptr->Next)
{
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
* 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};
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");
addr32_out(hamachi_bug + 2, nnic->ipaddr);
nnic->ipx_node = addr48_in(hamachi_bug);
addr32_out(hamachi_bug + 2, iface->ipaddr->ipaddr);
iface->ipx_node = addr48_in(hamachi_bug);
}
if(nnic->hwaddr == primary)
if(iface->hwaddr == primary)
{
/* Primary interface, insert at the start of the list */
DL_PREPEND(nics, nnic);
DL_PREPEND(nics, iface);
}
else{
DL_APPEND(nics, nnic);
DL_APPEND(nics, iface);
}
}
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)
{
@ -148,7 +185,7 @@ ipx_interface_t *get_interfaces(int ifnum)
if(this_ifnum++ != ifnum)
{
DL_DELETE(nics, iface);
free(iface);
free_ipx_interface(iface);
}
}
}
@ -156,13 +193,28 @@ ipx_interface_t *get_interfaces(int ifnum)
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;
DL_FOREACH_SAFE(list, iface, tmp)
DL_FOREACH_SAFE(*list, iface, tmp)
{
DL_DELETE(list, iface);
free(iface);
DL_DELETE(*list, iface);
free_ipx_interface(iface);
}
}

View File

@ -23,23 +23,44 @@
#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 netmask;
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;
addr32_t ipx_net;
addr48_t ipx_node;
ipx_interface_ip_t *ipaddr;
ipx_interface_t *prev;
ipx_interface_t *next;
};
IP_ADAPTER_INFO *get_sys_interfaces(void);
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 */

View File

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

View File

@ -345,6 +345,9 @@ static int router_bind(struct router_vars *router, SOCKET control, SOCKET sock,
if(
(sa_netnum == iface->ipx_net || sa_netnum == 0)
&& (sa_nodenum == iface->ipx_node || sa_nodenum == 0)
/* TODO: Remove this check. */
&& iface->ipaddr
) {
break;
}
@ -353,7 +356,7 @@ static int router_bind(struct router_vars *router, SOCKET control, SOCKET sock,
if(!iface) {
log_printf(LOG_ERROR, "bind failed: no such address");
free_interfaces(ifaces);
free_ipx_interfaces(&ifaces);
WSASetLastError(WSAEADDRNOTAVAIL);
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);
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;
uint32_t iface_netmask = iface->netmask;
*nic_bcast = iface->ipaddr->bcast;
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));

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