Reverse DNS for IP networl.mask match
This commit is contained in:
		
							parent
							
								
									39d7bf6c70
								
							
						
					
					
						commit
						187731f80e
					
				
							
								
								
									
										10
									
								
								configure.ac
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								configure.ac
									
									
									
									
									
								
							@ -101,6 +101,16 @@ if test x"$transparent_enabled" = x"yes"; then
 | 
			
		||||
   AC_DEFINE(TRANSPARENT_PROXY)
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
dnl Include support for reverse dns to match IP network/mask ?
 | 
			
		||||
AH_TEMPLATE([RDNS_ENABLE],
 | 
			
		||||
	    [Include support for reverse dns to match IP network/mask.])
 | 
			
		||||
TP_ARG_ENABLE(rdns,
 | 
			
		||||
	      [Enable support for reverse dns to match IP network/mask (default is YES)],
 | 
			
		||||
	      yes)
 | 
			
		||||
if test x"$rdns__enabled" = x"yes"; then
 | 
			
		||||
   AC_DEFINE(RDNS_ENABLE)
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
dnl Let user decide whether he wants support for manpages
 | 
			
		||||
dnl Which require either pod2man or a tarball release
 | 
			
		||||
AH_TEMPLATE([MANPAGE_SUPPORT],
 | 
			
		||||
 | 
			
		||||
@ -2,6 +2,18 @@
 | 
			
		||||
#include "hostspec.h"
 | 
			
		||||
#include "heap.h"
 | 
			
		||||
#include "network.h"
 | 
			
		||||
#ifdef RDNS_ENABLE
 | 
			
		||||
#include "log.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static int dotted_mask(char *bitmask_string, unsigned char array[])
 | 
			
		||||
{
 | 
			
		||||
	unsigned char v4bits[4];
 | 
			
		||||
	if (1 != inet_pton (AF_INET, bitmask_string, v4bits)) return -1;
 | 
			
		||||
	memset (array, 0xff, IPV6_LEN-4);
 | 
			
		||||
	memcpy (array + IPV6_LEN-4, v4bits, 4);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Fills in the netmask array given a numeric value.
 | 
			
		||||
@ -13,13 +25,17 @@
 | 
			
		||||
 */
 | 
			
		||||
static int
 | 
			
		||||
fill_netmask_array (char *bitmask_string, int v6,
 | 
			
		||||
		    unsigned char array[], size_t len)
 | 
			
		||||
		    unsigned char array[])
 | 
			
		||||
{
 | 
			
		||||
	unsigned int i;
 | 
			
		||||
	unsigned long int mask;
 | 
			
		||||
	char *endptr;
 | 
			
		||||
 | 
			
		||||
	errno = 0;              /* to distinguish success/failure after call */
 | 
			
		||||
	if (strchr (bitmask_string, '.')) {
 | 
			
		||||
		if (v6) return -1; /* ipv6 doesn't supported dotted netmasks */
 | 
			
		||||
		return dotted_mask(bitmask_string, array);
 | 
			
		||||
	}
 | 
			
		||||
	mask = strtoul (bitmask_string, &endptr, 10);
 | 
			
		||||
 | 
			
		||||
	/* check for various conversion errors */
 | 
			
		||||
@ -35,11 +51,11 @@ fill_netmask_array (char *bitmask_string, int v6,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* check valid range for a bit mask */
 | 
			
		||||
	if (mask > (8 * len))
 | 
			
		||||
	if (mask > (8 * IPV6_LEN))
 | 
			
		||||
		return -1;
 | 
			
		||||
 | 
			
		||||
	/* we have a valid range to fill in the array */
 | 
			
		||||
	for (i = 0; i != len; ++i) {
 | 
			
		||||
	for (i = 0; i != IPV6_LEN; ++i) {
 | 
			
		||||
		if (mask >= 8) {
 | 
			
		||||
			array[i] = 0xff;
 | 
			
		||||
			mask -= 8;
 | 
			
		||||
@ -88,7 +104,7 @@ int hostspec_parse(char *location, struct hostspec *h) {
 | 
			
		||||
				v6 = 0;
 | 
			
		||||
 | 
			
		||||
			if (fill_netmask_array
 | 
			
		||||
			    (mask, v6, &(h->address.ip.mask[0]), IPV6_LEN)
 | 
			
		||||
			    (mask, v6, &(h->address.ip.mask[0]))
 | 
			
		||||
			     < 0)
 | 
			
		||||
				goto err;
 | 
			
		||||
 | 
			
		||||
@ -146,6 +162,42 @@ static int numeric_match(const uint8_t addr[], const struct hostspec *h)
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef RDNS_ENABLE
 | 
			
		||||
static int reverse_dns_numeric_match(const char *ip, const struct hostspec *h)
 | 
			
		||||
{
 | 
			
		||||
	int ret;
 | 
			
		||||
	struct addrinfo *res, *ressave;
 | 
			
		||||
	uint8_t numeric_addr[IPV6_LEN];
 | 
			
		||||
	char ipbuf[512];
 | 
			
		||||
 | 
			
		||||
	errno = 0;
 | 
			
		||||
 | 
			
		||||
        ret =getaddrinfo (ip, NULL, NULL, &res);
 | 
			
		||||
 | 
			
		||||
	ressave = res; 
 | 
			
		||||
 | 
			
		||||
        if (ret != 0) {
 | 
			
		||||
		if (ret == EAI_SYSTEM)
 | 
			
		||||
			log_message (LOG_ERR, "Could not retrieve address info for %s : %s",ip,strerror(errno));
 | 
			
		||||
		else
 | 
			
		||||
			log_message (LOG_ERR, "Could not retrieve address info for %s : %s",ip,gai_strerror(errno));
 | 
			
		||||
	} else {
 | 
			
		||||
		do {
 | 
			
		||||
			/* return if IP matches */
 | 
			
		||||
			get_ip_string (res->ai_addr, ipbuf, sizeof (ipbuf));
 | 
			
		||||
			full_inet_pton (ipbuf, &numeric_addr);
 | 
			
		||||
			if (numeric_match (numeric_addr, h)) {
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		} while ((res = res->ai_next) != NULL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	freeaddrinfo (ressave);
 | 
			
		||||
 | 
			
		||||
	return numeric_match (numeric_addr, h);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* check whether ip matches hostspec.
 | 
			
		||||
   return 1 on match, 0 on non-match */
 | 
			
		||||
int hostspec_match(const char *ip, const struct hostspec *h) {
 | 
			
		||||
@ -158,6 +210,9 @@ int hostspec_match(const char *ip, const struct hostspec *h) {
 | 
			
		||||
		if(is_numeric_addr) return 0;
 | 
			
		||||
		return string_match (ip, h->address.string);
 | 
			
		||||
	case HST_NUMERIC:
 | 
			
		||||
#ifdef RDNS_ENABLE
 | 
			
		||||
		if(!is_numeric_addr) return reverse_dns_numeric_match(ip, h);
 | 
			
		||||
#endif
 | 
			
		||||
		return numeric_match (numeric_addr, h);
 | 
			
		||||
	case HST_NONE:
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user