summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladislav Grishenko <themiron@mail.ru>2014-09-01 15:03:51 +0600
committerDmitry Kozlov <xeb@mail.ru>2014-09-13 11:01:15 +0400
commit9d89c061153285971ebf4cc79f68a8d4dd598c8a (patch)
treec9971b96ecac6c5e69a8732b76d4a86cb1bfac5f
parent8e4a659d3830f83216308e5203933af2c4c72a19 (diff)
downloadaccel-ppp-9d89c061153285971ebf4cc79f68a8d4dd598c8a.tar.gz
accel-ppp-9d89c061153285971ebf4cc79f68a8d4dd598c8a.zip
ppp: improve LCP magic number negotiation
-rw-r--r--accel-pppd/ppp/lcp_opt_magic.c47
-rw-r--r--accel-pppd/ppp/ppp_lcp.c2
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);
}