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 /accel-pptpd/ppp_lcp.c | |
parent | 00785e9cb2adc570a267c160b869bbf9d33bbbe4 (diff) | |
download | accel-ppp-xebd-4a268755565ced740c391a4c8c7fc7c98b7fc3c7.tar.gz accel-ppp-xebd-4a268755565ced740c391a4c8c7fc7c98b7fc3c7.zip |
* written base code of lcp module
* written generic auth module
Diffstat (limited to 'accel-pptpd/ppp_lcp.c')
-rw-r--r-- | accel-pptpd/ppp_lcp.c | 327 |
1 files changed, 199 insertions, 128 deletions
diff --git a/accel-pptpd/ppp_lcp.c b/accel-pptpd/ppp_lcp.c index 994fe29..dc996e0 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; } } + |