提交 3c82158d 编写于 作者: K Kozlov Dmitry 提交者: Dmitry Kozlov

implemented IPCP primary/secondary dns configuration option

上级 29bfdacc
......@@ -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
......
#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);
}
......@@ -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)
......
......@@ -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;
};
......
......@@ -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));
......
......@@ -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
......
......@@ -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));
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册