1 /*
2 * P2P - IE builder
3 * Copyright (c) 2009-2010, Atheros Communications
4 *
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
7 */
8
9 #include "includes.h"
10
11 #include "common.h"
12 #include "common/ieee802_11_defs.h"
13 #include "common/ieee802_11_common.h"
14 #include "common/qca-vendor.h"
15 #include "wps/wps_i.h"
16 #include "p2p_i.h"
17
18
p2p_buf_add_action_hdr(struct wpabuf * buf,u8 subtype,u8 dialog_token)19 void p2p_buf_add_action_hdr(struct wpabuf *buf, u8 subtype, u8 dialog_token)
20 {
21 wpabuf_put_u8(buf, WLAN_ACTION_VENDOR_SPECIFIC);
22 wpabuf_put_be32(buf, P2P_IE_VENDOR_TYPE);
23
24 wpabuf_put_u8(buf, subtype); /* OUI Subtype */
25 wpabuf_put_u8(buf, dialog_token);
26 wpa_printf(MSG_DEBUG, "P2P: * Dialog Token: %d", dialog_token);
27 }
28
29
p2p_buf_add_public_action_hdr(struct wpabuf * buf,u8 subtype,u8 dialog_token)30 void p2p_buf_add_public_action_hdr(struct wpabuf *buf, u8 subtype,
31 u8 dialog_token)
32 {
33 wpabuf_put_u8(buf, WLAN_ACTION_PUBLIC);
34 wpabuf_put_u8(buf, WLAN_PA_VENDOR_SPECIFIC);
35 wpabuf_put_be32(buf, P2P_IE_VENDOR_TYPE);
36
37 wpabuf_put_u8(buf, subtype); /* OUI Subtype */
38 wpabuf_put_u8(buf, dialog_token);
39 wpa_printf(MSG_DEBUG, "P2P: * Dialog Token: %d", dialog_token);
40 }
41
42
p2p_buf_add_ie_hdr(struct wpabuf * buf)43 u8 * p2p_buf_add_ie_hdr(struct wpabuf *buf)
44 {
45 u8 *len;
46
47 /* P2P IE header */
48 wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
49 len = wpabuf_put(buf, 1); /* IE length to be filled */
50 wpabuf_put_be32(buf, P2P_IE_VENDOR_TYPE);
51 wpa_printf(MSG_DEBUG, "P2P: * P2P IE header");
52 return len;
53 }
54
55
p2p_buf_update_ie_hdr(struct wpabuf * buf,u8 * len)56 void p2p_buf_update_ie_hdr(struct wpabuf *buf, u8 *len)
57 {
58 /* Update P2P/P2P2 IE Length */
59 *len = (u8 *) wpabuf_put(buf, 0) - len - 1;
60 }
61
62
p2p_buf_add_p2p2_ie_hdr(struct wpabuf * buf)63 u8 * p2p_buf_add_p2p2_ie_hdr(struct wpabuf *buf)
64 {
65 u8 *len;
66
67 /* P2P2 IE header */
68 wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
69 len = wpabuf_put(buf, 1); /* IE length to be filled */
70 wpabuf_put_be32(buf, P2P2_IE_VENDOR_TYPE);
71 wpa_printf(MSG_DEBUG, "P2P: * P2P2 IE header");
72 return len;
73 }
74
75
p2p_buf_add_capability(struct wpabuf * buf,u8 dev_capab,u8 group_capab)76 void p2p_buf_add_capability(struct wpabuf *buf, u8 dev_capab, u8 group_capab)
77 {
78 /* P2P Capability */
79 wpabuf_put_u8(buf, P2P_ATTR_CAPABILITY);
80 wpabuf_put_le16(buf, 2);
81 wpabuf_put_u8(buf, dev_capab); /* Device Capabilities */
82 wpabuf_put_u8(buf, group_capab); /* Group Capabilities */
83 wpa_printf(MSG_DEBUG, "P2P: * Capability dev=%02x group=%02x",
84 dev_capab, group_capab);
85 }
86
87
p2p_buf_add_go_intent(struct wpabuf * buf,u8 go_intent)88 void p2p_buf_add_go_intent(struct wpabuf *buf, u8 go_intent)
89 {
90 /* Group Owner Intent */
91 wpabuf_put_u8(buf, P2P_ATTR_GROUP_OWNER_INTENT);
92 wpabuf_put_le16(buf, 1);
93 wpabuf_put_u8(buf, go_intent);
94 wpa_printf(MSG_DEBUG, "P2P: * GO Intent: Intent %u Tie breaker %u",
95 go_intent >> 1, go_intent & 0x01);
96 }
97
98
p2p_buf_add_listen_channel(struct wpabuf * buf,const char * country,u8 reg_class,u8 channel)99 void p2p_buf_add_listen_channel(struct wpabuf *buf, const char *country,
100 u8 reg_class, u8 channel)
101 {
102 /* Listen Channel */
103 wpabuf_put_u8(buf, P2P_ATTR_LISTEN_CHANNEL);
104 wpabuf_put_le16(buf, 5);
105 wpabuf_put_data(buf, country, 3);
106 wpabuf_put_u8(buf, reg_class); /* Regulatory Class */
107 wpabuf_put_u8(buf, channel); /* Channel Number */
108 wpa_printf(MSG_DEBUG, "P2P: * Listen Channel: Regulatory Class %u "
109 "Channel %u", reg_class, channel);
110 }
111
112
p2p_buf_add_operating_channel(struct wpabuf * buf,const char * country,u8 reg_class,u8 channel)113 void p2p_buf_add_operating_channel(struct wpabuf *buf, const char *country,
114 u8 reg_class, u8 channel)
115 {
116 /* Operating Channel */
117 wpabuf_put_u8(buf, P2P_ATTR_OPERATING_CHANNEL);
118 wpabuf_put_le16(buf, 5);
119 wpabuf_put_data(buf, country, 3);
120 wpabuf_put_u8(buf, reg_class); /* Regulatory Class */
121 wpabuf_put_u8(buf, channel); /* Channel Number */
122 wpa_printf(MSG_DEBUG, "P2P: * Operating Channel: Regulatory Class %u "
123 "Channel %u", reg_class, channel);
124 }
125
126
p2p_buf_add_pref_channel_list(struct wpabuf * buf,const struct weighted_pcl * pref_freq_list,unsigned int size)127 void p2p_buf_add_pref_channel_list(struct wpabuf *buf,
128 const struct weighted_pcl *pref_freq_list,
129 unsigned int size)
130 {
131 unsigned int i, count = 0;
132 u8 op_class, op_channel;
133
134 if (!size)
135 return;
136
137 /*
138 * First, determine the number of P2P supported channels in the
139 * pref_freq_list returned from driver. This is needed for calculations
140 * of the vendor IE size.
141 */
142 for (i = 0; i < size; i++) {
143 if (p2p_freq_to_channel(pref_freq_list[i].freq, &op_class,
144 &op_channel) == 0 &&
145 !(pref_freq_list[i].flag & WEIGHTED_PCL_EXCLUDE))
146 count++;
147 }
148
149 wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
150 wpabuf_put_u8(buf, 4 + count * sizeof(u16));
151 wpabuf_put_be24(buf, OUI_QCA);
152 wpabuf_put_u8(buf, QCA_VENDOR_ELEM_P2P_PREF_CHAN_LIST);
153 for (i = 0; i < size; i++) {
154 if (p2p_freq_to_channel(pref_freq_list[i].freq, &op_class,
155 &op_channel) < 0 ||
156 (pref_freq_list[i].flag & WEIGHTED_PCL_EXCLUDE)) {
157 wpa_printf(MSG_DEBUG, "Unsupported frequency %u MHz",
158 pref_freq_list[i].freq);
159 continue;
160 }
161 wpabuf_put_u8(buf, op_class);
162 wpabuf_put_u8(buf, op_channel);
163 }
164 }
165
166
p2p_buf_add_channel_list(struct wpabuf * buf,const char * country,struct p2p_channels * chan,bool is_6ghz_capab)167 void p2p_buf_add_channel_list(struct wpabuf *buf, const char *country,
168 struct p2p_channels *chan, bool is_6ghz_capab)
169 {
170 u8 *len;
171 size_t i;
172
173 /* Channel List */
174 wpabuf_put_u8(buf, P2P_ATTR_CHANNEL_LIST);
175 len = wpabuf_put(buf, 2); /* IE length to be filled */
176 wpabuf_put_data(buf, country, 3); /* Country String */
177
178 for (i = 0; i < chan->reg_classes; i++) {
179 struct p2p_reg_class *c = &chan->reg_class[i];
180
181 if (is_6ghz_op_class(c->reg_class) && !is_6ghz_capab)
182 continue;
183 wpabuf_put_u8(buf, c->reg_class);
184 wpabuf_put_u8(buf, c->channels);
185 wpabuf_put_data(buf, c->channel, c->channels);
186 }
187
188 /* Update attribute length */
189 WPA_PUT_LE16(len, (u8 *) wpabuf_put(buf, 0) - len - 2);
190 wpa_hexdump(MSG_DEBUG, "P2P: * Channel List",
191 len + 2, (u8 *) wpabuf_put(buf, 0) - len - 2);
192 }
193
194
p2p_buf_add_status(struct wpabuf * buf,u8 status)195 void p2p_buf_add_status(struct wpabuf *buf, u8 status)
196 {
197 /* Status */
198 wpabuf_put_u8(buf, P2P_ATTR_STATUS);
199 wpabuf_put_le16(buf, 1);
200 wpabuf_put_u8(buf, status);
201 wpa_printf(MSG_DEBUG, "P2P: * Status: %d", status);
202 }
203
204
p2p_buf_add_device_info(struct wpabuf * buf,struct p2p_data * p2p,struct p2p_device * peer)205 void p2p_buf_add_device_info(struct wpabuf *buf, struct p2p_data *p2p,
206 struct p2p_device *peer)
207 {
208 u8 *len;
209 u16 methods;
210 size_t nlen, i;
211
212 /* P2P Device Info */
213 wpabuf_put_u8(buf, P2P_ATTR_DEVICE_INFO);
214 len = wpabuf_put(buf, 2); /* IE length to be filled */
215
216 /* P2P Device address */
217 wpabuf_put_data(buf, p2p->cfg->dev_addr, ETH_ALEN);
218
219 /* Config Methods */
220 methods = 0;
221 if (peer && peer->wps_method != WPS_NOT_READY) {
222 if (peer->wps_method == WPS_PBC)
223 methods |= WPS_CONFIG_PUSHBUTTON;
224 else if (peer->wps_method == WPS_P2PS)
225 methods |= WPS_CONFIG_P2PS;
226 else if (peer->wps_method == WPS_PIN_DISPLAY ||
227 peer->wps_method == WPS_PIN_KEYPAD)
228 methods |= WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD;
229 } else if (p2p->cfg->config_methods) {
230 methods |= p2p->cfg->config_methods &
231 (WPS_CONFIG_PUSHBUTTON | WPS_CONFIG_DISPLAY |
232 WPS_CONFIG_KEYPAD | WPS_CONFIG_P2PS);
233 } else {
234 methods |= WPS_CONFIG_PUSHBUTTON;
235 methods |= WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD;
236 methods |= WPS_CONFIG_P2PS;
237 }
238 wpabuf_put_be16(buf, methods);
239
240 /* Primary Device Type */
241 wpabuf_put_data(buf, p2p->cfg->pri_dev_type,
242 sizeof(p2p->cfg->pri_dev_type));
243
244 /* Number of Secondary Device Types */
245 wpabuf_put_u8(buf, p2p->cfg->num_sec_dev_types);
246
247 /* Secondary Device Type List */
248 for (i = 0; i < p2p->cfg->num_sec_dev_types; i++)
249 wpabuf_put_data(buf, p2p->cfg->sec_dev_type[i],
250 WPS_DEV_TYPE_LEN);
251
252 /* Device Name */
253 nlen = p2p->cfg->dev_name ? os_strlen(p2p->cfg->dev_name) : 0;
254 wpabuf_put_be16(buf, ATTR_DEV_NAME);
255 wpabuf_put_be16(buf, nlen);
256 wpabuf_put_data(buf, p2p->cfg->dev_name, nlen);
257
258 /* Update attribute length */
259 WPA_PUT_LE16(len, (u8 *) wpabuf_put(buf, 0) - len - 2);
260 wpa_printf(MSG_DEBUG, "P2P: * Device Info");
261 }
262
263
p2p_buf_add_device_id(struct wpabuf * buf,const u8 * dev_addr)264 void p2p_buf_add_device_id(struct wpabuf *buf, const u8 *dev_addr)
265 {
266 /* P2P Device ID */
267 wpabuf_put_u8(buf, P2P_ATTR_DEVICE_ID);
268 wpabuf_put_le16(buf, ETH_ALEN);
269 wpabuf_put_data(buf, dev_addr, ETH_ALEN);
270 wpa_printf(MSG_DEBUG, "P2P: * Device ID: " MACSTR, MAC2STR(dev_addr));
271 }
272
273
p2p_buf_add_config_timeout(struct wpabuf * buf,u8 go_timeout,u8 client_timeout)274 void p2p_buf_add_config_timeout(struct wpabuf *buf, u8 go_timeout,
275 u8 client_timeout)
276 {
277 /* Configuration Timeout */
278 wpabuf_put_u8(buf, P2P_ATTR_CONFIGURATION_TIMEOUT);
279 wpabuf_put_le16(buf, 2);
280 wpabuf_put_u8(buf, go_timeout);
281 wpabuf_put_u8(buf, client_timeout);
282 wpa_printf(MSG_DEBUG, "P2P: * Configuration Timeout: GO %d (*10ms) "
283 "client %d (*10ms)", go_timeout, client_timeout);
284 }
285
286
p2p_buf_add_intended_addr(struct wpabuf * buf,const u8 * interface_addr)287 void p2p_buf_add_intended_addr(struct wpabuf *buf, const u8 *interface_addr)
288 {
289 /* Intended P2P Interface Address */
290 wpabuf_put_u8(buf, P2P_ATTR_INTENDED_INTERFACE_ADDR);
291 wpabuf_put_le16(buf, ETH_ALEN);
292 wpabuf_put_data(buf, interface_addr, ETH_ALEN);
293 wpa_printf(MSG_DEBUG, "P2P: * Intended P2P Interface Address " MACSTR,
294 MAC2STR(interface_addr));
295 }
296
297
p2p_buf_add_group_bssid(struct wpabuf * buf,const u8 * bssid)298 void p2p_buf_add_group_bssid(struct wpabuf *buf, const u8 *bssid)
299 {
300 /* P2P Group BSSID */
301 wpabuf_put_u8(buf, P2P_ATTR_GROUP_BSSID);
302 wpabuf_put_le16(buf, ETH_ALEN);
303 wpabuf_put_data(buf, bssid, ETH_ALEN);
304 wpa_printf(MSG_DEBUG, "P2P: * P2P Group BSSID " MACSTR,
305 MAC2STR(bssid));
306 }
307
308
p2p_buf_add_group_id(struct wpabuf * buf,const u8 * dev_addr,const u8 * ssid,size_t ssid_len)309 void p2p_buf_add_group_id(struct wpabuf *buf, const u8 *dev_addr,
310 const u8 *ssid, size_t ssid_len)
311 {
312 /* P2P Group ID */
313 wpabuf_put_u8(buf, P2P_ATTR_GROUP_ID);
314 wpabuf_put_le16(buf, ETH_ALEN + ssid_len);
315 wpabuf_put_data(buf, dev_addr, ETH_ALEN);
316 wpabuf_put_data(buf, ssid, ssid_len);
317 wpa_printf(MSG_DEBUG, "P2P: * P2P Group ID " MACSTR,
318 MAC2STR(dev_addr));
319 wpa_hexdump_ascii(MSG_DEBUG, "P2P: P2P Group ID SSID", ssid, ssid_len);
320 }
321
322
p2p_buf_add_invitation_flags(struct wpabuf * buf,u8 flags)323 void p2p_buf_add_invitation_flags(struct wpabuf *buf, u8 flags)
324 {
325 /* Invitation Flags */
326 wpabuf_put_u8(buf, P2P_ATTR_INVITATION_FLAGS);
327 wpabuf_put_le16(buf, 1);
328 wpabuf_put_u8(buf, flags);
329 wpa_printf(MSG_DEBUG, "P2P: * Invitation Flags: bitmap 0x%x", flags);
330 }
331
332
p2p_buf_add_noa_desc(struct wpabuf * buf,struct p2p_noa_desc * desc)333 static void p2p_buf_add_noa_desc(struct wpabuf *buf, struct p2p_noa_desc *desc)
334 {
335 if (desc == NULL)
336 return;
337
338 wpabuf_put_u8(buf, desc->count_type);
339 wpabuf_put_le32(buf, desc->duration);
340 wpabuf_put_le32(buf, desc->interval);
341 wpabuf_put_le32(buf, desc->start_time);
342 }
343
344
p2p_buf_add_noa(struct wpabuf * buf,u8 noa_index,u8 opp_ps,u8 ctwindow,struct p2p_noa_desc * desc1,struct p2p_noa_desc * desc2)345 void p2p_buf_add_noa(struct wpabuf *buf, u8 noa_index, u8 opp_ps, u8 ctwindow,
346 struct p2p_noa_desc *desc1, struct p2p_noa_desc *desc2)
347 {
348 /* Notice of Absence */
349 wpabuf_put_u8(buf, P2P_ATTR_NOTICE_OF_ABSENCE);
350 wpabuf_put_le16(buf, 2 + (desc1 ? 13 : 0) + (desc2 ? 13 : 0));
351 wpabuf_put_u8(buf, noa_index);
352 wpabuf_put_u8(buf, (opp_ps ? 0x80 : 0) | (ctwindow & 0x7f));
353 p2p_buf_add_noa_desc(buf, desc1);
354 p2p_buf_add_noa_desc(buf, desc2);
355 wpa_printf(MSG_DEBUG, "P2P: * Notice of Absence");
356 }
357
358
p2p_buf_add_ext_listen_timing(struct wpabuf * buf,u16 period,u16 interval)359 void p2p_buf_add_ext_listen_timing(struct wpabuf *buf, u16 period,
360 u16 interval)
361 {
362 /* Extended Listen Timing */
363 wpabuf_put_u8(buf, P2P_ATTR_EXT_LISTEN_TIMING);
364 wpabuf_put_le16(buf, 4);
365 wpabuf_put_le16(buf, period);
366 wpabuf_put_le16(buf, interval);
367 wpa_printf(MSG_DEBUG, "P2P: * Extended Listen Timing (period %u msec "
368 "interval %u msec)", period, interval);
369 }
370
371
p2p_buf_add_p2p_interface(struct wpabuf * buf,struct p2p_data * p2p)372 void p2p_buf_add_p2p_interface(struct wpabuf *buf, struct p2p_data *p2p)
373 {
374 /* P2P Interface */
375 wpabuf_put_u8(buf, P2P_ATTR_INTERFACE);
376 wpabuf_put_le16(buf, ETH_ALEN + 1 + ETH_ALEN);
377 /* P2P Device address */
378 wpabuf_put_data(buf, p2p->cfg->dev_addr, ETH_ALEN);
379 /*
380 * FIX: Fetch interface address list from driver. Do not include
381 * the P2P Device address if it is never used as interface address.
382 */
383 /* P2P Interface Address Count */
384 wpabuf_put_u8(buf, 1);
385 wpabuf_put_data(buf, p2p->cfg->dev_addr, ETH_ALEN);
386 }
387
388
p2p_buf_add_oob_go_neg_channel(struct wpabuf * buf,const char * country,u8 oper_class,u8 channel,enum p2p_role_indication role)389 void p2p_buf_add_oob_go_neg_channel(struct wpabuf *buf, const char *country,
390 u8 oper_class, u8 channel,
391 enum p2p_role_indication role)
392 {
393 /* OOB Group Owner Negotiation Channel */
394 wpabuf_put_u8(buf, P2P_ATTR_OOB_GO_NEG_CHANNEL);
395 wpabuf_put_le16(buf, 6);
396 wpabuf_put_data(buf, country, 3);
397 wpabuf_put_u8(buf, oper_class); /* Operating Class */
398 wpabuf_put_u8(buf, channel); /* Channel Number */
399 wpabuf_put_u8(buf, (u8) role); /* Role indication */
400 wpa_printf(MSG_DEBUG, "P2P: * OOB GO Negotiation Channel: Operating "
401 "Class %u Channel %u Role %d",
402 oper_class, channel, role);
403 }
404
405
p2p_buf_add_service_hash(struct wpabuf * buf,struct p2p_data * p2p)406 void p2p_buf_add_service_hash(struct wpabuf *buf, struct p2p_data *p2p)
407 {
408 if (!p2p)
409 return;
410
411 /* Service Hash */
412 wpabuf_put_u8(buf, P2P_ATTR_SERVICE_HASH);
413 wpabuf_put_le16(buf, p2p->p2ps_seek_count * P2PS_HASH_LEN);
414 wpabuf_put_data(buf, p2p->p2ps_seek_hash,
415 p2p->p2ps_seek_count * P2PS_HASH_LEN);
416 wpa_hexdump(MSG_DEBUG, "P2P: * Service Hash",
417 p2p->p2ps_seek_hash, p2p->p2ps_seek_count * P2PS_HASH_LEN);
418 }
419
420
p2p_buf_add_usd_service_hash(struct wpabuf * buf,struct p2p_data * p2p)421 void p2p_buf_add_usd_service_hash(struct wpabuf *buf, struct p2p_data *p2p)
422 {
423 if (!p2p)
424 return;
425
426 /* USD Service Hash */
427 wpabuf_put_u8(buf, P2P_ATTR_SERVICE_HASH);
428 wpabuf_put_le16(buf, P2PS_HASH_LEN);
429 wpabuf_put_data(buf, p2p->p2p_service_hash, P2PS_HASH_LEN);
430 wpa_hexdump(MSG_DEBUG, "P2P: * Service Hash",
431 p2p->p2p_service_hash, P2PS_HASH_LEN);
432 }
433
434
p2p_buf_add_session_info(struct wpabuf * buf,const char * info)435 void p2p_buf_add_session_info(struct wpabuf *buf, const char *info)
436 {
437 size_t info_len = 0;
438
439 if (info && info[0])
440 info_len = os_strlen(info);
441
442 /* Session Information Data Info */
443 wpabuf_put_u8(buf, P2P_ATTR_SESSION_INFORMATION_DATA);
444 wpabuf_put_le16(buf, (u16) info_len);
445
446 if (info) {
447 wpabuf_put_data(buf, info, info_len);
448 wpa_printf(MSG_DEBUG, "P2P: * Session Info Data (%s)", info);
449 }
450 }
451
452
p2p_buf_add_connection_capability(struct wpabuf * buf,u8 connection_cap)453 void p2p_buf_add_connection_capability(struct wpabuf *buf, u8 connection_cap)
454 {
455 /* Connection Capability Info */
456 wpabuf_put_u8(buf, P2P_ATTR_CONNECTION_CAPABILITY);
457 wpabuf_put_le16(buf, 1);
458 wpabuf_put_u8(buf, connection_cap);
459 wpa_printf(MSG_DEBUG, "P2P: * Connection Capability: 0x%x",
460 connection_cap);
461 }
462
463
p2p_buf_add_advertisement_id(struct wpabuf * buf,u32 id,const u8 * mac)464 void p2p_buf_add_advertisement_id(struct wpabuf *buf, u32 id, const u8 *mac)
465 {
466 if (!buf || !mac)
467 return;
468
469 /* Advertisement ID Info */
470 wpabuf_put_u8(buf, P2P_ATTR_ADVERTISEMENT_ID);
471 wpabuf_put_le16(buf, (u16) (sizeof(u32) + ETH_ALEN));
472 wpabuf_put_le32(buf, id);
473 wpabuf_put_data(buf, mac, ETH_ALEN);
474 wpa_printf(MSG_DEBUG, "P2P: * Advertisement ID (%x) " MACSTR,
475 id, MAC2STR(mac));
476 }
477
478
p2ps_wildcard_hash(struct p2p_data * p2p,const u8 * hash,u8 hash_count)479 static int p2ps_wildcard_hash(struct p2p_data *p2p,
480 const u8 *hash, u8 hash_count)
481 {
482 u8 i;
483 const u8 *test = hash;
484
485 for (i = 0; i < hash_count; i++) {
486 if (os_memcmp(test, p2p->wild_card_hash, P2PS_HASH_LEN) == 0)
487 return 1;
488 test += P2PS_HASH_LEN;
489 }
490
491 return 0;
492 }
493
494
p2p_wfa_service_adv(struct p2p_data * p2p)495 static int p2p_wfa_service_adv(struct p2p_data *p2p)
496 {
497 struct p2ps_advertisement *adv;
498
499 for (adv = p2p->p2ps_adv_list; adv; adv = adv->next) {
500 if (os_strncmp(adv->svc_name, P2PS_WILD_HASH_STR,
501 os_strlen(P2PS_WILD_HASH_STR)) == 0)
502 return 1;
503 }
504
505 return 0;
506 }
507
508
p2p_buf_add_service_info(struct wpabuf * buf,struct p2p_data * p2p,u32 adv_id,u16 config_methods,const char * svc_name,u8 ** ie_len,u8 ** pos,size_t * total_len,u8 * attr_len)509 static int p2p_buf_add_service_info(struct wpabuf *buf, struct p2p_data *p2p,
510 u32 adv_id, u16 config_methods,
511 const char *svc_name, u8 **ie_len, u8 **pos,
512 size_t *total_len, u8 *attr_len)
513 {
514 size_t svc_len;
515 size_t remaining;
516 size_t info_len;
517
518 p2p_dbg(p2p, "Add service info for %s (adv_id=%u)", svc_name, adv_id);
519 svc_len = os_strlen(svc_name);
520 info_len = sizeof(adv_id) + sizeof(config_methods) + sizeof(u8) +
521 svc_len;
522
523 if (info_len + *total_len > MAX_SVC_ADV_LEN) {
524 p2p_dbg(p2p,
525 "Unsufficient buffer, failed to add advertised service info");
526 return -1;
527 }
528
529 if (svc_len > 255) {
530 p2p_dbg(p2p,
531 "Invalid service name length (%u bytes), failed to add advertised service info",
532 (unsigned int) svc_len);
533 return -1;
534 }
535
536 if (*ie_len) {
537 int ie_data_len = (*pos - *ie_len) - 1;
538
539 if (ie_data_len < 0 || ie_data_len > 255) {
540 p2p_dbg(p2p,
541 "Invalid IE length, failed to add advertised service info");
542 return -1;
543 }
544 remaining = 255 - ie_data_len;
545 } else {
546 /*
547 * Adding new P2P IE header takes 6 extra bytes:
548 * - 2 byte IE header (1 byte IE id and 1 byte length)
549 * - 4 bytes of IE_VENDOR_TYPE are reduced from 255 below
550 */
551 *ie_len = p2p_buf_add_ie_hdr(buf);
552 remaining = 255 - 4;
553 }
554
555 if (remaining < sizeof(u32) + sizeof(u16) + sizeof(u8)) {
556 /*
557 * Split adv_id, config_methods, and svc_name_len between two
558 * IEs.
559 */
560 size_t front = remaining;
561 size_t back = sizeof(u32) + sizeof(u16) + sizeof(u8) - front;
562 u8 holder[sizeof(u32) + sizeof(u16) + sizeof(u8)];
563
564 WPA_PUT_LE32(holder, adv_id);
565 WPA_PUT_BE16(&holder[sizeof(u32)], config_methods);
566 holder[sizeof(u32) + sizeof(u16)] = svc_len;
567
568 if (front)
569 wpabuf_put_data(buf, holder, front);
570
571 p2p_buf_update_ie_hdr(buf, *ie_len);
572 *ie_len = p2p_buf_add_ie_hdr(buf);
573
574 wpabuf_put_data(buf, &holder[front], back);
575 remaining = 255 - 4 - (sizeof(u32) + sizeof(u16) + sizeof(u8)) -
576 back;
577 } else {
578 wpabuf_put_le32(buf, adv_id);
579 wpabuf_put_be16(buf, config_methods);
580 wpabuf_put_u8(buf, svc_len);
581 remaining -= sizeof(adv_id) + sizeof(config_methods) +
582 sizeof(u8);
583 }
584
585 if (remaining < svc_len) {
586 /* split svc_name between two or three IEs */
587 size_t front = remaining;
588 size_t back = svc_len - front;
589
590 if (front)
591 wpabuf_put_data(buf, svc_name, front);
592
593 p2p_buf_update_ie_hdr(buf, *ie_len);
594 *ie_len = p2p_buf_add_ie_hdr(buf);
595
596 /* In rare cases, we must split across 3 attributes */
597 if (back > 255 - 4) {
598 wpabuf_put_data(buf, &svc_name[front], 255 - 4);
599 back -= 255 - 4;
600 front += 255 - 4;
601 p2p_buf_update_ie_hdr(buf, *ie_len);
602 *ie_len = p2p_buf_add_ie_hdr(buf);
603 }
604
605 wpabuf_put_data(buf, &svc_name[front], back);
606 remaining = 255 - 4 - back;
607 } else {
608 wpabuf_put_data(buf, svc_name, svc_len);
609 remaining -= svc_len;
610 }
611
612 p2p_buf_update_ie_hdr(buf, *ie_len);
613
614 /* set *ie_len to NULL if a new IE has to be added on the next call */
615 if (!remaining)
616 *ie_len = NULL;
617
618 /* set *pos to point to the next byte to update */
619 *pos = wpabuf_put(buf, 0);
620
621 *total_len += info_len;
622 WPA_PUT_LE16(attr_len, (u16) *total_len);
623 return 0;
624 }
625
626
p2p_buf_add_service_instance(struct wpabuf * buf,struct p2p_data * p2p,u8 hash_count,const u8 * hash,struct p2ps_advertisement * adv_list)627 void p2p_buf_add_service_instance(struct wpabuf *buf, struct p2p_data *p2p,
628 u8 hash_count, const u8 *hash,
629 struct p2ps_advertisement *adv_list)
630 {
631 struct p2ps_advertisement *adv;
632 int p2ps_wildcard;
633 size_t total_len;
634 struct wpabuf *tmp_buf = NULL;
635 u8 *pos, *attr_len, *ie_len = NULL;
636
637 if (!adv_list || !hash || !hash_count)
638 return;
639
640 wpa_hexdump(MSG_DEBUG, "P2PS: Probe Request service hash values",
641 hash, hash_count * P2PS_HASH_LEN);
642 p2ps_wildcard = p2ps_wildcard_hash(p2p, hash, hash_count) &&
643 p2p_wfa_service_adv(p2p);
644
645 /* Allocate temp buffer, allowing for overflow of 1 instance */
646 tmp_buf = wpabuf_alloc(MAX_SVC_ADV_IE_LEN + 256 + P2PS_HASH_LEN);
647 if (!tmp_buf)
648 return;
649
650 /*
651 * Attribute data can be split into a number of IEs. Start with the
652 * first IE and the attribute headers here.
653 */
654 ie_len = p2p_buf_add_ie_hdr(tmp_buf);
655
656 total_len = 0;
657
658 wpabuf_put_u8(tmp_buf, P2P_ATTR_ADVERTISED_SERVICE);
659 attr_len = wpabuf_put(tmp_buf, sizeof(u16));
660 WPA_PUT_LE16(attr_len, (u16) total_len);
661 p2p_buf_update_ie_hdr(tmp_buf, ie_len);
662 pos = wpabuf_put(tmp_buf, 0);
663
664 if (p2ps_wildcard) {
665 /* org.wi-fi.wfds match found */
666 p2p_buf_add_service_info(tmp_buf, p2p, 0, 0, P2PS_WILD_HASH_STR,
667 &ie_len, &pos, &total_len, attr_len);
668 }
669
670 /* add advertised service info of matching services */
671 for (adv = adv_list; adv && total_len <= MAX_SVC_ADV_LEN;
672 adv = adv->next) {
673 const u8 *test = hash;
674 u8 i;
675
676 for (i = 0; i < hash_count; i++) {
677 /* exact name hash match */
678 if (os_memcmp(test, adv->hash, P2PS_HASH_LEN) == 0 &&
679 p2p_buf_add_service_info(tmp_buf, p2p,
680 adv->id,
681 adv->config_methods,
682 adv->svc_name,
683 &ie_len, &pos,
684 &total_len,
685 attr_len))
686 break;
687
688 test += P2PS_HASH_LEN;
689 }
690 }
691
692 if (total_len)
693 wpabuf_put_buf(buf, tmp_buf);
694 wpabuf_free(tmp_buf);
695 }
696
697
p2p_buf_add_session_id(struct wpabuf * buf,u32 id,const u8 * mac)698 void p2p_buf_add_session_id(struct wpabuf *buf, u32 id, const u8 *mac)
699 {
700 if (!buf || !mac)
701 return;
702
703 /* Session ID Info */
704 wpabuf_put_u8(buf, P2P_ATTR_SESSION_ID);
705 wpabuf_put_le16(buf, (u16) (sizeof(u32) + ETH_ALEN));
706 wpabuf_put_le32(buf, id);
707 wpabuf_put_data(buf, mac, ETH_ALEN);
708 wpa_printf(MSG_DEBUG, "P2P: * Session ID Info (%x) " MACSTR,
709 id, MAC2STR(mac));
710 }
711
712
p2p_buf_add_feature_capability(struct wpabuf * buf,u16 len,const u8 * mask)713 void p2p_buf_add_feature_capability(struct wpabuf *buf, u16 len, const u8 *mask)
714 {
715 if (!buf || !len || !mask)
716 return;
717
718 /* Feature Capability */
719 wpabuf_put_u8(buf, P2P_ATTR_FEATURE_CAPABILITY);
720 wpabuf_put_le16(buf, len);
721 wpabuf_put_data(buf, mask, len);
722 wpa_printf(MSG_DEBUG, "P2P: * Feature Capability (%d)", len);
723 }
724
725
p2p_buf_add_persistent_group_info(struct wpabuf * buf,const u8 * dev_addr,const u8 * ssid,size_t ssid_len)726 void p2p_buf_add_persistent_group_info(struct wpabuf *buf, const u8 *dev_addr,
727 const u8 *ssid, size_t ssid_len)
728 {
729 /* P2P Group ID */
730 wpabuf_put_u8(buf, P2P_ATTR_PERSISTENT_GROUP);
731 wpabuf_put_le16(buf, ETH_ALEN + ssid_len);
732 wpabuf_put_data(buf, dev_addr, ETH_ALEN);
733 wpabuf_put_data(buf, ssid, ssid_len);
734 wpa_printf(MSG_DEBUG, "P2P: * P2P Group ID " MACSTR,
735 MAC2STR(dev_addr));
736 }
737
738
p2p_buf_add_pcea(struct wpabuf * buf,struct p2p_data * p2p)739 void p2p_buf_add_pcea(struct wpabuf *buf, struct p2p_data *p2p)
740 {
741 u8 *len;
742 u16 capability_info = 0;
743
744 /* P2P Capability Extension */
745 wpabuf_put_u8(buf, P2P_ATTR_CAPABILITY_EXTENSION);
746 /* Length to be filled */
747 len = wpabuf_put(buf, 2);
748
749 if (!p2p->cfg->p2p_6ghz_disable)
750 capability_info |= P2P_PCEA_6GHZ;
751
752 if (p2p->cfg->reg_info)
753 capability_info |= P2P_PCEA_REG_INFO;
754
755 if (p2p->cfg->dfs_owner)
756 capability_info |= P2P_PCEA_DFS_OWNER;
757
758 if (p2p->cfg->chan_switch_req_enable)
759 capability_info |= P2P_PCEA_CLI_REQ_CS;
760
761 if (p2p->cfg->pairing_config.pairing_capable)
762 capability_info |= P2P_PCEA_PAIRING_CAPABLE;
763
764 if (p2p->cfg->pairing_config.enable_pairing_setup)
765 capability_info |= P2P_PCEA_PAIRING_SETUP_ENABLED;
766
767 if (p2p->cfg->pairing_config.enable_pairing_cache)
768 capability_info |= P2P_PCEA_PMK_CACHING;
769
770 if (p2p->cfg->pairing_config.pasn_type)
771 capability_info |= P2P_PCEA_PASN_TYPE;
772
773 if (p2p->cfg->twt_power_mgmt)
774 capability_info |= P2P_PCEA_TWT_POWER_MGMT;
775
776 /* Field length is (n-1), n in octets */
777 capability_info |= (2 - 1) & P2P_PCEA_LEN_MASK;
778 wpabuf_put_le16(buf, capability_info);
779
780 if (capability_info & P2P_PCEA_REG_INFO)
781 wpabuf_put_u8(buf, p2p->cfg->reg_info);
782
783 if (capability_info & P2P_PCEA_PASN_TYPE)
784 wpabuf_put_u8(buf, p2p->cfg->pairing_config.pasn_type);
785
786 /* Update attribute length */
787 WPA_PUT_LE16(len, (u8 *) wpabuf_put(buf, 0) - len - 2);
788
789 wpa_printf(MSG_DEBUG, "P2P: * Capability Extension info=0x%x",
790 capability_info);
791 }
792
793
p2p_buf_add_pbma(struct wpabuf * buf,u16 bootstrap,const u8 * cookie,size_t cookie_len,int comeback_after)794 void p2p_buf_add_pbma(struct wpabuf *buf, u16 bootstrap, const u8 *cookie,
795 size_t cookie_len, int comeback_after)
796 {
797 u8 *len;
798
799 /* P2P Pairing and Bootstrapping methods */
800 wpabuf_put_u8(buf, P2P_ATTR_PAIRING_AND_BOOTSTRAPPING);
801 /* Length to be filled */
802 len = wpabuf_put(buf, 2);
803
804 if (cookie && cookie_len) {
805 if (comeback_after)
806 wpabuf_put_le16(buf, comeback_after);
807 wpabuf_put_u8(buf, cookie_len);
808 wpabuf_put_data(buf, cookie, cookie_len);
809 }
810 wpabuf_put_le16(buf, bootstrap);
811
812 /* Update attribute length */
813 WPA_PUT_LE16(len, (u8 *) wpabuf_put(buf, 0) - len - 2);
814
815 wpa_printf(MSG_DEBUG, "P2P: * Bootstrapping method=0x%x",
816 bootstrap);
817 }
818
819
p2p_buf_add_dira(struct wpabuf * buf,struct p2p_data * p2p)820 void p2p_buf_add_dira(struct wpabuf *buf, struct p2p_data *p2p)
821 {
822 u8 *len;
823 struct p2p_id_key *dev_ik;
824
825 if (!p2p->cfg->pairing_config.pairing_capable ||
826 !p2p->cfg->pairing_config.enable_pairing_cache)
827 return;
828
829 dev_ik = &p2p->pairing_info->dev_ik;
830 /* P2P DIRA */
831 wpabuf_put_u8(buf, P2P_ATTR_DEVICE_IDENTITY_RESOLUTION);
832 /* Length to be filled */
833 len = wpabuf_put(buf, 2);
834
835 wpabuf_put_u8(buf, dev_ik->cipher_version);
836 wpabuf_put_data(buf, dev_ik->dira_nonce, dev_ik->dira_nonce_len);
837 wpabuf_put_data(buf, dev_ik->dira_tag, dev_ik->dira_tag_len);
838
839 /* Update attribute length */
840 WPA_PUT_LE16(len, (u8 *) wpabuf_put(buf, 0) - len - 2);
841
842 wpa_printf(MSG_DEBUG, "P2P: * DIRA");
843 }
844
845
p2p_add_wps_string(struct wpabuf * buf,enum wps_attribute attr,const char * val)846 static int p2p_add_wps_string(struct wpabuf *buf, enum wps_attribute attr,
847 const char *val)
848 {
849 size_t len;
850
851 len = val ? os_strlen(val) : 0;
852 if (wpabuf_tailroom(buf) < 4 + len)
853 return -1;
854 wpabuf_put_be16(buf, attr);
855 #ifndef CONFIG_WPS_STRICT
856 if (len == 0) {
857 /*
858 * Some deployed WPS implementations fail to parse zeor-length
859 * attributes. As a workaround, send a space character if the
860 * device attribute string is empty.
861 */
862 if (wpabuf_tailroom(buf) < 3)
863 return -1;
864 wpabuf_put_be16(buf, 1);
865 wpabuf_put_u8(buf, ' ');
866 return 0;
867 }
868 #endif /* CONFIG_WPS_STRICT */
869 wpabuf_put_be16(buf, len);
870 if (val)
871 wpabuf_put_data(buf, val, len);
872 return 0;
873 }
874
875
p2p_build_wps_ie(struct p2p_data * p2p,struct wpabuf * buf,int pw_id,int all_attr)876 int p2p_build_wps_ie(struct p2p_data *p2p, struct wpabuf *buf, int pw_id,
877 int all_attr)
878 {
879 u8 *len;
880 int i;
881
882 if (wpabuf_tailroom(buf) < 6)
883 return -1;
884 wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
885 len = wpabuf_put(buf, 1);
886 wpabuf_put_be32(buf, WPS_DEV_OUI_WFA);
887
888 if (wps_build_version(buf) < 0)
889 return -1;
890
891 if (all_attr) {
892 if (wpabuf_tailroom(buf) < 5)
893 return -1;
894 wpabuf_put_be16(buf, ATTR_WPS_STATE);
895 wpabuf_put_be16(buf, 1);
896 wpabuf_put_u8(buf, WPS_STATE_NOT_CONFIGURED);
897 }
898
899 if (pw_id >= 0) {
900 if (wpabuf_tailroom(buf) < 6)
901 return -1;
902 /* Device Password ID */
903 wpabuf_put_be16(buf, ATTR_DEV_PASSWORD_ID);
904 wpabuf_put_be16(buf, 2);
905 wpa_printf(MSG_DEBUG, "P2P: WPS IE Device Password ID: %d",
906 pw_id);
907 wpabuf_put_be16(buf, pw_id);
908 }
909
910 if (all_attr) {
911 if (wpabuf_tailroom(buf) < 5)
912 return -1;
913 wpabuf_put_be16(buf, ATTR_RESPONSE_TYPE);
914 wpabuf_put_be16(buf, 1);
915 wpabuf_put_u8(buf, WPS_RESP_ENROLLEE_INFO);
916
917 if (wps_build_uuid_e(buf, p2p->cfg->uuid) < 0 ||
918 p2p_add_wps_string(buf, ATTR_MANUFACTURER,
919 p2p->cfg->manufacturer) < 0 ||
920 p2p_add_wps_string(buf, ATTR_MODEL_NAME,
921 p2p->cfg->model_name) < 0 ||
922 p2p_add_wps_string(buf, ATTR_MODEL_NUMBER,
923 p2p->cfg->model_number) < 0 ||
924 p2p_add_wps_string(buf, ATTR_SERIAL_NUMBER,
925 p2p->cfg->serial_number) < 0)
926 return -1;
927
928 if (wpabuf_tailroom(buf) < 4 + WPS_DEV_TYPE_LEN)
929 return -1;
930 wpabuf_put_be16(buf, ATTR_PRIMARY_DEV_TYPE);
931 wpabuf_put_be16(buf, WPS_DEV_TYPE_LEN);
932 wpabuf_put_data(buf, p2p->cfg->pri_dev_type, WPS_DEV_TYPE_LEN);
933
934 if (p2p_add_wps_string(buf, ATTR_DEV_NAME, p2p->cfg->dev_name)
935 < 0)
936 return -1;
937
938 if (wpabuf_tailroom(buf) < 6)
939 return -1;
940 wpabuf_put_be16(buf, ATTR_CONFIG_METHODS);
941 wpabuf_put_be16(buf, 2);
942 wpabuf_put_be16(buf, p2p->cfg->config_methods);
943 }
944
945 if (wps_build_wfa_ext(buf, 0, NULL, 0, 0) < 0)
946 return -1;
947
948 if (all_attr && p2p->cfg->num_sec_dev_types) {
949 if (wpabuf_tailroom(buf) <
950 4 + WPS_DEV_TYPE_LEN * p2p->cfg->num_sec_dev_types)
951 return -1;
952 wpabuf_put_be16(buf, ATTR_SECONDARY_DEV_TYPE_LIST);
953 wpabuf_put_be16(buf, WPS_DEV_TYPE_LEN *
954 p2p->cfg->num_sec_dev_types);
955 wpabuf_put_data(buf, p2p->cfg->sec_dev_type,
956 WPS_DEV_TYPE_LEN *
957 p2p->cfg->num_sec_dev_types);
958 }
959
960 /* Add the WPS vendor extensions */
961 for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) {
962 if (p2p->wps_vendor_ext[i] == NULL)
963 break;
964 if (wpabuf_tailroom(buf) <
965 4 + wpabuf_len(p2p->wps_vendor_ext[i]))
966 continue;
967 wpabuf_put_be16(buf, ATTR_VENDOR_EXT);
968 wpabuf_put_be16(buf, wpabuf_len(p2p->wps_vendor_ext[i]));
969 wpabuf_put_buf(buf, p2p->wps_vendor_ext[i]);
970 }
971
972 p2p_buf_update_ie_hdr(buf, len);
973
974 return 0;
975 }
976
977
p2p_encaps_ie(const struct wpabuf * subelems,u32 ie_type)978 struct wpabuf * p2p_encaps_ie(const struct wpabuf *subelems, u32 ie_type)
979 {
980 struct wpabuf *ie;
981 const u8 *pos, *end;
982 size_t len;
983
984 if (!subelems)
985 return NULL;
986
987 len = wpabuf_len(subelems) + 1000;
988
989 ie = wpabuf_alloc(len);
990 if (!ie)
991 return NULL;
992
993 pos = wpabuf_head(subelems);
994 end = pos + wpabuf_len(subelems);
995
996 while (end > pos) {
997 size_t frag_len = end - pos;
998
999 if (frag_len > 251)
1000 frag_len = 251;
1001 wpabuf_put_u8(ie, WLAN_EID_VENDOR_SPECIFIC);
1002 wpabuf_put_u8(ie, 4 + frag_len);
1003 wpabuf_put_be32(ie, ie_type);
1004 wpabuf_put_data(ie, pos, frag_len);
1005 pos += frag_len;
1006 }
1007
1008 return ie;
1009 }
1010