aboutsummaryrefslogtreecommitdiff
path: root/wpa_supplicant/ctrl_iface.c
diff options
context:
space:
mode:
Diffstat (limited to 'wpa_supplicant/ctrl_iface.c')
-rw-r--r--wpa_supplicant/ctrl_iface.c623
1 files changed, 617 insertions, 6 deletions
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 8a6a829b6665..9dc17f5eef85 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -568,10 +568,10 @@ static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,
(wps_version_number & 0xf0) >> 4,
wps_version_number & 0x0f);
}
- } else if (os_strcasecmp(cmd, "wps_testing_dummy_cred") == 0) {
- wps_testing_dummy_cred = atoi(value);
- wpa_printf(MSG_DEBUG, "WPS: Testing - dummy_cred=%d",
- wps_testing_dummy_cred);
+ } else if (os_strcasecmp(cmd, "wps_testing_stub_cred") == 0) {
+ wps_testing_stub_cred = atoi(value);
+ wpa_printf(MSG_DEBUG, "WPS: Testing - stub_cred=%d",
+ wps_testing_stub_cred);
} else if (os_strcasecmp(cmd, "wps_corrupt_pkhash") == 0) {
wps_corrupt_pkhash = atoi(value);
wpa_printf(MSG_DEBUG, "WPS: Testing - wps_corrupt_pkhash=%d",
@@ -830,6 +830,10 @@ static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,
wpa_s->sae_commit_override = wpabuf_parse_bin(value);
} else if (os_strcasecmp(cmd, "driver_signal_override") == 0) {
ret = wpas_ctrl_iface_set_dso(wpa_s, value);
+ } else if (os_strcasecmp(cmd, "disable_scs_support") == 0) {
+ wpa_s->disable_scs_support = !!atoi(value);
+ } else if (os_strcasecmp(cmd, "disable_mscs_support") == 0) {
+ wpa_s->disable_mscs_support = !!atoi(value);
#ifdef CONFIG_DPP
} else if (os_strcasecmp(cmd, "dpp_config_obj_override") == 0) {
os_free(wpa_s->dpp_config_obj_override);
@@ -918,6 +922,8 @@ static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,
return -1;
wnm_set_coloc_intf_elems(wpa_s, elems);
#endif /* CONFIG_WNM */
+ } else if (os_strcasecmp(cmd, "enable_dscp_policy_capa") == 0) {
+ wpa_s->enable_dscp_policy_capa = !!atoi(value);
} else {
value[-1] = '=';
ret = wpa_config_process_global(wpa_s->conf, cmd, -1);
@@ -5918,7 +5924,7 @@ static struct p2ps_provision * p2p_parse_asp_provision_cmd(const char *cmd)
for (i = 0; p2ps_prov->cpt_priority[i]; i++)
p2ps_prov->cpt_mask |= p2ps_prov->cpt_priority[i];
- /* force conncap with tstCap (no sanity checks) */
+ /* force conncap with tstCap (no validity checks) */
pos = os_strstr(cmd, "tstCap=");
if (pos) {
role = strtol(pos + 7, NULL, 16);
@@ -6122,6 +6128,9 @@ static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd,
if (max_oper_chwidth < 0)
return -1;
+ if (allow_6ghz && chwidth == 40)
+ max_oper_chwidth = CHANWIDTH_40MHZ_6GHZ;
+
pos2 = os_strstr(pos, " ssid=");
if (pos2) {
char *end;
@@ -6775,6 +6784,9 @@ static int p2p_ctrl_invite_persistent(struct wpa_supplicant *wpa_s, char *cmd)
allow_6ghz = os_strstr(cmd, " allow_6ghz") != NULL;
+ if (allow_6ghz && chwidth == 40)
+ max_oper_chwidth = CHANWIDTH_40MHZ_6GHZ;
+
return wpas_p2p_invite(wpa_s, _peer, ssid, NULL, freq, freq2, ht40, vht,
max_oper_chwidth, pref_freq, he, edmg,
allow_6ghz);
@@ -6918,6 +6930,13 @@ static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd)
if (max_oper_chwidth < 0)
return -1;
+ if (allow_6ghz && chwidth == 40)
+ max_oper_chwidth = CHANWIDTH_40MHZ_6GHZ;
+
+ /* Allow DFS to be used for Autonomous GO */
+ wpa_s->p2p_go_allow_dfs = !!(wpa_s->drv_flags &
+ WPA_DRIVER_FLAGS_DFS_OFFLOAD);
+
if (group_id >= 0)
return p2p_ctrl_group_add_persistent(wpa_s, group_id,
freq, freq2, ht40, vht,
@@ -8428,7 +8447,7 @@ static void wpa_supplicant_ctrl_iface_flush(struct wpa_supplicant *wpa_s)
#ifdef CONFIG_WPS_TESTING
wps_version_number = 0x20;
- wps_testing_dummy_cred = 0;
+ wps_testing_stub_cred = 0;
wps_corrupt_pkhash = 0;
wps_force_auth_types_in_use = 0;
wps_force_encr_types_in_use = 0;
@@ -8551,6 +8570,9 @@ static void wpa_supplicant_ctrl_iface_flush(struct wpa_supplicant *wpa_s)
wpabuf_free(wpa_s->rsnxe_override_eapol);
wpa_s->rsnxe_override_eapol = NULL;
wpas_clear_driver_signal_override(wpa_s);
+ wpa_s->disable_scs_support = 0;
+ wpa_s->disable_mscs_support = 0;
+ wpa_s->enable_dscp_policy_capa = 0;
wpa_s->oci_freq_override_eapol = 0;
wpa_s->oci_freq_override_saquery_req = 0;
wpa_s->oci_freq_override_saquery_resp = 0;
@@ -10602,6 +10624,8 @@ static int wpas_ctrl_iface_pmksa_add(struct wpa_supplicant *wpa_s,
if (sscanf(pos, "%d %d %d %d", &reauth_time, &expiration,
&entry->akmp, &entry->opportunistic) != 4)
goto fail;
+ if (reauth_time > expiration)
+ goto fail;
for (i = 0; i < 4; i++) {
pos = os_strchr(pos, ' ');
if (!pos) {
@@ -10887,6 +10911,581 @@ static int wpas_ctrl_iface_pasn_deauthenticate(struct wpa_supplicant *wpa_s,
#endif /* CONFIG_PASN */
+static int set_type4_frame_classifier(const char *cmd,
+ struct type4_params *param)
+{
+ const char *pos, *end;
+ u8 classifier_mask = 0;
+ int ret;
+ char addr[INET6_ADDRSTRLEN];
+ size_t alen;
+
+ if (os_strstr(cmd, "ip_version=ipv4")) {
+ param->ip_version = IPV4;
+ } else if (os_strstr(cmd, "ip_version=ipv6")) {
+ param->ip_version = IPV6;
+ } else {
+ wpa_printf(MSG_ERROR, "IP version missing/invalid");
+ return -1;
+ }
+
+ classifier_mask |= BIT(0);
+
+ pos = os_strstr(cmd, "src_ip=");
+ if (pos) {
+ pos += 7;
+ end = os_strchr(pos, ' ');
+ if (!end)
+ end = pos + os_strlen(pos);
+
+ alen = end - pos;
+ if (alen >= INET6_ADDRSTRLEN)
+ return -1;
+ os_memcpy(addr, pos, alen);
+ addr[alen] = '\0';
+ if (param->ip_version == IPV4)
+ ret = inet_pton(AF_INET, addr,
+ &param->ip_params.v4.src_ip);
+ else
+ ret = inet_pton(AF_INET6, addr,
+ &param->ip_params.v6.src_ip);
+
+ if (ret != 1) {
+ wpa_printf(MSG_ERROR,
+ "Error converting src IP address to binary ret=%d",
+ ret);
+ return -1;
+ }
+
+ classifier_mask |= BIT(1);
+ }
+
+ pos = os_strstr(cmd, "dst_ip=");
+ if (pos) {
+ pos += 7;
+ end = os_strchr(pos, ' ');
+ if (!end)
+ end = pos + os_strlen(pos);
+
+ alen = end - pos;
+ if (alen >= INET6_ADDRSTRLEN)
+ return -1;
+ os_memcpy(addr, pos, alen);
+ addr[alen] = '\0';
+ if (param->ip_version == IPV4)
+ ret = inet_pton(AF_INET, addr,
+ &param->ip_params.v4.dst_ip);
+ else
+ ret = inet_pton(AF_INET6, addr,
+ &param->ip_params.v6.dst_ip);
+
+ if (ret != 1) {
+ wpa_printf(MSG_ERROR,
+ "Error converting dst IP address to binary ret=%d",
+ ret);
+ return -1;
+ }
+
+ classifier_mask |= BIT(2);
+ }
+
+ pos = os_strstr(cmd, "src_port=");
+ if (pos && atoi(pos + 9) > 0) {
+ if (param->ip_version == IPV4)
+ param->ip_params.v4.src_port = atoi(pos + 9);
+ else
+ param->ip_params.v6.src_port = atoi(pos + 9);
+ classifier_mask |= BIT(3);
+ }
+
+ pos = os_strstr(cmd, "dst_port=");
+ if (pos && atoi(pos + 9) > 0) {
+ if (param->ip_version == IPV4)
+ param->ip_params.v4.dst_port = atoi(pos + 9);
+ else
+ param->ip_params.v6.dst_port = atoi(pos + 9);
+ classifier_mask |= BIT(4);
+ }
+
+ pos = os_strstr(cmd, "dscp=");
+ if (pos && atoi(pos + 5) > 0) {
+ if (param->ip_version == IPV4)
+ param->ip_params.v4.dscp = atoi(pos + 5);
+ else
+ param->ip_params.v6.dscp = atoi(pos + 5);
+ classifier_mask |= BIT(5);
+ }
+
+ if (param->ip_version == IPV4) {
+ pos = os_strstr(cmd, "protocol=");
+ if (pos) {
+ if (os_strstr(pos, "udp")) {
+ param->ip_params.v4.protocol = 17;
+ } else if (os_strstr(pos, "tcp")) {
+ param->ip_params.v4.protocol = 6;
+ } else if (os_strstr(pos, "esp")) {
+ param->ip_params.v4.protocol = 50;
+ } else {
+ wpa_printf(MSG_ERROR, "Invalid protocol");
+ return -1;
+ }
+ classifier_mask |= BIT(6);
+ }
+ } else {
+ pos = os_strstr(cmd, "next_header=");
+ if (pos) {
+ if (os_strstr(pos, "udp")) {
+ param->ip_params.v6.next_header = 17;
+ } else if (os_strstr(pos, "tcp")) {
+ param->ip_params.v6.next_header = 6;
+ } else if (os_strstr(pos, "esp")) {
+ param->ip_params.v6.next_header = 50;
+ } else {
+ wpa_printf(MSG_ERROR, "Invalid next header");
+ return -1;
+ }
+
+ classifier_mask |= BIT(6);
+ }
+
+ pos = os_strstr(cmd, "flow_label=");
+ if (pos) {
+ pos += 11;
+ end = os_strchr(pos, ' ');
+ if (!end)
+ end = pos + os_strlen(pos);
+
+ if (end - pos != 6 ||
+ hexstr2bin(pos, param->ip_params.v6.flow_label,
+ 3) ||
+ param->ip_params.v6.flow_label[0] > 0x0F) {
+ wpa_printf(MSG_ERROR, "Invalid flow label");
+ return -1;
+ }
+
+ classifier_mask |= BIT(7);
+ }
+ }
+
+ param->classifier_mask = classifier_mask;
+ return 0;
+}
+
+
+static int set_type10_frame_classifier(const char *cmd,
+ struct type10_params *param)
+{
+ const char *pos, *end;
+ size_t filter_len;
+
+ pos = os_strstr(cmd, "prot_instance=");
+ if (!pos) {
+ wpa_printf(MSG_ERROR, "Protocol instance missing");
+ return -1;
+ }
+ param->prot_instance = atoi(pos + 14);
+
+ pos = os_strstr(cmd, "prot_number=");
+ if (!pos) {
+ wpa_printf(MSG_ERROR, "Protocol number missing");
+ return -1;
+ }
+ if (os_strstr(pos, "udp")) {
+ param->prot_number = 17;
+ } else if (os_strstr(pos, "tcp")) {
+ param->prot_number = 6;
+ } else if (os_strstr(pos, "esp")) {
+ param->prot_number = 50;
+ } else {
+ wpa_printf(MSG_ERROR, "Invalid protocol number");
+ return -1;
+ }
+
+ pos = os_strstr(cmd, "filter_value=");
+ if (!pos) {
+ wpa_printf(MSG_ERROR,
+ "Classifier parameter filter_value missing");
+ return -1;
+ }
+
+ pos += 13;
+ end = os_strchr(pos, ' ');
+ if (!end)
+ end = pos + os_strlen(pos);
+
+ filter_len = (end - pos) / 2;
+ param->filter_value = os_malloc(filter_len);
+ if (!param->filter_value)
+ return -1;
+
+ if (hexstr2bin(pos, param->filter_value, filter_len)) {
+ wpa_printf(MSG_ERROR, "Invalid filter_value %s", pos);
+ goto free;
+ }
+
+ pos = os_strstr(cmd, "filter_mask=");
+ if (!pos) {
+ wpa_printf(MSG_ERROR,
+ "Classifier parameter filter_mask missing");
+ goto free;
+ }
+
+ pos += 12;
+ end = os_strchr(pos, ' ');
+ if (!end)
+ end = pos + os_strlen(pos);
+
+ if (filter_len != (size_t) (end - pos) / 2) {
+ wpa_printf(MSG_ERROR,
+ "Filter mask length mismatch expected=%zu received=%zu",
+ filter_len, (size_t) (end - pos) / 2);
+ goto free;
+ }
+
+ param->filter_mask = os_malloc(filter_len);
+ if (!param->filter_mask)
+ goto free;
+
+ if (hexstr2bin(pos, param->filter_mask, filter_len)) {
+ wpa_printf(MSG_ERROR, "Invalid filter mask %s", pos);
+ os_free(param->filter_mask);
+ param->filter_mask = NULL;
+ goto free;
+ }
+
+ param->filter_len = filter_len;
+ return 0;
+free:
+ os_free(param->filter_value);
+ param->filter_value = NULL;
+ return -1;
+}
+
+
+static int scs_parse_type4(struct tclas_element *elem, const char *pos)
+{
+ struct type4_params type4_param = { 0 };
+
+ if (set_type4_frame_classifier(pos, &type4_param) == -1) {
+ wpa_printf(MSG_ERROR, "Failed to set frame_classifier 4");
+ return -1;
+ }
+
+ os_memcpy(&elem->frame_classifier.type4_param,
+ &type4_param, sizeof(struct type4_params));
+ return 0;
+}
+
+
+static int scs_parse_type10(struct tclas_element *elem, const char *pos)
+{
+ struct type10_params type10_param = { 0 };
+
+ if (set_type10_frame_classifier(pos, &type10_param) == -1) {
+ wpa_printf(MSG_ERROR, "Failed to set frame_classifier 10");
+ return -1;
+ }
+
+ os_memcpy(&elem->frame_classifier.type10_param,
+ &type10_param, sizeof(struct type10_params));
+ return 0;
+}
+
+
+static int wpas_ctrl_iface_configure_scs(struct wpa_supplicant *wpa_s,
+ char *cmd)
+{
+ char *pos1, *pos;
+ struct scs_robust_av_data *scs_data = &wpa_s->scs_robust_av_req;
+ struct scs_desc_elem desc_elem = { 0 };
+ int val;
+ unsigned int num_scs_desc = 0;
+
+ if (wpa_s->ongoing_scs_req) {
+ wpa_printf(MSG_ERROR, "%s: SCS Request already in queue",
+ __func__);
+ return -1;
+ }
+
+ /**
+ * format:
+ * [scs_id=<decimal number>] <add|remove|change> [scs_up=<0-7>]
+ * [classifier_type=<4|10>]
+ * [classifier params based on classifier type]
+ * [tclas_processing=<0|1>] [scs_id=<decimal number>] ...
+ */
+ pos1 = os_strstr(cmd, "scs_id=");
+ if (!pos1) {
+ wpa_printf(MSG_ERROR, "SCSID not present");
+ return -1;
+ }
+
+ free_up_scs_desc(scs_data);
+
+ while (pos1) {
+ struct scs_desc_elem *n1;
+ struct active_scs_elem *active_scs_desc;
+ char *next_scs_desc;
+ unsigned int num_tclas_elem = 0;
+ bool scsid_active = false;
+
+ desc_elem.scs_id = atoi(pos1 + 7);
+ pos1 += 7;
+
+ next_scs_desc = os_strstr(pos1, "scs_id=");
+ if (next_scs_desc) {
+ char temp[20];
+
+ os_snprintf(temp, sizeof(temp), "scs_id=%d ",
+ desc_elem.scs_id);
+ if (os_strstr(next_scs_desc, temp)) {
+ wpa_printf(MSG_ERROR,
+ "Multiple SCS descriptors configured with same SCSID(=%d)",
+ desc_elem.scs_id);
+ goto free_scs_desc;
+ }
+ pos1[next_scs_desc - pos1 - 1] = '\0';
+ }
+
+ dl_list_for_each(active_scs_desc, &wpa_s->active_scs_ids,
+ struct active_scs_elem, list) {
+ if (desc_elem.scs_id == active_scs_desc->scs_id) {
+ scsid_active = true;
+ break;
+ }
+ }
+
+ if (os_strstr(pos1, "add ")) {
+ desc_elem.request_type = SCS_REQ_ADD;
+ if (scsid_active) {
+ wpa_printf(MSG_ERROR, "SCSID %d already active",
+ desc_elem.scs_id);
+ return -1;
+ }
+ } else if (os_strstr(pos1, "remove")) {
+ desc_elem.request_type = SCS_REQ_REMOVE;
+ if (!scsid_active) {
+ wpa_printf(MSG_ERROR, "SCSID %d not active",
+ desc_elem.scs_id);
+ return -1;
+ }
+ goto scs_desc_end;
+ } else if (os_strstr(pos1, "change ")) {
+ desc_elem.request_type = SCS_REQ_CHANGE;
+ if (!scsid_active) {
+ wpa_printf(MSG_ERROR, "SCSID %d not active",
+ desc_elem.scs_id);
+ return -1;
+ }
+ } else {
+ wpa_printf(MSG_ERROR, "SCS Request type invalid");
+ goto free_scs_desc;
+ }
+
+ pos1 = os_strstr(pos1, "scs_up=");
+ if (!pos1) {
+ wpa_printf(MSG_ERROR,
+ "Intra-Access user priority not present");
+ goto free_scs_desc;
+ }
+
+ val = atoi(pos1 + 7);
+ if (val < 0 || val > 7) {
+ wpa_printf(MSG_ERROR,
+ "Intra-Access user priority invalid %d",
+ val);
+ goto free_scs_desc;
+ }
+
+ desc_elem.intra_access_priority = val;
+ desc_elem.scs_up_avail = true;
+
+ pos = os_strstr(pos1, "classifier_type=");
+ if (!pos) {
+ wpa_printf(MSG_ERROR, "classifier type empty");
+ goto free_scs_desc;
+ }
+
+ while (pos) {
+ struct tclas_element elem = { 0 }, *n;
+ char *next_tclas_elem;
+
+ val = atoi(pos + 16);
+ if (val != 4 && val != 10) {
+ wpa_printf(MSG_ERROR,
+ "classifier type invalid %d", val);
+ goto free_scs_desc;
+ }
+
+ elem.classifier_type = val;
+ pos += 16;
+
+ next_tclas_elem = os_strstr(pos, "classifier_type=");
+ if (next_tclas_elem) {
+ pos1 = next_tclas_elem;
+ pos[next_tclas_elem - pos - 1] = '\0';
+ }
+
+ switch (val) {
+ case 4:
+ if (scs_parse_type4(&elem, pos) < 0)
+ goto free_scs_desc;
+ break;
+ case 10:
+ if (scs_parse_type10(&elem, pos) < 0)
+ goto free_scs_desc;
+ break;
+ }
+
+ n = os_realloc(desc_elem.tclas_elems,
+ (num_tclas_elem + 1) * sizeof(elem));
+ if (!n)
+ goto free_scs_desc;
+
+ desc_elem.tclas_elems = n;
+ os_memcpy((u8 *) desc_elem.tclas_elems +
+ num_tclas_elem * sizeof(elem),
+ &elem, sizeof(elem));
+ num_tclas_elem++;
+ desc_elem.num_tclas_elem = num_tclas_elem;
+ pos = next_tclas_elem;
+ }
+
+ if (desc_elem.num_tclas_elem > 1) {
+ pos1 = os_strstr(pos1, "tclas_processing=");
+ if (!pos1) {
+ wpa_printf(MSG_ERROR, "tclas_processing empty");
+ goto free_scs_desc;
+ }
+
+ val = atoi(pos1 + 17);
+ if (val != 0 && val != 1) {
+ wpa_printf(MSG_ERROR,
+ "tclas_processing invalid");
+ goto free_scs_desc;
+ }
+
+ desc_elem.tclas_processing = val;
+ }
+
+scs_desc_end:
+ n1 = os_realloc(scs_data->scs_desc_elems, (num_scs_desc + 1) *
+ sizeof(struct scs_desc_elem));
+ if (!n1)
+ goto free_scs_desc;
+
+ scs_data->scs_desc_elems = n1;
+ os_memcpy((u8 *) scs_data->scs_desc_elems + num_scs_desc *
+ sizeof(desc_elem), &desc_elem, sizeof(desc_elem));
+ num_scs_desc++;
+ scs_data->num_scs_desc = num_scs_desc;
+ pos1 = next_scs_desc;
+ os_memset(&desc_elem, 0, sizeof(desc_elem));
+ }
+
+ return wpas_send_scs_req(wpa_s);
+
+free_scs_desc:
+ free_up_tclas_elem(&desc_elem);
+ free_up_scs_desc(scs_data);
+ return -1;
+}
+
+
+static int wpas_ctrl_iface_send_dscp_resp(struct wpa_supplicant *wpa_s,
+ const char *cmd)
+{
+ char *pos;
+ struct dscp_policy_status *policy = NULL, *n;
+ int num_policies = 0, ret = -1;
+ struct dscp_resp_data resp_data;
+
+ /*
+ * format:
+ * <[reset]>/<[solicited] [policy_id=1 status=0...]> [more]
+ */
+
+ os_memset(&resp_data, 0, sizeof(resp_data));
+
+ resp_data.more = os_strstr(cmd, "more") != NULL;
+
+ if (os_strstr(cmd, "reset")) {
+ resp_data.reset = true;
+ resp_data.solicited = false;
+ goto send_resp;
+ }
+
+ resp_data.solicited = os_strstr(cmd, "solicited") != NULL;
+
+ pos = os_strstr(cmd, "policy_id=");
+ while (pos) {
+ n = os_realloc(policy, (num_policies + 1) * sizeof(*policy));
+ if (!n)
+ goto fail;
+
+ policy = n;
+ pos += 10;
+ policy[num_policies].id = atoi(pos);
+ if (policy[num_policies].id == 0) {
+ wpa_printf(MSG_ERROR, "DSCP: Invalid policy id");
+ goto fail;
+ }
+
+ pos = os_strstr(pos, "status=");
+ if (!pos) {
+ wpa_printf(MSG_ERROR,
+ "DSCP: Status is not found for a policy");
+ goto fail;
+ }
+
+ pos += 7;
+ policy[num_policies].status = atoi(pos);
+ num_policies++;
+
+ pos = os_strstr(pos, "policy_id");
+ }
+
+ resp_data.policy = policy;
+ resp_data.num_policies = num_policies;
+send_resp:
+ ret = wpas_send_dscp_response(wpa_s, &resp_data);
+ if (ret)
+ wpa_printf(MSG_ERROR, "DSCP: Failed to send DSCP response");
+fail:
+ os_free(policy);
+ return ret;
+}
+
+
+static int wpas_ctrl_iface_send_dscp_query(struct wpa_supplicant *wpa_s,
+ const char *cmd)
+{
+ char *pos;
+
+ /*
+ * format:
+ * Wildcard DSCP query
+ * <wildcard>
+ *
+ * DSCP query with a domain name attribute:
+ * [domain_name=<string>]
+ */
+
+ if (os_strstr(cmd, "wildcard")) {
+ wpa_printf(MSG_DEBUG, "QM: Send wildcard DSCP policy query");
+ return wpas_send_dscp_query(wpa_s, NULL, 0);
+ }
+
+ pos = os_strstr(cmd, "domain_name=");
+ if (!pos || !os_strlen(pos + 12)) {
+ wpa_printf(MSG_ERROR, "QM: Domain name not preset");
+ return -1;
+ }
+
+ return wpas_send_dscp_query(wpa_s, pos + 12, os_strlen(pos + 12));
+}
+
+
char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
char *buf, size_t *resp_len)
{
@@ -11458,6 +12057,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
} else if (os_strcmp(buf, "STOP_AP") == 0) {
if (wpas_ap_stop_ap(wpa_s))
reply_len = -1;
+ } else if (os_strcmp(buf, "UPDATE_BEACON") == 0) {
+ if (wpas_ap_update_beacon(wpa_s))
+ reply_len = -1;
#endif /* CONFIG_AP */
} else if (os_strcmp(buf, "SUSPEND") == 0) {
wpas_notify_suspend(wpa_s->global);
@@ -11812,6 +12414,15 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
if (wpas_ctrl_iface_pasn_deauthenticate(wpa_s, buf + 12) < 0)
reply_len = -1;
#endif /* CONFIG_PASN */
+ } else if (os_strncmp(buf, "SCS ", 4) == 0) {
+ if (wpas_ctrl_iface_configure_scs(wpa_s, buf + 4))
+ reply_len = -1;
+ } else if (os_strncmp(buf, "DSCP_RESP ", 10) == 0) {
+ if (wpas_ctrl_iface_send_dscp_resp(wpa_s, buf + 10))
+ reply_len = -1;
+ } else if (os_strncmp(buf, "DSCP_QUERY ", 11) == 0) {
+ if (wpas_ctrl_iface_send_dscp_query(wpa_s, buf + 11))
+ reply_len = -1;
} else {
os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
reply_len = 16;