summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKozlov Dmitry <dima@server>2010-08-06 13:59:54 +0400
committerKozlov Dmitry <dima@server>2010-08-06 13:59:54 +0400
commit4a268755565ced740c391a4c8c7fc7c98b7fc3c7 (patch)
treeabfd4918ffbb26dac07ae970aa4ff628fd19c583
parent00785e9cb2adc570a267c160b869bbf9d33bbbe4 (diff)
downloadaccel-ppp-xebd-4a268755565ced740c391a4c8c7fc7c98b7fc3c7.tar.gz
accel-ppp-xebd-4a268755565ced740c391a4c8c7fc7c98b7fc3c7.zip
* written base code of lcp module
* written generic auth module
-rw-r--r--accel-pptpd/CMakeLists.txt3
-rw-r--r--accel-pptpd/ppp.c36
-rw-r--r--accel-pptpd/ppp.h1
-rw-r--r--accel-pptpd/ppp_auth.c111
-rw-r--r--accel-pptpd/ppp_auth.h24
-rw-r--r--accel-pptpd/ppp_fsm.c30
-rw-r--r--accel-pptpd/ppp_fsm.h14
-rw-r--r--accel-pptpd/ppp_lcp.c327
-rw-r--r--accel-pptpd/ppp_lcp.h64
9 files changed, 428 insertions, 182 deletions
diff --git a/accel-pptpd/CMakeLists.txt b/accel-pptpd/CMakeLists.txt
index 5ee16fd..2e46e5b 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 c24987f..2c9c47d 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 8e8558b..13e6934 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 0000000..b66727b
--- /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 0000000..79ceb64
--- /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 f966cd0..fdbcbe9 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 c4430c4..6b19bf7 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 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;
}
}
+
diff --git a/accel-pptpd/ppp_lcp.h b/accel-pptpd/ppp_lcp.h
new file mode 100644
index 0000000..5c77a3f
--- /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
+