]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-dhcp6-client: introduce dhcp6_option_can_request()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 12 Oct 2021 06:51:09 +0000 (15:51 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 12 Oct 2021 17:49:49 +0000 (02:49 +0900)
src/libsystemd-network/dhcp6-internal.h
src/libsystemd-network/dhcp6-option.c
src/libsystemd-network/sd-dhcp6-client.c
src/libsystemd-network/test-dhcp6-client.c

index 4eb56aa8c9ec5dd6b165175239848ffade22a537..31482d7717594c7923f96577f054ffd2bd927727 100644 (file)
@@ -93,6 +93,7 @@ typedef struct DHCP6IA {
 
 typedef struct sd_dhcp6_client sd_dhcp6_client;
 
+bool dhcp6_option_can_request(uint16_t option);
 int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code,
                         size_t optlen, const void *optval);
 int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, const DHCP6IA *ia);
index f8d2c98b43dc17d8237d4baca1e143506d0bf770..42792d1d2fc1e940c5ce6a0817fa044c32343b2f 100644 (file)
 #define DHCP6_OPTION_IA_PD_LEN (sizeof(struct ia_pd))
 #define DHCP6_OPTION_IA_TA_LEN (sizeof(struct ia_ta))
 
+bool dhcp6_option_can_request(uint16_t option) {
+        /* See Client ORO field in
+         * https://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml#dhcpv6-parameters-2 */
+
+        switch (option) {
+        case SD_DHCP6_OPTION_CLIENTID:
+        case SD_DHCP6_OPTION_SERVERID:
+        case SD_DHCP6_OPTION_IA_NA:
+        case SD_DHCP6_OPTION_IA_TA:
+        case SD_DHCP6_OPTION_IAADDR:
+        case SD_DHCP6_OPTION_ORO:
+        case SD_DHCP6_OPTION_PREFERENCE:
+        case SD_DHCP6_OPTION_ELAPSED_TIME:
+        case SD_DHCP6_OPTION_RELAY_MSG:
+        case SD_DHCP6_OPTION_AUTH:
+        case SD_DHCP6_OPTION_UNICAST:
+        case SD_DHCP6_OPTION_STATUS_CODE:
+        case SD_DHCP6_OPTION_RAPID_COMMIT:
+        case SD_DHCP6_OPTION_USER_CLASS:
+        case SD_DHCP6_OPTION_VENDOR_CLASS:
+                return false;
+        case SD_DHCP6_OPTION_VENDOR_OPTS:
+                return true;
+        case SD_DHCP6_OPTION_INTERFACE_ID:
+        case SD_DHCP6_OPTION_RECONF_MSG:
+        case SD_DHCP6_OPTION_RECONF_ACCEPT:
+                return false;
+        case SD_DHCP6_OPTION_SIP_SERVER_DOMAIN_NAME:
+        case SD_DHCP6_OPTION_SIP_SERVER_ADDRESS:
+        case SD_DHCP6_OPTION_DNS_SERVERS:
+        case SD_DHCP6_OPTION_DOMAIN_LIST:
+                return true;
+        case SD_DHCP6_OPTION_IA_PD:
+        case SD_DHCP6_OPTION_IA_PD_PREFIX:
+                return false;
+        case SD_DHCP6_OPTION_NIS_SERVERS:
+        case SD_DHCP6_OPTION_NISP_SERVERS:
+        case SD_DHCP6_OPTION_NIS_DOMAIN_NAME:
+        case SD_DHCP6_OPTION_NISP_DOMAIN_NAME:
+        case SD_DHCP6_OPTION_SNTP_SERVERS:
+        case SD_DHCP6_OPTION_INFORMATION_REFRESH_TIME:
+        case SD_DHCP6_OPTION_BCMCS_SERVER_D:
+        case SD_DHCP6_OPTION_BCMCS_SERVER_A:
+        case SD_DHCP6_OPTION_GEOCONF_CIVIC:
+                return true;
+        case SD_DHCP6_OPTION_REMOTE_ID:
+        case SD_DHCP6_OPTION_SUBSCRIBER_ID:
+                return false;
+        case SD_DHCP6_OPTION_CLIENT_FQDN:
+        case SD_DHCP6_OPTION_PANA_AGENT:
+        case SD_DHCP6_OPTION_NEW_POSIX_TIMEZONE:
+        case SD_DHCP6_OPTION_NEW_TZDB_TIMEZONE:
+                return true;
+        case SD_DHCP6_OPTION_ERO:
+        case SD_DHCP6_OPTION_LQ_QUERY:
+        case SD_DHCP6_OPTION_CLIENT_DATA:
+        case SD_DHCP6_OPTION_CLT_TIME:
+        case SD_DHCP6_OPTION_LQ_RELAY_DATA:
+        case SD_DHCP6_OPTION_LQ_CLIENT_LINK:
+                return false;
+        case SD_DHCP6_OPTION_MIP6_HNIDF:
+        case SD_DHCP6_OPTION_MIP6_VDINF:
+        case SD_DHCP6_OPTION_V6_LOST:
+        case SD_DHCP6_OPTION_CAPWAP_AC_V6:
+                return true;
+        case SD_DHCP6_OPTION_RELAY_ID:
+                return false;
+        case SD_DHCP6_OPTION_IPV6_ADDRESS_MOS:
+        case SD_DHCP6_OPTION_IPV6_FQDN_MOS:
+        case SD_DHCP6_OPTION_NTP_SERVER:
+        case SD_DHCP6_OPTION_V6_ACCESS_DOMAIN:
+        case SD_DHCP6_OPTION_SIP_UA_CS_LIST:
+        case SD_DHCP6_OPTION_BOOTFILE_URL:
+        case SD_DHCP6_OPTION_BOOTFILE_PARAM:
+                return true;
+        case SD_DHCP6_OPTION_CLIENT_ARCH_TYPE:
+                return false;
+        case SD_DHCP6_OPTION_NII:
+        case SD_DHCP6_OPTION_GEOLOCATION:
+        case SD_DHCP6_OPTION_AFTR_NAME:
+        case SD_DHCP6_OPTION_ERP_LOCAL_DOMAIN_NAME:
+                return true;
+        case SD_DHCP6_OPTION_RSOO:
+                return false;
+        case SD_DHCP6_OPTION_PD_EXCLUDE:
+                return true;
+        case SD_DHCP6_OPTION_VSS:
+                return false;
+        case SD_DHCP6_OPTION_MIP6_IDINF:
+        case SD_DHCP6_OPTION_MIP6_UDINF:
+        case SD_DHCP6_OPTION_MIP6_HNP:
+        case SD_DHCP6_OPTION_MIP6_HAA:
+        case SD_DHCP6_OPTION_MIP6_HAF:
+        case SD_DHCP6_OPTION_RDNSS_SELECTION:
+        case SD_DHCP6_OPTION_KRB_PRINCIPAL_NAME:
+        case SD_DHCP6_OPTION_KRB_REALM_NAME:
+        case SD_DHCP6_OPTION_KRB_DEFAULT_REALM_NAME:
+        case SD_DHCP6_OPTION_KRB_KDC:
+                return true;
+        case SD_DHCP6_OPTION_CLIENT_LINKLAYER_ADDR:
+        case SD_DHCP6_OPTION_LINK_ADDRESS:
+        case SD_DHCP6_OPTION_RADIUS:
+                return false;
+        case SD_DHCP6_OPTION_SOL_MAX_RT:
+        case SD_DHCP6_OPTION_INF_MAX_RT:
+        case SD_DHCP6_OPTION_ADDRSEL:
+        case SD_DHCP6_OPTION_ADDRSEL_TABLE:
+        case SD_DHCP6_OPTION_V6_PCP_SERVER:
+                return true;
+        case SD_DHCP6_OPTION_DHCPV4_MSG:
+                return false;
+        case SD_DHCP6_OPTION_DHCP4_O_DHCP6_SERVER:
+                return true;
+        case SD_DHCP6_OPTION_S46_RULE:
+                return false;
+        case SD_DHCP6_OPTION_S46_BR:
+                return true;
+        case SD_DHCP6_OPTION_S46_DMR:
+        case SD_DHCP6_OPTION_S46_V4V6BIND:
+        case SD_DHCP6_OPTION_S46_PORTPARAMS:
+                return false;
+        case SD_DHCP6_OPTION_S46_CONT_MAPE:
+        case SD_DHCP6_OPTION_S46_CONT_MAPT:
+        case SD_DHCP6_OPTION_S46_CONT_LW:
+        case SD_DHCP6_OPTION_4RD:
+        case SD_DHCP6_OPTION_4RD_MAP_RULE:
+        case SD_DHCP6_OPTION_4RD_NON_MAP_RULE:
+                return true;
+        case SD_DHCP6_OPTION_LQ_BASE_TIME:
+        case SD_DHCP6_OPTION_LQ_START_TIME:
+        case SD_DHCP6_OPTION_LQ_END_TIME:
+                return false;
+        case SD_DHCP6_OPTION_CAPTIVE_PORTAL:
+        case SD_DHCP6_OPTION_MPL_PARAMETERS:
+                return true;
+        case SD_DHCP6_OPTION_ANI_ATT:
+        case SD_DHCP6_OPTION_ANI_NETWORK_NAME:
+        case SD_DHCP6_OPTION_ANI_AP_NAME:
+        case SD_DHCP6_OPTION_ANI_AP_BSSID:
+        case SD_DHCP6_OPTION_ANI_OPERATOR_ID:
+        case SD_DHCP6_OPTION_ANI_OPERATOR_REALM:
+                return false;
+        case SD_DHCP6_OPTION_S46_PRIORITY:
+                return true;
+        case SD_DHCP6_OPTION_MUD_URL_V6:
+                return false;
+        case SD_DHCP6_OPTION_V6_PREFIX64:
+                return true;
+        case SD_DHCP6_OPTION_F_BINDING_STATUS:
+        case SD_DHCP6_OPTION_F_CONNECT_FLAGS:
+        case SD_DHCP6_OPTION_F_DNS_REMOVAL_INFO:
+        case SD_DHCP6_OPTION_F_DNS_HOST_NAME:
+        case SD_DHCP6_OPTION_F_DNS_ZONE_NAME:
+        case SD_DHCP6_OPTION_F_DNS_FLAGS:
+        case SD_DHCP6_OPTION_F_EXPIRATION_TIME:
+        case SD_DHCP6_OPTION_F_MAX_UNACKED_BNDUPD:
+        case SD_DHCP6_OPTION_F_MCLT:
+        case SD_DHCP6_OPTION_F_PARTNER_LIFETIME:
+        case SD_DHCP6_OPTION_F_PARTNER_LIFETIME_SENT:
+        case SD_DHCP6_OPTION_F_PARTNER_DOWN_TIME:
+        case SD_DHCP6_OPTION_F_PARTNER_RAW_CLT_TIME:
+        case SD_DHCP6_OPTION_F_PROTOCOL_VERSION:
+        case SD_DHCP6_OPTION_F_KEEPALIVE_TIME:
+        case SD_DHCP6_OPTION_F_RECONFIGURE_DATA:
+        case SD_DHCP6_OPTION_F_RELATIONSHIP_NAME:
+        case SD_DHCP6_OPTION_F_SERVER_FLAGS:
+        case SD_DHCP6_OPTION_F_SERVER_STATE:
+        case SD_DHCP6_OPTION_F_START_TIME_OF_STATE:
+        case SD_DHCP6_OPTION_F_STATE_EXPIRATION_TIME:
+        case SD_DHCP6_OPTION_RELAY_PORT:
+                return false;
+        case SD_DHCP6_OPTION_V6_SZTP_REDIRECT:
+        case SD_DHCP6_OPTION_S46_BIND_IPV6_PREFIX:
+                return true;
+        case SD_DHCP6_OPTION_IA_LL:
+        case SD_DHCP6_OPTION_LLADDR:
+        case SD_DHCP6_OPTION_SLAP_QUAD:
+                return false;
+        case SD_DHCP6_OPTION_V6_DOTS_RI:
+        case SD_DHCP6_OPTION_V6_DOTS_ADDRESS:
+        case SD_DHCP6_OPTION_IPV6_ADDRESS_ANDSF:
+                return true;
+        default:
+                return false;
+        }
+}
+
 static int option_append_hdr(uint8_t **buf, size_t *buflen, uint16_t optcode, size_t optlen) {
         DHCP6Option *option;
 
index 00eac6540c3984b0f03212c84ff13139b3dd76ae..cb05bd216ee4391af31f38fce50e9b2e81988112 100644 (file)
@@ -487,7 +487,7 @@ int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client, uint16_t option)
         assert_return(client, -EINVAL);
         assert_return(client->state == DHCP6_STATE_STOPPED, -EBUSY);
 
