diff options
Diffstat (limited to 'accel-pptpd/iprange.c')
-rw-r--r-- | accel-pptpd/iprange.c | 58 |
1 files changed, 35 insertions, 23 deletions
diff --git a/accel-pptpd/iprange.c b/accel-pptpd/iprange.c index 0b1997e9..e55a5c4e 100644 --- a/accel-pptpd/iprange.c +++ b/accel-pptpd/iprange.c @@ -2,9 +2,11 @@ #include <stdio.h> #include <stdint.h> #include <unistd.h> +#include <string.h> #include "triton.h" #include "list.h" +#include "log.h" #include "iprange.h" @@ -13,11 +15,12 @@ struct iprange_t { struct list_head entry; - uint32_t prefix; - uint32_t mask; + uint32_t begin; uint32_t end; }; +static int conf_disable = 0; + static LIST_HEAD(client_ranges); //static LIST_HEAD(tunnel_ranges); @@ -26,27 +29,30 @@ static struct iprange_t *parse1(const char *str) { int n,f1,f2,f3,f4,m; struct iprange_t *r; + int mask; n = sscanf(str, "%u.%u.%u.%u/%u",&f1, &f2, &f3, &f4, &m); if (n != 5) return NULL; if (f1 > 255) return NULL; - if (f1 > 255) + if (f2 > 255) return NULL; - if (f1 > 255) + if (f3 > 255) return NULL; - if (f1 > 255) + if (f4 > 255) return NULL; if (m == 0 || m > 32) return NULL; r = _malloc(sizeof(*r)); - r->prefix = (f4 << 24) | (f3 << 16) | (f2 << 8) | f1; - r->mask = 0; + r->begin = (f4 << 24) | (f3 << 16) | (f2 << 8) | f1; + mask = 0; for (n = 0; n < m ; n++) - r->mask |= 1 << n; + mask |= 1 << n; + r->end = ntohl(r->begin | ~mask); + r->begin = ntohl(r->begin); return r; } @@ -72,9 +78,8 @@ static struct iprange_t *parse2(const char *str) return NULL; r = _malloc(sizeof(*r)); - r->prefix = (f4 << 24) | (f3 << 16) | (f2 << 8) | f1; - r->end = (m << 24) | (f3 << 16) | (f2 << 8) | f1; - r->mask = 0; + r->begin = ntohl((f4 << 24) | (f3 << 16) | (f2 << 8) | f1); + r->end = ntohl((m << 24) | (f3 << 16) | (f2 << 8) | f1); return r; } @@ -86,16 +91,21 @@ static void load_ranges(struct list_head *list, const char *conf_sect) struct iprange_t *r; if (!s) { - fprintf(stderr, "iprange: section '%s' not found in config file, pptp and l2tp probably will not work...\n", conf_sect); + log_emerg("iprange: section '%s' not found in config file, pptp and l2tp probably will not work...\n", conf_sect); return; } list_for_each_entry(opt, &s->items, entry) { + if (!strcmp(opt->name, "disable")) { + conf_disable = 1; + log_emerg("iprange: iprange module disabled so improper ip address assigning may cause kernel soft lockup!\n"); + continue; + } r = parse1(opt->name); if (!r) r = parse2(opt->name); if (!r) { - fprintf(stderr, "iprange: cann't parse '%s' in '%s'\n", opt->name, conf_sect); + log_emerg("iprange: cann't parse '%s' in '%s'\n", opt->name, conf_sect); _exit(EXIT_FAILURE); } list_add_tail(&r->entry, list); @@ -105,15 +115,11 @@ static void load_ranges(struct list_head *list, const char *conf_sect) static int check_range(struct list_head *list, in_addr_t ipaddr) { struct iprange_t *r; + uint32_t a = ntohl(ipaddr); list_for_each_entry(r, list, entry) { - if (r->mask) { - if ((r->prefix & r->mask) == (ipaddr & r->mask)) - return 0; - } else { - if (ipaddr >= r->prefix && ipaddr <= r->end) - return 0; - } + if (a >= r->begin && a <= r->end) + return 0; } return -1; @@ -121,12 +127,18 @@ static int check_range(struct list_head *list, in_addr_t ipaddr) int __export iprange_client_check(in_addr_t ipaddr) { + if (conf_disable) + return 0; + return check_range(&client_ranges, ipaddr); } -/*int __export iprange_tunnel_check(in_addr_t ipaddr) +int __export iprange_tunnel_check(in_addr_t ipaddr) { - return check_range(&tunnel_ranges, ipaddr); -}*/ + if (conf_disable) + return 0; + + return !check_range(&client_ranges, ipaddr); +} static void __init iprange_init(void) { |