diff options
Diffstat (limited to 'accel-pppd')
-rw-r--r-- | accel-pppd/extra/ippool.c | 128 | ||||
-rw-r--r-- | accel-pppd/triton/conf_file.c | 16 | ||||
-rw-r--r-- | accel-pppd/triton/triton.h | 1 |
3 files changed, 125 insertions, 20 deletions
diff --git a/accel-pppd/extra/ippool.c b/accel-pppd/extra/ippool.c index ccb3b2a2..62c56df1 100644 --- a/accel-pppd/extra/ippool.c +++ b/accel-pppd/extra/ippool.c @@ -6,12 +6,14 @@ #include <arpa/inet.h> #include "events.h" -#include "ipdb.h" +#include "log.h" #include "list.h" #include "spinlock.h" #include "backup.h" #include "ap_session_backup.h" +#include "ipdb.h" + #ifdef RADIUS #include "radius.h" #endif @@ -27,6 +29,7 @@ struct ippool_t struct list_head items; uint32_t startip; uint32_t endip; + void (*generate)(struct ippool_t *); spinlock_t lock; }; @@ -60,6 +63,7 @@ struct ippool_t *create_pool(const char *name) memset(p, 0, sizeof(*p)); if (name) p->name = strdup(name); + INIT_LIST_HEAD(&p->gw_list); INIT_LIST_HEAD(&p->tunnel_list); INIT_LIST_HEAD(&p->items); @@ -147,7 +151,7 @@ static int parse2(const char *str, uint32_t *begin, uint32_t *end) return 0; } -static void add_range(struct ippool_t *p, struct list_head *list, const char *name) +static void add_range(struct ippool_t *p, struct list_head *list, const char *name, void (*generate)(struct ippool_t *)) { uint32_t i,startip, endip; struct ipaddr_t *ip; @@ -168,9 +172,10 @@ static void add_range(struct ippool_t *p, struct list_head *list, const char *na p->startip = startip; p->endip = endip; + p->generate = generate; } -static void generate_pool(struct ippool_t *p) +static void generate_pool_p2p(struct ippool_t *p) { struct ippool_item_t *it; struct ipaddr_t *addr = NULL; @@ -212,6 +217,53 @@ static void generate_pool(struct ippool_t *p) } } +static void generate_pool_net30(struct ippool_t *p) +{ + struct ippool_item_t *it; + struct ipaddr_t *addr[4]; + int i; + + while (1) { + memset(addr, 0, sizeof(addr)); + + for (i = 0; i < 4; i++) { + if (list_empty(&p->tunnel_list)) + break; + + addr[i] = list_entry(p->tunnel_list.next, typeof(*addr[i]), entry); + list_del(&addr[i]->entry); + } + + if (!addr[2]) + break; + + + it = malloc(sizeof(*it)); + if (!it) { + log_emerg("ippool: out of memory\n"); + break; + } + + it->pool = p; + it->it.owner = &ipdb; + it->it.addr = addr[1]->addr; + it->it.peer_addr = addr[2]->addr; + + list_add_tail(&it->entry, &p->items); + + for (i = 0; i < 4; i++) { + if (addr[i]) + free(addr[i]); + } + } + + for (i = 0; i < 4; i++) { + if (addr[i]) + free(addr[i]); + } +} + + static struct ipv4db_item_t *get_ip(struct ap_session *ses) { struct ippool_item_t *it; @@ -401,12 +453,38 @@ static int parse_vendor_opt(const char *opt) } #endif +static void parse_options(const char *opt, char **pool_name, char **allocator) +{ + char *ptr1, *ptr2; + int len; + + ptr1 = strstr(opt, "name="); + if (ptr1) { + for (ptr2 = ptr1 + 5; *ptr2 && *ptr2 != ','; ptr2++); + len = ptr2 - (ptr1 + 5); + *pool_name = _malloc(len + 1); + memcpy(*pool_name, ptr1 + 5, len); + (*pool_name)[len] = 0; + } + + ptr1 = strstr(opt, "allocator="); + if (ptr1) { + for (ptr2 = ptr1 + 10; *ptr2 && *ptr2 != ','; ptr2++); + len = ptr2 - (ptr1 + 10); + *allocator = _malloc(len + 1); + memcpy(*allocator, ptr1 + 10, len); + (*allocator)[len] = 0; + } +} + static void ippool_init(void) { struct conf_sect_t *s = conf_get_section("ip-pool"); struct conf_option_t *opt; struct ippool_t *p; - char *pool_name; + char *pool_name = NULL; + char *allocator = NULL; + void (*generate)(struct ippool_t *pool); if (!s) return; @@ -430,26 +508,44 @@ static void ippool_init(void) if (!strcmp(opt->name, "gw-ip-address")) parse_gw_ip_address(opt->val); else { - if (opt->val) - pool_name = strchr(opt->val, ','); - else - pool_name = strchr(opt->name, ','); + pool_name = NULL; + allocator = NULL; + + parse_options(opt->raw, &pool_name, &allocator); + + if (allocator) { + if (strcmp(allocator, "p2p") == 0) + generate = generate_pool_p2p; + else if (strcmp(allocator, "net30") == 0) + generate = generate_pool_net30; + else { + log_error("ipool: '%s': unknown allocator\n", opt->raw); + } + } else + generate = generate_pool_p2p; - p = pool_name ? find_pool(pool_name + 1, 1) : def_pool; + p = pool_name ? find_pool(pool_name, 1) : def_pool; if (!strcmp(opt->name, "gw")) - add_range(p, &p->gw_list, opt->val); + add_range(p, &p->gw_list, opt->val, generate); else if (!strcmp(opt->name, "tunnel")) - add_range(p, &p->tunnel_list, opt->val); - else if (!opt->val) - add_range(p, &p->tunnel_list, opt->name); + add_range(p, &p->tunnel_list, opt->val, generate); + else if (!opt->val || strchr(opt->name, ',')) + add_range(p, &p->tunnel_list, opt->name, generate); + + if (pool_name) + _free(pool_name); + + if (allocator) + _free(allocator); } } - - generate_pool(def_pool); + + if (def_pool->generate) + def_pool->generate(def_pool); list_for_each_entry(p, &pool_list, entry) - generate_pool(p); + p->generate(p); ipdb_register(&ipdb); diff --git a/accel-pppd/triton/conf_file.c b/accel-pppd/triton/conf_file.c index ce8549c9..d859596e 100644 --- a/accel-pppd/triton/conf_file.c +++ b/accel-pppd/triton/conf_file.c @@ -24,14 +24,14 @@ static char* skip_word(char *str); static struct conf_sect_t *find_sect(const char *name); static struct conf_sect_t *create_sect(const char *name); -static void sect_add_item(struct conf_sect_t *sect, const char *name, const char *val); +static void sect_add_item(struct conf_sect_t *sect, const char *name, const char *val, char *raw); static struct conf_option_t *find_item(struct conf_sect_t *, const char *name); static char *buf; int __conf_load(const char *fname, struct conf_sect_t *cur_sect) { - char *str,*str2; + char *str, *str2, *raw; int cur_line = 0; FILE *f = fopen(fname, "r"); @@ -50,6 +50,7 @@ int __conf_load(const char *fname, struct conf_sect_t *cur_sect) str = skip_space(buf); if (*str == '#' || *str == 0) continue; + if (strncmp(str, "$include", 8) == 0) { str = skip_word(str); str = skip_space(str); @@ -57,6 +58,7 @@ int __conf_load(const char *fname, struct conf_sect_t *cur_sect) break; continue; } + if (*str == '[') { for (str2 = ++str; *str2 && *str2 != ']'; str2++); if (*str2 != ']') { @@ -69,15 +71,19 @@ int __conf_load(const char *fname, struct conf_sect_t *cur_sect) cur_sect = create_sect(str); continue; } + if (!cur_sect) { fprintf(stderr, "conf_file:%s:%i: no section opened\n", fname, cur_line); return -1; } + + raw = _strdup(str); str2 = skip_word(str); if (*str2 == ' ') { *str2 = 0; ++str2; } + str2 = skip_space(str2); if (*str2 == '=' || *str2 == ',') { *str2 = 0; @@ -99,7 +105,7 @@ int __conf_load(const char *fname, struct conf_sect_t *cur_sect) } } else str2 = NULL; - sect_add_item(cur_sect, str, str2); + sect_add_item(cur_sect, str, str2, raw); } fclose(f); @@ -162,6 +168,7 @@ int conf_reload(const char *fname) if (opt->val) _free(opt->val); _free(opt->name); + _free(opt->raw); _free(opt); } _free((char *)sect->sect->name); @@ -205,12 +212,13 @@ static struct conf_sect_t *create_sect(const char *name) return s->sect; } -static void sect_add_item(struct conf_sect_t *sect, const char *name, const char *val) +static void sect_add_item(struct conf_sect_t *sect, const char *name, const char *val, char *raw) { struct conf_option_t *opt = _malloc(sizeof(struct conf_option_t)); opt->name = _strdup(name); opt->val = val ? _strdup(val) : NULL; + opt->raw = raw; list_add_tail(&opt->entry, §->items); } diff --git a/accel-pppd/triton/triton.h b/accel-pppd/triton/triton.h index 95851c2d..98955dfc 100644 --- a/accel-pppd/triton/triton.h +++ b/accel-pppd/triton/triton.h @@ -42,6 +42,7 @@ struct conf_option_t struct list_head entry; char *name; char *val; + char *raw; }; struct conf_sect_t |