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