-        if (option <= 0 || option >= UINT8_MAX)
+        if (!dhcp6_option_can_request(option))
                 return -EINVAL;
 
         for (t = 0; t < client->req_opts_len; t++)
index d309e0ea10d430141f16f9fb301dee2c5e9b64f9..055b0c9dee19f8394d4ffe312c2463954e30c12e 100644 (file)
@@ -63,12 +63,16 @@ static int test_client_basic(sd_event *e) {
         assert_se(sd_dhcp6_client_set_fqdn(client, "~host") == -EINVAL);
         assert_se(sd_dhcp6_client_set_fqdn(client, "~host.domain") == -EINVAL);
 
-        assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_CLIENTID) == 0);
+        assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_CLIENTID) == -EINVAL);
         assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_DNS_SERVERS) == -EEXIST);
         assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_NTP_SERVER) == -EEXIST);
         assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_SNTP_SERVERS) == -EEXIST);
         assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_DOMAIN_LIST) == -EEXIST);
-        assert_se(sd_dhcp6_client_set_request_option(client, 10) == 0);
+        assert_se(sd_dhcp6_client_set_request_option(client, 10) == -EINVAL);
+        assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_NIS_SERVERS) == 0);
+        assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_NISP_SERVERS) == 0);
+        assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_NIS_SERVERS) == -EEXIST);
+        assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_NISP_SERVERS) == -EEXIST);
 
         assert_se(sd_dhcp6_client_set_information_request(client, 1) >= 0);
         v = 0;