diff options
author | Kozlov Dmitry <dima@server> | 2010-08-23 14:34:37 +0400 |
---|---|---|
committer | Kozlov Dmitry <dima@server> | 2010-08-23 18:33:09 +0400 |
commit | 5ec458e9d936e6aee1d8382290473c0f5ba68e48 (patch) | |
tree | c5025ea42ff1e998afc3a687562238ceccd0efd2 /accel-pptpd | |
parent | 76615aa33fb294f2fdfdee3e4687de94bb5efce9 (diff) | |
download | accel-ppp-5ec458e9d936e6aee1d8382290473c0f5ba68e48.tar.gz accel-ppp-5ec458e9d936e6aee1d8382290473c0f5ba68e48.zip |
implemented IPCP primary/secondary dns configuration option
Diffstat (limited to 'accel-pptpd')
-rw-r--r-- | accel-pptpd/CMakeLists.txt | 1 | ||||
-rw-r--r-- | accel-pptpd/ipcp_opt_dns.c | 146 | ||||
-rw-r--r-- | accel-pptpd/ppp.c | 11 | ||||
-rw-r--r-- | accel-pptpd/ppp.h | 1 | ||||
-rw-r--r-- | accel-pptpd/ppp_ipcp.c | 26 | ||||
-rw-r--r-- | accel-pptpd/ppp_ipcp.h | 2 | ||||
-rw-r--r-- | accel-pptpd/ppp_lcp.c | 29 |
7 files changed, 191 insertions, 25 deletions
diff --git a/accel-pptpd/CMakeLists.txt b/accel-pptpd/CMakeLists.txt index 452f914..e97d916 100644 --- a/accel-pptpd/CMakeLists.txt +++ b/accel-pptpd/CMakeLists.txt @@ -24,6 +24,7 @@ ADD_EXECUTABLE(pptpd ppp_ccp.c ppp_ipcp.c ipcp_opt_ipaddr.c + ipcp_opt_dns.c pwdb.c ipdb.c diff --git a/accel-pptpd/ipcp_opt_dns.c b/accel-pptpd/ipcp_opt_dns.c new file mode 100644 index 0000000..b741798 --- /dev/null +++ b/accel-pptpd/ipcp_opt_dns.c @@ -0,0 +1,146 @@ +#include <stdlib.h> +#include <string.h> +#include <arpa/inet.h> + +#include "ppp.h" +#include "ppp_ipcp.h" +#include "log.h" +#include "ipdb.h" + +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); +static int dns_send_conf_req(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *opt, uint8_t *ptr); +static int dns_send_conf_nak(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *opt, uint8_t *ptr); +static int dns_recv_conf_req(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *opt, uint8_t *ptr); +static void dns1_print(void (*print)(const char *fmt,...),struct ipcp_option_t*, uint8_t *ptr); +static void dns2_print(void (*print)(const char *fmt,...),struct ipcp_option_t*, uint8_t *ptr); + +struct dns_option_t +{ + struct ipcp_option_t opt; + in_addr_t addr; +}; + +static struct ipcp_option_handler_t dns1_opt_hnd= +{ + .init=dns1_init, + .send_conf_req=dns_send_conf_req, + .send_conf_nak=dns_send_conf_nak, + .recv_conf_req=dns_recv_conf_req, + .free=dns_free, + .print=dns1_print, +}; +static struct ipcp_option_handler_t dns2_opt_hnd= +{ + .init=dns2_init, + .send_conf_req=dns_send_conf_req, + .send_conf_nak=dns_send_conf_nak, + .recv_conf_req=dns_recv_conf_req, + .free=dns_free, + .print=dns2_print, +}; + +static struct ipcp_option_t *dns1_init(struct ppp_ipcp_t *ipcp) +{ + struct dns_option_t *dns_opt=malloc(sizeof(*dns_opt)); + memset(dns_opt,0,sizeof(*dns_opt)); + dns_opt->opt.id=CI_DNS1; + dns_opt->opt.len=6; + + return &dns_opt->opt; +} + +static struct ipcp_option_t *dns2_init(struct ppp_ipcp_t *ipcp) +{ + struct dns_option_t *dns_opt=malloc(sizeof(*dns_opt)); + memset(dns_opt,0,sizeof(*dns_opt)); + dns_opt->opt.id=CI_DNS2; + dns_opt->opt.len=6; + + return &dns_opt->opt; +} + +static void dns_free(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *opt) +{ + struct dns_option_t *dns_opt=container_of(opt,typeof(*dns_opt),opt); + + free(dns_opt); +} + +static int dns_send_conf_req(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *opt, uint8_t *ptr) +{ + struct dns_option_t *dns_opt=container_of(opt,typeof(*dns_opt),opt); + struct ipcp_opt32_t *opt32=(struct ipcp_opt32_t*)ptr; + + if (!dns_opt->addr) + return 0; + opt32->hdr.id=dns_opt->opt.id; + opt32->hdr.len=6; + opt32->val=dns_opt->addr; + return 6; +} + +static int dns_send_conf_nak(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *opt, uint8_t *ptr) +{ + struct dns_option_t *dns_opt=container_of(opt,typeof(*dns_opt),opt); + struct ipcp_opt32_t *opt32=(struct ipcp_opt32_t*)ptr; + opt32->hdr.id=dns_opt->opt.id; + opt32->hdr.len=6; + opt32->val=dns_opt->addr; + return 6; +} + +static int dns_recv_conf_req(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *opt, uint8_t *ptr) +{ + struct dns_option_t *dns_opt=container_of(opt,typeof(*dns_opt),opt); + struct ipcp_opt32_t *opt32=(struct ipcp_opt32_t*)ptr; + + 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->addr) + { + dns_opt->addr=opt32->val; + return IPCP_OPT_ACK; + } + } + + if (dns_opt->addr==opt32->val) + return IPCP_OPT_ACK; + + return IPCP_OPT_NAK; +} + +static void dns1_print(void (*print)(const char *fmt,...),struct ipcp_option_t *opt, uint8_t *ptr) +{ + struct dns_option_t *dns_opt=container_of(opt,typeof(*dns_opt),opt); + struct ipcp_opt32_t *opt32=(struct ipcp_opt32_t*)ptr; + struct in_addr in; + + if (ptr) in.s_addr=opt32->val; + else in.s_addr=dns_opt->addr; + + print("<dns1 %s>",inet_ntoa(in)); +} + +static void dns2_print(void (*print)(const char *fmt,...),struct ipcp_option_t *opt, uint8_t *ptr) +{ + struct dns_option_t *dns_opt=container_of(opt,typeof(*dns_opt),opt); + struct ipcp_opt32_t *opt32=(struct ipcp_opt32_t*)ptr; + struct in_addr in; + + if (ptr) in.s_addr=opt32->val; + else in.s_addr=dns_opt->addr; + + print("<dns2 %s>",inet_ntoa(in)); +} + +static void __init dns_opt_init() +{ + ipcp_option_register(&dns1_opt_hnd); + ipcp_option_register(&dns2_opt_hnd); +} + diff --git a/accel-pptpd/ppp.c b/accel-pptpd/ppp.c index 40f5ff7..518f757 100644 --- a/accel-pptpd/ppp.c +++ b/accel-pptpd/ppp.c @@ -255,7 +255,10 @@ void ppp_layer_started(struct ppp_t *ppp, struct ppp_layer_data_t *d) { n=list_entry(n->entry.next,typeof(*n),entry); list_for_each_entry(d,&n->items,entry) + { + d->starting=1; d->layer->start(d); + } } } @@ -263,13 +266,14 @@ void 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; list_for_each_entry(n,&ppp->layers,entry) { list_for_each_entry(d,&n->items,entry) { - if (d->started) + if (d->starting) return; } } @@ -288,7 +292,7 @@ void ppp_terminate(struct ppp_t *ppp) { list_for_each_entry(d,&n->items,entry) { - if (d->started) + if (d->starting) { s=1; d->layer->finish(d); @@ -394,7 +398,10 @@ static void start_first_layer(struct ppp_t *ppp) n=list_entry(ppp->layers.next,typeof(*n),entry); list_for_each_entry(d,&n->items,entry) + { + d->starting=1; d->layer->start(d); + } } struct ppp_layer_data_t *ppp_find_layer_data(struct ppp_t *ppp, struct ppp_layer_t *layer) diff --git a/accel-pptpd/ppp.h b/accel-pptpd/ppp.h index 9d8cdf1..39a0d41 100644 --- a/accel-pptpd/ppp.h +++ b/accel-pptpd/ppp.h @@ -95,6 +95,7 @@ struct ppp_layer_data_t struct list_head entry; struct ppp_layer_t *layer; struct layer_node_t *node; + int starting:1; int started:1; }; diff --git a/accel-pptpd/ppp_ipcp.c b/accel-pptpd/ppp_ipcp.c index e008117..5a37546 100644 --- a/accel-pptpd/ppp_ipcp.c +++ b/accel-pptpd/ppp_ipcp.c @@ -107,6 +107,8 @@ void ipcp_layer_finish(struct ppp_layer_data_t *ld) log_debug("ipcp_layer_finish\n"); + ppp_fsm_lower_down(&ipcp->fsm); + ppp_unregister_handler(ipcp->ppp,&ipcp->hnd); ipcp_options_free(ipcp); @@ -118,7 +120,7 @@ void ipcp_layer_free(struct ppp_layer_data_t *ld) struct ppp_ipcp_t *ipcp=container_of(ld,typeof(*ipcp),ld); log_debug("ipcp_layer_free\n"); - + free(ipcp); } @@ -146,7 +148,7 @@ static void print_ropt(struct recv_opt_t *ropt) { log_debug(" %x",ptr[i]); } - log_debug(">"); + log_debug(" >"); } static void send_conf_req(struct ppp_fsm_t *fsm) @@ -199,7 +201,7 @@ static void send_conf_nak(struct ppp_fsm_t *fsm) struct ppp_ipcp_t *ipcp=container_of(fsm,typeof(*ipcp),fsm); uint8_t *buf=malloc(ipcp->conf_req_len), *ptr=buf; struct ipcp_hdr_t *ipcp_hdr=(struct ipcp_hdr_t*)ptr; - struct ipcp_option_t *lopt; + struct recv_opt_t *ropt; log_debug("send [IPCP ConfNak id=%x",ipcp->fsm.recv_id); @@ -210,13 +212,13 @@ static void send_conf_nak(struct ppp_fsm_t *fsm) ptr+=sizeof(*ipcp_hdr); - list_for_each_entry(lopt,&ipcp->options,entry) + list_for_each_entry(ropt,&ipcp->ropt_list,entry) { - if (lopt->state==IPCP_OPT_NAK) + if (ropt->state==IPCP_OPT_NAK) { log_debug(" "); - lopt->h->print(log_debug,lopt,NULL); - ptr+=lopt->h->send_conf_nak(ipcp,lopt,ptr); + ropt->lopt->h->print(log_debug,ropt->lopt,NULL); + ptr+=ropt->lopt->h->send_conf_nak(ipcp,ropt->lopt,ptr); } } @@ -361,7 +363,9 @@ static int ipcp_recv_conf_rej(struct ppp_ipcp_t *ipcp,uint8_t *data,int size) { if (lopt->id==hdr->id) { - if (lopt->h->recv_conf_rej(ipcp,lopt,data)) + if (!lopt->h->recv_conf_rej) + res=-1; + else if (lopt->h->recv_conf_rej(ipcp,lopt,data)) res=-1; break; } @@ -498,8 +502,10 @@ static void ipcp_recv(struct ppp_handler_t*h) ppp_fsm_recv_conf_rej(&ipcp->fsm); break; case CONFREJ: - ipcp_recv_conf_rej(ipcp,(uint8_t*)(hdr+1),ntohs(hdr->len)-PPP_HDRLEN); - ppp_fsm_recv_conf_rej(&ipcp->fsm); + if (ipcp_recv_conf_rej(ipcp,(uint8_t*)(hdr+1),ntohs(hdr->len)-PPP_HDRLEN)) + ppp_terminate(ipcp->ppp); + else + ppp_fsm_recv_conf_rej(&ipcp->fsm); break; case TERMREQ: term_msg=strndup((uint8_t*)(hdr+1),ntohs(hdr->len)); diff --git a/accel-pptpd/ppp_ipcp.h b/accel-pptpd/ppp_ipcp.h index 0f83d44..a2ce3b3 100644 --- a/accel-pptpd/ppp_ipcp.h +++ b/accel-pptpd/ppp_ipcp.h @@ -10,7 +10,7 @@ */ #define CI_COMP 2 /* IP-Compress-Protocol */ #define CI_ADDR 3 /* IP-Address */ -#define CI_DNS1 128 /* Primary-DNS-Address */ +#define CI_DNS1 129 /* Primary-DNS-Address */ #define CI_DNS2 131 /* Secondary-DNS-Address */ struct ipcp_hdr_t diff --git a/accel-pptpd/ppp_lcp.c b/accel-pptpd/ppp_lcp.c index 2bb7e38..da0034c 100644 --- a/accel-pptpd/ppp_lcp.c +++ b/accel-pptpd/ppp_lcp.c @@ -106,9 +106,7 @@ void lcp_layer_finish(struct ppp_layer_data_t *ld) struct ppp_lcp_t *lcp=container_of(ld,typeof(*lcp),ld); log_debug("lcp_layer_finish\n"); - - ppp_unregister_handler(lcp->ppp,&lcp->hnd); - lcp_options_free(lcp); + ppp_fsm_close(&lcp->fsm); } void lcp_layer_free(struct ppp_layer_data_t *ld) @@ -117,6 +115,9 @@ void lcp_layer_free(struct ppp_layer_data_t *ld) log_debug("lcp_layer_free\n"); + ppp_unregister_handler(lcp->ppp,&lcp->hnd); + lcp_options_free(lcp); + free(lcp); } @@ -144,7 +145,7 @@ static void print_ropt(struct recv_opt_t *ropt) { log_debug(" %x",ptr[i]); } - log_debug(">"); + log_debug(" >"); } static void send_conf_req(struct ppp_fsm_t *fsm) @@ -197,7 +198,7 @@ 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 lcp_option_t *lopt; + struct recv_opt_t *ropt; log_debug("send [LCP ConfNak id=%x",lcp->fsm.recv_id); @@ -208,13 +209,13 @@ static void send_conf_nak(struct ppp_fsm_t *fsm) ptr+=sizeof(*lcp_hdr); - list_for_each_entry(lopt,&lcp->options,entry) + list_for_each_entry(ropt,&lcp->ropt_list,entry) { - if (lopt->state==LCP_OPT_NAK) + if (ropt->state==LCP_OPT_NAK) { log_debug(" "); - lopt->h->print(log_debug,lopt,NULL); - ptr+=lopt->h->send_conf_nak(lcp,lopt,ptr); + ropt->lopt->h->print(log_debug,ropt->lopt,NULL); + ptr+=ropt->lopt->h->send_conf_nak(lcp,ropt->lopt,ptr); } } @@ -358,7 +359,9 @@ static int lcp_recv_conf_rej(struct ppp_lcp_t *lcp,uint8_t *data,int size) { if (lopt->id==hdr->id) { - if (lopt->h->recv_conf_rej(lcp,lopt,data)) + if (!lopt->h->recv_conf_rej) + res=-1; + else if (lopt->h->recv_conf_rej(lcp,lopt,data)) res=-1; break; } @@ -518,8 +521,10 @@ static void lcp_recv(struct ppp_handler_t*h) ppp_fsm_recv_conf_rej(&lcp->fsm); break; case CONFREJ: - lcp_recv_conf_rej(lcp,(uint8_t*)(hdr+1),ntohs(hdr->len)-PPP_HDRLEN); - ppp_fsm_recv_conf_rej(&lcp->fsm); + if (lcp_recv_conf_rej(lcp,(uint8_t*)(hdr+1),ntohs(hdr->len)-PPP_HDRLEN)) + ppp_terminate(lcp->ppp); + else + ppp_fsm_recv_conf_rej(&lcp->fsm); break; case TERMREQ: term_msg=strndup((uint8_t*)(hdr+1),ntohs(hdr->len)); |