odhcp6c: add option to ignore Server Unicast option
authorAdrian Friedli <adi@koalatux.ch>
Wed, 11 Jul 2018 20:32:41 +0000 (22:32 +0200)
committerHans Dedecker <dedeckeh@gmail.com>
Fri, 13 Jul 2018 13:23:45 +0000 (15:23 +0200)
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 <adi@koalatux.ch>
Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
src/dhcpv6.c
src/odhcp6c.c
src/odhcp6c.h

index d70d533558abcd6525f766c35d9cef69d4c93a1a..01dd497e33ea7159269e9dfc8def043f6225867a 100644 (file)
@@ -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;
index 261513d4758b7429bf230db99c5a97356ec3d922..e0c9b76e31aefef96b362d79b84077ed1eb13ada 100644 (file)
@@ -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 <seconds>    Maximum timeout for DHCPv6-SOLICIT (120)\n"
        "       -m <seconds>    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 <pidfile>    Set pidfile (/var/run/odhcp6c.pid)\n"
        "       -d              Daemonize\n"
index 97809f1543672a8c6359cea20386560037c849a9..ad4f7937b3fd2c462d4556052f74a3b2de0e628d 100644 (file)
@@ -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,