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