Mercurial > hg > dhcpcd
changeset 2264:dd9d8cc5871a draft
Support RECONFIGURE DHCPv6 messages.
| author | Roy Marples <roy@marples.name> |
|---|---|
| date | Fri, 31 Jan 2014 14:25:18 +0000 |
| parents | f60ab8a8fb05 |
| children | f0ed6a59297f |
| files | dhcp6.c dhcp6.h |
| diffstat | 2 files changed, 74 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/dhcp6.c Fri Jan 31 12:45:55 2014 +0000 +++ b/dhcp6.c Fri Jan 31 14:25:18 2014 +0000 @@ -418,6 +418,8 @@ if (fqdn != FQDN_DISABLE) len += sizeof(*o) + 1 + encode_rfc1035(hostname, NULL); + + len += sizeof(*o); /* Reconfigure Accept */ } len += sizeof(*state->send); @@ -629,7 +631,7 @@ } } - if (state->send->type != DHCP6_RELEASE) { + if (state->send->type != DHCP6_RELEASE) { if (fqdn != FQDN_DISABLE) { o = D6_NEXT_OPTION(o); o->code = htons(D6_OPTION_FQDN); @@ -651,6 +653,10 @@ o->len = htons(l + 1); } + o = D6_NEXT_OPTION(o); + o->code = htons(D6_OPTION_RECONF_ACCEPT); + o->len = 0; + if (n_options) { o = D6_NEXT_OPTION(o); o->code = htons(D6_OPTION_ORO); @@ -2048,7 +2054,7 @@ const char *sfrom, *op; struct dhcp6_message *r; struct dhcp6_state *state; - const struct dhcp6_option *o; + const struct dhcp6_option *o, *auth; const struct dhcp_opt *opt; const struct if_options *ifo; struct ipv6_addr *ap; @@ -2112,9 +2118,10 @@ return; r = (struct dhcp6_message *)rcvhdr.msg_iov[0].iov_base; - if (r->xid[0] != state->send->xid[0] || + if (r->type != DHCP6_RECONFIGURE && + (r->xid[0] != state->send->xid[0] || r->xid[1] != state->send->xid[1] || - r->xid[2] != state->send->xid[2]) + r->xid[2] != state->send->xid[2])) { syslog(LOG_DEBUG, "%s: wrong xid 0x%02x%02x%02x" @@ -2155,11 +2162,11 @@ } /* Authenticate the message */ - o = dhcp6_getmoption(D6_OPTION_AUTH, r, len); - if (o) { + auth = dhcp6_getmoption(D6_OPTION_AUTH, r, len); + if (auth) { if (dhcp_auth_validate(&state->auth, &ifo->auth, (uint8_t *)r, len, 6, r->type, - D6_COPTION_DATA(o), ntohs(o->len)) == NULL) + D6_COPTION_DATA(auth), ntohs(auth->len)) == NULL) { syslog(LOG_DEBUG, "dhcp_auth_validate: %m"); syslog(LOG_ERR, "%s: authentication failed from %s", @@ -2238,6 +2245,63 @@ if (dhcp6_validatelease(ifp, r, len, sfrom) == -1) return; break; + case DHCP6_RECONFIGURE: + if (auth == NULL) { + syslog(LOG_ERR, + "%s: unauthenticated Force Renew from %s", + ifp->name, sfrom); + return; + } + if (state->state != DH6S_BOUND && + state->state != DH6S_INFORMED) + { + syslog(LOG_DEBUG, + "%s: not bound, ignoring Force Renew from %s", + ifp->name, sfrom); + return; + } + syslog(LOG_INFO, "%s: Force Renew from %s", ifp->name, sfrom); + o = dhcp6_getmoption(D6_OPTION_RECONF_MSG, r, len); + if (o == NULL) { + syslog(LOG_ERR, + "%s: missing Reconfigure Message option", + ifp->name); + return; + } + if (ntohs(o->len) != 1) { + syslog(LOG_ERR, + "%s: missing Reconfigure Message type", + ifp->name); + return; + } + switch(*D6_COPTION_DATA(o)) { + case DHCP6_RENEW: + if (state->state != DH6S_BOUND) { + syslog(LOG_ERR, + "%s: not bound, ignoring Force Renew", + ifp->name); + return; + } + eloop_timeout_delete(dhcp6_startrenew, ifp); + dhcp6_startrenew(ifp); + break; + case DHCP6_INFORMATION_REQ: + if (state->state != DH6S_INFORMED) { + syslog(LOG_ERR, + "%s: not informed, ignoring Force Renew", + ifp->name); + return; + } + eloop_timeout_delete(dhcp6_sendinform, ifp); + dhcp6_startinform(ifp); + break; + default: + syslog(LOG_ERR, + "%s: unsupported Reconfigure Message type", + ifp->name); + return; + } + break; default: syslog(LOG_ERR, "%s: invalid DHCP6 type %s (%d)", ifp->name, op, r->type);
--- a/dhcp6.h Fri Jan 31 12:45:55 2014 +0000 +++ b/dhcp6.h Fri Jan 31 14:25:18 2014 +0000 @@ -67,6 +67,9 @@ #define D6_OPTION_RAPID_COMMIT 14 #define D6_OPTION_VENDOR_CLASS 16 #define D6_OPTION_VENDOR_OPTS 17 +#define D6_OPTION_INTERFACE_ID 18 +#define D6_OPTION_RECONF_MSG 19 +#define D6_OPTION_RECONF_ACCEPT 20 #define D6_OPTION_SIP_SERVERS_NAME 21 #define D6_OPTION_SIP_SERVERS_ADDRESS 22 #define D6_OPTION_DNS_SERVERS 23
