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