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