2008-01-28 21:37:16 +00:00
|
|
|
/* source: xio-ip4.c */
|
2008-08-17 21:28:11 +00:00
|
|
|
/* Copyright Gerhard Rieger 2001-2008 */
|
2008-01-27 12:00:08 +00:00
|
|
|
/* Published under the GNU General Public License V.2, see file COPYING */
|
|
|
|
|
|
|
|
/* this file contains the source for IP4 related functions */
|
|
|
|
|
|
|
|
#include "xiosysincludes.h"
|
|
|
|
|
|
|
|
#if WITH_IP4
|
|
|
|
|
|
|
|
#include "xioopen.h"
|
|
|
|
#include "xio-socket.h"
|
|
|
|
#include "xio-ip.h"
|
|
|
|
#include "xio-ip4.h"
|
|
|
|
|
2008-08-17 21:28:11 +00:00
|
|
|
|
|
|
|
int xioparsenetwork_ip4(const char *rangename, struct xiorange *range) {
|
|
|
|
struct hostent *maskaddr;
|
|
|
|
struct in_addr *netaddr_in = &range->netaddr.ip4.sin_addr;
|
|
|
|
struct in_addr *netmask_in = &range->netmask.ip4.sin_addr;
|
|
|
|
char *rangename1; /* a copy of rangename with writing allowed */
|
|
|
|
char *delimpos; /* absolute address of delimiter */
|
|
|
|
int bits;
|
|
|
|
|
|
|
|
if ((rangename1 = strdup(rangename)) == NULL) {
|
|
|
|
Error1("strdup(\"%s\"): out of memory", rangename);
|
|
|
|
return STAT_RETRYLATER;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (delimpos = strchr(rangename1, '/')) {
|
|
|
|
bits = strtoul(delimpos+1, NULL, 10);
|
|
|
|
netmask_in->s_addr = htonl((0xffffffff << (32-bits)));
|
|
|
|
} else if (delimpos = strchr(rangename1, ':')) {
|
|
|
|
if ((maskaddr = Gethostbyname(delimpos+1)) == NULL) {
|
|
|
|
Error2("gethostbyname(\"%s\"): %s", delimpos+1,
|
|
|
|
h_errno == NETDB_INTERNAL ? strerror(errno) :
|
|
|
|
hstrerror(h_errno));
|
|
|
|
return STAT_NORETRY;
|
|
|
|
}
|
|
|
|
netmask_in->s_addr = *(uint32_t *)maskaddr->h_addr_list[0];
|
|
|
|
} else {
|
|
|
|
Error1("xioparsenetwork_ip4(\"%s\",,): missing netmask delimiter", rangename);
|
|
|
|
free(rangename1);
|
|
|
|
return STAT_NORETRY;
|
|
|
|
}
|
|
|
|
{
|
|
|
|
struct hostent *nameaddr;
|
|
|
|
*delimpos = 0;
|
|
|
|
if ((nameaddr = Gethostbyname(rangename1)) == NULL) {
|
|
|
|
Error2("gethostbyname(\"%s\"): %s", rangename1,
|
|
|
|
h_errno == NETDB_INTERNAL ? strerror(errno) :
|
|
|
|
hstrerror(h_errno));
|
|
|
|
free(rangename1);
|
|
|
|
return STAT_NORETRY;
|
|
|
|
}
|
|
|
|
netaddr_in->s_addr = *(unsigned long *)nameaddr->h_addr_list[0];
|
|
|
|
}
|
|
|
|
free(rangename1);
|
|
|
|
return STAT_OK;
|
|
|
|
}
|
|
|
|
|
2008-01-27 12:00:08 +00:00
|
|
|
/* check if peer address is within permitted range.
|
|
|
|
return >= 0 if so. */
|
2008-08-17 21:28:11 +00:00
|
|
|
int xiocheckrange_ip4(struct sockaddr_in *pa, struct xiorange *range) {
|
|
|
|
struct in_addr *netaddr_in = &range->netaddr.ip4.sin_addr;
|
|
|
|
struct in_addr *netmask_in = &range->netmask.ip4.sin_addr;
|
2008-01-27 12:00:08 +00:00
|
|
|
char addrbuf[256], maskbuf[256];
|
|
|
|
char peername[256];
|
|
|
|
|
|
|
|
/* is provided client address valid? */
|
|
|
|
if (pa->sin_addr.s_addr == 0) {
|
|
|
|
Warn("invalid client address 0.0.0.0");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
/* client address restriction */
|
|
|
|
Debug2("permitted client subnet: %s:%s",
|
|
|
|
inet4addr_info(ntohl(netaddr_in->s_addr), addrbuf, sizeof(addrbuf)),
|
|
|
|
inet4addr_info(ntohl(netmask_in->s_addr), maskbuf, sizeof(maskbuf)));
|
|
|
|
Debug1("client address is 0x%08x",
|
|
|
|
ntohl(pa->sin_addr.s_addr));
|
|
|
|
Debug1("masked address is 0x%08x",
|
|
|
|
ntohl(pa->sin_addr.s_addr & netmask_in->s_addr));
|
|
|
|
if ((pa->sin_addr.s_addr & netmask_in->s_addr)
|
|
|
|
!= netaddr_in->s_addr) {
|
|
|
|
Debug1("client address %s is not permitted",
|
|
|
|
sockaddr_inet4_info(pa, peername, sizeof(peername)));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* WITH_IP4 */
|