diff options
author | Vladislav Grishenko <themiron@mail.ru> | 2014-09-01 15:03:51 +0600 |
---|---|---|
committer | Dmitry Kozlov <xeb@mail.ru> | 2014-09-13 11:01:15 +0400 |
commit | 9d89c061153285971ebf4cc79f68a8d4dd598c8a (patch) | |
tree | c9971b96ecac6c5e69a8732b76d4a86cb1bfac5f /accel-pppd | |
parent | 8e4a659d3830f83216308e5203933af2c4c72a19 (diff) | |
download | accel-ppp-9d89c061153285971ebf4cc79f68a8d4dd598c8a.tar.gz accel-ppp-9d89c061153285971ebf4cc79f68a8d4dd598c8a.zip |
ppp: improve LCP magic number negotiation
Diffstat (limited to 'accel-pppd')
-rw-r--r-- | accel-pppd/ppp/lcp_opt_magic.c | 47 | ||||
-rw-r--r-- | accel-pppd/ppp/ppp_lcp.c | 2 |
2 files changed, 41 insertions, 8 deletions
diff --git a/accel-pppd/ppp/lcp_opt_magic.c b/accel-pppd/ppp/lcp_opt_magic.c index 81eadd6d..e2d9bade 100644 --- a/accel-pppd/ppp/lcp_opt_magic.c +++ b/accel-pppd/ppp/lcp_opt_magic.c @@ -14,7 +14,8 @@ static int magic_send_conf_req(struct ppp_lcp_t *lcp, struct lcp_option_t *opt, static int magic_send_conf_nak(struct ppp_lcp_t *lcp, struct lcp_option_t *opt, uint8_t *ptr); static int magic_recv_conf_req(struct ppp_lcp_t *lcp, struct lcp_option_t *opt, uint8_t *ptr); static int magic_recv_conf_rej(struct ppp_lcp_t *lcp, struct lcp_option_t *opt, uint8_t *ptr); -static void magic_print(void (*print)(const char *fmt,...),struct lcp_option_t*, uint8_t *ptr); +static int magic_recv_conf_nak(struct ppp_lcp_t *lcp, struct lcp_option_t *opt, uint8_t *ptr); +static void magic_print(void (*print)(const char *fmt, ...), struct lcp_option_t*, uint8_t *ptr); struct magic_option_t { @@ -29,15 +30,28 @@ static struct lcp_option_handler_t magic_opt_hnd= .send_conf_nak = magic_send_conf_nak, .recv_conf_req = magic_recv_conf_req, .recv_conf_rej = magic_recv_conf_rej, + .recv_conf_nak = magic_recv_conf_nak, .free = magic_free, .print = magic_print, }; +static int nzmagic(int old) +{ + int magic; + + do { + magic = random(); + } while (magic == old || !magic); + + return magic; +} + static struct lcp_option_t *magic_init(struct ppp_lcp_t *lcp) { struct magic_option_t *magic_opt = _malloc(sizeof(*magic_opt)); + memset(magic_opt, 0, sizeof(*magic_opt)); - do { magic_opt->magic = random(); } while (magic_opt->magic == 0); + magic_opt->magic = nzmagic(0); magic_opt->opt.id = CI_MAGIC; magic_opt->opt.len = 6; @@ -71,9 +85,10 @@ static int magic_send_conf_nak(struct ppp_lcp_t *lcp, struct lcp_option_t *opt, { struct magic_option_t *magic_opt = container_of(opt, typeof(*magic_opt), opt); struct lcp_opt32_t *opt32 = (struct lcp_opt32_t *)ptr; + opt32->hdr.id = CI_MAGIC; opt32->hdr.len = 6; - do { opt32->val = random(); } while (opt32->val == magic_opt->magic); + opt32->val = htonl(nzmagic(magic_opt->magic)); return 6; } @@ -84,11 +99,11 @@ static int magic_recv_conf_req(struct ppp_lcp_t *lcp, struct lcp_option_t *opt, /*if (!ptr) return LCP_OPT_NAK;*/ - + if (opt32->hdr.len != 6) return LCP_OPT_REJ; - if (magic_opt->magic == ntohl(opt32->val)) + if (magic_opt->magic && magic_opt->magic == ntohl(opt32->val)) return LCP_OPT_NAK; return LCP_OPT_ACK; @@ -97,14 +112,32 @@ static int magic_recv_conf_req(struct ppp_lcp_t *lcp, struct lcp_option_t *opt, static int magic_recv_conf_rej(struct ppp_lcp_t *lcp, struct lcp_option_t *opt, uint8_t *ptr) { struct magic_option_t *magic_opt = container_of(opt, typeof(*magic_opt), opt); - + magic_opt->magic = 0; lcp->magic = 0; return 0; } -static void magic_print(void (*print)(const char *fmt,...),struct lcp_option_t *opt, uint8_t *ptr) +static int magic_recv_conf_nak(struct ppp_lcp_t *lcp, struct lcp_option_t *opt, uint8_t *ptr) +{ + struct magic_option_t *magic_opt = container_of(opt, typeof(*magic_opt), opt); + struct lcp_opt32_t *opt32 = (struct lcp_opt32_t *)ptr; + + if (opt32->hdr.len != 6) + return -1; + + /* Loop-back detected */ + if (magic_opt->magic && magic_opt->magic == ntohl(opt32->val)) + return -1; + + magic_opt->magic = ntohl(opt32->val) ? : nzmagic(magic_opt->magic); + lcp->magic = magic_opt->magic; + + return 0; +} + +static void magic_print(void (*print)(const char *fmt, ...), struct lcp_option_t *opt, uint8_t *ptr) { struct magic_option_t *magic_opt = container_of(opt, typeof(*magic_opt), opt); struct lcp_opt32_t *opt32 = (struct lcp_opt32_t *)ptr; diff --git a/accel-pppd/ppp/ppp_lcp.c b/accel-pppd/ppp/ppp_lcp.c index 5975d5db..54826efc 100644 --- a/accel-pppd/ppp/ppp_lcp.c +++ b/accel-pppd/ppp/ppp_lcp.c @@ -609,7 +609,7 @@ static void lcp_recv_echo_repl(struct ppp_lcp_t *lcp, uint8_t *data, int size) if (conf_ppp_verbose) log_ppp_debug("recv [LCP EchoRep id=%x <magic %08x>]\n", lcp->fsm.recv_id, magic); - if (magic == lcp->magic) { + if (lcp->magic && magic == lcp->magic) { log_ppp_error("lcp: echo: loop-back detected\n"); ap_session_terminate(&lcp->ppp->ses, TERM_NAS_ERROR, 0); } |