summaryrefslogtreecommitdiff
path: root/accel-pptpd/ppp
diff options
context:
space:
mode:
Diffstat (limited to 'accel-pptpd/ppp')
-rw-r--r--accel-pptpd/ppp/ipcp_opt_dns.c18
-rw-r--r--accel-pptpd/ppp/lcp_opt_accomp.c8
-rw-r--r--accel-pptpd/ppp/lcp_opt_magic.c3
-rw-r--r--accel-pptpd/ppp/lcp_opt_mru.c3
-rw-r--r--accel-pptpd/ppp/lcp_opt_pcomp.c8
-rw-r--r--accel-pptpd/ppp/ppp.c16
-rw-r--r--accel-pptpd/ppp/ppp.h2
-rw-r--r--accel-pptpd/ppp/ppp_auth.c4
-rw-r--r--accel-pptpd/ppp/ppp_ccp.c45
-rw-r--r--accel-pptpd/ppp/ppp_ccp.h1
-rw-r--r--accel-pptpd/ppp/ppp_fsm.c59
-rw-r--r--accel-pptpd/ppp/ppp_fsm.h6
-rw-r--r--accel-pptpd/ppp/ppp_ipcp.c42
-rw-r--r--accel-pptpd/ppp/ppp_lcp.c72
14 files changed, 223 insertions, 64 deletions
diff --git a/accel-pptpd/ppp/ipcp_opt_dns.c b/accel-pptpd/ppp/ipcp_opt_dns.c
index 16ef7af..b0365da 100644
--- a/accel-pptpd/ppp/ipcp_opt_dns.c
+++ b/accel-pptpd/ppp/ipcp_opt_dns.c
@@ -9,6 +9,9 @@
#include "memdebug.h"
+static in_addr_t conf_dns1;
+static in_addr_t conf_dns2;
+
static struct ipcp_option_t *dns1_init(struct ppp_ipcp_t *ipcp);
static struct ipcp_option_t *dns2_init(struct ppp_ipcp_t *ipcp);
static void dns_free(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *opt);
@@ -100,8 +103,8 @@ static int dns_recv_conf_req(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *opt,
if (!dns_opt->addr)
{
- if (dns_opt->opt.id==CI_DNS1) dns_opt->addr=inet_addr("10.0.0.1");
- else dns_opt->addr=inet_addr("10.0.0.2");
+ if (dns_opt->opt.id == CI_DNS1 && conf_dns1) dns_opt->addr=conf_dns1;
+ else if (dns_opt->opt.id == CI_DNS2 && conf_dns2) dns_opt->addr=conf_dns2;
if (!dns_opt->addr)
{
@@ -142,7 +145,16 @@ static void dns2_print(void (*print)(const char *fmt,...),struct ipcp_option_t *
static void __init dns_opt_init()
{
+ char *opt;
+
+ opt = conf_get_opt("dns", "dns1");
+ if (opt)
+ conf_dns1 = inet_addr(opt);
+
+ opt = conf_get_opt("dns", "dns2");
+ if (opt)
+ conf_dns2 = inet_addr(opt);
+
ipcp_option_register(&dns1_opt_hnd);
ipcp_option_register(&dns2_opt_hnd);
}
-
diff --git a/accel-pptpd/ppp/lcp_opt_accomp.c b/accel-pptpd/ppp/lcp_opt_accomp.c
index 8545f9d..94fa128 100644
--- a/accel-pptpd/ppp/lcp_opt_accomp.c
+++ b/accel-pptpd/ppp/lcp_opt_accomp.c
@@ -19,6 +19,7 @@ struct accomp_option_t
{
struct lcp_option_t opt;
int accomp; // 0 - disabled, 1 - enabled, 2 - allow,disabled, 3 - allow,enabled
+ int require;
};
static struct lcp_option_handler_t accomp_opt_hnd=
@@ -75,6 +76,13 @@ static int accomp_recv_conf_req(struct ppp_lcp_t *lcp, struct lcp_option_t *opt,
{
struct accomp_option_t *accomp_opt=container_of(opt,typeof(*accomp_opt),opt);
+ if (!ptr) {
+ if (accomp_opt->require)
+ return LCP_OPT_NAK;
+ accomp_opt->accomp=0;
+ return LCP_OPT_ACK;
+ }
+
if (accomp_opt->accomp>0)
{
accomp_opt->accomp=1;
diff --git a/accel-pptpd/ppp/lcp_opt_magic.c b/accel-pptpd/ppp/lcp_opt_magic.c
index cec40ce..166c85c 100644
--- a/accel-pptpd/ppp/lcp_opt_magic.c
+++ b/accel-pptpd/ppp/lcp_opt_magic.c
@@ -64,6 +64,9 @@ static int magic_recv_conf_req(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;
+ if (!ptr)
+ return LCP_OPT_NAK;
+
if (magic_opt->magic==ntohl(opt32->val))
{
log_ppp_error("loop detected");
diff --git a/accel-pptpd/ppp/lcp_opt_mru.c b/accel-pptpd/ppp/lcp_opt_mru.c
index f13b014..096c0d5 100644
--- a/accel-pptpd/ppp/lcp_opt_mru.c
+++ b/accel-pptpd/ppp/lcp_opt_mru.c
@@ -86,6 +86,9 @@ static int mru_recv_conf_req(struct ppp_lcp_t *lcp, struct lcp_option_t *opt, ui
struct mru_option_t *mru_opt = container_of(opt,typeof(*mru_opt),opt);
struct lcp_opt16_t *opt16 = (struct lcp_opt16_t*)ptr;
+ if (!ptr)
+ return LCP_OPT_NAK;
+
if (ntohs(opt16->val) < conf_min_mtu || ntohs(opt16->val) > lcp->ppp->ctrl->max_mtu)
return LCP_OPT_NAK;
diff --git a/accel-pptpd/ppp/lcp_opt_pcomp.c b/accel-pptpd/ppp/lcp_opt_pcomp.c
index 0ff4d11..a1ceb8e 100644
--- a/accel-pptpd/ppp/lcp_opt_pcomp.c
+++ b/accel-pptpd/ppp/lcp_opt_pcomp.c
@@ -19,6 +19,7 @@ struct pcomp_option_t
{
struct lcp_option_t opt;
int pcomp; // 0 - disabled, 1 - enabled, 2 - allow,disabled, 3 - allow,enabled
+ int require;
};
static struct lcp_option_handler_t pcomp_opt_hnd=
@@ -75,6 +76,13 @@ static int pcomp_recv_conf_req(struct ppp_lcp_t *lcp, struct lcp_option_t *opt,
{
struct pcomp_option_t *pcomp_opt=container_of(opt,typeof(*pcomp_opt),opt);
+ if (!ptr) {
+ if (pcomp_opt->require)
+ return LCP_OPT_NAK;
+ pcomp_opt->pcomp=0;
+ return LCP_OPT_ACK;
+ }
+
if (pcomp_opt->pcomp>0)
{
pcomp_opt->pcomp=1;
diff --git a/accel-pptpd/ppp/ppp.c b/accel-pptpd/ppp/ppp.c
index dfe5bbe..03a8db0 100644
--- a/accel-pptpd/ppp/ppp.c
+++ b/accel-pptpd/ppp/ppp.c
@@ -351,15 +351,15 @@ void __export ppp_layer_started(struct ppp_t *ppp, struct ppp_layer_data_t *d)
void __export ppp_layer_finished(struct ppp_t *ppp, struct ppp_layer_data_t *d)
{
struct layer_node_t *n=d->node;
-
- d->starting=0;
- d->started=0;
+
+ d->finished = 1;
+ d->starting = 0;
list_for_each_entry(n,&ppp->layers,entry)
{
list_for_each_entry(d,&n->items,entry)
{
- if (d->starting)
+ if (!d->finished)
return;
}
}
@@ -373,6 +373,14 @@ void __export ppp_terminate(struct ppp_t *ppp, int hard)
struct ppp_layer_data_t *d;
int s = 0;
+ if (ppp->terminating) {
+ if (hard)
+ destablish_ppp(ppp);
+ return;
+ }
+
+ ppp->terminating = 1;
+
log_ppp_debug("ppp_terminate\n");
triton_event_fire(EV_PPP_FINISHING, ppp);
diff --git a/accel-pptpd/ppp/ppp.h b/accel-pptpd/ppp/ppp.h
index 5a8ac57..32615c2 100644
--- a/accel-pptpd/ppp/ppp.h
+++ b/accel-pptpd/ppp/ppp.h
@@ -86,6 +86,7 @@ struct ppp_t
struct ppp_ctrl_t *ctrl;
int log:1;
+ int terminating:1;
void *chan_buf;
int chan_buf_size;
@@ -111,6 +112,7 @@ struct ppp_layer_data_t
struct layer_node_t *node;
int starting:1;
int started:1;
+ int finished:1;
};
struct ppp_layer_t
diff --git a/accel-pptpd/ppp/ppp_auth.c b/accel-pptpd/ppp/ppp_auth.c
index d141b81..dfa5415 100644
--- a/accel-pptpd/ppp/ppp_auth.c
+++ b/accel-pptpd/ppp/ppp_auth.c
@@ -137,6 +137,10 @@ static int auth_recv_conf_req(struct ppp_lcp_t *lcp, struct lcp_option_t *opt, u
if (list_empty(&auth_opt->auth_list))
return LCP_OPT_REJ;
+
+ if (!ptr)
+ return LCP_OPT_ACK;
+
list_for_each_entry(d,&auth_opt->auth_list,entry)
{
diff --git a/accel-pptpd/ppp/ppp_ccp.c b/accel-pptpd/ppp/ppp_ccp.c
index 301c238..477b624 100644
--- a/accel-pptpd/ppp/ppp_ccp.c
+++ b/accel-pptpd/ppp/ppp_ccp.c
@@ -30,6 +30,8 @@ static int send_conf_req(struct ppp_fsm_t*);
static void send_conf_ack(struct ppp_fsm_t*);
static void send_conf_nak(struct ppp_fsm_t*);
static void send_conf_rej(struct ppp_fsm_t*);
+static void send_term_req(struct ppp_fsm_t *fsm);
+static void send_term_ack(struct ppp_fsm_t *fsm);
static void ccp_recv(struct ppp_handler_t*);
static void ccp_options_init(struct ppp_ccp_t *ccp)
@@ -78,6 +80,7 @@ static struct ppp_layer_data_t *ccp_layer_init(struct ppp_t *ppp)
ppp_register_unit_handler(ppp,&ccp->hnd);
+ ccp->fsm.proto = PPP_CCP;
ppp_fsm_init(&ccp->fsm);
ccp->fsm.layer_up=ccp_layer_up;
@@ -86,6 +89,8 @@ static struct ppp_layer_data_t *ccp_layer_init(struct ppp_t *ppp)
ccp->fsm.send_conf_ack=send_conf_ack;
ccp->fsm.send_conf_nak=send_conf_nak;
ccp->fsm.send_conf_rej=send_conf_rej;
+ ccp->fsm.send_term_req=send_term_req;
+ ccp->fsm.send_term_ack=send_term_ack;
INIT_LIST_HEAD(&ccp->options);
INIT_LIST_HEAD(&ccp->ropt_list);
@@ -134,6 +139,7 @@ static void ccp_layer_up(struct ppp_fsm_t *fsm)
{
struct ppp_ccp_t *ccp=container_of(fsm,typeof(*ccp),fsm);
log_ppp_debug("ccp_layer_started\n");
+ ccp->started = 1;
ppp_layer_started(ccp->ppp,&ccp->ld);
}
@@ -141,6 +147,9 @@ static void ccp_layer_down(struct ppp_fsm_t *fsm)
{
struct ppp_ccp_t *ccp=container_of(fsm,typeof(*ccp),fsm);
log_ppp_debug("ccp_layer_finished\n");
+ if (!ccp->started)
+ ppp_layer_started(ccp->ppp, &ccp->ld);
+ ccp->started = 0;
ppp_layer_finished(ccp->ppp,&ccp->ld);
}
@@ -480,6 +489,36 @@ static int ccp_recv_conf_ack(struct ppp_ccp_t *ccp,uint8_t *data,int size)
return res;
}
+static void send_term_req(struct ppp_fsm_t *fsm)
+{
+ struct ppp_ccp_t *ccp=container_of(fsm,typeof(*ccp),fsm);
+ struct ccp_hdr_t hdr = {
+ .proto = htons(PPP_CCP),
+ .code = TERMREQ,
+ .id = ++ccp->fsm.id,
+ .len = htons(4),
+ };
+
+ log_ppp_debug("send [CCP TermReq id=%i \"\"]\n",hdr.id);
+
+ ppp_chan_send(ccp->ppp, &hdr, 6);
+}
+
+static void send_term_ack(struct ppp_fsm_t *fsm)
+{
+ struct ppp_ccp_t *ccp=container_of(fsm,typeof(*ccp),fsm);
+ struct ccp_hdr_t hdr = {
+ .proto = htons(PPP_CCP),
+ .code = TERMACK,
+ .id = ccp->fsm.recv_id,
+ .len = htons(4),
+ };
+
+ log_ppp_debug("send [CCP TermAck id=%i \"\"]\n", hdr.id);
+
+ ppp_chan_send(ccp->ppp, &hdr, 6);
+}
+
static void ccp_recv(struct ppp_handler_t*h)
{
struct ccp_hdr_t *hdr;
@@ -544,14 +583,14 @@ static void ccp_recv(struct ppp_handler_t*h)
ppp_fsm_recv_conf_rej(&ccp->fsm);
break;
case TERMREQ:
- term_msg=_strndup((char*)(hdr+1),ntohs(hdr->len));
+ term_msg=_strndup((char*)(hdr+1),ntohs(hdr->len) - 4);
log_ppp_debug("recv [CCP TermReq id=%x \"%s\"]\n",hdr->id,term_msg);
_free(term_msg);
ppp_fsm_recv_term_req(&ccp->fsm);
- ppp_terminate(ccp->ppp, 0);
+ ppp_fsm_close(&ccp->fsm);
break;
case TERMACK:
- term_msg=_strndup((char*)(hdr+1),ntohs(hdr->len));
+ term_msg=_strndup((char*)(hdr+1),ntohs(hdr->len) - 4);
log_ppp_debug("recv [CCP TermAck id=%x \"%s\"]\n",hdr->id,term_msg);
_free(term_msg);
ppp_fsm_recv_term_ack(&ccp->fsm);
diff --git a/accel-pptpd/ppp/ppp_ccp.h b/accel-pptpd/ppp/ppp_ccp.h
index 3e45969..23f44f0 100644
--- a/accel-pptpd/ppp/ppp_ccp.h
+++ b/accel-pptpd/ppp/ppp_ccp.h
@@ -86,6 +86,7 @@ struct ppp_ccp_t
int ropt_len;
int conf_req_len;
+ int started:1;
};
int ccp_option_register(struct ccp_option_handler_t *h);
diff --git a/accel-pptpd/ppp/ppp_fsm.c b/accel-pptpd/ppp/ppp_fsm.c
index 8f8e855..4fc60c2 100644
--- a/accel-pptpd/ppp/ppp_fsm.c
+++ b/accel-pptpd/ppp/ppp_fsm.c
@@ -143,7 +143,7 @@ void ppp_fsm_close(struct ppp_fsm_t *layer)
case FSM_Ack_Sent:
//if (layer->init_req_cnt) layer->init_req_cnt(layer);
init_req_counter(layer,layer->max_terminate);
- send_term_req(layer);
+ layer->send_term_req(layer);
layer->fsm_state=FSM_Closing;
break;
default:
@@ -157,7 +157,7 @@ void ppp_fsm_timeout0(struct ppp_fsm_t *layer)
{
case FSM_Closing:
case FSM_Stopping:
- send_term_req(layer);
+ layer->send_term_req(layer);
break;
case FSM_Ack_Rcvd:
layer->fsm_state=FSM_Req_Sent;
@@ -202,7 +202,7 @@ void ppp_fsm_recv_conf_req_ack(struct ppp_fsm_t *layer)
switch(layer->fsm_state)
{
case FSM_Closed:
- send_term_ack(layer);
+ layer->send_term_ack(layer);
break;
case FSM_Stopped:
//if (layer->init_req_cnt) layer->init_req_cnt(layer);
@@ -237,7 +237,7 @@ void ppp_fsm_recv_conf_req_nak(struct ppp_fsm_t *layer)
switch(layer->fsm_state)
{
case FSM_Closed:
- send_term_ack(layer);
+ layer->send_term_ack(layer);
break;
case FSM_Stopped:
//if (layer->init_req_cnt) layer->init_req_cnt(layer);
@@ -269,7 +269,7 @@ void ppp_fsm_recv_conf_req_rej(struct ppp_fsm_t *layer)
switch(layer->fsm_state)
{
case FSM_Closed:
- send_term_ack(layer);
+ layer->send_term_ack(layer);
break;
case FSM_Stopped:
//if (layer->init_req_cnt) layer->init_req_cnt(layer);
@@ -302,7 +302,7 @@ void ppp_fsm_recv_conf_ack(struct ppp_fsm_t *layer)
{
case FSM_Closed:
case FSM_Stopped:
- send_term_ack(layer);
+ layer->send_term_ack(layer);
break;
case FSM_Req_Sent:
//if (layer->init_req_cnt) layer->init_req_cnt(layer);
@@ -338,9 +338,13 @@ void ppp_fsm_recv_conf_rej(struct ppp_fsm_t *layer)
{
case FSM_Closed:
case FSM_Stopped:
- send_term_ack(layer);
+ layer->send_term_ack(layer);
break;
case FSM_Req_Sent:
+ if (++layer->conf_failure == layer->max_failure) {
+ ppp_terminate(layer->ppp, 0);
+ return;
+ }
//if (layer->init_req_cnt) layer->init_req_cnt(layer);
init_req_counter(layer,layer->max_failure);
--layer->restart_counter;
@@ -375,7 +379,7 @@ void ppp_fsm_recv_term_req(struct ppp_fsm_t *layer)
case FSM_Opened:
if (layer->layer_down) layer->layer_down(layer);
//send_term_req(layer);
- send_term_ack(layer);
+ layer->send_term_ack(layer);
//if (layer->zero_req_cnt) layer->zero_req_cnt(layer);
zero_req_counter(layer);
layer->fsm_state=FSM_Stopping;
@@ -383,17 +387,18 @@ void ppp_fsm_recv_term_req(struct ppp_fsm_t *layer)
case FSM_Req_Sent:
case FSM_Ack_Rcvd:
case FSM_Ack_Sent:
- send_term_ack(layer);
+ layer->send_term_ack(layer);
layer->fsm_state=FSM_Req_Sent;
break;
default:
- send_term_req(layer);
+ layer->send_term_req(layer);
break;
}
}
void ppp_fsm_recv_term_ack(struct ppp_fsm_t *layer)
{
+ stop_timer(layer);
switch(layer->fsm_state)
{
case FSM_Closing:
@@ -420,7 +425,7 @@ void ppp_fsm_recv_term_ack(struct ppp_fsm_t *layer)
void ppp_fsm_recv_unk(struct ppp_fsm_t *layer)
{
- if (layer->send_conf_rej) layer->send_conf_rej(layer);
+ if (layer->send_code_rej) layer->send_code_rej(layer);
}
void ppp_fsm_recv_code_rej_perm(struct ppp_fsm_t *layer)
@@ -441,7 +446,7 @@ void ppp_fsm_recv_code_rej_bad(struct ppp_fsm_t *layer)
{
case FSM_Opened:
if (layer->layer_down) layer->layer_down(layer);
- send_term_req(layer);
+ layer->send_term_req(layer);
layer->fsm_state=FSM_Stopping;
break;
case FSM_Closing:
@@ -460,34 +465,6 @@ void ppp_fsm_recv_code_rej_bad(struct ppp_fsm_t *layer)
}
}
-void send_term_req(struct ppp_fsm_t *layer)
-{
- struct lcp_hdr_t hdr = {
- .proto = htons(PPP_LCP),
- .code = TERMREQ,
- .id = ++layer->id,
- .len = htons(4),
- };
-
- log_ppp_debug("send [LCP TermReq id=%i \"\"]\n",hdr.id);
-
- --layer->restart_counter;
- ppp_chan_send(layer->ppp, &hdr, 6);
-}
-void send_term_ack(struct ppp_fsm_t *layer)
-{
- struct lcp_hdr_t hdr = {
- .proto = htons(PPP_LCP),
- .code = TERMACK,
- .id = layer->recv_id,
- .len = htons(4),
- };
-
- log_ppp_debug("send [LCP TermAck id=%i \"\"]\n", hdr.id);
-
- ppp_chan_send(layer->ppp, &hdr, 6);
-}
-
static void stop_timer(struct ppp_fsm_t *fsm)
{
if (fsm->restart_timer.tpd)
@@ -510,6 +487,8 @@ static void restart_timer_func(struct triton_timer_t *t)
{
struct ppp_fsm_t *layer = container_of(t, typeof(*layer), restart_timer);
+ log_ppp_debug("fsm timeout\n");
+
if (layer->restart_counter>0)
ppp_fsm_timeout0(layer);
else
diff --git a/accel-pptpd/ppp/ppp_fsm.h b/accel-pptpd/ppp/ppp_fsm.h
index 908936d..4252a55 100644
--- a/accel-pptpd/ppp/ppp_fsm.h
+++ b/accel-pptpd/ppp/ppp_fsm.h
@@ -12,6 +12,7 @@ typedef enum {FSM_Initial=0,FSM_Starting,FSM_Closed,FSM_Stopped,FSM_Closing,FSM_
#define TERMREQ 5 /* Termination Request */
#define TERMACK 6 /* Termination Ack */
#define CODEREJ 7 /* Code Reject */
+#define PROTOREJ 8 /* Code Reject */
#define ECHOREQ 9 /* Echo Request */
#define ECHOREP 10 /* Echo Reply */
@@ -21,6 +22,7 @@ struct ppp_fsm_t
{
struct ppp_t *ppp;
FSM_STATE fsm_state;
+ uint16_t proto;
struct triton_timer_t restart_timer;
int restart_counter;
@@ -28,6 +30,7 @@ struct ppp_fsm_t
int max_configure;
int max_failure;
int timeout;
+ int conf_failure;
int id;
int recv_id;
@@ -41,6 +44,9 @@ struct ppp_fsm_t
void (*send_conf_ack)(struct ppp_fsm_t*);
void (*send_conf_nak)(struct ppp_fsm_t*);
void (*send_conf_rej)(struct ppp_fsm_t*);
+ void (*send_code_rej)(struct ppp_fsm_t*);
+ void (*send_term_req)(struct ppp_fsm_t*);
+ void (*send_term_ack)(struct ppp_fsm_t*);
};
void ppp_fsm_init(struct ppp_fsm_t*);
diff --git a/accel-pptpd/ppp/ppp_ipcp.c b/accel-pptpd/ppp/ppp_ipcp.c
index f3c20a6..795cbc0 100644
--- a/accel-pptpd/ppp/ppp_ipcp.c
+++ b/accel-pptpd/ppp/ppp_ipcp.c
@@ -31,6 +31,8 @@ static void send_conf_ack(struct ppp_fsm_t*);
static void send_conf_nak(struct ppp_fsm_t*);
static void send_conf_rej(struct ppp_fsm_t*);
static void ipcp_recv(struct ppp_handler_t*);
+static void send_term_req(struct ppp_fsm_t *fsm);
+static void send_term_ack(struct ppp_fsm_t *fsm);
static void ipcp_options_init(struct ppp_ipcp_t *ipcp)
{
@@ -77,7 +79,8 @@ static struct ppp_layer_data_t *ipcp_layer_init(struct ppp_t *ppp)
ipcp->hnd.recv=ipcp_recv;
ppp_register_unit_handler(ppp,&ipcp->hnd);
-
+
+ ipcp->fsm.proto = PPP_IPCP;
ppp_fsm_init(&ipcp->fsm);
ipcp->fsm.layer_up=ipcp_layer_up;
@@ -86,6 +89,8 @@ static struct ppp_layer_data_t *ipcp_layer_init(struct ppp_t *ppp)
ipcp->fsm.send_conf_ack=send_conf_ack;
ipcp->fsm.send_conf_nak=send_conf_nak;
ipcp->fsm.send_conf_rej=send_conf_rej;
+ ipcp->fsm.send_term_req=send_term_req;
+ ipcp->fsm.send_term_ack=send_term_ack;
INIT_LIST_HEAD(&ipcp->options);
INIT_LIST_HEAD(&ipcp->ropt_list);
@@ -477,6 +482,36 @@ static int ipcp_recv_conf_ack(struct ppp_ipcp_t *ipcp,uint8_t *data,int size)
return res;
}
+static void send_term_req(struct ppp_fsm_t *fsm)
+{
+ struct ppp_ipcp_t *ipcp=container_of(fsm,typeof(*ipcp),fsm);
+ struct ipcp_hdr_t hdr = {
+ .proto = htons(PPP_IPCP),
+ .code = TERMREQ,
+ .id = ++ipcp->fsm.id,
+ .len = htons(4),
+ };
+
+ log_ppp_debug("send [IPCP TermReq id=%i \"\"]\n",hdr.id);
+
+ ppp_unit_send(ipcp->ppp, &hdr, 6);
+}
+
+static void send_term_ack(struct ppp_fsm_t *fsm)
+{
+ struct ppp_ipcp_t *ipcp=container_of(fsm,typeof(*ipcp),fsm);
+ struct ipcp_hdr_t hdr = {
+ .proto = htons(PPP_IPCP),
+ .code = TERMACK,
+ .id = ipcp->fsm.recv_id,
+ .len = htons(4),
+ };
+
+ log_ppp_debug("send [IPCP TermAck id=%i \"\"]\n", hdr.id);
+
+ ppp_unit_send(ipcp->ppp, &hdr, 6);
+}
+
static void ipcp_recv(struct ppp_handler_t*h)
{
struct ipcp_hdr_t *hdr;
@@ -541,17 +576,18 @@ static void ipcp_recv(struct ppp_handler_t*h)
ppp_fsm_recv_conf_rej(&ipcp->fsm);
break;
case TERMREQ:
- term_msg=_strndup((char*)(hdr+1),ntohs(hdr->len));
+ term_msg=_strndup((char*)(hdr+1),ntohs(hdr->len) - 4);
log_ppp_debug("recv [IPCP TermReq id=%x \"%s\"]\n",hdr->id,term_msg);
_free(term_msg);
ppp_fsm_recv_term_req(&ipcp->fsm);
ppp_terminate(ipcp->ppp, 0);
break;
case TERMACK:
- term_msg=_strndup((char*)(hdr+1),ntohs(hdr->len));
+ term_msg=_strndup((char*)(hdr+1),ntohs(hdr->len) - 4);
log_ppp_debug("recv [IPCP TermAck id=%x \"%s\"]\n",hdr->id,term_msg);
_free(term_msg);
ppp_fsm_recv_term_ack(&ipcp->fsm);
+ ppp_terminate(ipcp->ppp, 0);
break;
case CODEREJ:
log_ppp_debug("recv [IPCP CodeRej id=%x]\n",hdr->id);
diff --git a/accel-pptpd/ppp/ppp_lcp.c b/accel-pptpd/ppp/ppp_lcp.c
index 7081cbb..66d31da 100644
--- a/accel-pptpd/ppp/ppp_lcp.c
+++ b/accel-pptpd/ppp/ppp_lcp.c
@@ -34,9 +34,12 @@ static int send_conf_req(struct ppp_fsm_t*);
static void send_conf_ack(struct ppp_fsm_t*);
static void send_conf_nak(struct ppp_fsm_t*);
static void send_conf_rej(struct ppp_fsm_t*);
-static void lcp_recv(struct ppp_handler_t*);
+static void send_code_rej(struct ppp_fsm_t*);
static void start_echo(struct ppp_lcp_t *lcp);
static void stop_echo(struct ppp_lcp_t *lcp);
+static void send_term_req(struct ppp_fsm_t *fsm);
+static void send_term_ack(struct ppp_fsm_t *fsm);
+static void lcp_recv(struct ppp_handler_t*);
static void lcp_options_init(struct ppp_lcp_t *lcp)
{
@@ -85,7 +88,8 @@ static struct ppp_layer_data_t *lcp_layer_init(struct ppp_t *ppp)
lcp->hnd.recv=lcp_recv;
ppp_register_chan_handler(ppp,&lcp->hnd);
-
+
+ lcp->fsm.proto = PPP_LCP;
ppp_fsm_init(&lcp->fsm);
lcp->fsm.layer_up=lcp_layer_up;
@@ -95,6 +99,9 @@ static struct ppp_layer_data_t *lcp_layer_init(struct ppp_t *ppp)
lcp->fsm.send_conf_ack=send_conf_ack;
lcp->fsm.send_conf_nak=send_conf_nak;
lcp->fsm.send_conf_rej=send_conf_rej;
+ lcp->fsm.send_code_rej=send_code_rej;
+ lcp->fsm.send_term_req=send_term_req;
+ lcp->fsm.send_term_ack=send_term_ack;
INIT_LIST_HEAD(&lcp->ropt_list);
@@ -237,12 +244,23 @@ static void send_conf_ack(struct ppp_fsm_t *fsm)
ppp_chan_send(lcp->ppp,hdr,ntohs(hdr->len)+2);
}
+static void send_code_rej(struct ppp_fsm_t *fsm)
+{
+ struct ppp_lcp_t *lcp=container_of(fsm,typeof(*lcp),fsm);
+ struct lcp_hdr_t *hdr=(struct lcp_hdr_t*)lcp->ppp->chan_buf;
+
+ hdr->code=CONFACK;
+ log_ppp_debug("send [LCP CodeRej %x id=%x ]\n",hdr->code, lcp->fsm.recv_id);
+
+ ppp_chan_send(lcp->ppp,hdr,ntohs(hdr->len)+2);
+}
+
static void send_conf_nak(struct ppp_fsm_t *fsm)
{
struct ppp_lcp_t *lcp=container_of(fsm,typeof(*lcp),fsm);
uint8_t *buf=_malloc(lcp->conf_req_len), *ptr=buf;
struct lcp_hdr_t *lcp_hdr=(struct lcp_hdr_t*)ptr;
- struct recv_opt_t *ropt;
+ struct lcp_option_t *lopt;
log_ppp_debug("send [LCP ConfNak id=%x",lcp->fsm.recv_id);
@@ -253,13 +271,11 @@ static void send_conf_nak(struct ppp_fsm_t *fsm)
ptr+=sizeof(*lcp_hdr);
- list_for_each_entry(ropt,&lcp->ropt_list,entry)
- {
- if (ropt->state==LCP_OPT_NAK)
- {
+ list_for_each_entry(lopt, &lcp->options, entry) {
+ if (lopt->state == LCP_OPT_NAK) {
log_ppp_debug(" ");
- ropt->lopt->h->print(log_ppp_debug,ropt->lopt,NULL);
- ptr+=ropt->lopt->h->send_conf_nak(lcp,ropt->lopt,ptr);
+ lopt->h->print(log_ppp_debug,lopt,NULL);
+ ptr+=lopt->h->send_conf_nak(lcp,lopt,ptr);
}
}
@@ -362,7 +378,7 @@ static int lcp_recv_conf_req(struct ppp_lcp_t *lcp,uint8_t *data,int size)
}
log_ppp_debug("]\n");
- /*list_for_each_entry(lopt,&lcp->options,entry)
+ list_for_each_entry(lopt,&lcp->options,entry)
{
if (lopt->state==LCP_OPT_NONE)
{
@@ -370,7 +386,7 @@ static int lcp_recv_conf_req(struct ppp_lcp_t *lcp,uint8_t *data,int size)
lopt->state=r;
if (r<ret) ret=r;
}
- }*/
+ }
return ret;
}
@@ -570,6 +586,36 @@ static void stop_echo(struct ppp_lcp_t *lcp)
triton_timer_del(&lcp->echo_timer);
}
+static void send_term_req(struct ppp_fsm_t *fsm)
+{
+ struct ppp_lcp_t *lcp=container_of(fsm,typeof(*lcp),fsm);
+ struct lcp_hdr_t hdr = {
+ .proto = htons(PPP_LCP),
+ .code = TERMREQ,
+ .id = ++lcp->fsm.id,
+ .len = htons(4),
+ };
+
+ log_ppp_debug("send [LCP TermReq id=%i \"\"]\n",hdr.id);
+
+ ppp_chan_send(lcp->ppp, &hdr, 6);
+}
+
+static void send_term_ack(struct ppp_fsm_t *fsm)
+{
+ struct ppp_lcp_t *lcp=container_of(fsm,typeof(*lcp),fsm);
+ struct lcp_hdr_t hdr = {
+ .proto = htons(PPP_LCP),
+ .code = TERMACK,
+ .id = lcp->fsm.recv_id,
+ .len = htons(4),
+ };
+
+ log_ppp_debug("send [LCP TermAck id=%i \"\"]\n", hdr.id);
+
+ ppp_chan_send(lcp->ppp, &hdr, 6);
+}
+
static void lcp_recv(struct ppp_handler_t*h)
{
struct lcp_hdr_t *hdr;
@@ -656,7 +702,11 @@ static void lcp_recv(struct ppp_handler_t*h)
case ECHOREP:
lcp_recv_echo_repl(lcp,(uint8_t*)(hdr+1),ntohs(hdr->len)-PPP_HDRLEN);
break;
+ case PROTOREJ:
+ log_ppp_debug("recv [LCP ProtoRej id=%x <%x>]\n",hdr->code, hdr->id, *(uint16_t*)(hdr + 1));
+ break;
default:
+ log_ppp_debug("recv [LCP Unknown %x]\n",hdr->code);
ppp_fsm_recv_unk(&lcp->fsm);
break;
}