diff --git a/CHANGELOG b/CHANGELOG index 53df36e..ffb60e6 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -63,6 +63,11 @@ version 2.67 Allow hostnames to start with a number, as allowed in RFC-1123. Thanks to Kyle Mestery for the patch. + Fixes to DHCP FQDN option handling: don't terminate FQDN + if domain not known and allow a FQDN option with blank + name to request that a FQDN option is returned in the + reply. Thanks to Roy Marples for the patch. + version 2.66 Add the ability to act as an authoritative DNS diff --git a/src/rfc2131.c b/src/rfc2131.c index 499f5c4..751aa47 100644 --- a/src/rfc2131.c +++ b/src/rfc2131.c @@ -615,7 +615,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, return message ? 0 : dhcp_packet_size(mess, agent_id, real_end); } - if ((opt = option_find(mess, sz, OPTION_CLIENT_FQDN, 4))) + if ((opt = option_find(mess, sz, OPTION_CLIENT_FQDN, 3))) { /* http://tools.ietf.org/wg/dhc/draft-ietf-dhc-fqdn-option/draft-ietf-dhc-fqdn-option-10.txt */ int len = option_len(opt); @@ -645,7 +645,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, } if (fqdn_flags & 0x04) - while (*op != 0 && ((op + (*op) + 1) - pp) < len) + while (*op != 0 && ((op + (*op)) - pp) < len) { memcpy(pq, op+1, *op); pq += *op; @@ -2289,7 +2289,9 @@ static void do_options(struct dhcp_context *context, if (domain) len += strlen(domain) + 1; - + else if (fqdn_flags & 0x04) + len--; + if ((p = free_space(mess, end, OPTION_CLIENT_FQDN, len))) { *(p++) = fqdn_flags & 0x0f; /* MBZ bits to zero */ @@ -2300,8 +2302,10 @@ static void do_options(struct dhcp_context *context, { p = do_rfc1035_name(p, hostname); if (domain) - p = do_rfc1035_name(p, domain); - *p++ = 0; + { + p = do_rfc1035_name(p, domain); + *p++ = 0; + } } else { diff --git a/src/rfc3315.c b/src/rfc3315.c index c8ba3d0..f846d19 100644 --- a/src/rfc3315.c +++ b/src/rfc3315.c @@ -1299,16 +1299,18 @@ struct dhcp_netid *add_options(struct state *state, struct in6_addr *fallback, s size_t len = strlen(state->hostname); if (state->send_domain) - len += strlen(state->send_domain) + 1; + len += strlen(state->send_domain) + 2; o = new_opt6(OPTION6_FQDN); - if ((p = expand(len + 3))) + if ((p = expand(len + 2))) { *(p++) = state->fqdn_flags; p = do_rfc1035_name(p, state->hostname); if (state->send_domain) - p = do_rfc1035_name(p, state->send_domain); - *p = 0; + { + p = do_rfc1035_name(p, state->send_domain); + *p = 0; + } } end_opt6(o); }