1
0
mirror of https://github.com/moparisthebest/socat synced 2024-12-22 06:58:47 -05:00
socat/xio-ip4.c
2008-09-20 17:17:27 +02:00

93 lines
2.9 KiB
C

/* source: xio-ip4.c */
/* Copyright Gerhard Rieger 2001-2008 */
/* 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"
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;
}
/* check if peer address is within permitted range.
return >= 0 if so. */
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;
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 */