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:
parent
7fe8d74f22
commit
bee68d52b9
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 */
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
15
src/router.c
15
src/router.c
@ -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));
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user