diff options
author | Kozlov Dmitry <dima@server> | 2010-08-06 13:59:54 +0400 |
---|---|---|
committer | Kozlov Dmitry <dima@server> | 2010-08-06 13:59:54 +0400 |
commit | 4a268755565ced740c391a4c8c7fc7c98b7fc3c7 (patch) | |
tree | abfd4918ffbb26dac07ae970aa4ff628fd19c583 | |
parent | 00785e9cb2adc570a267c160b869bbf9d33bbbe4 (diff) | |
download | accel-ppp-4a268755565ced740c391a4c8c7fc7c98b7fc3c7.tar.gz accel-ppp-4a268755565ced740c391a4c8c7fc7c98b7fc3c7.zip |
* written base code of lcp module
* written generic auth module
-rw-r--r-- | accel-pptpd/CMakeLists.txt | 3 | ||||
-rw-r--r-- | accel-pptpd/ppp.c | 36 | ||||
-rw-r--r-- | accel-pptpd/ppp.h | 1 | ||||
-rw-r--r-- | accel-pptpd/ppp_auth.c | 111 | ||||
-rw-r--r-- | accel-pptpd/ppp_auth.h | 24 | ||||
-rw-r--r-- | accel-pptpd/ppp_fsm.c | 30 | ||||
-rw-r--r-- | accel-pptpd/ppp_fsm.h | 14 | ||||
-rw-r--r-- | accel-pptpd/ppp_lcp.c | 327 | ||||
-rw-r--r-- | accel-pptpd/ppp_lcp.h | 64 |
9 files changed, 428 insertions, 182 deletions
diff --git a/accel-pptpd/CMakeLists.txt b/accel-pptpd/CMakeLists.txt index 5ee16fd2..2e46e5b4 100644 --- a/accel-pptpd/CMakeLists.txt +++ b/accel-pptpd/CMakeLists.txt @@ -12,5 +12,6 @@ ADD_EXECUTABLE(pptpd ppp.c ppp_fsm.c ppp_lcp.c + ppp_auth.c ) -TARGET_LINK_LIBRARIES(pptpd pthread triton)
\ No newline at end of file +TARGET_LINK_LIBRARIES(pptpd pthread triton) diff --git a/accel-pptpd/ppp.c b/accel-pptpd/ppp.c index c24987fa..2c9c47df 100644 --- a/accel-pptpd/ppp.c +++ b/accel-pptpd/ppp.c @@ -3,8 +3,10 @@ #include <fcntl.h> #include <unistd.h> #include <stdlib.h> +#include <stdint.h> #include <string.h> #include <sys/ioctl.h> +#include <arpa/inet.h> #include <linux/ppp_defs.h> #include <linux/if_ppp.h> @@ -87,6 +89,7 @@ int establish_ppp(struct ppp_t *ppp) INIT_LIST_HEAD(&ppp->layers); ppp->lcp_layer=ppp_lcp_init(ppp); + list_add_tail(&ppp->lcp_layer->entry,&ppp->layers); ppp_fsm_open(ppp->lcp_layer); ppp_fsm_lower_up(ppp->lcp_layer); @@ -121,36 +124,22 @@ int ppp_send(struct ppp_t *ppp, void *data, int size) static void ppp_read(struct triton_md_handler_t*h) { struct ppp_t *ppp=(struct ppp_t *)h->pd; - struct ppp_hdr_t *hdr=(struct ppp_hdr_t *)(ppp->in_buf+2); - u_int16_t proto; + struct ppp_layer_t *l=NULL; + uint16_t proto; ppp->in_buf_size=read(h->fd,ppp->in_buf,PPP_MRU+PPP_HDRLEN); - //if (ppp->in_buf_size==0) - if (ppp->in_buf_size<PPP_HDRLEN+2 || ppp->in_buf_size<ntohs(hdr->len)+2) - { - log_warn("discarding short packet\n"); - return; - } - proto=ntohs(*(u_int16_t*)ppp->in_buf); - if (proto==PPP_LCP) ppp->lcp_layer->recv(ppp->lcp_layer,hdr); - else if (ppp->lcp_layer->fsm_state!=FSM_Opened) + proto=ntohs(*(uint16_t*)ppp->in_buf); + list_for_each_entry(l,&ppp->layers,entry) { - log_warn("discarding non-LCP packet when LCP is not opened\n"); - return; - }else - { - struct ppp_layer_t *l=NULL; - list_for_each_entry(l,&ppp->layers,entry) - { - if (l->proto==proto) l->recv(l,hdr); - } - - if (!l) + if (l->proto==proto) { - log_warn("discarding unknown packet %x\n",proto); + l->recv(l); + return; } } + + log_warn("discarding unknown packet %x\n",proto); } static void ppp_write(struct triton_md_handler_t*h) { @@ -172,3 +161,4 @@ static void ppp_timeout(struct triton_md_handler_t*h) { } + diff --git a/accel-pptpd/ppp.h b/accel-pptpd/ppp.h index 8e8558bb..13e69341 100644 --- a/accel-pptpd/ppp.h +++ b/accel-pptpd/ppp.h @@ -41,7 +41,6 @@ #define PPP_CBCP 0xc029 /* Callback Control Protocol */ #define PPP_EAP 0xc227 /* Extensible Authentication Protocol */ - struct ppp_t { struct triton_md_handler_t *h; diff --git a/accel-pptpd/ppp_auth.c b/accel-pptpd/ppp_auth.c new file mode 100644 index 00000000..b66727b0 --- /dev/null +++ b/accel-pptpd/ppp_auth.c @@ -0,0 +1,111 @@ +#include "triton/triton.h" + +#include "ppp.h" +#include "ppp_lcp.h" +#include "ppp_fsm.h" +#include "ppp_auth.h" + +static LIST_HEAD(drv_list); + +int auth_register(struct auth_driver_t *new) +{ + struct auth_driver_t *drv; + + list_for_each_entry(drv,&drv_list,entry) + { + if (drv->type==new->type) + return -1; + } + list_add_tail(&new->entry,&drv_list); + return 0; +} + +int auth_get_conf_req(struct ppp_layer_t *l, struct lcp_opt32_t *opt) +{ + int i,n; + struct auth_driver_t *drv; + + for(i=0; i<AUTH_MAX; i++) + { + if (l->auth[i] && l->options.lcp.neg_auth[i]>0) + goto cont; + } + for(i=0; i<AUTH_MAX; i++) + { + if (l->auth[i] && l->options.lcp.neg_auth[i]==0) + goto cont; + } + return -1; + +cont: + list_for_each_entry(drv,&drv_list,entry) + { + if (drv->type==l->auth[i]) + break; + } + n=drv->get_conf_req(drv,l,opt); + opt->val=l->auth[i]; + opt->hdr.len=6+n; + return 0; +} +int auth_recv_conf_req(struct ppp_layer_t *l, struct lcp_opt_hdr_t *hdr) +{ + struct lcp_opt32_t *opt=(struct lcp_opt32_t*)hdr; + struct auth_driver_t *drv; + int i; + + for(i=0; i<AUTH_MAX; i++) + { + if (l->auth[i]==opt->val) + { + list_for_each_entry(drv,&drv_list,entry) + { + if (drv->type==l->auth[i]) + { + if (drv->recv_conf_req(drv,l,opt)) + return -1; + l->options.lcp.neg_auth[i]=1; + return 0; + } + } + return -1; + } + } + return -1; +} +int auth_recv_conf_rej(struct ppp_layer_t *l, struct lcp_opt_hdr_t *hdr) +{ + struct lcp_opt32_t *opt=(struct lcp_opt32_t*)hdr; + int i; + + for(i=0; i<AUTH_MAX; i++) + { + if (l->auth[i]==opt->val) + { + l->options.lcp.neg_auth[i]=-1; + break; + } + } + for(i=0; i<3; i++) + { + if (l->auth[i] && l->options.lcp.neg_auth[i]!=-1) + return 0; + } + return -1; +} +int auth_recv_conf_nak(struct ppp_layer_t *l, struct lcp_opt_hdr_t *hdr) +{ + struct lcp_opt32_t *opt=(struct lcp_opt32_t*)hdr; + int i; + + for(i=0; i<AUTH_MAX; i++) + { + if (l->auth[i]==opt->val) + { + l->options.lcp.neg_auth[i]=2; + return 0; + } + } + return -1; +} + diff --git a/accel-pptpd/ppp_auth.h b/accel-pptpd/ppp_auth.h new file mode 100644 index 00000000..79ceb645 --- /dev/null +++ b/accel-pptpd/ppp_auth.h @@ -0,0 +1,24 @@ +#ifndef PPP_AUTH_H +#define PPP_AUTH_H + +#include "list.h" + +struct ppp_layer_t; +struct lcp_opt_hdr_t; +struct lcp_opt32_t; + +struct auth_driver_t +{ + struct list_head entry; + int type; + int (*get_conf_req)(struct auth_driver_t*, struct ppp_layer_t*, struct lcp_opt32_t*); + int (*recv_conf_req)(struct auth_driver_t*, struct ppp_layer_t*, struct lcp_opt32_t*); +}; + +int auth_get_conf_req(struct ppp_layer_t *l, struct lcp_opt32_t *); +int auth_recv_conf_req(struct ppp_layer_t *l, struct lcp_opt_hdr_t *); +int auth_recv_conf_rej(struct ppp_layer_t *l, struct lcp_opt_hdr_t *); +int auth_recv_conf_nak(struct ppp_layer_t *l, struct lcp_opt_hdr_t *); + +#endif + diff --git a/accel-pptpd/ppp_fsm.c b/accel-pptpd/ppp_fsm.c index f966cd07..fdbcbe96 100644 --- a/accel-pptpd/ppp_fsm.c +++ b/accel-pptpd/ppp_fsm.c @@ -13,6 +13,7 @@ #include "triton/triton.h" #include "ppp.h" #include "ppp_fsm.h" +#include "ppp_lcp.h" void send_term_req(struct ppp_layer_t *layer); void send_term_ack(struct ppp_layer_t *layer); @@ -33,7 +34,7 @@ void ppp_fsm_init(struct ppp_layer_t *layer) layer->max_terminate=2; layer->max_configure=10; layer->max_failure=5; - layer->seq=0; + layer->id=0; } void ppp_fsm_lower_up(struct ppp_layer_t *layer) @@ -405,17 +406,12 @@ void ppp_fsm_recv_code_rej_bad(struct ppp_layer_t *layer) } } -void ppp_fsm_recv_echo(struct ppp_layer_t *layer) -{ - if (layer->fsm_state==FSM_Opened) - send_echo_reply(layer); -} - void send_term_req(struct ppp_layer_t *layer) { - struct ppp_hdr_t hdr={ + struct lcp_hdr_t hdr={ + .proto=PPP_LCP, .code=TERMREQ, - .id=++layer->seq, + .id=++layer->id, .len=4, }; @@ -423,7 +419,8 @@ void send_term_req(struct ppp_layer_t *layer) } void send_term_ack(struct ppp_layer_t *layer) { - struct ppp_hdr_t hdr={ + struct lcp_hdr_t hdr={ + .proto=PPP_LCP, .code=TERMACK, .id=layer->recv_id, .len=4, @@ -431,19 +428,6 @@ void send_term_ack(struct ppp_layer_t *layer) ppp_send(layer->ppp,&hdr,hdr.len); } -void send_echo_reply(struct ppp_layer_t *layer) -{ - struct ppp_hdr_t hdr={ - .code=ECHOREP, - .id=layer->recv_id, - .len=8, - }; - - *(int*)hdr.data=layer->magic_num; - - ppp_send(layer->ppp,&hdr,hdr.len); -} - void ppp_fsm_recv(struct ppp_layer_t *layer) { } diff --git a/accel-pptpd/ppp_fsm.h b/accel-pptpd/ppp_fsm.h index c4430c4d..6b19bf77 100644 --- a/accel-pptpd/ppp_fsm.h +++ b/accel-pptpd/ppp_fsm.h @@ -1,6 +1,7 @@ #ifndef PPP_FSM_H #define PPP_FSM_H +#include "triton/triton.h" #include "list.h" typedef enum {FSM_Initial=0,FSM_Starting,FSM_Closed,FSM_Stopped,FSM_Closing,FSM_Stopping,FSM_Req_Sent,FSM_Ack_Rcvd,FSM_Ack_Sent,FSM_Opened} FSM_STATE; @@ -19,19 +20,20 @@ typedef enum {FSM_Initial=0,FSM_Starting,FSM_Closed,FSM_Stopped,FSM_Closing,FSM_ struct ppp_hdr_t; +#define AUTH_MAX 3 struct lcp_options_t { + int magic; int mtu; int mru; int accomp; // 0 - disabled, 1 - enable, 2 - allow, disabled, 3 - allow,enabled int pcomp; // 0 - disabled, 1 - enable, 2 - allow, disabled, 3 - allow,enabled - int auth[3]; // 0 - none, 1 - pap, 2 - eap, 3 - mschap // negotiated options; int neg_mru; int neg_mtu; int neg_accomp; // -1 - rejected int neg_pcomp; - int neg_auth; + int neg_auth[AUTH_MAX]; }; struct ppp_layer_t @@ -55,13 +57,14 @@ struct ppp_layer_t int max_configure; int max_failure; - int seq; + int id; int recv_id; - int magic_num; + int auth[AUTH_MAX]; int opt_restart:1; int opt_passive:1; + void *last_conf_req; //fsm handling void (*layer_up)(struct ppp_layer_t*); void (*layer_down)(struct ppp_layer_t*); @@ -71,8 +74,7 @@ struct ppp_layer_t void (*send_conf_ack)(struct ppp_layer_t*); void (*send_conf_nak)(struct ppp_layer_t*); void (*send_conf_rej)(struct ppp_layer_t*); - - void (*recv)(struct ppp_layer_t*,struct ppp_hdr_t*); + void (*recv)(struct ppp_layer_t*); }; void ppp_fsm_init(struct ppp_layer_t*); diff --git a/accel-pptpd/ppp_lcp.c b/accel-pptpd/ppp_lcp.c index 994fe29c..dc996e0e 100644 --- a/accel-pptpd/ppp_lcp.c +++ b/accel-pptpd/ppp_lcp.c @@ -6,87 +6,32 @@ #include "triton/triton.h" -#include "ppp.h" -#include "ppp_fsm.h" #include "events.h" #include "log.h" +#include "ppp.h" +#include "ppp_fsm.h" +#include "ppp_lcp.h" +#include "ppp_auth.h" + char* accomp="allow,disabled"; char* pcomp="allow,disabled"; char* auth="pap,eap,mschap-v2"; char* mppe="allow,disabled"; char* pwdb="radius"; -/* - * Options. - */ -#define CI_VENDOR 0 /* Vendor Specific */ -#define CI_MRU 1 /* Maximum Receive Unit */ -#define CI_ASYNCMAP 2 /* Async Control Character Map */ -#define CI_AUTHTYPE 3 /* Authentication Type */ -#define CI_QUALITY 4 /* Quality Protocol */ -#define CI_MAGIC 5 /* Magic Number */ -#define CI_PCOMP 7 /* Protocol Field Compression */ -#define CI_ACCOMP 8 /* Address/Control Field Compression */ -#define CI_FCSALTERN 9 /* FCS-Alternatives */ -#define CI_SDP 10 /* Self-Describing-Pad */ -#define CI_NUMBERED 11 /* Numbered-Mode */ -#define CI_CALLBACK 13 /* callback */ -#define CI_MRRU 17 /* max reconstructed receive unit; multilink */ -#define CI_SSNHF 18 /* short sequence numbers for multilink */ -#define CI_EPDISC 19 /* endpoint discriminator */ -#define CI_MPPLUS 22 /* Multi-Link-Plus-Procedure */ -#define CI_LDISC 23 /* Link-Discriminator */ -#define CI_LCPAUTH 24 /* LCP Authentication */ -#define CI_COBS 25 /* Consistent Overhead Byte Stuffing */ -#define CI_PREFELIS 26 /* Prefix Elision */ -#define CI_MPHDRFMT 27 /* MP Header Format */ -#define CI_I18N 28 /* Internationalization */ -#define CI_SDL 29 /* Simple Data Link */ - -struct lcp_hdr_t -{ - uint8_t code; - uint8_t id; - uint16_t len; -} __attribute__((packed)); -struct lcp_opt_hdr_t -{ - uint8_t type; - uint8_t len; -} __attribute__((packed)); -struct lcp_opt8_t -{ - struct lcp_opt_hdr_t hdr; - uint8_t val; -} __attribute__((packed)); -struct lcp_opt16_t -{ - struct lcp_opt_hdr_t hdr; - uint16_t val; -} __attribute__((packed)); -struct lcp_opt32_t -{ - struct lcp_opt_hdr_t hdr; - uint32_t val; -} __attribute__((packed)); - -/*static void layer_up(struct ppp_layer_t*); -static void layer_down(struct ppp_layer_t*); -static void layer_started(struct ppp_layer_t*); -static void layer_finished(struct ppp_layer_t*);*/ static void send_conf_req(struct ppp_layer_t*); static void send_conf_ack(struct ppp_layer_t*); static void send_conf_nak(struct ppp_layer_t*); static void send_conf_rej(struct ppp_layer_t*); -static void lcp_recv(struct ppp_layer_t*`); +static void lcp_recv(struct ppp_layer_t*); struct ppp_layer_t* ppp_lcp_init(struct ppp_t *ppp) { struct ppp_layer_t *layer=malloc(sizeof(*layer)); memset(layer,0,sizeof(*layer)); - layer->proto=PPP_PROTO_LCP; + layer->proto=PPP_LCP; layer->ppp=ppp; ppp_fsm_init(layer); @@ -101,69 +46,38 @@ struct ppp_layer_t* ppp_lcp_init(struct ppp_t *ppp) return layer; } -/*void ev_ppp_packet(int proto,struct ppp_t *ppp) -{ - struct ppp_hdr_t *hdr; - - if (proto!=PPP_LCP) return; - if (ppp->in_buf_size-2<PPP_HEADERLEN) - { - log_debug("LCP: short packet received\n"); - return; - } - - hdr=(struct ppp_hdr_t *)(ppp->in_buf+2); - if (hdr->len<PPP_HEADERLEN) - { - log_debug("LCP: short packet received\n"); - return; - } - - //ppp_fsm_recv(); -}*/ - -/*static void layer_up(struct ppp_layer_t*) -{ -} -static void layer_down(struct ppp_layer_t*) -{ -} -static void layer_started(struct ppp_layer_t*) -{ -} -static void layer_finished(struct ppp_layer_t*) -{ -}*/ static void send_conf_req(struct ppp_layer_t*l) { - uint8_t buf[128],*ptr; + uint8_t buf[128],*ptr=buf; struct lcp_opt_hdr_t *opt0; - struct lcp_opt8_t *opt8; struct lcp_opt16_t *opt16; - struct lcp_opt24_t *opt24; + struct lcp_opt32_t *opt32; struct lcp_hdr_t *lcp_hdr=(struct lcp_hdr_t*)ptr; ptr+=sizeof(*lcp_hdr); log_msg("send [LCP ConfReq"); + lcp_hdr->proto=PPP_LCP; lcp_hdr->code=CONFREQ; - lcp_hdr->id=++l->seq; + lcp_hdr->id=++l->id; lcp_hdr->len=0; log_msg(" id=%x",lcp_hdr->id); //mru opt16=(struct lcp_opt16_t*)ptr; ptr+=sizeof(*opt16); - opt16.hdr.type=CI_MRU; - opt16.hdr.len=4; - opt16.val=htons(l->options.lcp.mtu); + opt16->hdr.type=CI_MRU; + opt16->hdr.len=4; + opt16->val=htons(l->options.lcp.mtu); log_msg(" <mru %i>",l->options.lcp.mtu); //auth - ptr+=auth_get_conf_req(l,ptr); + opt32=(struct lcp_opt32_t*)ptr;; + if (auth_get_conf_req(l,opt32)) + ptr+=opt32->hdr.len; //magic opt32=(struct lcp_opt32_t*)ptr; ptr+=sizeof(*opt32); - opt32.hdr.type=CI_MAGIC; - opt32.hdr.len=6; - opt32.val=htonl(l->options.lcp.magic); + opt32->hdr.type=CI_MAGIC; + opt32->hdr.len=6; + opt32->val=htonl(l->options.lcp.magic); log_msg(" <magic %x>",l->options.lcp.magic); @@ -171,8 +85,8 @@ static void send_conf_req(struct ppp_layer_t*l) if (l->options.lcp.pcomp==1 || (l->options.lcp.pcomp==3 && l->options.lcp.neg_pcomp!=-1)) { opt0=(struct lcp_opt_hdr_t*)ptr; ptr+=sizeof(*opt0); - opt0.type=CI_PCOMP; - opt0.len=2; + opt0->type=CI_PCOMP; + opt0->len=2; log_msg(" <pcomp>"); } @@ -180,28 +94,41 @@ static void send_conf_req(struct ppp_layer_t*l) if (l->options.lcp.accomp==1 || (l->options.lcp.accomp==3 && l->options.lcp.neg_accomp!=-1)) { opt0=(struct lcp_opt_hdr_t*)ptr; ptr+=sizeof(*opt0); - opt0.type=CI_ACCOMP; - opt0.len=2; + opt0->type=CI_ACCOMP; + opt0->len=2; log_msg(" <accomp>"); } - log_msg("\n"); + log_msg("]\n"); + + lcp_hdr->len=ptr-buf; + ppp_send(l->ppp,lcp_hdr,lcp_hdr->len+2); } static void send_conf_ack(struct ppp_layer_t*l) { + struct lcp_hdr_t *hdr=(struct lcp_hdr_t*)l->ppp->in_buf; + + hdr->code=CONFACK; + log_msg("send [LCP ConfAck id=%x\n",l->recv_id); + + ppp_send(l->ppp,hdr,hdr->len+2); } static void send_conf_nak(struct ppp_layer_t*l) { } static void send_conf_rej(struct ppp_layer_t*l) { + struct lcp_hdr_t *hdr=(struct lcp_hdr_t*)l->ppp->in_buf; + + hdr->code=CONFREJ; + log_msg("send [LCP ConfRej id=%x\n",l->recv_id); + + ppp_send(l->ppp,hdr,hdr->len+2); } static int lcp_recv_conf_req(struct ppp_layer_t*l,uint8_t *data,int size) { struct lcp_opt_hdr_t *opt; - struct lcp_opt8_t *opt8; struct lcp_opt16_t *opt16; - struct lcp_opt32_t *opt32; int res=0; log_debug("recv [LCP ConfReq id=%x",l->recv_id); @@ -213,18 +140,18 @@ static int lcp_recv_conf_req(struct ppp_layer_t*l,uint8_t *data,int size) { case CI_MRU: opt16=(struct lcp_opt16_t*)data; - l->options.lcp.neg_mru=ntohs(opt16.val); + l->options.lcp.neg_mru=ntohs(opt16->val); log_debug(" <mru %i>",l->options.lcp.neg_mru); break; case CI_ASYNCMAP: log_debug(" <asyncmap ...>"); break; case CI_AUTHTYPE: - if (auth_proc_conf_req(l,opt)) + if (auth_recv_conf_req(l,opt)) res=-1; break; - case CI_MAGICNUMBER: - if (*(u_int32_t*)data==l->magic_num) + case CI_MAGIC: + if (*(uint32_t*)data==l->options.lcp.magic) { log_error("loop detected\n"); res=-1; @@ -254,20 +181,163 @@ static int lcp_recv_conf_req(struct ppp_layer_t*l,uint8_t *data,int size) return res; } +static int lcp_recv_conf_rej(struct ppp_layer_t*l,uint8_t *data,int size) +{ + struct lcp_opt_hdr_t *opt; + struct lcp_opt16_t *opt16; + int res=0; + + log_debug("recv [LCP ConfRej id=%x",l->recv_id); + + if (l->recv_id!=l->id) + { + log_debug(": id mismatch\n"); + return 0; + } + + while(size) + { + opt=(struct lcp_opt_hdr_t *)data; + switch(opt->type) + { + case CI_MRU: + opt16=(struct lcp_opt16_t*)data; + log_debug(" <mru %i>",l->options.lcp.neg_mru); + break; + case CI_ASYNCMAP: + log_debug(" <asyncmap ...>"); + break; + case CI_AUTHTYPE: + if (auth_recv_conf_rej(l,opt)) + res=-1; + break; + case CI_MAGIC: + if (*(uint32_t*)data==l->options.lcp.magic) + { + log_error("loop detected\n"); + res=-1; + } + break; + case CI_PCOMP: + log_debug(" <pcomp>"); + if (l->options.lcp.pcomp>=1) l->options.lcp.neg_pcomp=-1; + else { + l->options.lcp.neg_pcomp=-2; + res=-1; + } + break; + case CI_ACCOMP: + log_debug(" <accomp>"); + if (l->options.lcp.accomp>=1) l->options.lcp.neg_accomp=-1; + else { + l->options.lcp.neg_accomp=-2; + res=-1; + } + break; + } + data+=opt->len; + size-=opt->len; + } + log_debug("\n"); + return res; +} +static int lcp_recv_conf_nak(struct ppp_layer_t*l,uint8_t *data,int size) +{ + struct lcp_opt_hdr_t *opt; + struct lcp_opt16_t *opt16; + int res=0; + + log_debug("recv [LCP ConfNak id=%x",l->recv_id); + + if (l->recv_id!=l->id) + { + log_debug(": id mismatch\n"); + return 0; + } + + while(size) + { + opt=(struct lcp_opt_hdr_t *)data; + switch(opt->type) + { + case CI_MRU: + opt16=(struct lcp_opt16_t*)data; + log_debug(" <mru %i>",l->options.lcp.neg_mru); + break; + case CI_ASYNCMAP: + log_debug(" <asyncmap ...>"); + break; + case CI_AUTHTYPE: + if (auth_recv_conf_nak(l,opt)) + res=-1; + break; + case CI_MAGIC: + if (*(uint32_t*)data==l->options.lcp.magic) + { + log_error("loop detected\n"); + res=-1; + } + break; + case CI_PCOMP: + log_debug(" <pcomp>"); + if (l->options.lcp.pcomp>=1) l->options.lcp.neg_pcomp=-1; + else { + l->options.lcp.neg_pcomp=-2; + res=-1; + } + break; + case CI_ACCOMP: + log_debug(" <accomp>"); + if (l->options.lcp.accomp>=1) l->options.lcp.neg_accomp=-1; + else { + l->options.lcp.neg_accomp=-2; + res=-1; + } + break; + } + data+=opt->len; + size-=opt->len; + } + log_debug("\n"); + return res; +} +static void lcp_recv_echo_repl(struct ppp_layer_t*l,uint8_t *data,int size) +{ + +} + +void send_echo_reply(struct ppp_layer_t *layer) +{ + struct lcp_echo_reply_t + { + struct lcp_hdr_t hdr; + struct lcp_opt32_t magic; + } __attribute__((packed)) msg = + { + .hdr.proto=PPP_LCP, + .hdr.code=ECHOREP, + .hdr.id=layer->recv_id, + .hdr.len=8, + .magic.val=layer->options.lcp.magic, + }; + + ppp_send(layer->ppp,&msg,msg.hdr.len+2); +} + static void lcp_recv(struct ppp_layer_t*l) { struct lcp_hdr_t *hdr; - if (l->ppp->in_buf_size-2<PPP_HEADERLEN) + if (l->ppp->in_buf_size<PPP_HEADERLEN+2) { - log_debug("LCP: short packet received\n"); + log_warn("LCP: short packet received\n"); return; } - hdr=(struct lcp_hdr_t *)(l->ppp->in_buf+2); + hdr=(struct lcp_hdr_t *)l->ppp->in_buf; if (ntohs(hdr->len)<PPP_HEADERLEN) { - log_debug("LCP: short packet received\n"); + log_warn("LCP: short packet received\n"); return; } @@ -275,21 +345,21 @@ static void lcp_recv(struct ppp_layer_t*l) switch(hdr->code) { case CONFREQ: - if (lcp_recv_conf_req(l,hdr->data,ntohs(hdr->len)-PPP_HDRLEN)) + if (lcp_recv_conf_req(l,(uint8_t*)(hdr+1),ntohs(hdr->len)-PPP_HDRLEN)) ppp_fsm_recv_conf_req_bad(l); else ppp_fsm_recv_conf_req_good(l); break; case CONFACK: - lcp_recv_conf_ack(l,hdr->data,ntohs(hdr->len)-PPP_HDRLEN); + //lcp_recv_conf_ack(l,hdr+1,ntohs(hdr->len)-PPP_HDRLEN); ppp_fsm_recv_conf_ack(l); break; case CONFNAK: - lcp_recv_conf_nak(l,hdr->data,ntohs(hdr->len)-PPP_HDRLEN); - ppp_fsm_recv_conf_nak(l); + lcp_recv_conf_nak(l,(uint8_t*)(hdr+1),ntohs(hdr->len)-PPP_HDRLEN); + ppp_fsm_recv_conf_rej(l); break; case CONFREJ: - lcp_recv_conf_rej(l,hdr->data,ntohs(hdr->len)-PPP_HDRLEN); + lcp_recv_conf_rej(l,(uint8_t*)(hdr+1),ntohs(hdr->len)-PPP_HDRLEN); ppp_fsm_recv_conf_rej(l); break; case TERMREQ: @@ -302,13 +372,14 @@ static void lcp_recv(struct ppp_layer_t*l) ppp_fsm_recv_code_rej_bad(l); break; case ECHOREQ: - ppp_fsm_recv_echo_req(l); + send_echo_reply(l); break; case ECHOREP: - lcp_recv_echo_rep(l); + lcp_recv_echo_repl(l,(uint8_t*)(hdr+1),ntohs(hdr->len)-PPP_HDRLEN); break; default: ppp_fsm_recv_unk(l); break; } } + diff --git a/accel-pptpd/ppp_lcp.h b/accel-pptpd/ppp_lcp.h new file mode 100644 index 00000000..5c77a3f2 --- /dev/null +++ b/accel-pptpd/ppp_lcp.h @@ -0,0 +1,64 @@ +#ifndef PPP_LCP_H +#define PPP_LCP_H + +#include <stdint.h> + +/* + * Options. + */ +#define CI_VENDOR 0 /* Vendor Specific */ +#define CI_MRU 1 /* Maximum Receive Unit */ +#define CI_ASYNCMAP 2 /* Async Control Character Map */ +#define CI_AUTHTYPE 3 /* Authentication Type */ +#define CI_QUALITY 4 /* Quality Protocol */ +#define CI_MAGIC 5 /* Magic Number */ +#define CI_PCOMP 7 /* Protocol Field Compression */ +#define CI_ACCOMP 8 /* Address/Control Field Compression */ +#define CI_FCSALTERN 9 /* FCS-Alternatives */ +#define CI_SDP 10 /* Self-Describing-Pad */ +#define CI_NUMBERED 11 /* Numbered-Mode */ +#define CI_CALLBACK 13 /* callback */ +#define CI_MRRU 17 /* max reconstructed receive unit; multilink */ +#define CI_SSNHF 18 /* short sequence numbers for multilink */ +#define CI_EPDISC 19 /* endpoint discriminator */ +#define CI_MPPLUS 22 /* Multi-Link-Plus-Procedure */ +#define CI_LDISC 23 /* Link-Discriminator */ +#define CI_LCPAUTH 24 /* LCP Authentication */ +#define CI_COBS 25 /* Consistent Overhead Byte Stuffing */ +#define CI_PREFELIS 26 /* Prefix Elision */ +#define CI_MPHDRFMT 27 /* MP Header Format */ +#define CI_I18N 28 /* Internationalization */ +#define CI_SDL 29 /* Simple Data Link */ + +struct lcp_hdr_t +{ + uint16_t proto; + uint8_t code; + uint8_t id; + uint16_t len; +} __attribute__((packed)); +struct lcp_opt_hdr_t +{ + uint8_t type; + uint8_t len; +} __attribute__((packed)); +struct lcp_opt8_t +{ + struct lcp_opt_hdr_t hdr; + uint8_t val; +} __attribute__((packed)); +struct lcp_opt16_t +{ + struct lcp_opt_hdr_t hdr; + uint16_t val; +} __attribute__((packed)); +struct lcp_opt32_t +{ + struct lcp_opt_hdr_t hdr; + uint32_t val; +} __attribute__((packed)); + + + +#endif + |