+ } else if (os_strcmp(buf, "disassoc_low_ack") == 0) {
+ bss->disassoc_low_ack = atoi(pos);
+ } else if (os_strcmp(buf, "tdls_prohibit") == 0) {
+ if (atoi(pos))
+ bss->tdls |= TDLS_PROHIBIT;
+ else
+ bss->tdls &= ~TDLS_PROHIBIT;
+ } else if (os_strcmp(buf, "tdls_prohibit_chan_switch") == 0) {
+ if (atoi(pos))
+ bss->tdls |= TDLS_PROHIBIT_CHAN_SWITCH;
+ else
+ bss->tdls &= ~TDLS_PROHIBIT_CHAN_SWITCH;
+#ifdef CONFIG_RSN_TESTING
+ } else if (os_strcmp(buf, "rsn_testing") == 0) {
+ extern int rsn_testing;
+ rsn_testing = atoi(pos);
+#endif /* CONFIG_RSN_TESTING */
+ } else if (os_strcmp(buf, "time_advertisement") == 0) {
+ bss->time_advertisement = atoi(pos);
+ } else if (os_strcmp(buf, "time_zone") == 0) {
+ size_t tz_len = os_strlen(pos);
+ if (tz_len < 4 || tz_len > 255) {
+ wpa_printf(MSG_DEBUG, "Line %d: invalid time_zone",
+ line);
+ return 1;
+ }
+ os_free(bss->time_zone);
+ bss->time_zone = os_strdup(pos);
+ if (bss->time_zone == NULL)
+ return 1;
+#ifdef CONFIG_WNM
+ } else if (os_strcmp(buf, "wnm_sleep_mode") == 0) {
+ bss->wnm_sleep_mode = atoi(pos);
+ } else if (os_strcmp(buf, "bss_transition") == 0) {
+ bss->bss_transition = atoi(pos);
+#endif /* CONFIG_WNM */
+#ifdef CONFIG_INTERWORKING
+ } else if (os_strcmp(buf, "interworking") == 0) {
+ bss->interworking = atoi(pos);
+ } else if (os_strcmp(buf, "access_network_type") == 0) {
+ bss->access_network_type = atoi(pos);
+ if (bss->access_network_type < 0 ||
+ bss->access_network_type > 15) {
+ wpa_printf(MSG_ERROR,
+ "Line %d: invalid access_network_type",
+ line);
+ return 1;
+ }
+ } else if (os_strcmp(buf, "internet") == 0) {
+ bss->internet = atoi(pos);
+ } else if (os_strcmp(buf, "asra") == 0) {
+ bss->asra = atoi(pos);
+ } else if (os_strcmp(buf, "esr") == 0) {
+ bss->esr = atoi(pos);
+ } else if (os_strcmp(buf, "uesa") == 0) {
+ bss->uesa = atoi(pos);
+ } else if (os_strcmp(buf, "venue_group") == 0) {
+ bss->venue_group = atoi(pos);
+ bss->venue_info_set = 1;
+ } else if (os_strcmp(buf, "venue_type") == 0) {
+ bss->venue_type = atoi(pos);
+ bss->venue_info_set = 1;
+ } else if (os_strcmp(buf, "hessid") == 0) {
+ if (hwaddr_aton(pos, bss->hessid)) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid hessid", line);
+ return 1;
+ }
+ } else if (os_strcmp(buf, "roaming_consortium") == 0) {
+ if (parse_roaming_consortium(bss, pos, line) < 0)
+ return 1;
+ } else if (os_strcmp(buf, "venue_name") == 0) {
+ if (parse_venue_name(bss, pos, line) < 0)
+ return 1;
+ } else if (os_strcmp(buf, "network_auth_type") == 0) {
+ u8 auth_type;
+ u16 redirect_url_len;
+ if (hexstr2bin(pos, &auth_type, 1)) {
+ wpa_printf(MSG_ERROR,
+ "Line %d: Invalid network_auth_type '%s'",
+ line, pos);
+ return 1;
+ }
+ if (auth_type == 0 || auth_type == 2)
+ redirect_url_len = os_strlen(pos + 2);
+ else
+ redirect_url_len = 0;
+ os_free(bss->network_auth_type);
+ bss->network_auth_type = os_malloc(redirect_url_len + 3 + 1);
+ if (bss->network_auth_type == NULL)
+ return 1;
+ *bss->network_auth_type = auth_type;
+ WPA_PUT_LE16(bss->network_auth_type + 1, redirect_url_len);
+ if (redirect_url_len)
+ os_memcpy(bss->network_auth_type + 3, pos + 2,
+ redirect_url_len);
+ bss->network_auth_type_len = 3 + redirect_url_len;
+ } else if (os_strcmp(buf, "ipaddr_type_availability") == 0) {
+ if (hexstr2bin(pos, &bss->ipaddr_type_availability, 1)) {
+ wpa_printf(MSG_ERROR, "Line %d: Invalid ipaddr_type_availability '%s'",
+ line, pos);
+ bss->ipaddr_type_configured = 0;
+ return 1;
+ }
+ bss->ipaddr_type_configured = 1;
+ } else if (os_strcmp(buf, "domain_name") == 0) {
+ int j, num_domains, domain_len, domain_list_len = 0;
+ char *tok_start, *tok_prev;
+ u8 *domain_list, *domain_ptr;
+
+ domain_list_len = os_strlen(pos) + 1;
+ domain_list = os_malloc(domain_list_len);
+ if (domain_list == NULL)
+ return 1;
+
+ domain_ptr = domain_list;
+ tok_prev = pos;
+ num_domains = 1;
+ while ((tok_prev = os_strchr(tok_prev, ','))) {
+ num_domains++;
+ tok_prev++;
+ }
+ tok_prev = pos;
+ for (j = 0; j < num_domains; j++) {
+ tok_start = os_strchr(tok_prev, ',');
+ if (tok_start) {
+ domain_len = tok_start - tok_prev;
+ *domain_ptr = domain_len;
+ os_memcpy(domain_ptr + 1, tok_prev, domain_len);
+ domain_ptr += domain_len + 1;
+ tok_prev = ++tok_start;
+ } else {
+ domain_len = os_strlen(tok_prev);
+ *domain_ptr = domain_len;
+ os_memcpy(domain_ptr + 1, tok_prev, domain_len);
+ domain_ptr += domain_len + 1;
+ }
+ }
+
+ os_free(bss->domain_name);
+ bss->domain_name = domain_list;
+ bss->domain_name_len = domain_list_len;
+ } else if (os_strcmp(buf, "anqp_3gpp_cell_net") == 0) {
+ if (parse_3gpp_cell_net(bss, pos, line) < 0)
+ return 1;
+ } else if (os_strcmp(buf, "nai_realm") == 0) {
+ if (parse_nai_realm(bss, pos, line) < 0)
+ return 1;
+ } else if (os_strcmp(buf, "gas_frag_limit") == 0) {
+ bss->gas_frag_limit = atoi(pos);
+ } else if (os_strcmp(buf, "gas_comeback_delay") == 0) {
+ bss->gas_comeback_delay = atoi(pos);
+ } else if (os_strcmp(buf, "qos_map_set") == 0) {
+ if (parse_qos_map_set(bss, pos, line) < 0)
+ return 1;
+#endif /* CONFIG_INTERWORKING */
+#ifdef CONFIG_RADIUS_TEST
+ } else if (os_strcmp(buf, "dump_msk_file") == 0) {
+ os_free(bss->dump_msk_file);
+ bss->dump_msk_file = os_strdup(pos);
+#endif /* CONFIG_RADIUS_TEST */
+#ifdef CONFIG_HS20
+ } else if (os_strcmp(buf, "hs20") == 0) {
+ bss->hs20 = atoi(pos);
+ } else if (os_strcmp(buf, "disable_dgaf") == 0) {
+ bss->disable_dgaf = atoi(pos);
+ } else if (os_strcmp(buf, "proxy_arp") == 0) {
+ bss->proxy_arp = atoi(pos);
+ } else if (os_strcmp(buf, "na_mcast_to_ucast") == 0) {
+ bss->na_mcast_to_ucast = atoi(pos);
+ } else if (os_strcmp(buf, "osen") == 0) {
+ bss->osen = atoi(pos);
+ } else if (os_strcmp(buf, "anqp_domain_id") == 0) {
+ bss->anqp_domain_id = atoi(pos);
+ } else if (os_strcmp(buf, "hs20_deauth_req_timeout") == 0) {
+ bss->hs20_deauth_req_timeout = atoi(pos);
+ } else if (os_strcmp(buf, "hs20_oper_friendly_name") == 0) {
+ if (hs20_parse_oper_friendly_name(bss, pos, line) < 0)
+ return 1;
+ } else if (os_strcmp(buf, "hs20_wan_metrics") == 0) {
+ if (hs20_parse_wan_metrics(bss, pos, line) < 0)
+ return 1;
+ } else if (os_strcmp(buf, "hs20_conn_capab") == 0) {
+ if (hs20_parse_conn_capab(bss, pos, line) < 0) {
+ return 1;
+ }
+ } else if (os_strcmp(buf, "hs20_operating_class") == 0) {
+ u8 *oper_class;
+ size_t oper_class_len;
+ oper_class_len = os_strlen(pos);
+ if (oper_class_len < 2 || (oper_class_len & 0x01)) {
+ wpa_printf(MSG_ERROR,
+ "Line %d: Invalid hs20_operating_class '%s'",
+ line, pos);
+ return 1;
+ }
+ oper_class_len /= 2;
+ oper_class = os_malloc(oper_class_len);
+ if (oper_class == NULL)
+ return 1;
+ if (hexstr2bin(pos, oper_class, oper_class_len)) {
+ wpa_printf(MSG_ERROR,
+ "Line %d: Invalid hs20_operating_class '%s'",
+ line, pos);
+ os_free(oper_class);
+ return 1;
+ }
+ os_free(bss->hs20_operating_class);
+ bss->hs20_operating_class = oper_class;
+ bss->hs20_operating_class_len = oper_class_len;
+ } else if (os_strcmp(buf, "hs20_icon") == 0) {
+ if (hs20_parse_icon(bss, pos) < 0) {
+ wpa_printf(MSG_ERROR, "Line %d: Invalid hs20_icon '%s'",
+ line, pos);
+ return 1;
+ }
+ } else if (os_strcmp(buf, "osu_ssid") == 0) {
+ if (hs20_parse_osu_ssid(bss, pos, line) < 0)
+ return 1;
+ } else if (os_strcmp(buf, "osu_server_uri") == 0) {
+ if (hs20_parse_osu_server_uri(bss, pos, line) < 0)
+ return 1;
+ } else if (os_strcmp(buf, "osu_friendly_name") == 0) {
+ if (hs20_parse_osu_friendly_name(bss, pos, line) < 0)
+ return 1;
+ } else if (os_strcmp(buf, "osu_nai") == 0) {
+ if (hs20_parse_osu_nai(bss, pos, line) < 0)
+ return 1;
+ } else if (os_strcmp(buf, "osu_method_list") == 0) {
+ if (hs20_parse_osu_method_list(bss, pos, line) < 0)
+ return 1;
+ } else if (os_strcmp(buf, "osu_icon") == 0) {
+ if (hs20_parse_osu_icon(bss, pos, line) < 0)
+ return 1;
+ } else if (os_strcmp(buf, "osu_service_desc") == 0) {
+ if (hs20_parse_osu_service_desc(bss, pos, line) < 0)
+ return 1;
+ } else if (os_strcmp(buf, "subscr_remediation_url") == 0) {
+ os_free(bss->subscr_remediation_url);
+ bss->subscr_remediation_url = os_strdup(pos);
+ } else if (os_strcmp(buf, "subscr_remediation_method") == 0) {
+ bss->subscr_remediation_method = atoi(pos);
+#endif /* CONFIG_HS20 */
+#ifdef CONFIG_TESTING_OPTIONS
+#define PARSE_TEST_PROBABILITY(_val) \
+ } else if (os_strcmp(buf, #_val) == 0) { \
+ char *end; \
+ \
+ conf->_val = strtod(pos, &end); \
+ if (*end || conf->_val < 0.0 || \
+ conf->_val > 1.0) { \
+ wpa_printf(MSG_ERROR, \
+ "Line %d: Invalid value '%s'", \
+ line, pos); \
+ return 1; \
+ }
+ PARSE_TEST_PROBABILITY(ignore_probe_probability)
+ PARSE_TEST_PROBABILITY(ignore_auth_probability)
+ PARSE_TEST_PROBABILITY(ignore_assoc_probability)
+ PARSE_TEST_PROBABILITY(ignore_reassoc_probability)
+ PARSE_TEST_PROBABILITY(corrupt_gtk_rekey_mic_probability)
+ } else if (os_strcmp(buf, "bss_load_test") == 0) {
+ WPA_PUT_LE16(bss->bss_load_test, atoi(pos));
+ pos = os_strchr(pos, ':');
+ if (pos == NULL) {
+ wpa_printf(MSG_ERROR, "Line %d: Invalid bss_load_test",
+ line);
+ return 1;
+ }
+ pos++;
+ bss->bss_load_test[2] = atoi(pos);
+ pos = os_strchr(pos, ':');
+ if (pos == NULL) {
+ wpa_printf(MSG_ERROR, "Line %d: Invalid bss_load_test",
+ line);
+ return 1;
+ }
+ pos++;
+ WPA_PUT_LE16(&bss->bss_load_test[3], atoi(pos));
+ bss->bss_load_test_set = 1;
+ } else if (os_strcmp(buf, "radio_measurements") == 0) {
+ bss->radio_measurements = atoi(pos);
+ } else if (os_strcmp(buf, "own_ie_override") == 0) {
+ struct wpabuf *tmp;
+ size_t len = os_strlen(pos) / 2;
+
+ tmp = wpabuf_alloc(len);
+ if (!tmp)
+ return 1;
+
+ if (hexstr2bin(pos, wpabuf_put(tmp, len), len)) {
+ wpabuf_free(tmp);
+ wpa_printf(MSG_ERROR,
+ "Line %d: Invalid own_ie_override '%s'",
+ line, pos);
+ return 1;
+ }
+
+ wpabuf_free(bss->own_ie_override);
+ bss->own_ie_override = tmp;
+#endif /* CONFIG_TESTING_OPTIONS */
+ } else if (os_strcmp(buf, "vendor_elements") == 0) {
+ struct wpabuf *elems;
+ size_t len = os_strlen(pos);
+ if (len & 0x01) {
+ wpa_printf(MSG_ERROR,
+ "Line %d: Invalid vendor_elements '%s'",
+ line, pos);
+ return 1;
+ }
+ len /= 2;
+ if (len == 0) {
+ wpabuf_free(bss->vendor_elements);
+ bss->vendor_elements = NULL;
+ return 0;
+ }
+
+ elems = wpabuf_alloc(len);
+ if (elems == NULL)
+ return 1;
+
+ if (hexstr2bin(pos, wpabuf_put(elems, len), len)) {
+ wpabuf_free(elems);
+ wpa_printf(MSG_ERROR,
+ "Line %d: Invalid vendor_elements '%s'",
+ line, pos);
+ return 1;
+ }
+
+ wpabuf_free(bss->vendor_elements);
+ bss->vendor_elements = elems;
+ } else if (os_strcmp(buf, "sae_anti_clogging_threshold") == 0) {
+ bss->sae_anti_clogging_threshold = atoi(pos);
+ } else if (os_strcmp(buf, "sae_groups") == 0) {
+ if (hostapd_parse_intlist(&bss->sae_groups, pos)) {
+ wpa_printf(MSG_ERROR,
+ "Line %d: Invalid sae_groups value '%s'",
+ line, pos);
+ return 1;
+ }
+ } else if (os_strcmp(buf, "local_pwr_constraint") == 0) {
+ int val = atoi(pos);
+ if (val < 0 || val > 255) {
+ wpa_printf(MSG_ERROR, "Line %d: Invalid local_pwr_constraint %d (expected 0..255)",
+ line, val);
+ return 1;
+ }
+ conf->local_pwr_constraint = val;
+ } else if (os_strcmp(buf, "spectrum_mgmt_required") == 0) {
+ conf->spectrum_mgmt_required = atoi(pos);
+ } else if (os_strcmp(buf, "wowlan_triggers") == 0) {
+ os_free(bss->wowlan_triggers);
+ bss->wowlan_triggers = os_strdup(pos);
+#ifdef CONFIG_FST
+ } else if (os_strcmp(buf, "fst_group_id") == 0) {
+ size_t len = os_strlen(pos);
+
+ if (!len || len >= sizeof(conf->fst_cfg.group_id)) {
+ wpa_printf(MSG_ERROR,
+ "Line %d: Invalid fst_group_id value '%s'",
+ line, pos);
+ return 1;
+ }
+
+ if (conf->fst_cfg.group_id[0]) {
+ wpa_printf(MSG_ERROR,
+ "Line %d: Duplicate fst_group value '%s'",
+ line, pos);
+ return 1;
+ }
+
+ os_strlcpy(conf->fst_cfg.group_id, pos,
+ sizeof(conf->fst_cfg.group_id));
+ } else if (os_strcmp(buf, "fst_priority") == 0) {
+ char *endp;
+ long int val;
+
+ if (!*pos) {
+ wpa_printf(MSG_ERROR,
+ "Line %d: fst_priority value not supplied (expected 1..%u)",
+ line, FST_MAX_PRIO_VALUE);
+ return -1;
+ }
+
+ val = strtol(pos, &endp, 0);
+ if (*endp || val < 1 || val > FST_MAX_PRIO_VALUE) {
+ wpa_printf(MSG_ERROR,
+ "Line %d: Invalid fst_priority %ld (%s) (expected 1..%u)",
+ line, val, pos, FST_MAX_PRIO_VALUE);
+ return 1;
+ }
+ conf->fst_cfg.priority = (u8) val;
+ } else if (os_strcmp(buf, "fst_llt") == 0) {
+ char *endp;
+ long int val;
+
+ if (!*pos) {
+ wpa_printf(MSG_ERROR,
+ "Line %d: fst_llt value not supplied (expected 1..%u)",
+ line, FST_MAX_LLT_MS);
+ return -1;
+ }
+ val = strtol(pos, &endp, 0);
+ if (*endp || val < 1 || val > FST_MAX_LLT_MS) {
+ wpa_printf(MSG_ERROR,
+ "Line %d: Invalid fst_llt %ld (%s) (expected 1..%u)",
+ line, val, pos, FST_MAX_LLT_MS);
+ return 1;