Merge branch 'moonshot' of ssh://moonshot.suchdamage.org:822/srv/git/libeap into...
[libeap.git] / wpa_supplicant / config.c
index bbc720e..6e03760 100644 (file)
@@ -284,6 +284,12 @@ static int wpa_config_parse_bssid(const struct parse_data *data,
                                  struct wpa_ssid *ssid, int line,
                                  const char *value)
 {
+       if (value[0] == '\0' || os_strcmp(value, "\"\"") == 0 ||
+           os_strcmp(value, "any") == 0) {
+               ssid->bssid_set = 0;
+               wpa_printf(MSG_MSGDUMP, "BSSID any");
+               return 0;
+       }
        if (hwaddr_aton(value, ssid->bssid)) {
                wpa_printf(MSG_ERROR, "Line %d: Invalid BSSID '%s'.",
                           line, value);
@@ -1493,9 +1499,9 @@ static const struct parse_data ssid_fields[] = {
        { STRe(pac_file) },
        { INTe(fragment_size) },
 #endif /* IEEE8021X_EAPOL */
-       { INT_RANGE(mode, 0, 2) },
+       { INT_RANGE(mode, 0, 4) },
        { INT_RANGE(proactive_key_caching, 0, 1) },
-       { INT_RANGE(disabled, 0, 1) },
+       { INT_RANGE(disabled, 0, 2) },
        { STR(id_str) },
 #ifdef CONFIG_IEEE80211W
        { INT_RANGE(ieee80211w, 0, 2) },
@@ -1688,6 +1694,8 @@ void wpa_config_free(struct wpa_config *config)
        struct wpa_config_blob *blob, *prevblob;
 #endif /* CONFIG_NO_CONFIG_BLOBS */
        struct wpa_ssid *ssid, *prev = NULL;
+       int i;
+
        ssid = config->ssid;
        while (ssid) {
                prev = ssid;
@@ -1717,7 +1725,10 @@ void wpa_config_free(struct wpa_config *config)
        os_free(config->model_number);
        os_free(config->serial_number);
        os_free(config->device_type);
+       for (i = 0; i < MAX_SEC_DEVICE_TYPES; i++)
+               os_free(config->sec_device_type[i]);
        os_free(config->config_methods);
+       os_free(config->p2p_ssid_postfix);
        os_free(config->pssid);
        os_free(config);
 }
@@ -2132,6 +2143,8 @@ struct wpa_config * wpa_config_alloc_empty(const char *ctrl_interface,
        config->eapol_version = DEFAULT_EAPOL_VERSION;
        config->ap_scan = DEFAULT_AP_SCAN;
        config->fast_reauth = DEFAULT_FAST_REAUTH;
+       config->p2p_go_intent = DEFAULT_P2P_GO_INTENT;
+       config->p2p_intra_bss = DEFAULT_P2P_INTRA_BSS;
        config->bss_max_count = DEFAULT_BSS_MAX_COUNT;
 
        if (ctrl_interface)
@@ -2173,6 +2186,7 @@ struct global_parse_data {
        int (*parser)(const struct global_parse_data *data,
                      struct wpa_config *config, int line, const char *value);
        void *param1, *param2, *param3;
+       unsigned int changed_flag;
 };
 
 
@@ -2308,6 +2322,29 @@ static int wpa_config_process_os_version(const struct global_parse_data *data,
 
 #endif /* CONFIG_WPS */
 
+#ifdef CONFIG_P2P
+static int wpa_config_process_sec_device_type(
+       const struct global_parse_data *data,
+       struct wpa_config *config, int line, const char *pos)
+{
+       int idx;
+
+       for (idx = 0; idx < MAX_SEC_DEVICE_TYPES; idx++)
+               if (config->sec_device_type[idx] == NULL)
+                       break;
+       if (idx == MAX_SEC_DEVICE_TYPES) {
+               wpa_printf(MSG_ERROR, "Line %d: too many sec_device_type "
+                          "items", line);
+               return -1;
+       }
+
+       config->sec_device_type[idx] = os_strdup(pos);
+       if (config->sec_device_type[idx] == NULL)
+               return -1;
+       return 0;
+}
+#endif /* CONFIG_P2P */
+
 
 #ifdef OFFSET
 #undef OFFSET
@@ -2326,38 +2363,49 @@ static int wpa_config_process_os_version(const struct global_parse_data *data,
 
 static const struct global_parse_data global_fields[] = {
 #ifdef CONFIG_CTRL_IFACE
-       { STR(ctrl_interface) },
-       { STR(ctrl_interface_group) } /* deprecated */,
+       { STR(ctrl_interface), 0 },
+       { STR(ctrl_interface_group), 0 } /* deprecated */,
 #endif /* CONFIG_CTRL_IFACE */
-       { INT_RANGE(eapol_version, 1, 2) },
-       { INT(ap_scan) },
-       { INT(fast_reauth) },
-       { STR(opensc_engine_path) },
-       { STR(pkcs11_engine_path) },
-       { STR(pkcs11_module_path) },
-       { STR(driver_param) },
-       { INT(dot11RSNAConfigPMKLifetime) },
-       { INT(dot11RSNAConfigPMKReauthThreshold) },
-       { INT(dot11RSNAConfigSATimeout) },
+       { INT_RANGE(eapol_version, 1, 2), 0 },
+       { INT(ap_scan), 0 },
+       { INT(fast_reauth), 0 },
+       { STR(opensc_engine_path), 0 },
+       { STR(pkcs11_engine_path), 0 },
+       { STR(pkcs11_module_path), 0 },
+       { STR(driver_param), 0 },
+       { INT(dot11RSNAConfigPMKLifetime), 0 },
+       { INT(dot11RSNAConfigPMKReauthThreshold), 0 },
+       { INT(dot11RSNAConfigSATimeout), 0 },
 #ifndef CONFIG_NO_CONFIG_WRITE
-       { INT(update_config) },
+       { INT(update_config), 0 },
 #endif /* CONFIG_NO_CONFIG_WRITE */
-       { FUNC_NO_VAR(load_dynamic_eap) },
+       { FUNC_NO_VAR(load_dynamic_eap), 0 },
 #ifdef CONFIG_WPS
-       { FUNC(uuid) },
-       { STR_RANGE(device_name, 0, 32) },
-       { STR_RANGE(manufacturer, 0, 64) },
-       { STR_RANGE(model_name, 0, 32) },
-       { STR_RANGE(model_number, 0, 32) },
-       { STR_RANGE(serial_number, 0, 32) },
-       { STR(device_type) },
-       { FUNC(os_version) },
-       { STR(config_methods) },
-       { INT_RANGE(wps_cred_processing, 0, 2) },
+       { FUNC(uuid), CFG_CHANGED_UUID },
+       { STR_RANGE(device_name, 0, 32), CFG_CHANGED_DEVICE_NAME },
+       { STR_RANGE(manufacturer, 0, 64), CFG_CHANGED_WPS_STRING },
+       { STR_RANGE(model_name, 0, 32), CFG_CHANGED_WPS_STRING },
+       { STR_RANGE(model_number, 0, 32), CFG_CHANGED_WPS_STRING },
+       { STR_RANGE(serial_number, 0, 32), CFG_CHANGED_WPS_STRING },
+       { STR(device_type), CFG_CHANGED_DEVICE_TYPE },
+       { FUNC(os_version), CFG_CHANGED_OS_VERSION },
+       { STR(config_methods), CFG_CHANGED_CONFIG_METHODS },
+       { INT_RANGE(wps_cred_processing, 0, 2), 0 },
 #endif /* CONFIG_WPS */
-       { FUNC(country) },
-       { INT(bss_max_count) },
-       { INT_RANGE(filter_ssids, 0, 1) }
+#ifdef CONFIG_P2P
+       { FUNC(sec_device_type), CFG_CHANGED_SEC_DEVICE_TYPE },
+       { INT(p2p_listen_reg_class), 0 },
+       { INT(p2p_listen_channel), 0 },
+       { INT(p2p_oper_reg_class), 0 },
+       { INT(p2p_oper_channel), 0 },
+       { INT_RANGE(p2p_go_intent, 0, 15), 0 },
+       { STR(p2p_ssid_postfix), CFG_CHANGED_P2P_SSID_POSTFIX },
+       { INT_RANGE(persistent_reconnect, 0, 1), 0 },
+       { INT_RANGE(p2p_intra_bss, 0, 1), CFG_CHANGED_P2P_INTRA_BSS },
+#endif /* CONFIG_P2P */
+       { FUNC(country), CFG_CHANGED_COUNTRY },
+       { INT(bss_max_count), 0 },
+       { INT_RANGE(filter_ssids, 0, 1), 0 }
 };
 
 #undef FUNC
@@ -2387,9 +2435,12 @@ int wpa_config_process_global(struct wpa_config *config, char *pos, int line)
                                   "parse '%s'.", line, pos);
                        ret = -1;
                }
+               config->changed_parameters |= field->changed_flag;
                break;
        }
        if (i == NUM_GLOBAL_FIELDS) {
+               if (line < 0)
+                       return -1;
                wpa_printf(MSG_ERROR, "Line %d: unknown global field '%s'.",
                           line, pos);
                ret = -1;