]> git.decadent.org.uk Git - odhcp6c.git/blobdiff - src/dhcpv6.c
added command line switch for strict oro
[odhcp6c.git] / src / dhcpv6.c
index 5a6fd8303646a8f1902ba9d8ff42c4e8642cef6b..7416f6103eac1a9cbc77023e4447231cf70c062d 100644 (file)
@@ -76,19 +76,19 @@ static int dhcpv6_commit_advert(void);
 // RFC 3315 - 5.5 Timeout and Delay values
 static struct dhcpv6_retx dhcpv6_retx[_DHCPV6_MSG_MAX] = {
        [DHCPV6_MSG_UNKNOWN] = {false, 1, 120, 0, "<POLL>",
-                       dhcpv6_handle_reconfigure, NULL},
+                       dhcpv6_handle_reconfigure, NULL},
        [DHCPV6_MSG_SOLICIT] = {true, 1, DHCPV6_SOL_MAX_RT, 0, "SOLICIT",
-                       dhcpv6_handle_advert, dhcpv6_commit_advert},
+                       dhcpv6_handle_advert, dhcpv6_commit_advert},
        [DHCPV6_MSG_REQUEST] = {true, 1, DHCPV6_REQ_MAX_RT, 10, "REQUEST",
-                       dhcpv6_handle_reply, NULL},
+                       dhcpv6_handle_reply, NULL},
        [DHCPV6_MSG_RENEW] = {false, 10, DHCPV6_REN_MAX_RT, 0, "RENEW",
-                       dhcpv6_handle_reply, NULL},
+                       dhcpv6_handle_reply, NULL},
        [DHCPV6_MSG_REBIND] = {false, 10, DHCPV6_REB_MAX_RT, 0, "REBIND",
-                       dhcpv6_handle_rebind_reply, NULL},
+                       dhcpv6_handle_rebind_reply, NULL},
        [DHCPV6_MSG_RELEASE] = {false, 1, 0, 5, "RELEASE", NULL, NULL},
        [DHCPV6_MSG_DECLINE] = {false, 1, 0, 5, "DECLINE", NULL, NULL},
        [DHCPV6_MSG_INFO_REQ] = {true, 1, DHCPV6_INF_MAX_RT, 0, "INFOREQ",
-                       dhcpv6_handle_reply, NULL},
+                       dhcpv6_handle_reply, NULL},
 };
 
 
@@ -106,7 +106,7 @@ static bool accept_reconfig = false;
 static uint8_t reconf_key[16];
 
 
-int init_dhcpv6(const char *ifname, int request_pd, int sol_timeout)
+int init_dhcpv6(const char *ifname, int request_pd, bool strict_options, int sol_timeout)
 {
        request_prefix = request_pd;
        dhcpv6_retx[DHCPV6_MSG_SOLICIT].max_timeo = sol_timeout;
@@ -158,11 +158,13 @@ int init_dhcpv6(const char *ifname, int request_pd, int sol_timeout)
        }
 
        // Create ORO
-       uint16_t oro[] = {
+       if (!strict_options) {
+               uint16_t oro[] = {
                        htons(DHCPV6_OPT_SIP_SERVER_D),
                        htons(DHCPV6_OPT_SIP_SERVER_A),
                        htons(DHCPV6_OPT_DNS_SERVERS),
                        htons(DHCPV6_OPT_DNS_DOMAIN),
+                       htons(DHCPV6_OPT_SNTP_SERVERS),
                        htons(DHCPV6_OPT_NTP_SERVER),
                        htons(DHCPV6_OPT_AFTR_NAME),
                        htons(DHCPV6_OPT_PD_EXCLUDE),
@@ -171,8 +173,9 @@ int init_dhcpv6(const char *ifname, int request_pd, int sol_timeout)
 #ifdef EXT_PREFIX_CLASS
                        htons(DHCPV6_OPT_PREFIX_CLASS),
 #endif
-       };
-       odhcp6c_add_state(STATE_ORO, oro, sizeof(oro));
+               };
+               odhcp6c_add_state(STATE_ORO, oro, sizeof(oro));
+       }
 
        // Configure IPv6-options
        int val = 1;
