diff options
Diffstat (limited to 'accel-pptpd/ppp')
-rw-r--r-- | accel-pptpd/ppp/ccp_mppe.c | 214 | ||||
-rw-r--r-- | accel-pptpd/ppp/ipcp_opt_dns.c | 3 | ||||
-rw-r--r-- | accel-pptpd/ppp/ipcp_opt_ipaddr.c | 3 | ||||
-rw-r--r-- | accel-pptpd/ppp/lcp_opt_accomp.c | 8 | ||||
-rw-r--r-- | accel-pptpd/ppp/lcp_opt_magic.c | 7 | ||||
-rw-r--r-- | accel-pptpd/ppp/lcp_opt_mru.c | 7 | ||||
-rw-r--r-- | accel-pptpd/ppp/lcp_opt_pcomp.c | 8 | ||||
-rw-r--r-- | accel-pptpd/ppp/ppp.c | 2 | ||||
-rw-r--r-- | accel-pptpd/ppp/ppp_ccp.c | 168 | ||||
-rw-r--r-- | accel-pptpd/ppp/ppp_ccp.h | 9 |
10 files changed, 362 insertions, 67 deletions
diff --git a/accel-pptpd/ppp/ccp_mppe.c b/accel-pptpd/ppp/ccp_mppe.c new file mode 100644 index 00000000..8958b520 --- /dev/null +++ b/accel-pptpd/ppp/ccp_mppe.c @@ -0,0 +1,214 @@ +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <sys/ioctl.h> +#include <linux/if_ppp.h> +#include <net/if.h> + +#include "ppp.h" +#include "ppp_ccp.h" +#include "log.h" +#include "events.h" + +#include "memdebug.h" + +#define MPPE_H (1 << 24) +#define MPPE_M (1 << 7) +#define MPPE_S (1 << 6) +#define MPPE_L (1 << 5) +#define MPPE_D (1 << 4) +#define MPPE_C (1 << 0) + +#define MPPE_PAD 4 + +static struct ccp_option_t *mppe_init(struct ppp_ccp_t *ccp); +static void mppe_free(struct ppp_ccp_t *ccp, struct ccp_option_t *opt); +static int mppe_send_conf_req(struct ppp_ccp_t *ccp, struct ccp_option_t *opt, uint8_t *ptr); +static int mppe_recv_conf_req(struct ppp_ccp_t *ccp, struct ccp_option_t *opt, uint8_t *ptr); +static void mppe_print(void (*print)(const char *fmt,...),struct ccp_option_t*, uint8_t *ptr); + +struct mppe_option_t +{ + struct ccp_option_t opt; + int mppe; + uint8_t recv_key[16]; + uint8_t send_key[16]; + int policy; // 1 - allowed, 2 - required +}; + +static struct ccp_option_handler_t mppe_opt_hnd = { + .init = mppe_init, + .send_conf_req = mppe_send_conf_req, + .send_conf_nak = mppe_send_conf_req, + .recv_conf_req = mppe_recv_conf_req, + .free = mppe_free, + .print = mppe_print, +}; + +static struct ccp_option_t *mppe_init(struct ppp_ccp_t *ccp) +{ + struct mppe_option_t *mppe_opt = _malloc(sizeof(*mppe_opt)); + memset(mppe_opt, 0, sizeof(*mppe_opt)); + mppe_opt->mppe = -1; + mppe_opt->opt.id = CI_MPPE; + mppe_opt->opt.len = 6; + + return &mppe_opt->opt; +} + +static void mppe_free(struct ppp_ccp_t *ccp, struct ccp_option_t *opt) +{ + struct mppe_option_t *mppe_opt = container_of(opt, typeof(*mppe_opt), opt); + + _free(mppe_opt); +} + +static int setup_mppe_key(int fd, int transmit, uint8_t *key) +{ + struct ppp_option_data data; + uint8_t buf[6 + 16]; + + memset(buf, 0, sizeof(buf)); + buf[0] = CI_MPPE; + buf[1] = 6; + *(uint32_t*)(buf + 2) = htonl(MPPE_S | MPPE_H); + if (key) + memcpy(buf + 6, key, 16); + + memset(&data, 0, sizeof(data)); + data.ptr = buf; + data.length = sizeof(buf); + data.transmit = transmit; + + if (ioctl(fd, PPPIOCSCOMPRESS, &data)) { + log_ppp_warn("mppe: MPPE requested but not supported by kernel\n"); + return -1; + } + + return 0; +} + +static int decrease_mtu(struct ppp_t *ppp) +{ + struct ifreq ifr; + + strcpy(ifr.ifr_name, ppp->ifname); + + if (ioctl(sock_fd, SIOCGIFMTU, &ifr)) { + log_ppp_error("mppe: failed to get MTU: %s\n", strerror(errno)); + return -1; + } + + ifr.ifr_mtu -= MPPE_PAD; + + if (ioctl(sock_fd, SIOCSIFMTU, &ifr)) { + log_ppp_error("mppe: failed to set MTU: %s\n", strerror(errno)); + return -1; + } + + return 0; +} + +static int mppe_send_conf_req(struct ppp_ccp_t *ccp, struct ccp_option_t *opt, uint8_t *ptr) +{ + struct mppe_option_t *mppe_opt = container_of(opt,typeof(*mppe_opt),opt); + struct ccp_opt32_t *opt32 = (struct ccp_opt32_t*)ptr; + + if (mppe_opt->policy == 2 || mppe_opt->mppe != -1) { + opt32->hdr.id = CI_MPPE; + opt32->hdr.len = 6; + opt32->val = mppe_opt->mppe ? htonl(MPPE_S | MPPE_H) : 0; + + if (mppe_opt->mppe && setup_mppe_key(ccp->ppp->unit_fd, 0, mppe_opt->recv_key)) + return 0; + + return 6; + } + return 0; +} + +static int mppe_recv_conf_req(struct ppp_ccp_t *ccp, struct ccp_option_t *opt, uint8_t *ptr) +{ + struct mppe_option_t *mppe_opt = container_of(opt, typeof(*mppe_opt), opt); + struct ccp_opt32_t *opt32 = (struct ccp_opt32_t *)ptr; + + /*if (!ptr) { + if (mppe_opt->policy == 2) + return CCP_OPT_NAK; + return CCP_OPT_ACK; + }*/ + + if (opt32->hdr.len != 6) + return CCP_OPT_REJ; + + if (mppe_opt->policy == 2) { + if (ntohl(opt32->val) != (MPPE_S | MPPE_H)) + return CCP_OPT_NAK; + } else if (mppe_opt->policy == 1) { + if (ntohl(opt32->val) == (MPPE_S | MPPE_H)) + mppe_opt->mppe = 1; + else if ((ntohl(opt32->val) & (MPPE_S | MPPE_H)) == (MPPE_S | MPPE_H)) { + mppe_opt->mppe = 1; + return CCP_OPT_NAK; + } else if (opt32->val) { + mppe_opt->mppe = 0; + return CCP_OPT_NAK; + } else + mppe_opt->mppe = 0; + } + + if (setup_mppe_key(ccp->ppp->unit_fd, 1, mppe_opt->send_key)) + return CCP_OPT_REJ; + + decrease_mtu(ccp->ppp); + + return CCP_OPT_ACK; +} + +static void mppe_print(void (*print)(const char *fmt,...),struct ccp_option_t *opt, uint8_t *ptr) +{ + struct mppe_option_t *mppe_opt = container_of(opt, typeof(*mppe_opt), opt); + struct ccp_opt32_t *opt32 = (struct ccp_opt32_t *)ptr; + uint32_t bits; + + if (ptr) + bits = ntohl(opt32->val); + else + if (mppe_opt->mppe) + bits = MPPE_S | MPPE_H; + else + bits = 0; + + print("<mppe %sH %sM %sS %sL %sD %sC>", + bits & MPPE_H ? "+" : "-", + bits & MPPE_M ? "+" : "-", + bits & MPPE_S ? "+" : "-", + bits & MPPE_L ? "+" : "-", + bits & MPPE_D ? "+" : "-", + bits & MPPE_C ? "+" : "-" + ); +} + +static void ev_mppe_keys(struct ev_mppe_keys_t *ev) +{ + struct mppe_option_t *mppe_opt = container_of(ccp_find_option(ev->ppp, &mppe_opt_hnd), typeof(*mppe_opt), opt); + + if ((ev->type & 0x02) == 0) { + log_ppp_warn("mppe: 128-bit session keys not allowed, disabling mppe ...\n"); + return; + } + + memcpy(mppe_opt->recv_key, ev->recv_key, 16); + memcpy(mppe_opt->send_key, ev->send_key, 16); + mppe_opt->policy = ev->policy; + + if (ev->policy == 2) + mppe_opt->mppe = 1; +} + +static void __init mppe_opt_init() +{ + ccp_option_register(&mppe_opt_hnd); + triton_event_register_handler(EV_MPPE_KEYS, (triton_event_func)ev_mppe_keys); +} + diff --git a/accel-pptpd/ppp/ipcp_opt_dns.c b/accel-pptpd/ppp/ipcp_opt_dns.c index b0365da2..4c48fd4c 100644 --- a/accel-pptpd/ppp/ipcp_opt_dns.c +++ b/accel-pptpd/ppp/ipcp_opt_dns.c @@ -101,6 +101,9 @@ static int dns_recv_conf_req(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *opt, struct dns_option_t *dns_opt=container_of(opt,typeof(*dns_opt),opt); struct ipcp_opt32_t *opt32=(struct ipcp_opt32_t*)ptr; + if (opt32->hdr.len != 6) + return IPCP_OPT_REJ; + if (!dns_opt->addr) { if (dns_opt->opt.id == CI_DNS1 && conf_dns1) dns_opt->addr=conf_dns1; diff --git a/accel-pptpd/ppp/ipcp_opt_ipaddr.c b/accel-pptpd/ppp/ipcp_opt_ipaddr.c index 963d4736..108e350c 100644 --- a/accel-pptpd/ppp/ipcp_opt_ipaddr.c +++ b/accel-pptpd/ppp/ipcp_opt_ipaddr.c @@ -104,6 +104,9 @@ static int ipaddr_recv_conf_req(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *o struct sockaddr_in addr; struct npioctl np; + if (opt32->hdr.len != 6) + return IPCP_OPT_REJ; + if (ipaddr_opt->ip->peer_addr == opt32->val) goto ack; diff --git a/accel-pptpd/ppp/lcp_opt_accomp.c b/accel-pptpd/ppp/lcp_opt_accomp.c index 94fa1281..241b0e06 100644 --- a/accel-pptpd/ppp/lcp_opt_accomp.c +++ b/accel-pptpd/ppp/lcp_opt_accomp.c @@ -75,13 +75,17 @@ static int accomp_send_conf_nak(struct ppp_lcp_t *lcp, struct lcp_option_t *opt, static int accomp_recv_conf_req(struct ppp_lcp_t *lcp, struct lcp_option_t *opt, uint8_t *ptr) { struct accomp_option_t *accomp_opt=container_of(opt,typeof(*accomp_opt),opt); + struct lcp_opt_hdr_t *opt0=(struct lcp_opt_hdr_t*)ptr; - if (!ptr) { + /*if (!ptr) { if (accomp_opt->require) return LCP_OPT_NAK; accomp_opt->accomp=0; return LCP_OPT_ACK; - } + }*/ + + if (opt0->len != 2) + return LCP_OPT_REJ; if (accomp_opt->accomp>0) { diff --git a/accel-pptpd/ppp/lcp_opt_magic.c b/accel-pptpd/ppp/lcp_opt_magic.c index 166c85c4..4a61ef91 100644 --- a/accel-pptpd/ppp/lcp_opt_magic.c +++ b/accel-pptpd/ppp/lcp_opt_magic.c @@ -64,8 +64,11 @@ 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 (!ptr) + return LCP_OPT_NAK;*/ + + if (opt32->hdr.len != 6) + return LCP_OPT_REJ; if (magic_opt->magic==ntohl(opt32->val)) { diff --git a/accel-pptpd/ppp/lcp_opt_mru.c b/accel-pptpd/ppp/lcp_opt_mru.c index 096c0d58..9bf7af67 100644 --- a/accel-pptpd/ppp/lcp_opt_mru.c +++ b/accel-pptpd/ppp/lcp_opt_mru.c @@ -86,8 +86,11 @@ 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 (!ptr) + return LCP_OPT_NAK;*/ + + if (opt16->hdr.len != 4) + return LCP_OPT_REJ; 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 a1ceb8e8..1f8532bb 100644 --- a/accel-pptpd/ppp/lcp_opt_pcomp.c +++ b/accel-pptpd/ppp/lcp_opt_pcomp.c @@ -75,13 +75,17 @@ static int pcomp_send_conf_nak(struct ppp_lcp_t *lcp, struct lcp_option_t *opt, static int pcomp_recv_conf_req(struct ppp_lcp_t *lcp, struct lcp_option_t *opt, uint8_t *ptr) { struct pcomp_option_t *pcomp_opt=container_of(opt,typeof(*pcomp_opt),opt); + struct lcp_opt_hdr_t *opt0=(struct lcp_opt_hdr_t*)ptr; - if (!ptr) { + /*if (!ptr) { if (pcomp_opt->require) return LCP_OPT_NAK; pcomp_opt->pcomp=0; return LCP_OPT_ACK; - } + }*/ + + if (opt0->len != 2) + return LCP_OPT_REJ; if (pcomp_opt->pcomp>0) { diff --git a/accel-pptpd/ppp/ppp.c b/accel-pptpd/ppp/ppp.c index 94919779..ee7e13cc 100644 --- a/accel-pptpd/ppp/ppp.c +++ b/accel-pptpd/ppp/ppp.c @@ -424,8 +424,8 @@ static int get_layer_order(const char *name) { if (!strcmp(name,"lcp")) return 0; if (!strcmp(name,"auth")) return 1; - if (!strcmp(name,"ipcp")) return 2; if (!strcmp(name,"ccp")) return 2; + if (!strcmp(name,"ipcp")) return 3; return -1; } diff --git a/accel-pptpd/ppp/ppp_ccp.c b/accel-pptpd/ppp/ppp_ccp.c index 6deaeb18..36db6f9a 100644 --- a/accel-pptpd/ppp/ppp_ccp.c +++ b/accel-pptpd/ppp/ppp_ccp.c @@ -1,8 +1,9 @@ #include <stdlib.h> #include <string.h> +#include <errno.h> #include <linux/ppp_defs.h> #include <linux/if_ppp.h> -#include <arpa/inet.h> +#include <sys/ioctl.h> #include "triton.h" @@ -22,6 +23,7 @@ struct recv_opt_t struct ccp_option_t *lopt; }; +static struct ppp_layer_t ccp_layer; static LIST_HEAD(option_handlers); static void ccp_layer_up(struct ppp_fsm_t*); @@ -65,6 +67,26 @@ static void ccp_options_free(struct ppp_ccp_t *ccp) } } +static int ccp_set_flags(int fd, int isopen, int isup) +{ + int flags; + + if (ioctl(fd, PPPIOCGFLAGS, &flags)) { + log_ppp_error("ccp: failed to get flags: %s\n", strerror(errno)); + return -1; + } + + flags &= ~(SC_CCP_OPEN | SC_CCP_UP); + flags |= (isopen ? SC_CCP_OPEN : 0) | (isup ? SC_CCP_UP : 0); + + if (ioctl(fd, PPPIOCSFLAGS, &flags)) { + log_ppp_error("ccp: failed to set flags: %s\n", strerror(errno)); + return -1; + } + + return 0; +} + static struct ppp_layer_data_t *ccp_layer_init(struct ppp_t *ppp) { struct ppp_ccp_t *ccp=_malloc(sizeof(*ccp)); @@ -80,6 +102,11 @@ static struct ppp_layer_data_t *ccp_layer_init(struct ppp_t *ppp) ppp_register_unit_handler(ppp,&ccp->hnd); + INIT_LIST_HEAD(&ccp->options); + ccp_options_init(ccp); + + ccp->passive = 1; + ccp->fsm.proto = PPP_CCP; ppp_fsm_init(&ccp->fsm); @@ -92,7 +119,6 @@ static struct ppp_layer_data_t *ccp_layer_init(struct ppp_t *ppp) 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); return &ccp->ld; @@ -104,8 +130,6 @@ int ccp_layer_start(struct ppp_layer_data_t *ld) log_ppp_debug("ccp_layer_start\n"); - ccp_options_init(ccp); - if (list_empty(&ccp->options)) { ppp_layer_started(ccp->ppp, &ccp->ld); return 0; @@ -115,6 +139,11 @@ int ccp_layer_start(struct ppp_layer_data_t *ld) if (ppp_fsm_open(&ccp->fsm)) return -1; + if (ccp_set_flags(ccp->ppp->unit_fd, 1, 0)) { + ppp_fsm_close(&ccp->fsm); + return -1; + } + return 0; } @@ -123,6 +152,8 @@ void ccp_layer_finish(struct ppp_layer_data_t *ld) struct ppp_ccp_t *ccp=container_of(ld,typeof(*ccp),ld); log_ppp_debug("ccp_layer_finish\n"); + + ccp_set_flags(ccp->ppp->unit_fd, 0, 0); ccp->fsm.fsm_state = FSM_Closed; ppp_layer_finished(ccp->ppp,&ccp->ld); @@ -146,6 +177,10 @@ 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; + if (ccp_set_flags(ccp->ppp->unit_fd, 1, 1)) { + ppp_terminate(ccp->ppp, 0); + return; + } ppp_layer_started(ccp->ppp,&ccp->ld); } @@ -174,38 +209,45 @@ static void print_ropt(struct recv_opt_t *ropt) static int send_conf_req(struct ppp_fsm_t *fsm) { - struct ppp_ccp_t *ccp=container_of(fsm,typeof(*ccp),fsm); - uint8_t *buf=_malloc(ccp->conf_req_len), *ptr=buf; - struct ccp_hdr_t *ccp_hdr=(struct ccp_hdr_t*)ptr; + struct ppp_ccp_t *ccp = container_of(fsm, typeof(*ccp), fsm); + uint8_t *buf, *ptr; + struct ccp_hdr_t *ccp_hdr; struct ccp_option_t *lopt; int n; - log_ppp_debug("send [CCP ConfReq"); - ccp_hdr->proto=htons(PPP_CCP); - ccp_hdr->code=CONFREQ; - ccp_hdr->id=++ccp->fsm.id; - ccp_hdr->len=0; - log_ppp_debug(" id=%x",ccp_hdr->id); + ccp->need_req = 0; + + if (ccp->passive) + return 0; + + buf = _malloc(ccp->conf_req_len); + ccp_hdr = (struct ccp_hdr_t*)buf; + + ccp_hdr->proto = htons(PPP_CCP); + ccp_hdr->code = CONFREQ; + ccp_hdr->id = ++ccp->fsm.id; + ccp_hdr->len = 0; - ptr+=sizeof(*ccp_hdr); + ptr = (uint8_t*)(ccp_hdr + 1); - list_for_each_entry(lopt,&ccp->options,entry) - { - n=lopt->h->send_conf_req(ccp,lopt,ptr); + log_ppp_debug("send [CCP ConfReq id=%x", ccp_hdr->id); + + list_for_each_entry(lopt,&ccp->options,entry) { + n = lopt->h->send_conf_req(ccp,lopt,ptr); if (n < 0) return -1; - if (n) - { + if (n) { log_ppp_debug(" "); - lopt->h->print(log_ppp_debug,lopt,NULL); - ptr+=n; + lopt->h->print(log_ppp_debug, lopt, NULL); + lopt->state = CCP_OPT_ACK; } + ptr += n; } log_ppp_debug("]\n"); - - ccp_hdr->len=htons((ptr-buf)-2); - ppp_unit_send(ccp->ppp,ccp_hdr,ptr-buf); + + ccp_hdr->len = htons((ptr-buf)-2); + ppp_unit_send(ccp->ppp, ccp_hdr, ptr-buf); _free(buf); @@ -298,9 +340,10 @@ static int ccp_recv_conf_req(struct ppp_ccp_t *ccp,uint8_t *data,int size) struct ccp_opt_hdr_t *hdr; struct recv_opt_t *ropt; struct ccp_option_t *lopt; - int r,ret=1,ack=0; + int r, ret = 1, ack = 0; - ccp->ropt_len=size; + ccp->need_req = 0; + ccp->ropt_len = size; while(size>0) { @@ -318,41 +361,37 @@ static int ccp_recv_conf_req(struct ppp_ccp_t *ccp,uint8_t *data,int size) size-=ropt->len; } - list_for_each_entry(lopt,&ccp->options,entry) - lopt->state=CCP_OPT_NONE; - - log_ppp_debug("recv [CCP ConfReq id=%x",ccp->fsm.recv_id); - list_for_each_entry(ropt,&ccp->ropt_list,entry) + log_ppp_debug("recv [CCP ConfReq id=%x", ccp->fsm.recv_id); + list_for_each_entry(ropt, &ccp->ropt_list, entry) { - list_for_each_entry(lopt,&ccp->options,entry) + list_for_each_entry(lopt, &ccp->options, entry) { - if (lopt->id==ropt->hdr->id) - { + if (lopt->id == ropt->hdr->id) { log_ppp_debug(" "); - lopt->h->print(log_ppp_debug,lopt,(uint8_t*)ropt->hdr); - r=lopt->h->recv_conf_req(ccp,lopt,(uint8_t*)ropt->hdr); - if (ack) - { - lopt->state=CCP_OPT_REJ; - ropt->state=CCP_OPT_REJ; - }else - { - lopt->state=r; - ropt->state=r; + lopt->h->print(log_ppp_debug, lopt, (uint8_t*)ropt->hdr); + r = lopt->h->recv_conf_req(ccp, lopt, (uint8_t*)ropt->hdr); + if (ack) { + lopt->state = CCP_OPT_REJ; + ropt->state = CCP_OPT_REJ; + } else { + if (lopt->state == CCP_OPT_NAK && r == CCP_OPT_ACK) + ccp->need_req = 1; + lopt->state = r; + ropt->state = r; } - ropt->lopt=lopt; - if (r<ret) ret=r; + ropt->lopt = lopt; + if (r < ret) + ret = r; break; } } - if (ropt->state==CCP_OPT_ACK || ropt->state==CCP_OPT_NAK) - ack=1; - else if (!ropt->lopt) - { + if (ropt->state == CCP_OPT_ACK || ropt->state == CCP_OPT_NAK) + ack = 1; + else if (!ropt->lopt) { log_ppp_debug(" "); print_ropt(ropt); - ropt->state=CCP_OPT_REJ; - ret=CCP_OPT_REJ; + ropt->state = CCP_OPT_REJ; + ret = CCP_OPT_REJ; } } log_ppp_debug("]\n"); @@ -570,14 +609,22 @@ static void ccp_recv(struct ppp_handler_t*h) break; } ccp_free_conf_req(ccp); - if (r==CCP_OPT_FAIL) + + if (r == CCP_OPT_ACK && ccp->passive) { + ccp->passive = 0; + send_conf_req(&ccp->fsm); + } + if (r == CCP_OPT_FAIL) ppp_terminate(ccp->ppp, 0); break; case CONFACK: if (ccp_recv_conf_ack(ccp,(uint8_t*)(hdr+1),ntohs(hdr->len)-PPP_HDRLEN)) ppp_terminate(ccp->ppp, 0); - else + else { ppp_fsm_recv_conf_ack(&ccp->fsm); + if (ccp->need_req) + send_conf_req(&ccp->fsm); + } break; case CONFNAK: ccp_recv_conf_nak(ccp,(uint8_t*)(hdr+1),ntohs(hdr->len)-PPP_HDRLEN); @@ -625,6 +672,19 @@ int ccp_option_register(struct ccp_option_handler_t *h) return 0; } +struct ccp_option_t *ccp_find_option(struct ppp_t *ppp, struct ccp_option_handler_t *h) +{ + struct ppp_ccp_t *ccp = container_of(ppp_find_layer_data(ppp, &ccp_layer), typeof(*ccp), ld); + struct ccp_option_t *opt; + + list_for_each_entry(opt, &ccp->options, entry) + if (opt->h == h) + return opt; + + log_emerg("ccp: BUG: option not found\n"); + abort(); +} + static struct ppp_layer_t ccp_layer= { .init=ccp_layer_init, diff --git a/accel-pptpd/ppp/ppp_ccp.h b/accel-pptpd/ppp/ppp_ccp.h index 23f44f0f..27b303e6 100644 --- a/accel-pptpd/ppp/ppp_ccp.h +++ b/accel-pptpd/ppp/ppp_ccp.h @@ -8,10 +8,8 @@ /* * Options. */ -#define CI_COMP 2 /* IP-Compress-Protocol */ -#define CI_ADDR 3 /* IP-Address */ -#define CI_DNS1 129 /* Primary-DNS-Address */ -#define CI_DNS2 131 /* Secondary-DNS-Address */ + +#define CI_MPPE 18 /* MPPE */ struct ccp_hdr_t { @@ -87,9 +85,12 @@ struct ppp_ccp_t int conf_req_len; int started:1; + int passive:1; + int need_req:1; }; int ccp_option_register(struct ccp_option_handler_t *h); +struct ccp_option_t *ccp_find_option(struct ppp_t *ppp, struct ccp_option_handler_t *h); #endif |