diff options
Diffstat (limited to 'accel-pptpd')
-rw-r--r-- | accel-pptpd/extra/ippool.c | 6 | ||||
-rw-r--r-- | accel-pptpd/iprange.c | 58 | ||||
-rw-r--r-- | accel-pptpd/ppp/ipcp_opt_ipaddr.c | 4 |
3 files changed, 40 insertions, 28 deletions
diff --git a/accel-pptpd/extra/ippool.c b/accel-pptpd/extra/ippool.c index 5f90fe8a..6136a14d 100644 --- a/accel-pptpd/extra/ippool.c +++ b/accel-pptpd/extra/ippool.c @@ -50,11 +50,11 @@ static int parse1(const char *str, uint32_t *begin, uint32_t *end) return -1; if (f1 > 255) return -1; - if (f1 > 255) + if (f2 > 255) return -1; - if (f1 > 255) + if (f3 > 255) return -1; - if (f1 > 255) + if (f4 > 255) return -1; if (m == 0 || m > 32) return -1; 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) { diff --git a/accel-pptpd/ppp/ipcp_opt_ipaddr.c b/accel-pptpd/ppp/ipcp_opt_ipaddr.c index d96b6c1a..93ddb10f 100644 --- a/accel-pptpd/ppp/ipcp_opt_ipaddr.c +++ b/accel-pptpd/ppp/ipcp_opt_ipaddr.c @@ -73,8 +73,8 @@ static int ipaddr_send_conf_req(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *o return -1; } } - if (!iprange_client_check(ipaddr_opt->ip->peer_addr)) { - log_ppp_warn("ppp:ipcp: to avoid hard loops requested IP cannot be assigned (%i.%i.%i.%i)\n", + if (iprange_tunnel_check(ipaddr_opt->ip->peer_addr)) { + log_ppp_warn("ppp:ipcp: to avoid kernel soft lockup requested IP cannot be assigned (%i.%i.%i.%i)\n", ipaddr_opt->ip->peer_addr&0xff, (ipaddr_opt->ip->peer_addr >> 8)&0xff, (ipaddr_opt->ip->peer_addr >> 16)&0xff, |