@@ -688,12 +691,12 @@ static int dhcpv6_handle_advert(enum dhcpv6_msg orig, const int rc,
                        cand.wants_reconfigure = true;
                } else if (otype == DHCPV6_OPT_SOL_MAX_RT && olen == 4) {
                        uint32_t sol_max_rt = ntohl(*((uint32_t *)odata));
-                       if (sol_max_rt >= DHCPV6_SOL_MAX_RT_MIN && 
+                       if (sol_max_rt >= DHCPV6_SOL_MAX_RT_MIN &&
                                        sol_max_rt <= DHCPV6_SOL_MAX_RT_MAX)
                                cand.sol_max_rt = sol_max_rt;
                } else if (otype == DHCPV6_OPT_INF_MAX_RT && olen == 4) {
                        uint32_t inf_max_rt = ntohl(*((uint32_t *)odata));
-                       if (inf_max_rt >= DHCPV6_INF_MAX_RT_MIN && 
+                       if (inf_max_rt >= DHCPV6_INF_MAX_RT_MIN &&
                                        inf_max_rt <= DHCPV6_INF_MAX_RT_MAX)
                                cand.inf_max_rt = inf_max_rt;
                } else if (otype == DHCPV6_OPT_IA_PD && request_prefix) {
@@ -717,8 +720,8 @@ static int dhcpv6_handle_advert(enum dhcpv6_msg orig, const int rc,
 
        if ((!have_na && na_mode == IA_MODE_FORCE) ||
                        (!have_pd && pd_mode == IA_MODE_FORCE)) {
-               /* 
-                * RFC7083 states to process the SOL_MAX_RT and 
+               /*
+                * RFC7083 states to process the SOL_MAX_RT and
                 * INF_MAX_RT options even if the DHCPv6 server
                 * did not propose any IA_NA and/or IA_PD
                 */
@@ -808,7 +811,8 @@ static int dhcpv6_handle_reply(enum dhcpv6_msg orig, _unused const int rc,
                odhcp6c_clear_state(STATE_DNS);
                odhcp6c_clear_state(STATE_SEARCH);
                odhcp6c_clear_state(STATE_SNTP_IP);
-               odhcp6c_clear_state(STATE_SNTP_FQDN);
+               odhcp6c_clear_state(STATE_NTP_IP);
+               odhcp6c_clear_state(STATE_NTP_FQDN);
                odhcp6c_clear_state(STATE_SIP_IP);
                odhcp6c_clear_state(STATE_SIP_FQDN);
                odhcp6c_clear_state(STATE_AFTR_NAME);
@@ -865,6 +869,9 @@ static int dhcpv6_handle_reply(enum dhcpv6_msg orig, _unused const int rc,
                                odhcp6c_add_state(STATE_DNS, odata, olen);
                } else if (otype == DHCPV6_OPT_DNS_DOMAIN) {
                        odhcp6c_add_state(STATE_SEARCH, odata, olen);
+               } else if (otype == DHCPV6_OPT_SNTP_SERVERS) {
+                       if (olen % 16 == 0)
+                               odhcp6c_add_state(STATE_SNTP_IP, odata, olen);
                } else if (otype == DHCPV6_OPT_NTP_SERVER) {
                        uint16_t stype, slen;
                        uint8_t *sdata;
@@ -873,10 +880,10 @@ static int dhcpv6_handle_reply(enum dhcpv6_msg orig, _unused const int rc,
                                        stype, slen, sdata) {
                                if (slen == 16 && (stype == NTP_MC_ADDR ||
                                                stype == NTP_SRV_ADDR))
-                                       odhcp6c_add_state(STATE_SNTP_IP,
+                                       odhcp6c_add_state(STATE_NTP_IP,
                                                        sdata, slen);
                                else if (slen > 0 && stype == NTP_SRV_FQDN)
-                                       odhcp6c_add_state(STATE_SNTP_FQDN,
+                                       odhcp6c_add_state(STATE_NTP_FQDN,
                                                        sdata, slen);
                        }
                } else if (otype == DHCPV6_OPT_SIP_SERVER_A) {
@@ -899,12 +906,12 @@ static int dhcpv6_handle_reply(enum dhcpv6_msg orig, _unused const int rc,
                                odhcp6c_add_state(STATE_AFTR_NAME, odata, olen);
                } else if (otype == DHCPV6_OPT_SOL_MAX_RT && olen == 4) {
                        uint32_t sol_max_rt = ntohl(*((uint32_t *)odata));
-                       if (sol_max_rt >= DHCPV6_SOL_MAX_RT_MIN && 
+                       if (sol_max_rt >= DHCPV6_SOL_MAX_RT_MIN &&
                                        sol_max_rt <= DHCPV6_SOL_MAX_RT_MAX)
                                dhcpv6_retx[DHCPV6_MSG_SOLICIT].max_timeo = sol_max_rt;
                } else if (otype == DHCPV6_OPT_INF_MAX_RT && olen == 4) {
                        uint32_t inf_max_rt = ntohl(*((uint32_t *)odata));
-                       if (inf_max_rt >= DHCPV6_INF_MAX_RT_MIN && 
+                       if (inf_max_rt >= DHCPV6_INF_MAX_RT_MIN &&
                                        inf_max_rt <= DHCPV6_INF_MAX_RT_MAX)
                                dhcpv6_retx[DHCPV6_MSG_INFO_REQ].max_timeo = inf_max_rt;
                }else if (otype != DHCPV6_OPT_CLIENTID &&
@@ -992,7 +999,7 @@ static int dhcpv6_parse_ia(void *opt, void *end)
                        uint8_t *sdata;
 
 #ifdef EXT_PREFIX_CLASS
-                        // Find prefix class, if any
+                       // Find prefix class, if any
                        dhcpv6_for_each_option(&prefix[1], odata + olen,
                                        stype, slen, sdata)
                                if (stype == DHCPV6_OPT_PREFIX_CLASS && slen == 2)
@@ -1295,7 +1302,7 @@ int dhcpv6_promote_server_cand(void)
 
        dhcpv6_retx[DHCPV6_MSG_SOLICIT].max_timeo = cand->sol_max_rt;
        dhcpv6_retx[DHCPV6_MSG_INFO_REQ].max_timeo = cand->inf_max_rt;
-       
+
        odhcp6c_remove_state(STATE_SERVER_CAND, 0, sizeof(*cand));
 
        return ret;