• 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;
603 	struct active_scs_elem *scs_desc, *prev;
604 
605 	if (len < 2)
606 		return;
607 	if (!wpa_s->ongoing_scs_req) {
608 		wpa_printf(MSG_INFO,
609 			   "SCS: Drop received response due to no ongoing request");
610 		return;
611 	}
612 
613 	dialog_token = *buf++;
614 	len--;
615 	if (dialog_token != wpa_s->scs_dialog_token) {
616 		wpa_printf(MSG_INFO,
617 			   "SCS: Drop received frame due to dialog token mismatch: received:%u expected:%u",
618 			   dialog_token, wpa_s->scs_dialog_token);
619 		return;
620 	}
621 
622 	/* This Count field does not exist in the IEEE Std 802.11-2020
623 	 * definition of the SCS Response frame. However, it was accepted to
624 	 * be added into REVme per REVme/D0.0 CC35 CID 49 (edits in document
625 	 * 11-21-0688-07). */
626 	count = *buf++;
627 	len--;
628 	if (count == 0 || count * 3 > len) {
629 		wpa_printf(MSG_INFO,
630 			   "SCS: Drop received frame due to invalid count: %u (remaining %zu octets)",
631 			   count, len);
632 		return;
633 	}
634 
635 	for (i = 0; i < count; i++) {
636 		u8 id;
637 		u16 status;
638 		bool scs_desc_found = false;
639 
640 		id = *buf++;
641 		status = WPA_GET_LE16(buf);
642 		buf += 2;
643 		len -= 3;
644 
645 		dl_list_for_each(scs_desc, &wpa_s->active_scs_ids,
646 				 struct active_scs_elem, list) {
647 			if (id == scs_desc->scs_id) {
648 				scs_desc_found = true;
649 				break;
650 			}
651 		}
652 
653 		if (!scs_desc_found) {
654 			wpa_printf(MSG_INFO, "SCS: SCS ID invalid %u", id);
655 			continue;
656 		}
657 
658 		if (status != WLAN_STATUS_SUCCESS) {
659 			dl_list_del(&scs_desc->list);
660 			os_free(scs_desc);
661 		} else if (status == WLAN_STATUS_SUCCESS) {
662 			scs_desc->status = SCS_DESC_SUCCESS;
663 		}
664 
665 		wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_SCS_RESULT "bssid=" MACSTR
666 			" SCSID=%u status_code=%u", MAC2STR(src), id, status);
667 	}
668 
669 	eloop_cancel_timeout(scs_request_timer, wpa_s, NULL);
670 	wpa_s->ongoing_scs_req = false;
671 
672 	dl_list_for_each_safe(scs_desc, prev, &wpa_s->active_scs_ids,
673 			      struct active_scs_elem, list) {
674 		if (scs_desc->status != SCS_DESC_SUCCESS) {
675 			wpa_msg(wpa_s, MSG_INFO,
676 				WPA_EVENT_SCS_RESULT "bssid=" MACSTR
677 				" SCSID=%u status_code=response_not_received",
678 				MAC2STR(src), scs_desc->scs_id);
679 			dl_list_del(&scs_desc->list);
680 			os_free(scs_desc);
681 		}
682 	}
683 }
684 
685 
wpas_clear_active_scs_ids(struct wpa_supplicant * wpa_s)686 static void wpas_clear_active_scs_ids(struct wpa_supplicant *wpa_s)
687 {
688 	struct active_scs_elem *scs_elem;
689 
690 	while ((scs_elem = dl_list_first(&wpa_s->active_scs_ids,
691 					 struct active_scs_elem, list))) {
692 		dl_list_del(&scs_elem->list);
693 		os_free(scs_elem);
694 	}
695 }
696 
697 
wpas_scs_deinit(struct wpa_supplicant * wpa_s)698 void wpas_scs_deinit(struct wpa_supplicant *wpa_s)
699 {
700 	free_up_scs_desc(&wpa_s->scs_robust_av_req);
701 	wpa_s->scs_dialog_token = 0;
702 	wpas_clear_active_scs_ids(wpa_s);
703 	eloop_cancel_timeout(scs_request_timer, wpa_s, NULL);
704 	wpa_s->ongoing_scs_req = false;
705 }
706 
707 
write_ipv4_info(char * pos,int total_len,const struct ipv4_params * v4)708 static int write_ipv4_info(char *pos, int total_len,
709 			   const struct ipv4_params *v4)
710 {
711 	int res, rem_len;
712 	char addr[INET_ADDRSTRLEN];
713 
714 	rem_len = total_len;
715 
716 	if (v4->param_mask & BIT(1)) {
717 		if (!inet_ntop(AF_INET, &v4->src_ip, addr, INET_ADDRSTRLEN)) {
718 			wpa_printf(MSG_ERROR,
719 				   "QM: Failed to set IPv4 source address");
720 			return -1;
721 		}
722 
723 		res = os_snprintf(pos, rem_len, " src_ip=%s", addr);
724 		if (os_snprintf_error(rem_len, res))
725 			return -1;
726 
727 		pos += res;
728 		rem_len -= res;
729 	}
730 
731 	if (v4->param_mask & BIT(2)) {
732 		if (!inet_ntop(AF_INET, &v4->dst_ip, addr, INET_ADDRSTRLEN)) {
733 			wpa_printf(MSG_ERROR,
734 				   "QM: Failed to set IPv4 destination address");
735 			return -1;
736 		}
737 
738 		res = os_snprintf(pos, rem_len, " dst_ip=%s", addr);
739 		if (os_snprintf_error(rem_len, res))
740 			return -1;
741 
742 		pos += res;
743 		rem_len -= res;
744 	}
745 
746 	if (v4->param_mask & BIT(3)) {
747 		res = os_snprintf(pos, rem_len, " src_port=%d", v4->src_port);
748 		if (os_snprintf_error(rem_len, res))
749 			return -1;
750 
751 		pos += res;
752 		rem_len -= res;
753 	}
754 
755 	if (v4->param_mask & BIT(4)) {
756 		res = os_snprintf(pos, rem_len, " dst_port=%d", v4->dst_port);
757 		if (os_snprintf_error(rem_len, res))
758 			return -1;
759 
760 		pos += res;
761 		rem_len -= res;
762 	}
763 
764 	if (v4->param_mask & BIT(6)) {
765 		res = os_snprintf(pos, rem_len, " protocol=%d", v4->protocol);
766 		if (os_snprintf_error(rem_len, res))
767 			return -1;
768 
769 		pos += res;
770 		rem_len -= res;
771 	}
772 
773 	return total_len - rem_len;
774 }
775 
776 
write_ipv6_info(char * pos,int total_len,const struct ipv6_params * v6)777 static int write_ipv6_info(char *pos, int total_len,
778 			   const struct ipv6_params *v6)
779 {
780 	int res, rem_len;
781 	char addr[INET6_ADDRSTRLEN];
782 
783 	rem_len = total_len;
784 
785 	if (v6->param_mask & BIT(1)) {
786 		if (!inet_ntop(AF_INET6, &v6->src_ip, addr, INET6_ADDRSTRLEN)) {
787 			wpa_printf(MSG_ERROR,
788 				   "QM: Failed to set IPv6 source addr");
789 			return -1;
790 		}
791 
792 		res = os_snprintf(pos, rem_len, " src_ip=%s", addr);
793 		if (os_snprintf_error(rem_len, res))
794 			return -1;
795 
796 		pos += res;
797 		rem_len -= res;
798 	}
799 
800 	if (v6->param_mask & BIT(2)) {
801 		if (!inet_ntop(AF_INET6, &v6->dst_ip, addr, INET6_ADDRSTRLEN)) {
802 			wpa_printf(MSG_ERROR,
803 				   "QM: Failed to set IPv6 destination addr");
804 			return -1;
805 		}
806 
807 		res = os_snprintf(pos, rem_len, " dst_ip=%s", addr);
808 		if (os_snprintf_error(rem_len, res))
809 			return -1;
810 
811 		pos += res;
812 		rem_len -= res;
813 	}
814 
815 	if (v6->param_mask & BIT(3)) {
816 		res = os_snprintf(pos, rem_len, " src_port=%d", v6->src_port);
817 		if (os_snprintf_error(rem_len, res))
818 			return -1;
819 
820 		pos += res;
821 		rem_len -= res;
822 	}
823 
824 	if (v6->param_mask & BIT(4)) {
825 		res = os_snprintf(pos, rem_len, " dst_port=%d", v6->dst_port);
826 		if (os_snprintf_error(rem_len, res))
827 			return -1;
828 
829 		pos += res;
830 		rem_len -= res;
831 	}
832 
833 	if (v6->param_mask & BIT(6)) {
834 		res = os_snprintf(pos, rem_len, " protocol=%d",
835 				  v6->next_header);
836 		if (os_snprintf_error(rem_len, res))
837 			return -1;
838 
839 		pos += res;
840 		rem_len -= res;
841 	}
842 
843 	return total_len - rem_len;
844 }
845 
846 
set_frame_classifier_type4_ipv4(struct dscp_policy_data * policy)847 static int set_frame_classifier_type4_ipv4(struct dscp_policy_data *policy)
848 {
849 	u8 classifier_mask;
850 	const u8 *frame_classifier = policy->frame_classifier;
851 	struct type4_params *type4_param = &policy->type4_param;
852 
853 	if (policy->frame_classifier_len < 18) {
854 		wpa_printf(MSG_ERROR,
855 			   "QM: Received IPv4 frame classifier with insufficient length %d",
856 			   policy->frame_classifier_len);
857 		return -1;
858 	}
859 
860 	classifier_mask = frame_classifier[1];
861 
862 	/* Classifier Mask - bit 1 = Source IP Address */
863 	if (classifier_mask & BIT(1)) {
864 		type4_param->ip_params.v4.param_mask |= BIT(1);
865 		os_memcpy(&type4_param->ip_params.v4.src_ip,
866 			  &frame_classifier[3], 4);
867 	}
868 
869 	/* Classifier Mask - bit 2 = Destination IP Address */
870 	if (classifier_mask & BIT(2)) {
871 		if (policy->domain_name) {
872 			wpa_printf(MSG_ERROR,
873 				   "QM: IPv4: Both domain name and destination IP address not expected");
874 			return -1;
875 		}
876 
877 		type4_param->ip_params.v4.param_mask |= BIT(2);
878 		os_memcpy(&type4_param->ip_params.v4.dst_ip,
879 			  &frame_classifier[7], 4);
880 	}
881 
882 	/* Classifier Mask - bit 3 = Source Port */
883 	if (classifier_mask & BIT(3)) {
884 		type4_param->ip_params.v4.param_mask |= BIT(3);
885 		type4_param->ip_params.v4.src_port =
886 			WPA_GET_BE16(&frame_classifier[11]);
887 	}
888 
889 	/* Classifier Mask - bit 4 = Destination Port */
890 	if (classifier_mask & BIT(4)) {
891 		if (policy->port_range_info) {
892 			wpa_printf(MSG_ERROR,
893 				   "QM: IPv4: Both port range and destination port not expected");
894 			return -1;
895 		}
896 
897 		type4_param->ip_params.v4.param_mask |= BIT(4);
898 		type4_param->ip_params.v4.dst_port =
899 			WPA_GET_BE16(&frame_classifier[13]);
900 	}
901 
902 	/* Classifier Mask - bit 5 = DSCP (ignored) */
903 
904 	/* Classifier Mask - bit 6 = Protocol */
905 	if (classifier_mask & BIT(6)) {
906 		type4_param->ip_params.v4.param_mask |= BIT(6);
907 		type4_param->ip_params.v4.protocol = frame_classifier[16];
908 	}
909 
910 	return 0;
911 }
912 
913 
set_frame_classifier_type4_ipv6(struct dscp_policy_data * policy)914 static int set_frame_classifier_type4_ipv6(struct dscp_policy_data *policy)
915 {
916 	u8 classifier_mask;
917 	const u8 *frame_classifier = policy->frame_classifier;
918 	struct type4_params *type4_param = &policy->type4_param;
919 
920 	if (policy->frame_classifier_len < 44) {
921 		wpa_printf(MSG_ERROR,
922 			   "QM: Received IPv6 frame classifier with insufficient length %d",
923 			   policy->frame_classifier_len);
924 		return -1;
925 	}
926 
927 	classifier_mask = frame_classifier[1];
928 
929 	/* Classifier Mask - bit 1 = Source IP Address */
930 	if (classifier_mask & BIT(1)) {
931 		type4_param->ip_params.v6.param_mask |= BIT(1);
932 		os_memcpy(&type4_param->ip_params.v6.src_ip,
933 			  &frame_classifier[3], 16);
934 	}
935 
936 	/* Classifier Mask - bit 2 = Destination IP Address */
937 	if (classifier_mask & BIT(2)) {
938 		if (policy->domain_name) {
939 			wpa_printf(MSG_ERROR,
940 				   "QM: IPv6: Both domain name and destination IP address not expected");
941 			return -1;
942 		}
943 		type4_param->ip_params.v6.param_mask |= BIT(2);
944 		os_memcpy(&type4_param->ip_params.v6.dst_ip,
945 			  &frame_classifier[19], 16);
946 	}
947 
948 	/* Classifier Mask - bit 3 = Source Port */
949 	if (classifier_mask & BIT(3)) {
950 		type4_param->ip_params.v6.param_mask |= BIT(3);
951 		type4_param->ip_params.v6.src_port =
952 				WPA_GET_BE16(&frame_classifier[35]);
953 	}
954 
955 	/* Classifier Mask - bit 4 = Destination Port */
956 	if (classifier_mask & BIT(4)) {
957 		if (policy->port_range_info) {
958 			wpa_printf(MSG_ERROR,
959 				   "IPv6: Both port range and destination port not expected");
960 			return -1;
961 		}
962 
963 		type4_param->ip_params.v6.param_mask |= BIT(4);
964 		type4_param->ip_params.v6.dst_port =
965 				WPA_GET_BE16(&frame_classifier[37]);
966 	}
967 
968 	/* Classifier Mask - bit 5 = DSCP (ignored) */
969 
970 	/* Classifier Mask - bit 6 = Next Header */
971 	if (classifier_mask & BIT(6)) {
972 		type4_param->ip_params.v6.param_mask |= BIT(6);
973 		type4_param->ip_params.v6.next_header = frame_classifier[40];
974 	}
975 
976 	return 0;
977 }
978 
979 
wpas_set_frame_classifier_params(struct dscp_policy_data * policy)980 static int wpas_set_frame_classifier_params(struct dscp_policy_data *policy)
981 {
982 	const u8 *frame_classifier = policy->frame_classifier;
983 	u8 frame_classifier_len = policy->frame_classifier_len;
984 
985 	if (frame_classifier_len < 3) {
986 		wpa_printf(MSG_ERROR,
987 			   "QM: Received frame classifier with insufficient length %d",
988 			   frame_classifier_len);
989 		return -1;
990 	}
991 
992 	/* Only allowed Classifier Type: IP and higher layer parameters (4) */
993 	if (frame_classifier[0] != 4) {
994 		wpa_printf(MSG_ERROR,
995 			   "QM: Received frame classifier with invalid classifier type %d",
996 			   frame_classifier[0]);
997 		return -1;
998 	}
999 
1000 	/* Classifier Mask - bit 0 = Version */
1001 	if (!(frame_classifier[1] & BIT(0))) {
1002 		wpa_printf(MSG_ERROR,
1003 			   "QM: Received frame classifier without IP version");
1004 		return -1;
1005 	}
1006 
1007 	/* Version (4 or 6) */
1008 	if (frame_classifier[2] == 4) {
1009 		if (set_frame_classifier_type4_ipv4(policy)) {
1010 			wpa_printf(MSG_ERROR,
1011 				   "QM: Failed to set IPv4 parameters");
1012 			return -1;
1013 		}
1014 
1015 		policy->type4_param.ip_version = IPV4;
1016 	} else if (frame_classifier[2] == 6) {
1017 		if (set_frame_classifier_type4_ipv6(policy)) {
1018 			wpa_printf(MSG_ERROR,
1019 				   "QM: Failed to set IPv6 parameters");
1020 			return -1;
1021 		}
1022 
1023 		policy->type4_param.ip_version = IPV6;
1024 	} else {
1025 		wpa_printf(MSG_ERROR,
1026 			   "QM: Received unknown IP version %d",
1027 			   frame_classifier[2]);
1028 		return -1;
1029 	}
1030 
1031 	return 0;
1032 }
1033 
1034 
dscp_valid_domain_name(const char * str)1035 static bool dscp_valid_domain_name(const char *str)
1036 {
1037 	if (!str[0])
1038 		return false;
1039 
1040 	while (*str) {
1041 		if (is_ctrl_char(*str) || *str == ' ' || *str == '=')
1042 			return false;
1043 		str++;
1044 	}
1045 
1046 	return true;
1047 }
1048 
1049 
wpas_add_dscp_policy(struct wpa_supplicant * wpa_s,struct dscp_policy_data * policy)1050 static int  wpas_add_dscp_policy(struct wpa_supplicant *wpa_s,
1051 				 struct dscp_policy_data *policy)
1052 {
1053 	int ip_ver = 0, res;
1054 	char policy_str[1000], *pos;
1055 	int len;
1056 
1057 	if (!policy->frame_classifier && !policy->domain_name &&
1058 	    !policy->port_range_info) {
1059 		wpa_printf(MSG_ERROR,
1060 			   "QM: Invalid DSCP policy - no attributes present");
1061 		goto fail;
1062 	}
1063 
1064 	policy_str[0] = '\0';
1065 	pos = policy_str;
1066 	len = sizeof(policy_str);
1067 
1068 	if (policy->frame_classifier) {
1069 		struct type4_params *type4 = &policy->type4_param;
1070 
1071 		if (wpas_set_frame_classifier_params(policy)) {
1072 			wpa_printf(MSG_ERROR,
1073 				   "QM: Failed to set frame classifier parameters");
1074 			goto fail;
1075 		}
1076 
1077 		if (type4->ip_version == IPV4)
1078 			res = write_ipv4_info(pos, len, &type4->ip_params.v4);
1079 		else
1080 			res = write_ipv6_info(pos, len, &type4->ip_params.v6);
1081 
1082 		if (res <= 0) {
1083 			wpa_printf(MSG_ERROR,
1084 				   "QM: Failed to write IP parameters");
1085 			goto fail;
1086 		}
1087 
1088 		ip_ver = type4->ip_version;
1089 
1090 		pos += res;
1091 		len -= res;
1092 	}
1093 
1094 	if (policy->port_range_info) {
1095 		res = os_snprintf(pos, len, " start_port=%u end_port=%u",
1096 				  policy->start_port, policy->end_port);
1097 		if (os_snprintf_error(len, res)) {
1098 			wpa_printf(MSG_ERROR,
1099 				   "QM: Failed to write port range attributes for policy id = %d",
1100 				   policy->policy_id);
1101 			goto fail;
1102 		}
1103 
1104 		pos += res;
1105 		len -= res;
1106 	}
1107 
1108 	if (policy->domain_name) {
1109 		char domain_name_str[250];
1110 
1111 		if (policy->domain_name_len >= sizeof(domain_name_str)) {
1112 			wpa_printf(MSG_ERROR,
1113 				   "QM: Domain name length higher than max expected");
1114 			goto fail;
1115 		}
1116 		os_memcpy(domain_name_str, policy->domain_name,
1117 			  policy->domain_name_len);
1118 		domain_name_str[policy->domain_name_len] = '\0';
1119 		if (!dscp_valid_domain_name(domain_name_str)) {
1120 			wpa_printf(MSG_ERROR, "QM: Invalid domain name string");
1121 			goto fail;
1122 		}
1123 		res = os_snprintf(pos, len, " domain_name=%s", domain_name_str);
1124 		if (os_snprintf_error(len, res)) {
1125 			wpa_printf(MSG_ERROR,
1126 				   "QM: Failed to write domain name attribute for policy id = %d",
1127 				   policy->policy_id);
1128 			goto fail;
1129 		}
1130 	}
1131 
1132 	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY
1133 		"add policy_id=%u dscp=%u ip_version=%d%s",
1134 		policy->policy_id, policy->dscp, ip_ver, policy_str);
1135 	return 0;
1136 fail:
1137 	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "reject policy_id=%u",
1138 		policy->policy_id);
1139 	return -1;
1140 }
1141 
1142 
wpas_dscp_deinit(struct wpa_supplicant * wpa_s)1143 void wpas_dscp_deinit(struct wpa_supplicant *wpa_s)
1144 {
1145 	wpa_printf(MSG_DEBUG, "QM: Clear all active DSCP policies");
1146 	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "clear_all");
1147 	wpa_s->dscp_req_dialog_token = 0;
1148 	wpa_s->dscp_query_dialog_token = 0;
1149 	wpa_s->connection_dscp = 0;
1150 	if (wpa_s->wait_for_dscp_req) {
1151 		wpa_s->wait_for_dscp_req = 0;
1152 		eloop_cancel_timeout(wpas_wait_for_dscp_req_timer, wpa_s, NULL);
1153 	}
1154 }
1155 
1156 
wpas_fill_dscp_policy(struct dscp_policy_data * policy,u8 attr_id,u8 attr_len,const u8 * attr_data)1157 static void wpas_fill_dscp_policy(struct dscp_policy_data *policy, u8 attr_id,
1158 				  u8 attr_len, const u8 *attr_data)
1159 {
1160 	switch (attr_id) {
1161 	case QM_ATTR_PORT_RANGE:
1162 		if (attr_len < 4) {
1163 			wpa_printf(MSG_ERROR,
1164 				   "QM: Received Port Range attribute with insufficient length %d",
1165 				    attr_len);
1166 			break;
1167 		}
1168 		policy->start_port = WPA_GET_BE16(attr_data);
1169 		policy->end_port = WPA_GET_BE16(attr_data + 2);
1170 		policy->port_range_info = true;
1171 		break;
1172 	case QM_ATTR_DSCP_POLICY:
1173 		if (attr_len < 3) {
1174 			wpa_printf(MSG_ERROR,
1175 				   "QM: Received DSCP Policy attribute with insufficient length %d",
1176 				   attr_len);
1177 			return;
1178 		}
1179 		policy->policy_id = attr_data[0];
1180 		policy->req_type = attr_data[1];
1181 		policy->dscp = attr_data[2];
1182 		policy->dscp_info = true;
1183 		break;
1184 	case QM_ATTR_TCLAS:
1185 		if (attr_len < 1) {
1186 			wpa_printf(MSG_ERROR,
1187 				   "QM: Received TCLAS attribute with insufficient length %d",
1188 				   attr_len);
1189 			return;
1190 		}
1191 		policy->frame_classifier = attr_data;
1192 		policy->frame_classifier_len = attr_len;
1193 		break;
1194 	case QM_ATTR_DOMAIN_NAME:
1195 		if (attr_len < 1) {
1196 			wpa_printf(MSG_ERROR,
1197 				   "QM: Received domain name attribute with insufficient length %d",
1198 				   attr_len);
1199 			return;
1200 		}
1201 		policy->domain_name = attr_data;
1202 		policy->domain_name_len = attr_len;
1203 		break;
1204 	default:
1205 		wpa_printf(MSG_ERROR, "QM: Received invalid QoS attribute %d",
1206 			   attr_id);
1207 		break;
1208 	}
1209 }
1210 
1211 
wpas_handle_qos_mgmt_recv_action(struct wpa_supplicant * wpa_s,const u8 * src,const u8 * buf,size_t len)1212 void wpas_handle_qos_mgmt_recv_action(struct wpa_supplicant *wpa_s,
1213 				      const u8 *src,
1214 				      const u8 *buf, size_t len)
1215 {
1216 	int rem_len;
1217 	const u8 *qos_ie, *attr;
1218 	int more, reset;
1219 
1220         struct dscp_policy_data *policies = NULL, *policies_temp;
1221         int num_dscp_policies = 0;
1222 
1223 	if (!wpa_s->enable_dscp_policy_capa) {
1224 		wpa_printf(MSG_ERROR,
1225 			   "QM: Ignore DSCP Policy frame since the capability is not enabled");
1226 		return;
1227 	}
1228 
1229 	if (!pmf_in_use(wpa_s, src)) {
1230 		wpa_printf(MSG_ERROR,
1231 			   "QM: Ignore DSCP Policy frame since PMF is not in use");
1232 		return;
1233 	}
1234 
1235 	if (!wpa_s->connection_dscp) {
1236 		 wpa_printf(MSG_DEBUG,
1237 			    "QM: DSCP Policy capability not enabled for the current association - ignore QoS Management Action frames");
1238 		return;
1239 	}
1240 
1241 	if (len < 1)
1242 		return;
1243 
1244 	/* Handle only DSCP Policy Request frame */
1245 	if (buf[0] != QM_DSCP_POLICY_REQ) {
1246 		wpa_printf(MSG_ERROR, "QM: Received unexpected QoS action frame %d",
1247 			   buf[0]);
1248 		return;
1249 	}
1250 
1251 	if (len < 3) {
1252 		wpa_printf(MSG_ERROR,
1253 			   "Received QoS Management DSCP Policy Request frame with invalid length %zu",
1254 			   len);
1255 		return;
1256 	}
1257 
1258 	/* Clear wait_for_dscp_req on receiving first DSCP request from AP */
1259 	if (wpa_s->wait_for_dscp_req) {
1260 		wpa_s->wait_for_dscp_req = 0;
1261 		eloop_cancel_timeout(wpas_wait_for_dscp_req_timer, wpa_s, NULL);
1262 	}
1263 
1264 	wpa_s->dscp_req_dialog_token = buf[1];
1265 	more = buf[2] & DSCP_POLICY_CTRL_MORE;
1266 	reset = buf[2] & DSCP_POLICY_CTRL_RESET;
1267 
1268         if (reset)
1269                 wpas_notify_qos_policy_reset(wpa_s);
1270 
1271 	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "request_start%s%s",
1272 		reset ? " clear_all" : "", more ? " more" : "");
1273 
1274 	qos_ie = buf + 3;
1275 	rem_len = len - 3;
1276 	while (rem_len > 2) {
1277 		struct dscp_policy_data policy;
1278 		int res = 0;
1279 		int rem_attrs_len, ie_len;
1280 
1281 		ie_len = 2 + qos_ie[1];
1282 		if (rem_len < ie_len)
1283 			break;
1284 
1285 		if (rem_len < 6 || qos_ie[0] != WLAN_EID_VENDOR_SPECIFIC ||
1286 		    qos_ie[1] < 4 ||
1287 		    WPA_GET_BE32(&qos_ie[2]) != QM_IE_VENDOR_TYPE) {
1288 			rem_len -= ie_len;
1289 			qos_ie += ie_len;
1290 			continue;
1291 		}
1292 
1293 		os_memset(&policy, 0, sizeof(struct dscp_policy_data));
1294 		attr = qos_ie + 6;
1295 		rem_attrs_len = qos_ie[1] - 4;
1296 
1297 		while (rem_attrs_len > 2 && rem_attrs_len >= 2 + attr[1]) {
1298 			wpas_fill_dscp_policy(&policy, attr[0], attr[1],
1299 					      &attr[2]);
1300 			rem_attrs_len -= 2 + attr[1];
1301 			attr += 2 + attr[1];
1302 		}
1303 
1304 		rem_len -= ie_len;
1305 		qos_ie += ie_len;
1306 
1307 		if (!policy.dscp_info) {
1308 			wpa_printf(MSG_ERROR,
1309 				   "QM: Received QoS IE without DSCP Policy attribute");
1310 			continue;
1311 		}
1312 
1313 		if (policy.req_type == DSCP_POLICY_REQ_ADD)
1314 			res = wpas_add_dscp_policy(wpa_s, &policy);
1315 		else if (policy.req_type == DSCP_POLICY_REQ_REMOVE)
1316 			wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY
1317 				"remove policy_id=%u", policy.policy_id);
1318 		else {
1319 			wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY
1320 				"reject policy_id=%u", policy.policy_id);
1321 			res = -1;
1322 		}
1323 
1324 		if (res)
1325 			continue;
1326 
1327 		policies_temp = os_realloc(policies,
1328 					   (num_dscp_policies + 1)  *
1329 					   sizeof(struct dscp_policy_data));
1330 		if (!policies_temp)
1331 			goto fail;
1332 
1333 		policies = policies_temp;
1334 		policies[num_dscp_policies] = policy;
1335 		num_dscp_policies++;
1336 	}
1337 
1338 	wpas_notify_qos_policy_request(wpa_s, policies, num_dscp_policies);
1339 
1340 	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "request_end");
1341 
1342 fail:
1343         os_free(policies);
1344         return;
1345 }
1346 
1347 
wpas_send_dscp_response(struct wpa_supplicant * wpa_s,struct dscp_resp_data * resp_data)1348 int wpas_send_dscp_response(struct wpa_supplicant *wpa_s,
1349 			    struct dscp_resp_data *resp_data)
1350 {
1351 	struct wpabuf *buf = NULL;
1352 	size_t buf_len;
1353 	int ret = -1, i;
1354 	u8 resp_control = 0;
1355 
1356 	if (wpa_s->wpa_state != WPA_COMPLETED || !wpa_s->current_ssid) {
1357 		wpa_printf(MSG_ERROR,
1358 			   "QM: Failed to send DSCP response - not connected to AP");
1359 		return -1;
1360 	}
1361 
1362 	if (resp_data->solicited && !wpa_s->dscp_req_dialog_token) {
1363 		wpa_printf(MSG_ERROR, "QM: No ongoing DSCP request");
1364 		return -1;
1365 	}
1366 
1367 	if (!wpa_s->connection_dscp) {
1368 		wpa_printf(MSG_ERROR,
1369 			   "QM: Failed to send DSCP response - DSCP capability not enabled for the current association");
1370 		return -1;
1371 
1372 	}
1373 
1374 	buf_len = 1 +	/* Category */
1375 		  3 +	/* OUI */
1376 		  1 +	/* OUI Type */
1377 		  1 +	/* OUI Subtype */
1378 		  1 +	/* Dialog Token */
1379 		  1 +	/* Response Control */
1380 		  1 +	/* Count */
1381 		  2 * resp_data->num_policies;  /* Status list */
1382 	buf = wpabuf_alloc(buf_len);
1383 	if (!buf) {
1384 		wpa_printf(MSG_ERROR,
1385 			   "QM: Failed to allocate DSCP policy response");
1386 		return -1;
1387 	}
1388 
1389 	wpabuf_put_u8(buf, WLAN_ACTION_VENDOR_SPECIFIC_PROTECTED);
1390 	wpabuf_put_be24(buf, OUI_WFA);
1391 	wpabuf_put_u8(buf, QM_ACTION_OUI_TYPE);
1392 	wpabuf_put_u8(buf, QM_DSCP_POLICY_RESP);
1393 
1394 	wpabuf_put_u8(buf, resp_data->solicited ?
1395 		      wpa_s->dscp_req_dialog_token : 0);
1396 
1397 	if (resp_data->more)
1398 		resp_control |= DSCP_POLICY_CTRL_MORE;
1399 	if (resp_data->reset)
1400 		resp_control |= DSCP_POLICY_CTRL_RESET;
1401 	wpabuf_put_u8(buf, resp_control);
1402 
1403 	wpabuf_put_u8(buf, resp_data->num_policies);
1404 	for (i = 0; i < resp_data->num_policies; i++) {
1405 		wpabuf_put_u8(buf, resp_data->policy[i].id);
1406 		wpabuf_put_u8(buf, resp_data->policy[i].status);
1407 	}
1408 
1409 	wpa_hexdump_buf(MSG_MSGDUMP, "DSCP response frame: ", buf);
1410 	ret = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
1411 				  wpa_s->own_addr, wpa_s->bssid,
1412 				  wpabuf_head(buf), wpabuf_len(buf), 0);
1413 	if (ret < 0) {
1414 		wpa_msg(wpa_s, MSG_INFO, "QM: Failed to send DSCP response");
1415 		goto fail;
1416 	}
1417 
1418 	/*
1419 	 * Mark DSCP request complete whether response sent is solicited or
1420 	 * unsolicited
1421 	 */
1422 	wpa_s->dscp_req_dialog_token = 0;
1423 
1424 fail:
1425 	wpabuf_free(buf);
1426 	return ret;
1427 }
1428 
1429 
wpas_send_dscp_query(struct wpa_supplicant * wpa_s,const char * domain_name,size_t domain_name_length)1430 int wpas_send_dscp_query(struct wpa_supplicant *wpa_s, const char *domain_name,
1431 			 size_t domain_name_length)
1432 {
1433 	struct wpabuf *buf = NULL;
1434 	int ret, dscp_query_size;
1435 
1436 	if (wpa_s->wpa_state != WPA_COMPLETED || !wpa_s->current_ssid)
1437 		return -1;
1438 
1439 	if (!wpa_s->connection_dscp) {
1440 		wpa_printf(MSG_ERROR,
1441 			   "QM: Failed to send DSCP query - DSCP capability not enabled for the current association");
1442 		return -1;
1443 	}
1444 
1445 	if (wpa_s->wait_for_dscp_req) {
1446 		wpa_printf(MSG_INFO, "QM: Wait until AP sends a DSCP request");
1447 		return -1;
1448 	}
1449 
1450 #define DOMAIN_NAME_OFFSET (4 /* OUI */ + 1 /* Attr Id */ + 1 /* Attr len */)
1451 
1452 	if (domain_name_length > 255 - DOMAIN_NAME_OFFSET) {
1453 		wpa_printf(MSG_ERROR, "QM: Too long domain name");
1454 		return -1;
1455 	}
1456 
1457 	dscp_query_size = 1 + /* Category */
1458 			  4 + /* OUI Type */
1459 			  1 + /* OUI subtype */
1460 			  1; /* Dialog Token */
1461 	if (domain_name && domain_name_length)
1462 		dscp_query_size += 1 + /* Element ID */
1463 			1 + /* IE Length */
1464 			DOMAIN_NAME_OFFSET + domain_name_length;
1465 
1466 	buf = wpabuf_alloc(dscp_query_size);
1467 	if (!buf) {
1468 		wpa_printf(MSG_ERROR, "QM: Failed to allocate DSCP query");
1469 		return -1;
1470 	}
1471 
1472 	wpabuf_put_u8(buf, WLAN_ACTION_VENDOR_SPECIFIC_PROTECTED);
1473 	wpabuf_put_be32(buf, QM_ACTION_VENDOR_TYPE);
1474 	wpabuf_put_u8(buf, QM_DSCP_POLICY_QUERY);
1475 	wpa_s->dscp_query_dialog_token++;
1476 	if (wpa_s->dscp_query_dialog_token == 0)
1477 		wpa_s->dscp_query_dialog_token++;
1478 	wpabuf_put_u8(buf, wpa_s->dscp_query_dialog_token);
1479 
1480 	if (domain_name && domain_name_length) {
1481 		/* Domain Name attribute */
1482 		wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
1483 		wpabuf_put_u8(buf, DOMAIN_NAME_OFFSET + domain_name_length);
1484 		wpabuf_put_be32(buf, QM_IE_VENDOR_TYPE);
1485 		wpabuf_put_u8(buf, QM_ATTR_DOMAIN_NAME);
1486 		wpabuf_put_u8(buf, domain_name_length);
1487 		wpabuf_put_data(buf, domain_name, domain_name_length);
1488 	}
1489 #undef DOMAIN_NAME_OFFSET
1490 
1491 	ret = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
1492 				  wpa_s->own_addr, wpa_s->bssid,
1493 				  wpabuf_head(buf), wpabuf_len(buf), 0);
1494 	if (ret < 0) {
1495 		wpa_dbg(wpa_s, MSG_ERROR, "QM: Failed to send DSCP query");
1496 		wpa_s->dscp_query_dialog_token--;
1497 	}
1498 
1499 	wpabuf_free(buf);
1500 	return ret;
1501 }
1502