summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKozlov Dmitry <xeb@mail.ru>2011-08-30 21:10:47 +0400
committerKozlov Dmitry <xeb@mail.ru>2011-08-30 21:10:47 +0400
commit556d8e927a220905692d3e6253945bce7a44dc0d (patch)
treed2a074014ad0c6eddee899af4dcf43d77ee3f523
parent8c96b6928e397d6d5e4b6e34c89bc1e17b3df1b9 (diff)
downloadaccel-ppp-556d8e927a220905692d3e6253945bce7a44dc0d.tar.gz
accel-ppp-556d8e927a220905692d3e6253945bce7a44dc0d.zip
dhcpv6: implemented reply to Information-Request
-rw-r--r--accel-pppd/ipv6/dhcpv6.c37
1 files changed, 29 insertions, 8 deletions
diff --git a/accel-pppd/ipv6/dhcpv6.c b/accel-pppd/ipv6/dhcpv6.c
index aad59344..c79dfd1d 100644
--- a/accel-pppd/ipv6/dhcpv6.c
+++ b/accel-pppd/ipv6/dhcpv6.c
@@ -207,12 +207,16 @@ static void insert_oro(struct dhcpv6_packet *reply, struct dhcpv6_option *opt)
for (i = ntohs(opt->hdr->len) / 2, ptr = (uint16_t *)opt->hdr->data; i; i--, ptr++) {
if (ntohs(*ptr) == D6_OPTION_DNS_SERVERS) {
- opt1 = dhcpv6_option_alloc(reply, D6_OPTION_DNS_SERVERS, conf_dns_count * sizeof(addr));
- for (j = 0, addr_ptr = (struct in6_addr *)opt1->hdr->data; j < conf_dns_count; j++, addr_ptr++)
- memcpy(addr_ptr, conf_dns + j, sizeof(addr));
+ if (conf_dns_count) {
+ opt1 = dhcpv6_option_alloc(reply, D6_OPTION_DNS_SERVERS, conf_dns_count * sizeof(addr));
+ for (j = 0, addr_ptr = (struct in6_addr *)opt1->hdr->data; j < conf_dns_count; j++, addr_ptr++)
+ memcpy(addr_ptr, conf_dns + j, sizeof(addr));
+ }
} else if (ntohs(*ptr) == D6_OPTION_DOMAIN_LIST) {
- opt1 = dhcpv6_option_alloc(reply, D6_OPTION_DOMAIN_LIST, conf_dnssl_size);
- memcpy(opt1->hdr->data, conf_dnssl, conf_dnssl_size);
+ if (conf_dnssl_size) {
+ opt1 = dhcpv6_option_alloc(reply, D6_OPTION_DOMAIN_LIST, conf_dnssl_size);
+ memcpy(opt1->hdr->data, conf_dnssl, conf_dnssl_size);
+ }
}
}
}
@@ -235,7 +239,7 @@ static void dhcpv6_send_reply(struct dhcpv6_packet *req, struct dhcpv6_pd *pd, i
list_for_each_entry(opt, &req->opt_list, entry) {
// IA_NA
- if (ntohs(opt->hdr->code) == D6_OPTION_IA_NA) {
+ if (ntohs(opt->hdr->code) == D6_OPTION_IA_NA && req->hdr->type != D6_INFORMATION_REQUEST) {
opt1 = dhcpv6_option_alloc(reply, D6_OPTION_IA_NA, sizeof(struct dhcpv6_opt_ia_na) - sizeof(struct dhcpv6_opt_hdr));
memcpy(opt1->hdr + 1, opt->hdr + 1, ntohs(opt1->hdr->len));
@@ -297,7 +301,7 @@ static void dhcpv6_send_reply(struct dhcpv6_packet *req, struct dhcpv6_pd *pd, i
}
// IA_PD
- } else if (ntohs(opt->hdr->code) == D6_OPTION_IA_PD) {
+ } else if (ntohs(opt->hdr->code) == D6_OPTION_IA_PD && req->hdr->type != D6_INFORMATION_REQUEST) {
opt1 = dhcpv6_option_alloc(reply, D6_OPTION_IA_PD, sizeof(struct dhcpv6_opt_ia_na) - sizeof(struct dhcpv6_opt_hdr));
memcpy(opt1->hdr + 1, opt->hdr + 1, ntohs(opt1->hdr->len));
@@ -365,7 +369,7 @@ static void dhcpv6_send_reply(struct dhcpv6_packet *req, struct dhcpv6_pd *pd, i
}
// IA_TA
- } else if (ntohs(opt->hdr->code) == D6_OPTION_IA_TA) {
+ } else if (ntohs(opt->hdr->code) == D6_OPTION_IA_TA && req->hdr->type != D6_INFORMATION_REQUEST) {
opt1 = dhcpv6_option_alloc(reply, D6_OPTION_IA_TA, sizeof(struct dhcpv6_opt_ia_ta) - sizeof(struct dhcpv6_opt_hdr));
memcpy(opt1->hdr + 1, opt->hdr + 1, ntohs(opt1->hdr->len));
@@ -492,6 +496,20 @@ static void dhcpv6_recv_renew(struct dhcpv6_packet *req)
dhcpv6_send_reply(req, pd, D6_REPLY);
}
+static void dhcpv6_recv_information_request(struct dhcpv6_packet *req)
+{
+ struct dhcpv6_pd *pd = find_pd(req->ppp);
+
+ if (req->rapid_commit) {
+ log_ppp_error("dhcpv6: unexpected Rapid-Commit option\n");
+ return;
+ }
+
+ req->serverid = &conf_serverid;
+
+ dhcpv6_send_reply(req, pd, D6_REPLY);
+}
+
static void dhcpv6_recv_rebind(struct dhcpv6_packet *req)
{
// don't answer
@@ -533,6 +551,9 @@ static void dhcpv6_recv_packet(struct dhcpv6_packet *pkt)
case D6_DECLINE:
dhcpv6_recv_decline(pkt);
break;
+ case D6_INFORMATION_REQUEST:
+ dhcpv6_recv_information_request(pkt);
+ break;
}
dhcpv6_packet_free(pkt);