1 /*
2  * wpa_supplicant - Robust AV procedures
3  * Copyright (c) 2020, The Linux Foundation
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8 
9 #include "utils/includes.h"
10 #include "utils/common.h"
11 #include "utils/eloop.h"
12 #include "common/wpa_ctrl.h"
13 #include "common/ieee802_11_common.h"
14 #include "wpa_supplicant_i.h"
15 #include "driver_i.h"
16 #include "bss.h"
17 
18 
19 #define SCS_RESP_TIMEOUT 1
20 #define DSCP_REQ_TIMEOUT 5
21 
22 
23 void wpas_populate_mscs_descriptor_ie(struct robust_av_data *robust_av,
24 				      struct wpabuf *buf)
25 {
26 	u8 *len, *len1;
27 
28 	/* MSCS descriptor element */
29 	wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
30 	len = wpabuf_put(buf, 1);
31 	wpabuf_put_u8(buf, WLAN_EID_EXT_MSCS_DESCRIPTOR);
32 	wpabuf_put_u8(buf, robust_av->request_type);
33 	wpabuf_put_u8(buf, robust_av->up_bitmap);
34 	wpabuf_put_u8(buf, robust_av->up_limit);
35 	wpabuf_put_le32(buf, robust_av->stream_timeout);
36 
37 	if (robust_av->request_type != SCS_REQ_REMOVE) {
38 		/* TCLAS mask element */
39 		wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
40 		len1 = wpabuf_put(buf, 1);
41 		wpabuf_put_u8(buf, WLAN_EID_EXT_TCLAS_MASK);
42 
43 		/* Frame classifier */
44 		wpabuf_put_data(buf, robust_av->frame_classifier,
45 				robust_av->frame_classifier_len);
46 		*len1 = (u8 *) wpabuf_put(buf, 0) - len1 - 1;
47 	}
48 
49 	*len = (u8 *) wpabuf_put(buf, 0) - len - 1;
50 }
51 
52 
53 static int wpas_populate_type4_classifier(struct type4_params *type4_param,
54 					  struct wpabuf *buf)
55 {
56 	/* classifier parameters */
57 	wpabuf_put_u8(buf, type4_param->classifier_mask);
58 	if (type4_param->ip_version == IPV4) {
59 		wpabuf_put_u8(buf, IPV4); /* IP version */
60 		wpabuf_put_data(buf, &type4_param->ip_params.v4.src_ip.s_addr,
61 				4);
62 		wpabuf_put_data(buf, &type4_param->ip_params.v4.dst_ip.s_addr,
63 				4);
64 		wpabuf_put_be16(buf, type4_param->ip_params.v4.src_port);
65 		wpabuf_put_be16(buf, type4_param->ip_params.v4.dst_port);
66 		wpabuf_put_u8(buf, type4_param->ip_params.v4.dscp);
67 		wpabuf_put_u8(buf, type4_param->ip_params.v4.protocol);
68 		wpabuf_put_u8(buf, 0); /* Reserved octet */
69 	} else {
70 		wpabuf_put_u8(buf, IPV6);
71 		wpabuf_put_data(buf, &type4_param->ip_params.v6.src_ip.s6_addr,
72 				16);
73 		wpabuf_put_data(buf, &type4_param->ip_params.v6.dst_ip.s6_addr,
74 				16);
75 		wpabuf_put_be16(buf, type4_param->ip_params.v6.src_port);
76 		wpabuf_put_be16(buf, type4_param->ip_params.v6.dst_port);
77 		wpabuf_put_u8(buf, type4_param->ip_params.v6.dscp);
78 		wpabuf_put_u8(buf, type4_param->ip_params.v6.next_header);
79 		wpabuf_put_data(buf, type4_param->ip_params.v6.flow_label, 3);
80 	}
81 
82 	return 0;
83 }
84 
85 
86 static int wpas_populate_type10_classifier(struct type10_params *type10_param,
87 					   struct wpabuf *buf)
88 {
89 	/* classifier parameters */
90 	wpabuf_put_u8(buf, type10_param->prot_instance);
91 	wpabuf_put_u8(buf, type10_param->prot_number);
92 	wpabuf_put_data(buf, type10_param->filter_value,
93 			type10_param->filter_len);
94 	wpabuf_put_data(buf, type10_param->filter_mask,
95 			type10_param->filter_len);
96 	return 0;
97 }
98 
99 
100 static int wpas_populate_scs_descriptor_ie(struct scs_desc_elem *desc_elem,
101 					   struct wpabuf *buf)
102 {
103 	u8 *len, *len1;
104 	struct tclas_element *tclas_elem;
105 	unsigned int i;
106 
107 	/* SCS Descriptor element */
108 	wpabuf_put_u8(buf, WLAN_EID_SCS_DESCRIPTOR);
109 	len = wpabuf_put(buf, 1);
110 	wpabuf_put_u8(buf, desc_elem->scs_id);
111 	wpabuf_put_u8(buf, desc_elem->request_type);
112 	if (desc_elem->request_type == SCS_REQ_REMOVE)
113 		goto end;
114 
115 	if (desc_elem->intra_access_priority || desc_elem->scs_up_avail) {
116 		wpabuf_put_u8(buf, WLAN_EID_INTRA_ACCESS_CATEGORY_PRIORITY);
117 		wpabuf_put_u8(buf, 1);
118 		wpabuf_put_u8(buf, desc_elem->intra_access_priority);
119 	}
120 
121 	tclas_elem = desc_elem->tclas_elems;
122 
123 	if (!tclas_elem)
124 		return -1;
125 
126 	for (i = 0; i < desc_elem->num_tclas_elem; i++, tclas_elem++) {
127 		int ret;
128 
129 		/* TCLAS element */
130 		wpabuf_put_u8(buf, WLAN_EID_TCLAS);
131 		len1 = wpabuf_put(buf, 1);
132 		wpabuf_put_u8(buf, 255); /* User Priority: not compared */
133 		/* Frame Classifier */
134 		wpabuf_put_u8(buf, tclas_elem->classifier_type);
135 		/* Frame classifier parameters */
136 		switch (tclas_elem->classifier_type) {
137 		case 4:
138 			ret = wpas_populate_type4_classifier(
139 				&tclas_elem->frame_classifier.type4_param,
140 				buf);
141 			break;
142 		case 10:
143 			ret = wpas_populate_type10_classifier(
144 				&tclas_elem->frame_classifier.type10_param,
145 				buf);
146 			break;
147 		default:
148 			return -1;
149 		}
150 
151 		if (ret == -1) {
152 			wpa_printf(MSG_ERROR,
153 				   "Failed to populate frame classifier");
154 			return -1;
155 		}
156 
157 		*len1 = (u8 *) wpabuf_put(buf, 0) - len1 - 1;
158 	}
159 
160 	if (desc_elem->num_tclas_elem > 1) {
161 		/* TCLAS Processing element */
162 		wpabuf_put_u8(buf, WLAN_EID_TCLAS_PROCESSING);
163 		wpabuf_put_u8(buf, 1);
164 		wpabuf_put_u8(buf, desc_elem->tclas_processing);
165 	}
166 
167 end:
168 	*len = (u8 *) wpabuf_put(buf, 0) - len - 1;
169 	return 0;
170 }
171 
172 
173 int wpas_send_mscs_req(struct wpa_supplicant *wpa_s)
174 {
175 	struct wpabuf *buf;
176 	size_t buf_len;
177 	int ret;
178 
179 	if (wpa_s->wpa_state != WPA_COMPLETED || !wpa_s->current_ssid)
180 		return 0;
181 
182 	if (!wpa_bss_ext_capab(wpa_s->current_bss, WLAN_EXT_CAPAB_MSCS)) {
183 		wpa_dbg(wpa_s, MSG_INFO,
184 			"AP does not support MSCS - could not send MSCS Req");
185 		return -1;
186 	}
187 
188 	if (!wpa_s->mscs_setup_done &&
189 	    wpa_s->robust_av.request_type != SCS_REQ_ADD) {
190 		wpa_msg(wpa_s, MSG_INFO,
191 			"MSCS: Failed to send MSCS Request: request type invalid");
192 		return -1;
193 	}
194 
195 	buf_len = 3 +	/* Action frame header */
196 		  3 +	/* MSCS descriptor IE header */
197 		  1 +	/* Request type */
198 		  2 +	/* User priority control */
199 		  4 +	/* Stream timeout */
200 		  3 +	/* TCLAS Mask IE header */
201 		  wpa_s->robust_av.frame_classifier_len;
202 
203 	buf = wpabuf_alloc(buf_len);
204 	if (!buf) {
205 		wpa_printf(MSG_ERROR, "Failed to allocate MSCS req");
206 		return -1;
207 	}
208 
209 	wpabuf_put_u8(buf, WLAN_ACTION_ROBUST_AV_STREAMING);
210 	wpabuf_put_u8(buf, ROBUST_AV_MSCS_REQ);
211 	wpa_s->robust_av.dialog_token++;
212 	wpabuf_put_u8(buf, wpa_s->robust_av.dialog_token);
213 
214 	/* MSCS descriptor element */
215 	wpas_populate_mscs_descriptor_ie(&wpa_s->robust_av, buf);
216 
217 	wpa_hexdump_buf(MSG_MSGDUMP, "MSCS Request", buf);
218 	ret = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
219 				  wpa_s->own_addr, wpa_s->bssid,
220 				  wpabuf_head(buf), wpabuf_len(buf), 0);
221 	if (ret < 0)
222 		wpa_dbg(wpa_s, MSG_INFO, "MSCS: Failed to send MSCS Request");
223 
224 	wpabuf_free(buf);
225 	return ret;
226 }
227 
228 
229 static size_t tclas_elem_len(const struct tclas_element *elem)
230 {
231 	size_t buf_len = 0;
232 
233 	buf_len += 2 +	/* TCLAS element header */
234 		1 +	/* User Priority */
235 		1 ;	/* Classifier Type */
236 
237 	if (elem->classifier_type == 4) {
238 		enum ip_version ip_ver;
239 
240 		buf_len += 1 +	/* Classifier mask */
241 			1 +	/* IP version */
242 			1 +	/* user priority */
243 			2 +	/* src_port */
244 			2 +	/* dst_port */
245 			1 ;	/* dscp */
246 		ip_ver = elem->frame_classifier.type4_param.ip_version;
247 		if (ip_ver == IPV4) {
248 			buf_len += 4 +  /* src_ip */
249 				4 +	/* dst_ip */
250 				1 +	/* protocol */
251 				1 ;  /* Reserved */
252 		} else if (ip_ver == IPV6) {
253 			buf_len += 16 +  /* src_ip */
254 				16 +  /* dst_ip */
255 				1  +  /* next_header */
256 				3  ;  /* flow_label */
257 		} else {
258 			wpa_printf(MSG_ERROR, "%s: Incorrect IP version %d",
259 				   __func__, ip_ver);
260 			return 0;
261 		}
262 	} else if (elem->classifier_type == 10) {
263 		buf_len += 1 +	/* protocol instance */
264 			1 +	/* protocol number */
265 			2 * elem->frame_classifier.type10_param.filter_len;
266 	} else {
267 		wpa_printf(MSG_ERROR, "%s: Incorrect classifier type %u",
268 			   __func__, elem->classifier_type);
269 		return 0;
270 	}
271 
272 	return buf_len;
273 }
274 
275 
276 static struct wpabuf * allocate_scs_buf(struct scs_desc_elem *desc_elem,
277 					unsigned int num_scs_desc)
278 {
279 	struct wpabuf *buf;
280 	size_t buf_len = 0;
281 	unsigned int i, j;
282 
283 	buf_len = 3; /* Action frame header */
284 
285 	for (i = 0; i < num_scs_desc; i++, desc_elem++) {
286 		struct tclas_element *tclas_elem;
287 
288 		buf_len += 2 +	/* SCS descriptor IE header */
289 			   1 +	/* SCSID */
290 			   1 ;	/* Request type */
291 
292 		if (desc_elem->request_type == SCS_REQ_REMOVE)
293 			continue;
294 
295 		if (desc_elem->intra_access_priority || desc_elem->scs_up_avail)
296 			buf_len += 3;
297 
298 		tclas_elem = desc_elem->tclas_elems;
299 		if (!tclas_elem) {
300 			wpa_printf(MSG_ERROR, "%s: TCLAS element null",
301 				   __func__);
302 			return NULL;
303 		}
304 
305 		for (j = 0; j < desc_elem->num_tclas_elem; j++, tclas_elem++) {
306 			size_t elen;
307 
308 			elen = tclas_elem_len(tclas_elem);
309 			if (elen == 0)
310 				return NULL;
311 			buf_len += elen;
312 		}
313 
314 		if (desc_elem->num_tclas_elem > 1) {
315 			buf_len += 1 +	/* TCLAS Processing eid */
316 				   1 +	/* length */
317 				   1 ;	/* processing */
318 		}
319 	}
320 
321 	buf = wpabuf_alloc(buf_len);
322 	if (!buf) {
323 		wpa_printf(MSG_ERROR, "Failed to allocate SCS req");
324 		return NULL;
325 	}
326 
327 	return buf;
328 }
329 
330 
331 static void scs_request_timer(void *eloop_ctx, void *timeout_ctx)
332 {
333 	struct wpa_supplicant *wpa_s = eloop_ctx;
334 	struct active_scs_elem *scs_desc, *prev;
335 
336 	if (wpa_s->wpa_state != WPA_COMPLETED || !wpa_s->current_ssid)
337 		return;
338 
339 	/* Once timeout is over, remove all SCS descriptors with no response */
340 	dl_list_for_each_safe(scs_desc, prev, &wpa_s->active_scs_ids,
341 			      struct active_scs_elem, list) {
342 		u8 bssid[ETH_ALEN] = { 0 };
343 		const u8 *src;
344 
345 		if (scs_desc->status == SCS_DESC_SUCCESS)
346 			continue;
347 
348 		if (wpa_s->current_bss)
349 			src = wpa_s->current_bss->bssid;
350 		else
351 			src = bssid;
352 
353 		wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_SCS_RESULT "bssid=" MACSTR
354 			" SCSID=%u status_code=timedout", MAC2STR(src),
355 			scs_desc->scs_id);
356 
357 		dl_list_del(&scs_desc->list);
358 		wpa_printf(MSG_INFO, "%s: SCSID %d removed after timeout",
359 			   __func__, scs_desc->scs_id);
360 		os_free(scs_desc);
361 	}
362 
363 	eloop_cancel_timeout(scs_request_timer, wpa_s, NULL);
364 	wpa_s->ongoing_scs_req = false;
365 }
366 
367 
368 int wpas_send_scs_req(struct wpa_supplicant *wpa_s)
369 {
370 	struct wpabuf *buf = NULL;
371 	struct scs_desc_elem *desc_elem = NULL;
372 	int ret = -1;
373 	unsigned int i;
374 
375 	if (wpa_s->wpa_state != WPA_COMPLETED || !wpa_s->current_ssid)
376 		return -1;
377 
378 	if (!wpa_bss_ext_capab(wpa_s->current_bss, WLAN_EXT_CAPAB_SCS)) {
379 		wpa_dbg(wpa_s, MSG_INFO,
380 			"AP does not support SCS - could not send SCS Request");
381 		return -1;
382 	}
383 
384 	desc_elem = wpa_s->scs_robust_av_req.scs_desc_elems;
385 	if (!desc_elem)
386 		return -1;
387 
388 	buf = allocate_scs_buf(desc_elem,
389 			       wpa_s->scs_robust_av_req.num_scs_desc);
390 	if (!buf)
391 		return -1;
392 
393 	wpabuf_put_u8(buf, WLAN_ACTION_ROBUST_AV_STREAMING);
394 	wpabuf_put_u8(buf, ROBUST_AV_SCS_REQ);
395 	wpa_s->scs_dialog_token++;
396 	if (wpa_s->scs_dialog_token == 0)
397 		wpa_s->scs_dialog_token++;
398 	wpabuf_put_u8(buf, wpa_s->scs_dialog_token);
399 
400 	for (i = 0; i < wpa_s->scs_robust_av_req.num_scs_desc;
401 	     i++, desc_elem++) {
402 		/* SCS Descriptor element */
403 		if (wpas_populate_scs_descriptor_ie(desc_elem, buf) < 0)
404 			goto end;
405 	}
406 
407 	wpa_hexdump_buf(MSG_DEBUG, "SCS Request", buf);
408 	ret = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
409 				  wpa_s->own_addr, wpa_s->bssid,
410 				  wpabuf_head(buf), wpabuf_len(buf), 0);
411 	if (ret < 0) {
412 		wpa_dbg(wpa_s, MSG_ERROR, "SCS: Failed to send SCS Request");
413 		wpa_s->scs_dialog_token--;
414 		goto end;
415 	}
416 
417 	desc_elem = wpa_s->scs_robust_av_req.scs_desc_elems;
418 	for (i = 0; i < wpa_s->scs_robust_av_req.num_scs_desc;
419 	     i++, desc_elem++) {
420 		struct active_scs_elem *active_scs_elem;
421 
422 		if (desc_elem->request_type != SCS_REQ_ADD)
423 			continue;
424 
425 		active_scs_elem = os_malloc(sizeof(struct active_scs_elem));
426 		if (!active_scs_elem)
427 			break;
428 		active_scs_elem->scs_id = desc_elem->scs_id;
429 		active_scs_elem->status = SCS_DESC_SENT;
430 		dl_list_add(&wpa_s->active_scs_ids, &active_scs_elem->list);
431 	}
432 
433 	/*
434 	 * Register a timeout after which this request will be removed from
435 	 * the cache.
436 	 */
437 	eloop_register_timeout(SCS_RESP_TIMEOUT, 0, scs_request_timer, wpa_s,
438 			       NULL);
439 	wpa_s->ongoing_scs_req = true;
440 
441 end:
442 	wpabuf_free(buf);
443 	free_up_scs_desc(&wpa_s->scs_robust_av_req);
444 
445 	return ret;
446 }
447 
448 
449 void free_up_tclas_elem(struct scs_desc_elem *elem)
450 {
451 	struct tclas_element *tclas_elems = elem->tclas_elems;
452 	unsigned int num_tclas_elem = elem->num_tclas_elem;
453 	struct tclas_element *tclas_data;
454 	unsigned int j;
455 
456 	elem->tclas_elems = NULL;
457 	elem->num_tclas_elem = 0;
458 
459 	if (!tclas_elems)
460 		return;
461 
462 	tclas_data = tclas_elems;
463 	for (j = 0; j < num_tclas_elem; j++, tclas_data++) {
464 		if (tclas_data->classifier_type != 10)
465 			continue;
466 
467 		os_free(tclas_data->frame_classifier.type10_param.filter_value);
468 		os_free(tclas_data->frame_classifier.type10_param.filter_mask);
469 	}
470 
471 	os_free(tclas_elems);
472 }
473 
474 
475 void free_up_scs_desc(struct scs_robust_av_data *data)
476 {
477 	struct scs_desc_elem *desc_elems = data->scs_desc_elems;
478 	unsigned int num_scs_desc = data->num_scs_desc;
479 	struct scs_desc_elem *desc_data;
480 	unsigned int i;
481 
482 	data->scs_desc_elems = NULL;
483 	data->num_scs_desc = 0;
484 
485 	if (!desc_elems)
486 		return;
487 
488 	desc_data = desc_elems;
489 	for (i = 0; i < num_scs_desc; i++, desc_data++) {
490 		if (desc_data->request_type == SCS_REQ_REMOVE ||
491 		    !desc_data->tclas_elems)
492 			continue;
493 
494 		free_up_tclas_elem(desc_data);
495 	}
496 	os_free(desc_elems);
497 }
498 
499 
500 void wpas_handle_robust_av_recv_action(struct wpa_supplicant *wpa_s,
501 				       const u8 *src, const u8 *buf, size_t len)
502 {
503 	u8 dialog_token;
504 	u16 status_code;
505 
506 	if (len < 3)
507 		return;
508 
509 	dialog_token = *buf++;
510 	if (dialog_token != wpa_s->robust_av.dialog_token) {
511 		wpa_printf(MSG_INFO,
512 			   "MSCS: Drop received frame due to dialog token mismatch: received:%u expected:%u",
513 			   dialog_token, wpa_s->robust_av.dialog_token);
514 		return;
515 	}
516 
517 	status_code = WPA_GET_LE16(buf);
518 	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_MSCS_RESULT "bssid=" MACSTR
519 		" status_code=%u", MAC2STR(src), status_code);
520 	wpa_s->mscs_setup_done = status_code == WLAN_STATUS_SUCCESS;
521 }
522 
523 
524 void wpas_handle_assoc_resp_mscs(struct wpa_supplicant *wpa_s, const u8 *bssid,
525 				 const u8 *ies, size_t ies_len)
526 {
527 	const u8 *mscs_desc_ie, *mscs_status;
528 	u16 status;
529 
530 	/* Process optional MSCS Status subelement when MSCS IE is in
531 	 * (Re)Association Response frame */
532 	if (!ies || ies_len == 0 || !wpa_s->robust_av.valid_config)
533 		return;
534 
535 	mscs_desc_ie = get_ie_ext(ies, ies_len, WLAN_EID_EXT_MSCS_DESCRIPTOR);
536 	if (!mscs_desc_ie || mscs_desc_ie[1] <= 8)
537 		return;
538 
539 	/* Subelements start after (ie_id(1) + ie_len(1) + ext_id(1) +
540 	 * request type(1) + upc(2) + stream timeout(4) =) 10.
541 	 */
542 	mscs_status = get_ie(&mscs_desc_ie[10], mscs_desc_ie[1] - 8,
543 			     MCSC_SUBELEM_STATUS);
544 	if (!mscs_status || mscs_status[1] < 2)
545 		return;
546 
547 	status = WPA_GET_LE16(mscs_status + 2);
548 	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_MSCS_RESULT "bssid=" MACSTR
549 		" status_code=%u", MAC2STR(bssid), status);
550 	wpa_s->mscs_setup_done = status == WLAN_STATUS_SUCCESS;
551 }
552 
553 
554 static void wpas_wait_for_dscp_req_timer(void *eloop_ctx, void *timeout_ctx)
555 {
556 	struct wpa_supplicant *wpa_s = eloop_ctx;
557 
558 	/* Once timeout is over, reset wait flag and allow sending DSCP query */
559 	wpa_printf(MSG_DEBUG,
560 		   "QM: Wait time over for sending DSCP request - allow DSCP query");
561 	wpa_s->wait_for_dscp_req = 0;
562 	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "request_wait end");
563 }
564 
565 
566 void wpas_handle_assoc_resp_qos_mgmt(struct wpa_supplicant *wpa_s,
567 				     const u8 *ies, size_t ies_len)
568 {
569 	const u8 *wfa_capa;
570 
571 	wpa_s->connection_dscp = 0;
572 	if (wpa_s->wait_for_dscp_req)
573 		eloop_cancel_timeout(wpas_wait_for_dscp_req_timer, wpa_s, NULL);
574 
575 	if (!ies || ies_len == 0 || !wpa_s->enable_dscp_policy_capa)
576 		return;
577 
578 	wfa_capa = get_vendor_ie(ies, ies_len, WFA_CAPA_IE_VENDOR_TYPE);
579 	if (!wfa_capa || wfa_capa[1] < 6 || wfa_capa[6] < 1 ||
580 	    !(wfa_capa[7] & WFA_CAPA_QM_DSCP_POLICY))
581 		return; /* AP does not enable QM DSCP Policy */
582 
583 	wpa_s->connection_dscp = 1;
584 	wpa_s->wait_for_dscp_req = !!(wfa_capa[7] &
585 				      WFA_CAPA_QM_UNSOLIC_DSCP);
586 	if (!wpa_s->wait_for_dscp_req)
587 		return;
588 
589 	/* Register a timeout after which dscp query can be sent to AP. */
590 	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "request_wait start");
591 	eloop_register_timeout(DSCP_REQ_TIMEOUT, 0,
592 			       wpas_wait_for_dscp_req_timer, wpa_s, NULL);
593 }
594 
595 
596 void wpas_handle_robust_av_scs_recv_action(struct wpa_supplicant *wpa_s,
597 					   const u8 *src, const u8 *buf,
598 					   size_t len)
599 {
600 	u8 dialog_token;
601 	unsigned int i, count;
602 	struct active_scs_elem *scs_desc, *prev;
603 
604 	if (len < 2)
605 		return;
606 	if (!wpa_s->ongoing_scs_req) {
607 		wpa_printf(MSG_INFO,
608 			   "SCS: Drop received response due to no ongoing request");
609 		return;
610 	}
611 
612 	dialog_token = *buf++;
613 	len--;
614 	if (dialog_token != wpa_s->scs_dialog_token) {
615 		wpa_printf(MSG_INFO,
616 			   "SCS: Drop received frame due to dialog token mismatch: received:%u expected:%u",
617 			   dialog_token, wpa_s->scs_dialog_token);
618 		return;
619 	}
620 
621 	/* This Count field does not exist in the IEEE Std 802.11-2020
622 	 * definition of the SCS Response frame. However, it was accepted to
623 	 * be added into REVme per REVme/D0.0 CC35 CID 49 (edits in document
624 	 * 11-21-0688-07). */
625 	count = *buf++;
626 	len--;
627 	if (count == 0 || count * 3 > len) {
628 		wpa_printf(MSG_INFO,
629 			   "SCS: Drop received frame due to invalid count: %u (remaining %zu octets)",
630 			   count, len);
631 		return;
632 	}
633 
634 	for (i = 0; i < count; i++) {
635 		u8 id;
636 		u16 status;
637 		bool scs_desc_found = false;
638 
639 		id = *buf++;
640 		status = WPA_GET_LE16(buf);
641 		buf += 2;
642 		len -= 3;
643 
644 		dl_list_for_each(scs_desc, &wpa_s->active_scs_ids,
645 				 struct active_scs_elem, list) {
646 			if (id == scs_desc->scs_id) {
647 				scs_desc_found = true;
648 				break;
649 			}
650 		}
651 
652 		if (!scs_desc_found) {
653 			wpa_printf(MSG_INFO, "SCS: SCS ID invalid %u", id);
654 			continue;
655 		}
656 
657 		if (status != WLAN_STATUS_SUCCESS) {
658 			dl_list_del(&scs_desc->list);
659 			os_free(scs_desc);
660 		} else if (status == WLAN_STATUS_SUCCESS) {
661 			scs_desc->status = SCS_DESC_SUCCESS;
662 		}
663 
664 		wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_SCS_RESULT "bssid=" MACSTR
665 			" SCSID=%u status_code=%u", MAC2STR(src), id, status);
666 	}
667 
668 	eloop_cancel_timeout(scs_request_timer, wpa_s, NULL);
669 	wpa_s->ongoing_scs_req = false;
670 
671 	dl_list_for_each_safe(scs_desc, prev, &wpa_s->active_scs_ids,
672 			      struct active_scs_elem, list) {
673 		if (scs_desc->status != SCS_DESC_SUCCESS) {
674 			wpa_msg(wpa_s, MSG_INFO,
675 				WPA_EVENT_SCS_RESULT "bssid=" MACSTR
676 				" SCSID=%u status_code=response_not_received",
677 				MAC2STR(src), scs_desc->scs_id);
678 			dl_list_del(&scs_desc->list);
679 			os_free(scs_desc);
680 		}
681 	}
682 }
683 
684 
685 static void wpas_clear_active_scs_ids(struct wpa_supplicant *wpa_s)
686 {
687 	struct active_scs_elem *scs_elem;
688 
689 	while ((scs_elem = dl_list_first(&wpa_s->active_scs_ids,
690 					 struct active_scs_elem, list))) {
691 		dl_list_del(&scs_elem->list);
692 		os_free(scs_elem);
693 	}
694 }
695 
696 
697 void wpas_scs_deinit(struct wpa_supplicant *wpa_s)
698 {
699 	free_up_scs_desc(&wpa_s->scs_robust_av_req);
700 	wpa_s->scs_dialog_token = 0;
701 	wpas_clear_active_scs_ids(wpa_s);
702 	eloop_cancel_timeout(scs_request_timer, wpa_s, NULL);
703 	wpa_s->ongoing_scs_req = false;
704 }
705 
706 
707 static int write_ipv4_info(char *pos, int total_len,
708 			   const struct ipv4_params *v4)
709 {
710 	int res, rem_len;
711 	char addr[INET_ADDRSTRLEN];
712 
713 	rem_len = total_len;
714 
715 	if (v4->param_mask & BIT(1)) {
716 		if (!inet_ntop(AF_INET, &v4->src_ip, addr, INET_ADDRSTRLEN)) {
717 			wpa_printf(MSG_ERROR,
718 				   "QM: Failed to set IPv4 source address");
719 			return -1;
720 		}
721 
722 		res = os_snprintf(pos, rem_len, " src_ip=%s", addr);
723 		if (os_snprintf_error(rem_len, res))
724 			return -1;
725 
726 		pos += res;
727 		rem_len -= res;
728 	}
729 
730 	if (v4->param_mask & BIT(2)) {
731 		if (!inet_ntop(AF_INET, &v4->dst_ip, addr, INET_ADDRSTRLEN)) {
732 			wpa_printf(MSG_ERROR,
733 				   "QM: Failed to set IPv4 destination address");
734 			return -1;
735 		}
736 
737 		res = os_snprintf(pos, rem_len, " dst_ip=%s", addr);
738 		if (os_snprintf_error(rem_len, res))
739 			return -1;
740 
741 		pos += res;
742 		rem_len -= res;
743 	}
744 
745 	if (v4->param_mask & BIT(3)) {
746 		res = os_snprintf(pos, rem_len, " src_port=%d", v4->src_port);
747 		if (os_snprintf_error(rem_len, res))
748 			return -1;
749 
750 		pos += res;
751 		rem_len -= res;
752 	}
753 
754 	if (v4->param_mask & BIT(4)) {
755 		res = os_snprintf(pos, rem_len, " dst_port=%d", v4->dst_port);
756 		if (os_snprintf_error(rem_len, res))
757 			return -1;
758 
759 		pos += res;
760 		rem_len -= res;
761 	}
762 
763 	if (v4->param_mask & BIT(6)) {
764 		res = os_snprintf(pos, rem_len, " protocol=%d", v4->protocol);
765 		if (os_snprintf_error(rem_len, res))
766 			return -1;
767 
768 		pos += res;
769 		rem_len -= res;
770 	}
771 
772 	return total_len - rem_len;
773 }
774 
775 
776 static int write_ipv6_info(char *pos, int total_len,
777 			   const struct ipv6_params *v6)
778 {
779 	int res, rem_len;
780 	char addr[INET6_ADDRSTRLEN];
781 
782 	rem_len = total_len;
783 
784 	if (v6->param_mask & BIT(1)) {
785 		if (!inet_ntop(AF_INET6, &v6->src_ip, addr, INET6_ADDRSTRLEN)) {
786 			wpa_printf(MSG_ERROR,
787 				   "QM: Failed to set IPv6 source addr");
788 			return -1;
789 		}
790 
791 		res = os_snprintf(pos, rem_len, " src_ip=%s", addr);
792 		if (os_snprintf_error(rem_len, res))
793 			return -1;
794 
795 		pos += res;
796 		rem_len -= res;
797 	}
798 
799 	if (v6->param_mask & BIT(2)) {
800 		if (!inet_ntop(AF_INET6, &v6->dst_ip, addr, INET6_ADDRSTRLEN)) {
801 			wpa_printf(MSG_ERROR,
802 				   "QM: Failed to set IPv6 destination addr");
803 			return -1;
804 		}
805 
806 		res = os_snprintf(pos, rem_len, " dst_ip=%s", addr);
807 		if (os_snprintf_error(rem_len, res))
808 			return -1;
809 
810 		pos += res;
811 		rem_len -= res;
812 	}
813 
814 	if (v6->param_mask & BIT(3)) {
815 		res = os_snprintf(pos, rem_len, " src_port=%d", v6->src_port);
816 		if (os_snprintf_error(rem_len, res))
817 			return -1;
818 
819 		pos += res;
820 		rem_len -= res;
821 	}
822 
823 	if (v6->param_mask & BIT(4)) {
824 		res = os_snprintf(pos, rem_len, " dst_port=%d", v6->dst_port);
825 		if (os_snprintf_error(rem_len, res))
826 			return -1;
827 
828 		pos += res;
829 		rem_len -= res;
830 	}
831 
832 	if (v6->param_mask & BIT(6)) {
833 		res = os_snprintf(pos, rem_len, " protocol=%d",
834 				  v6->next_header);
835 		if (os_snprintf_error(rem_len, res))
836 			return -1;
837 
838 		pos += res;
839 		rem_len -= res;
840 	}
841 
842 	return total_len - rem_len;
843 }
844 
845 
846 struct dscp_policy_data {
847 	u8 policy_id;
848 	u8 req_type;
849 	u8 dscp;
850 	bool dscp_info;
851 	const u8 *frame_classifier;
852 	u8 frame_classifier_len;
853 	struct type4_params type4_param;
854 	const u8 *domain_name;
855 	u8 domain_name_len;
856 	u16 start_port;
857 	u16 end_port;
858 	bool port_range_info;
859 };
860 
861 
862 static int set_frame_classifier_type4_ipv4(struct dscp_policy_data *policy)
863 {
864 	u8 classifier_mask;
865 	const u8 *frame_classifier = policy->frame_classifier;
866 	struct type4_params *type4_param = &policy->type4_param;
867 
868 	if (policy->frame_classifier_len < 18) {
869 		wpa_printf(MSG_ERROR,
870 			   "QM: Received IPv4 frame classifier with insufficient length %d",
871 			   policy->frame_classifier_len);
872 		return -1;
873 	}
874 
875 	classifier_mask = frame_classifier[1];
876 
877 	/* Classifier Mask - bit 1 = Source IP Address */
878 	if (classifier_mask & BIT(1)) {
879 		type4_param->ip_params.v4.param_mask |= BIT(1);
880 		os_memcpy(&type4_param->ip_params.v4.src_ip,
881 			  &frame_classifier[3], 4);
882 	}
883 
884 	/* Classifier Mask - bit 2 = Destination IP Address */
885 	if (classifier_mask & BIT(2)) {
886 		if (policy->domain_name) {
887 			wpa_printf(MSG_ERROR,
888 				   "QM: IPv4: Both domain name and destination IP address not expected");
889 			return -1;
890 		}
891 
892 		type4_param->ip_params.v4.param_mask |= BIT(2);
893 		os_memcpy(&type4_param->ip_params.v4.dst_ip,
894 			  &frame_classifier[7], 4);
895 	}
896 
897 	/* Classifier Mask - bit 3 = Source Port */
898 	if (classifier_mask & BIT(3)) {
899 		type4_param->ip_params.v4.param_mask |= BIT(3);
900 		type4_param->ip_params.v4.src_port =
901 			WPA_GET_BE16(&frame_classifier[11]);
902 	}
903 
904 	/* Classifier Mask - bit 4 = Destination Port */
905 	if (classifier_mask & BIT(4)) {
906 		if (policy->port_range_info) {
907 			wpa_printf(MSG_ERROR,
908 				   "QM: IPv4: Both port range and destination port not expected");
909 			return -1;
910 		}
911 
912 		type4_param->ip_params.v4.param_mask |= BIT(4);
913 		type4_param->ip_params.v4.dst_port =
914 			WPA_GET_BE16(&frame_classifier[13]);
915 	}
916 
917 	/* Classifier Mask - bit 5 = DSCP (ignored) */
918 
919 	/* Classifier Mask - bit 6 = Protocol */
920 	if (classifier_mask & BIT(6)) {
921 		type4_param->ip_params.v4.param_mask |= BIT(6);
922 		type4_param->ip_params.v4.protocol = frame_classifier[16];
923 	}
924 
925 	return 0;
926 }
927 
928 
929 static int set_frame_classifier_type4_ipv6(struct dscp_policy_data *policy)
930 {
931 	u8 classifier_mask;
932 	const u8 *frame_classifier = policy->frame_classifier;
933 	struct type4_params *type4_param = &policy->type4_param;
934 
935 	if (policy->frame_classifier_len < 44) {
936 		wpa_printf(MSG_ERROR,
937 			   "QM: Received IPv6 frame classifier with insufficient length %d",
938 			   policy->frame_classifier_len);
939 		return -1;
940 	}
941 
942 	classifier_mask = frame_classifier[1];
943 
944 	/* Classifier Mask - bit 1 = Source IP Address */
945 	if (classifier_mask & BIT(1)) {
946 		type4_param->ip_params.v6.param_mask |= BIT(1);
947 		os_memcpy(&type4_param->ip_params.v6.src_ip,
948 			  &frame_classifier[3], 16);
949 	}
950 
951 	/* Classifier Mask - bit 2 = Destination IP Address */
952 	if (classifier_mask & BIT(2)) {
953 		if (policy->domain_name) {
954 			wpa_printf(MSG_ERROR,
955 				   "QM: IPv6: Both domain name and destination IP address not expected");
956 			return -1;
957 		}
958 		type4_param->ip_params.v6.param_mask |= BIT(2);
959 		os_memcpy(&type4_param->ip_params.v6.dst_ip,
960 			  &frame_classifier[19], 16);
961 	}
962 
963 	/* Classifier Mask - bit 3 = Source Port */
964 	if (classifier_mask & BIT(3)) {
965 		type4_param->ip_params.v6.param_mask |= BIT(3);
966 		type4_param->ip_params.v6.src_port =
967 				WPA_GET_BE16(&frame_classifier[35]);
968 	}
969 
970 	/* Classifier Mask - bit 4 = Destination Port */
971 	if (classifier_mask & BIT(4)) {
972 		if (policy->port_range_info) {
973 			wpa_printf(MSG_ERROR,
974 				   "IPv6: Both port range and destination port not expected");
975 			return -1;
976 		}
977 
978 		type4_param->ip_params.v6.param_mask |= BIT(4);
979 		type4_param->ip_params.v6.dst_port =
980 				WPA_GET_BE16(&frame_classifier[37]);
981 	}
982 
983 	/* Classifier Mask - bit 5 = DSCP (ignored) */
984 
985 	/* Classifier Mask - bit 6 = Next Header */
986 	if (classifier_mask & BIT(6)) {
987 		type4_param->ip_params.v6.param_mask |= BIT(6);
988 		type4_param->ip_params.v6.next_header = frame_classifier[40];
989 	}
990 
991 	return 0;
992 }
993 
994 
995 static int wpas_set_frame_classifier_params(struct dscp_policy_data *policy)
996 {
997 	const u8 *frame_classifier = policy->frame_classifier;
998 	u8 frame_classifier_len = policy->frame_classifier_len;
999 
1000 	if (frame_classifier_len < 3) {
1001 		wpa_printf(MSG_ERROR,
1002 			   "QM: Received frame classifier with insufficient length %d",
1003 			   frame_classifier_len);
1004 		return -1;
1005 	}
1006 
1007 	/* Only allowed Classifier Type: IP and higher layer parameters (4) */
1008 	if (frame_classifier[0] != 4) {
1009 		wpa_printf(MSG_ERROR,
1010 			   "QM: Received frame classifier with invalid classifier type %d",
1011 			   frame_classifier[0]);
1012 		return -1;
1013 	}
1014 
1015 	/* Classifier Mask - bit 0 = Version */
1016 	if (!(frame_classifier[1] & BIT(0))) {
1017 		wpa_printf(MSG_ERROR,
1018 			   "QM: Received frame classifier without IP version");
1019 		return -1;
1020 	}
1021 
1022 	/* Version (4 or 6) */
1023 	if (frame_classifier[2] == 4) {
1024 		if (set_frame_classifier_type4_ipv4(policy)) {
1025 			wpa_printf(MSG_ERROR,
1026 				   "QM: Failed to set IPv4 parameters");
1027 			return -1;
1028 		}
1029 
1030 		policy->type4_param.ip_version = IPV4;
1031 	} else if (frame_classifier[2] == 6) {
1032 		if (set_frame_classifier_type4_ipv6(policy)) {
1033 			wpa_printf(MSG_ERROR,
1034 				   "QM: Failed to set IPv6 parameters");
1035 			return -1;
1036 		}
1037 
1038 		policy->type4_param.ip_version = IPV6;
1039 	} else {
1040 		wpa_printf(MSG_ERROR,
1041 			   "QM: Received unknown IP version %d",
1042 			   frame_classifier[2]);
1043 		return -1;
1044 	}
1045 
1046 	return 0;
1047 }
1048 
1049 
1050 static bool dscp_valid_domain_name(const char *str)
1051 {
1052 	if (!str[0])
1053 		return false;
1054 
1055 	while (*str) {
1056 		if (is_ctrl_char(*str) || *str == ' ' || *str == '=')
1057 			return false;
1058 		str++;
1059 	}
1060 
1061 	return true;
1062 }
1063 
1064 
1065 static void wpas_add_dscp_policy(struct wpa_supplicant *wpa_s,
1066 				 struct dscp_policy_data *policy)
1067 {
1068 	int ip_ver = 0, res;
1069 	char policy_str[1000], *pos;
1070 	int len;
1071 
1072 	if (!policy->frame_classifier && !policy->domain_name &&
1073 	    !policy->port_range_info) {
1074 		wpa_printf(MSG_ERROR,
1075 			   "QM: Invalid DSCP policy - no attributes present");
1076 		goto fail;
1077 	}
1078 
1079 	policy_str[0] = '\0';
1080 	pos = policy_str;
1081 	len = sizeof(policy_str);
1082 
1083 	if (policy->frame_classifier) {
1084 		struct type4_params *type4 = &policy->type4_param;
1085 
1086 		if (wpas_set_frame_classifier_params(policy)) {
1087 			wpa_printf(MSG_ERROR,
1088 				   "QM: Failed to set frame classifier parameters");
1089 			goto fail;
1090 		}
1091 
1092 		if (type4->ip_version == IPV4)
1093 			res = write_ipv4_info(pos, len, &type4->ip_params.v4);
1094 		else
1095 			res = write_ipv6_info(pos, len, &type4->ip_params.v6);
1096 
1097 		if (res <= 0) {
1098 			wpa_printf(MSG_ERROR,
1099 				   "QM: Failed to write IP parameters");
1100 			goto fail;
1101 		}
1102 
1103 		ip_ver = type4->ip_version;
1104 
1105 		pos += res;
1106 		len -= res;
1107 	}
1108 
1109 	if (policy->port_range_info) {
1110 		res = os_snprintf(pos, len, " start_port=%u end_port=%u",
1111 				  policy->start_port, policy->end_port);
1112 		if (os_snprintf_error(len, res)) {
1113 			wpa_printf(MSG_ERROR,
1114 				   "QM: Failed to write port range attributes for policy id = %d",
1115 				   policy->policy_id);
1116 			goto fail;
1117 		}
1118 
1119 		pos += res;
1120 		len -= res;
1121 	}
1122 
1123 	if (policy->domain_name) {
1124 		char domain_name_str[250];
1125 
1126 		if (policy->domain_name_len >= sizeof(domain_name_str)) {
1127 			wpa_printf(MSG_ERROR,
1128 				   "QM: Domain name length higher than max expected");
1129 			goto fail;
1130 		}
1131 		os_memcpy(domain_name_str, policy->domain_name,
1132 			  policy->domain_name_len);
1133 		domain_name_str[policy->domain_name_len] = '\0';
1134 		if (!dscp_valid_domain_name(domain_name_str)) {
1135 			wpa_printf(MSG_ERROR, "QM: Invalid domain name string");
1136 			goto fail;
1137 		}
1138 		res = os_snprintf(pos, len, " domain_name=%s", domain_name_str);
1139 		if (os_snprintf_error(len, res)) {
1140 			wpa_printf(MSG_ERROR,
1141 				   "QM: Failed to write domain name attribute for policy id = %d",
1142 				   policy->policy_id);
1143 			goto fail;
1144 		}
1145 	}
1146 
1147 	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY
1148 		"add policy_id=%u dscp=%u ip_version=%d%s",
1149 		policy->policy_id, policy->dscp, ip_ver, policy_str);
1150 	return;
1151 fail:
1152 	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "reject policy_id=%u",
1153 		policy->policy_id);
1154 }
1155 
1156 
1157 void wpas_dscp_deinit(struct wpa_supplicant *wpa_s)
1158 {
1159 	wpa_printf(MSG_DEBUG, "QM: Clear all active DSCP policies");
1160 	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "clear_all");
1161 	wpa_s->dscp_req_dialog_token = 0;
1162 	wpa_s->dscp_query_dialog_token = 0;
1163 	wpa_s->connection_dscp = 0;
1164 	if (wpa_s->wait_for_dscp_req) {
1165 		wpa_s->wait_for_dscp_req = 0;
1166 		eloop_cancel_timeout(wpas_wait_for_dscp_req_timer, wpa_s, NULL);
1167 	}
1168 }
1169 
1170 
1171 static void wpas_fill_dscp_policy(struct dscp_policy_data *policy, u8 attr_id,
1172 				  u8 attr_len, const u8 *attr_data)
1173 {
1174 	switch (attr_id) {
1175 	case QM_ATTR_PORT_RANGE:
1176 		if (attr_len < 4) {
1177 			wpa_printf(MSG_ERROR,
1178 				   "QM: Received Port Range attribute with insufficient length %d",
1179 				    attr_len);
1180 			break;
1181 		}
1182 		policy->start_port = WPA_GET_BE16(attr_data);
1183 		policy->end_port = WPA_GET_BE16(attr_data + 2);
1184 		policy->port_range_info = true;
1185 		break;
1186 	case QM_ATTR_DSCP_POLICY:
1187 		if (attr_len < 3) {
1188 			wpa_printf(MSG_ERROR,
1189 				   "QM: Received DSCP Policy attribute with insufficient length %d",
1190 				   attr_len);
1191 			return;
1192 		}
1193 		policy->policy_id = attr_data[0];
1194 		policy->req_type = attr_data[1];
1195 		policy->dscp = attr_data[2];
1196 		policy->dscp_info = true;
1197 		break;
1198 	case QM_ATTR_TCLAS:
1199 		if (attr_len < 1) {
1200 			wpa_printf(MSG_ERROR,
1201 				   "QM: Received TCLAS attribute with insufficient length %d",
1202 				   attr_len);
1203 			return;
1204 		}
1205 		policy->frame_classifier = attr_data;
1206 		policy->frame_classifier_len = attr_len;
1207 		break;
1208 	case QM_ATTR_DOMAIN_NAME:
1209 		if (attr_len < 1) {
1210 			wpa_printf(MSG_ERROR,
1211 				   "QM: Received domain name attribute with insufficient length %d",
1212 				   attr_len);
1213 			return;
1214 		}
1215 		policy->domain_name = attr_data;
1216 		policy->domain_name_len = attr_len;
1217 		break;
1218 	default:
1219 		wpa_printf(MSG_ERROR, "QM: Received invalid QoS attribute %d",
1220 			   attr_id);
1221 		break;
1222 	}
1223 }
1224 
1225 
1226 void wpas_handle_qos_mgmt_recv_action(struct wpa_supplicant *wpa_s,
1227 				      const u8 *src,
1228 				      const u8 *buf, size_t len)
1229 {
1230 	int rem_len;
1231 	const u8 *qos_ie, *attr;
1232 	int more, reset;
1233 
1234 	if (!wpa_s->enable_dscp_policy_capa) {
1235 		wpa_printf(MSG_ERROR,
1236 			   "QM: Ignore DSCP Policy frame since the capability is not enabled");
1237 		return;
1238 	}
1239 
1240 	if (!pmf_in_use(wpa_s, src)) {
1241 		wpa_printf(MSG_ERROR,
1242 			   "QM: Ignore DSCP Policy frame since PMF is not in use");
1243 		return;
1244 	}
1245 
1246 	if (!wpa_s->connection_dscp) {
1247 		 wpa_printf(MSG_DEBUG,
1248 			    "QM: DSCP Policy capability not enabled for the current association - ignore QoS Management Action frames");
1249 		return;
1250 	}
1251 
1252 	if (len < 1)
1253 		return;
1254 
1255 	/* Handle only DSCP Policy Request frame */
1256 	if (buf[0] != QM_DSCP_POLICY_REQ) {
1257 		wpa_printf(MSG_ERROR, "QM: Received unexpected QoS action frame %d",
1258 			   buf[0]);
1259 		return;
1260 	}
1261 
1262 	if (len < 3) {
1263 		wpa_printf(MSG_ERROR,
1264 			   "Received QoS Management DSCP Policy Request frame with invalid length %zu",
1265 			   len);
1266 		return;
1267 	}
1268 
1269 	/* Clear wait_for_dscp_req on receiving first DSCP request from AP */
1270 	if (wpa_s->wait_for_dscp_req) {
1271 		wpa_s->wait_for_dscp_req = 0;
1272 		eloop_cancel_timeout(wpas_wait_for_dscp_req_timer, wpa_s, NULL);
1273 	}
1274 
1275 	wpa_s->dscp_req_dialog_token = buf[1];
1276 	more = buf[2] & DSCP_POLICY_CTRL_MORE;
1277 	reset = buf[2] & DSCP_POLICY_CTRL_RESET;
1278 
1279 	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "request_start%s%s",
1280 		reset ? " clear_all" : "", more ? " more" : "");
1281 
1282 	qos_ie = buf + 3;
1283 	rem_len = len - 3;
1284 	while (rem_len > 2) {
1285 		struct dscp_policy_data policy;
1286 		int rem_attrs_len, ie_len;
1287 
1288 		ie_len = 2 + qos_ie[1];
1289 		if (rem_len < ie_len)
1290 			break;
1291 
1292 		if (rem_len < 6 || qos_ie[0] != WLAN_EID_VENDOR_SPECIFIC ||
1293 		    qos_ie[1] < 4 ||
1294 		    WPA_GET_BE32(&qos_ie[2]) != QM_IE_VENDOR_TYPE) {
1295 			rem_len -= ie_len;
1296 			qos_ie += ie_len;
1297 			continue;
1298 		}
1299 
1300 		os_memset(&policy, 0, sizeof(struct dscp_policy_data));
1301 		attr = qos_ie + 6;
1302 		rem_attrs_len = qos_ie[1] - 4;
1303 
1304 		while (rem_attrs_len > 2 && rem_attrs_len >= 2 + attr[1]) {
1305 			wpas_fill_dscp_policy(&policy, attr[0], attr[1],
1306 					      &attr[2]);
1307 			rem_attrs_len -= 2 + attr[1];
1308 			attr += 2 + attr[1];
1309 		}
1310 
1311 		rem_len -= ie_len;
1312 		qos_ie += ie_len;
1313 
1314 		if (!policy.dscp_info) {
1315 			wpa_printf(MSG_ERROR,
1316 				   "QM: Received QoS IE without DSCP Policy attribute");
1317 			continue;
1318 		}
1319 
1320 		if (policy.req_type == DSCP_POLICY_REQ_ADD)
1321 			wpas_add_dscp_policy(wpa_s, &policy);
1322 		else if (policy.req_type == DSCP_POLICY_REQ_REMOVE)
1323 			wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY
1324 				"remove policy_id=%u", policy.policy_id);
1325 		else
1326 			wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY
1327 				"reject policy_id=%u", policy.policy_id);
1328 	}
1329 
1330 	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "request_end");
1331 }
1332 
1333 
1334 int wpas_send_dscp_response(struct wpa_supplicant *wpa_s,
1335 			    struct dscp_resp_data *resp_data)
1336 {
1337 	struct wpabuf *buf = NULL;
1338 	size_t buf_len;
1339 	int ret = -1, i;
1340 	u8 resp_control = 0;
1341 
1342 	if (wpa_s->wpa_state != WPA_COMPLETED || !wpa_s->current_ssid) {
1343 		wpa_printf(MSG_ERROR,
1344 			   "QM: Failed to send DSCP response - not connected to AP");
1345 		return -1;
1346 	}
1347 
1348 	if (resp_data->solicited && !wpa_s->dscp_req_dialog_token) {
1349 		wpa_printf(MSG_ERROR, "QM: No ongoing DSCP request");
1350 		return -1;
1351 	}
1352 
1353 	if (!wpa_s->connection_dscp) {
1354 		wpa_printf(MSG_ERROR,
1355 			   "QM: Failed to send DSCP response - DSCP capability not enabled for the current association");
1356 		return -1;
1357 
1358 	}
1359 
1360 	buf_len = 1 +	/* Category */
1361 		  3 +	/* OUI */
1362 		  1 +	/* OUI Type */
1363 		  1 +	/* OUI Subtype */
1364 		  1 +	/* Dialog Token */
1365 		  1 +	/* Response Control */
1366 		  1 +	/* Count */
1367 		  2 * resp_data->num_policies;  /* Status list */
1368 	buf = wpabuf_alloc(buf_len);
1369 	if (!buf) {
1370 		wpa_printf(MSG_ERROR,
1371 			   "QM: Failed to allocate DSCP policy response");
1372 		return -1;
1373 	}
1374 
1375 	wpabuf_put_u8(buf, WLAN_ACTION_VENDOR_SPECIFIC_PROTECTED);
1376 	wpabuf_put_be24(buf, OUI_WFA);
1377 	wpabuf_put_u8(buf, QM_ACTION_OUI_TYPE);
1378 	wpabuf_put_u8(buf, QM_DSCP_POLICY_RESP);
1379 
1380 	wpabuf_put_u8(buf, resp_data->solicited ?
1381 		      wpa_s->dscp_req_dialog_token : 0);
1382 
1383 	if (resp_data->more)
1384 		resp_control |= DSCP_POLICY_CTRL_MORE;
1385 	if (resp_data->reset)
1386 		resp_control |= DSCP_POLICY_CTRL_RESET;
1387 	wpabuf_put_u8(buf, resp_control);
1388 
1389 	wpabuf_put_u8(buf, resp_data->num_policies);
1390 	for (i = 0; i < resp_data->num_policies; i++) {
1391 		wpabuf_put_u8(buf, resp_data->policy[i].id);
1392 		wpabuf_put_u8(buf, resp_data->policy[i].status);
1393 	}
1394 
1395 	wpa_hexdump_buf(MSG_MSGDUMP, "DSCP response frame: ", buf);
1396 	ret = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
1397 				  wpa_s->own_addr, wpa_s->bssid,
1398 				  wpabuf_head(buf), wpabuf_len(buf), 0);
1399 	if (ret < 0) {
1400 		wpa_msg(wpa_s, MSG_INFO, "QM: Failed to send DSCP response");
1401 		goto fail;
1402 	}
1403 
1404 	/*
1405 	 * Mark DSCP request complete whether response sent is solicited or
1406 	 * unsolicited
1407 	 */
1408 	wpa_s->dscp_req_dialog_token = 0;
1409 
1410 fail:
1411 	wpabuf_free(buf);
1412 	return ret;
1413 }
1414 
1415 
1416 int wpas_send_dscp_query(struct wpa_supplicant *wpa_s, const char *domain_name,
1417 			 size_t domain_name_length)
1418 {
1419 	struct wpabuf *buf = NULL;
1420 	int ret, dscp_query_size;
1421 
1422 	if (wpa_s->wpa_state != WPA_COMPLETED || !wpa_s->current_ssid)
1423 		return -1;
1424 
1425 	if (!wpa_s->connection_dscp) {
1426 		wpa_printf(MSG_ERROR,
1427 			   "QM: Failed to send DSCP query - DSCP capability not enabled for the current association");
1428 		return -1;
1429 	}
1430 
1431 	if (wpa_s->wait_for_dscp_req) {
1432 		wpa_printf(MSG_INFO, "QM: Wait until AP sends a DSCP request");
1433 		return -1;
1434 	}
1435 
1436 #define DOMAIN_NAME_OFFSET (4 /* OUI */ + 1 /* Attr Id */ + 1 /* Attr len */)
1437 
1438 	if (domain_name_length > 255 - DOMAIN_NAME_OFFSET) {
1439 		wpa_printf(MSG_ERROR, "QM: Too long domain name");
1440 		return -1;
1441 	}
1442 
1443 	dscp_query_size = 1 + /* Category */
1444 			  4 + /* OUI Type */
1445 			  1 + /* OUI subtype */
1446 			  1; /* Dialog Token */
1447 	if (domain_name && domain_name_length)
1448 		dscp_query_size += 1 + /* Element ID */
1449 			1 + /* IE Length */
1450 			DOMAIN_NAME_OFFSET + domain_name_length;
1451 
1452 	buf = wpabuf_alloc(dscp_query_size);
1453 	if (!buf) {
1454 		wpa_printf(MSG_ERROR, "QM: Failed to allocate DSCP query");
1455 		return -1;
1456 	}
1457 
1458 	wpabuf_put_u8(buf, WLAN_ACTION_VENDOR_SPECIFIC_PROTECTED);
1459 	wpabuf_put_be32(buf, QM_ACTION_VENDOR_TYPE);
1460 	wpabuf_put_u8(buf, QM_DSCP_POLICY_QUERY);
1461 	wpa_s->dscp_query_dialog_token++;
1462 	if (wpa_s->dscp_query_dialog_token == 0)
1463 		wpa_s->dscp_query_dialog_token++;
1464 	wpabuf_put_u8(buf, wpa_s->dscp_query_dialog_token);
1465 
1466 	if (domain_name && domain_name_length) {
1467 		/* Domain Name attribute */
1468 		wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
1469 		wpabuf_put_u8(buf, DOMAIN_NAME_OFFSET + domain_name_length);
1470 		wpabuf_put_be32(buf, QM_IE_VENDOR_TYPE);
1471 		wpabuf_put_u8(buf, QM_ATTR_DOMAIN_NAME);
1472 		wpabuf_put_u8(buf, domain_name_length);
1473 		wpabuf_put_data(buf, domain_name, domain_name_length);
1474 	}
1475 #undef DOMAIN_NAME_OFFSET
1476 
1477 	ret = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
1478 				  wpa_s->own_addr, wpa_s->bssid,
1479 				  wpabuf_head(buf), wpabuf_len(buf), 0);
1480 	if (ret < 0) {
1481 		wpa_dbg(wpa_s, MSG_ERROR, "QM: Failed to send DSCP query");
1482 		wpa_s->dscp_query_dialog_token--;
1483 	}
1484 
1485 	wpabuf_free(buf);
1486 	return ret;
1487 }
1488