diff options
author | Kozlov Dmitry <xeb@mail.ru> | 2013-01-24 23:58:56 +0400 |
---|---|---|
committer | Kozlov Dmitry <xeb@mail.ru> | 2013-01-24 23:58:56 +0400 |
commit | cf3de06a3346854d770ba147f081e3b22e93c1bc (patch) | |
tree | 0c1a138d292c140c2547361615bf556ff2b98f9f /accel-pppd/ctrl/pppoe | |
parent | 35b55103979145284d63bc1db4ebd6e9d6666b34 (diff) | |
download | accel-ppp-cf3de06a3346854d770ba147f081e3b22e93c1bc.tar.gz accel-ppp-cf3de06a3346854d770ba147f081e3b22e93c1bc.zip |
backport 1.7
* l2tp: Fix allocation checking when adding octets AVP
* cli, tcp: Fix non-NULL terminated string reception
* Fix va_end() missing calls
* chap-secrets: implemented encryption
* auth_pap: make messages like other auth modules
* cli: check xmit_buf is not null at enter to write function
* pppoe: implemented regular expression support
* chap-secrets: implemented encryption
* ippool: fixed initialization order
* optional shaper compiling
* ppp: dns/wins code cleanup
Diffstat (limited to 'accel-pppd/ctrl/pppoe')
-rw-r--r-- | accel-pppd/ctrl/pppoe/pppoe.c | 90 |
1 files changed, 76 insertions, 14 deletions
diff --git a/accel-pppd/ctrl/pppoe/pppoe.c b/accel-pppd/ctrl/pppoe/pppoe.c index 22fcd62..b01369d 100644 --- a/accel-pppd/ctrl/pppoe/pppoe.c +++ b/accel-pppd/ctrl/pppoe/pppoe.c @@ -26,6 +26,7 @@ #include "radius.h" #endif +#include "iputils.h" #include "connlimit.h" #include "pppoe.h" @@ -73,6 +74,13 @@ struct padi_t uint8_t addr[ETH_ALEN]; }; +struct iplink_arg +{ + pcre *re; + const char *opt; + void *cli; +}; + int conf_verbose; char *conf_service_name; char *conf_ac_name; @@ -106,6 +114,7 @@ static void pppoe_send_PADT(struct pppoe_conn_t *conn); static void _server_stop(struct pppoe_serv_t *serv); void pppoe_server_free(struct pppoe_serv_t *serv); static int init_secret(struct pppoe_serv_t *serv); +static void __pppoe_server_start(const char *ifname, const char *opt, void *cli); static void disconnect(struct pppoe_conn_t *conn) { @@ -1109,41 +1118,94 @@ static void pppoe_serv_close(struct triton_context_t *ctx) pthread_mutex_unlock(&serv->lock); } -static int parse_server(const char *opt, char **ifname, int *padi_limit) +static int parse_server(const char *opt, int *padi_limit) { - char *str = _strdup(opt); - char *ptr1, *ptr2, *endptr; + char *ptr, *endptr; - ptr1 = strchr(str, ','); - if (ptr1) { - ptr2 = strstr(ptr1, ",padi-limit="); - *padi_limit = strtol(ptr2 + 12, &endptr, 10); + ptr = strstr(opt, ",padi-limit="); + if (ptr) { + *padi_limit = strtol(ptr + 12, &endptr, 10); if (*endptr != 0 && *endptr != ',') goto out_err; - - *ptr1 = 0; } - *ifname = str; - return 0; out_err: - _free(str); return -1; } +static int __pppoe_add_interface_re(int index, int flags, const char *name, struct iplink_arg *arg) +{ + if (pcre_exec(arg->re, NULL, name, strlen(name), 0, 0, NULL, 0) < 0) + return 0; + + __pppoe_server_start(name, arg->opt, arg->cli); + + return 0; +} + +static void pppoe_add_interface_re(const char *opt, void *cli) +{ + pcre *re = NULL; + const char *pcre_err; + char *pattern; + const char *ptr; + int pcre_offset; + struct iplink_arg arg; + + for (ptr = opt; *ptr && *ptr != ','; ptr++); + + pattern = _malloc(ptr - (opt + 3) + 1); + memcpy(pattern, opt + 3, ptr - (opt + 3)); + pattern[ptr - (opt + 3)] = 0; + + re = pcre_compile2(pattern, 0, NULL, &pcre_err, &pcre_offset, NULL); + + if (!re) { + log_error("pppoe: %s at %i\r\n", pcre_err, pcre_offset); + return; + } + + arg.re = re; + arg.opt = ptr; + arg.cli = cli; + + iplink_list((iplink_list_func)__pppoe_add_interface_re, &arg); + + pcre_free(re); + _free(pattern); +} + void pppoe_server_start(const char *opt, void *cli) { + char name[IFNAMSIZ]; + const char *ptr; + + if (strlen(opt) > 3 && memcmp(opt, "re:", 3) == 0) { + pppoe_add_interface_re(opt, cli); + return; + } + + ptr = strchr(opt, ','); + if (ptr) { + memcpy(name, opt, ptr - opt); + name[ptr - opt] = 0; + __pppoe_server_start(name, ptr, cli); + } else + __pppoe_server_start(opt, opt, cli); +} + +static void __pppoe_server_start(const char *ifname, const char *opt, void *cli) +{ struct pppoe_serv_t *serv; int sock; int f = 1; struct ifreq ifr; struct sockaddr_ll sa; - char *ifname = NULL; int padi_limit = conf_padi_limit; - if (parse_server(opt, &ifname, &padi_limit)) { + if (parse_server(opt, &padi_limit)) { if (cli) cli_sendv(cli, "failed to parse '%s'\r\n", opt); else |