From: Adrian Friedli Date: Wed, 11 Jul 2018 20:32:41 +0000 (+0200) Subject: odhcp6c: add option to ignore Server Unicast option X-Git-Url: http://git.openwrt.org/?p=project%2Fodhcp6c.git;a=commitdiff_plain;h=67ae6a71b5762292e114b281d0e329cc24209ae6 odhcp6c: add option to ignore Server Unicast option Add option -U to ignore Server Unicast option and force odhcp6c to use the multicast address. This allows a workaround for broken setups. Signed-off-by: Adrian Friedli Signed-off-by: Hans Dedecker --- diff --git a/src/dhcpv6.c b/src/dhcpv6.c index d70d533..01dd497 100644 --- a/src/dhcpv6.c +++ b/src/dhcpv6.c @@ -183,7 +183,6 @@ int init_dhcpv6(const char *ifname, unsigned int options, int sol_timeout) htons(DHCPV6_OPT_SIP_SERVER_A), htons(DHCPV6_OPT_DNS_SERVERS), htons(DHCPV6_OPT_DNS_DOMAIN), - htons(DHCPV6_OPT_UNICAST), htons(DHCPV6_OPT_SNTP_SERVERS), htons(DHCPV6_OPT_NTP_SERVER), htons(DHCPV6_OPT_AFTR_NAME), @@ -198,6 +197,12 @@ int init_dhcpv6(const char *ifname, unsigned int options, int sol_timeout) htons(DHCPV6_OPT_S46_CONT_LW), }; odhcp6c_add_state(STATE_ORO, oro, sizeof(oro)); + + if (!(client_options & DHCPV6_IGNORE_OPT_UNICAST)) { + uint16_t otype = htons(DHCPV6_OPT_UNICAST); + + odhcp6c_add_state(STATE_ORO, &otype, sizeof(otype)); + } } // Configure IPv6-options @@ -856,7 +861,9 @@ static int dhcpv6_handle_advert(enum dhcpv6_msg orig, const int rc, cand.preference >= 0) { cand.preference = pref = odata[0]; } else if (otype == DHCPV6_OPT_UNICAST && olen == sizeof(cand.server_addr)) { - cand.server_addr = *(struct in6_addr *)odata; + if (!(client_options & DHCPV6_IGNORE_OPT_UNICAST)) + cand.server_addr = *(struct in6_addr *)odata; + } else if (otype == DHCPV6_OPT_RECONF_ACCEPT) { cand.wants_reconfigure = true; } else if (otype == DHCPV6_OPT_SOL_MAX_RT && olen == 4) { @@ -1048,8 +1055,11 @@ static int dhcpv6_handle_reply(enum dhcpv6_msg orig, _unused const int rc, continue; updated_IAs += dhcpv6_parse_ia(ia_hdr, odata + olen); - } else if (otype == DHCPV6_OPT_UNICAST && olen == sizeof(server_addr)) - server_addr = *(struct in6_addr *)odata; + } else if (otype == DHCPV6_OPT_UNICAST && olen == sizeof(server_addr)) { + if (!(client_options & DHCPV6_IGNORE_OPT_UNICAST)) + server_addr = *(struct in6_addr *)odata; + + } else if (otype == DHCPV6_OPT_STATUS && olen >= 2) { uint8_t *mdata = (olen > 2) ? &odata[2] : NULL; uint16_t mlen = (olen > 2) ? olen - 2 : 0; diff --git a/src/odhcp6c.c b/src/odhcp6c.c index 261513d..e0c9b76 100644 --- a/src/odhcp6c.c +++ b/src/odhcp6c.c @@ -138,7 +138,7 @@ int main(_unused int argc, char* const argv[]) unsigned int ra_options = RA_RDNSS_DEFAULT_LIFETIME; unsigned int ra_holdoff_interval = RA_MIN_ADV_INTERVAL; - while ((c = getopt(argc, argv, "S::N:V:P:FB:c:i:r:Ru:x:s:kt:m:Lhedp:fav")) != -1) { + while ((c = getopt(argc, argv, "S::N:V:P:FB:c:i:r:Ru:Ux:s:kt:m:Lhedp:fav")) != -1) { switch (c) { case 'S': allow_slaac_only = (optarg) ? atoi(optarg) : -1; @@ -280,6 +280,10 @@ int main(_unused int argc, char* const argv[]) free(o_data); break; + case 'U': + client_options |= DHCPV6_IGNORE_OPT_UNICAST; + break; + case 's': script = optarg; break; @@ -572,6 +576,7 @@ static int usage(void) " -t Maximum timeout for DHCPv6-SOLICIT (120)\n" " -m Minimum time between accepting RA updates (3)\n" " -L Ignore default lifetime for RDNSS records\n" + " -U Ignore Server Unicast option\n" "\nInvocation options:\n" " -p Set pidfile (/var/run/odhcp6c.pid)\n" " -d Daemonize\n" diff --git a/src/odhcp6c.h b/src/odhcp6c.h index 97809f1..ad4f793 100644 --- a/src/odhcp6c.h +++ b/src/odhcp6c.h @@ -119,6 +119,7 @@ enum dhcpv6_config { DHCPV6_STRICT_OPTIONS = 1, DHCPV6_CLIENT_FQDN = 2, DHCPV6_ACCEPT_RECONFIGURE = 4, + DHCPV6_IGNORE_OPT_UNICAST = 8, }; typedef int(reply_handler)(enum dhcpv6_msg orig, const int rc,