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_session_info(struct wpabuf * buf,const char * info)421 void p2p_buf_add_session_info(struct wpabuf *buf, const char *info)
422 {
423 size_t info_len = 0;
424
425 if (info && info[0])
426 info_len = os_strlen(info);
427
428 /* Session Information Data Info */
429 wpabuf_put_u8(buf, P2P_ATTR_SESSION_INFORMATION_DATA);
430 wpabuf_put_le16(buf, (u16) info_len);
431
432 if (info) {
433 wpabuf_put_data(buf, info, info_len);
434 wpa_printf(MSG_DEBUG, "P2P: * Session Info Data (%s)", info);
435 }
436 }
437
438
p2p_buf_add_connection_capability(struct wpabuf * buf,u8 connection_cap)439 void p2p_buf_add_connection_capability(struct wpabuf *buf, u8 connection_cap)
440 {
441 /* Connection Capability Info */
442 wpabuf_put_u8(buf, P2P_ATTR_CONNECTION_CAPABILITY);
443 wpabuf_put_le16(buf, 1);
444 wpabuf_put_u8(buf, connection_cap);
445 wpa_printf(MSG_DEBUG, "P2P: * Connection Capability: 0x%x",
446 connection_cap);
447 }
448
449
p2p_buf_add_advertisement_id(struct wpabuf * buf,u32 id,const u8 * mac)450 void p2p_buf_add_advertisement_id(struct wpabuf *buf, u32 id, const u8 *mac)
451 {
452 if (!buf || !mac)
453 return;
454
455 /* Advertisement ID Info */
456 wpabuf_put_u8(buf, P2P_ATTR_ADVERTISEMENT_ID);
457 wpabuf_put_le16(buf, (u16) (sizeof(u32) + ETH_ALEN));
458 wpabuf_put_le32(buf, id);
459 wpabuf_put_data(buf, mac, ETH_ALEN);
460 wpa_printf(MSG_DEBUG, "P2P: * Advertisement ID (%x) " MACSTR,
461 id, MAC2STR(mac));
462 }
463
464
p2ps_wildcard_hash(struct p2p_data * p2p,const u8 * hash,u8 hash_count)465 static int p2ps_wildcard_hash(struct p2p_data *p2p,
466 const u8 *hash, u8 hash_count)
467 {
468 u8 i;
469 const u8 *test = hash;
470
471 for (i = 0; i < hash_count; i++) {
472 if (os_memcmp(test, p2p->wild_card_hash, P2PS_HASH_LEN) == 0)
473 return 1;
474 test += P2PS_HASH_LEN;
475 }
476
477 return 0;
478 }
479
480
p2p_wfa_service_adv(struct p2p_data * p2p)481 static int p2p_wfa_service_adv(struct p2p_data *p2p)
482 {
483 struct p2ps_advertisement *adv;
484
485 for (adv = p2p->p2ps_adv_list; adv; adv = adv->next) {
486 if (os_strncmp(adv->svc_name, P2PS_WILD_HASH_STR,
487 os_strlen(P2PS_WILD_HASH_STR)) == 0)
488 return 1;
489 }
490
491 return 0;
492 }
493
494
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)495 static int p2p_buf_add_service_info(struct wpabuf *buf, struct p2p_data *p2p,
496 u32 adv_id, u16 config_methods,
497 const char *svc_name, u8 **ie_len, u8 **pos,
498 size_t *total_len, u8 *attr_len)
499 {
500 size_t svc_len;
501 size_t remaining;
502 size_t info_len;
503
504 p2p_dbg(p2p, "Add service info for %s (adv_id=%u)", svc_name, adv_id);
505 svc_len = os_strlen(svc_name);
506 info_len = sizeof(adv_id) + sizeof(config_methods) + sizeof(u8) +
507 svc_len;
508
509 if (info_len + *total_len > MAX_SVC_ADV_LEN) {
510 p2p_dbg(p2p,
511 "Unsufficient buffer, failed to add advertised service info");
512 return -1;
513 }
514
515 if (svc_len > 255) {
516 p2p_dbg(p2p,
517 "Invalid service name length (%u bytes), failed to add advertised service info",
518 (unsigned int) svc_len);
519 return -1;
520 }
521
522 if (*ie_len) {
523 int ie_data_len = (*pos - *ie_len) - 1;
524
525 if (ie_data_len < 0 || ie_data_len > 255) {
526 p2p_dbg(p2p,
527 "Invalid IE length, failed to add advertised service info");
528 return -1;
529 }
530 remaining = 255 - ie_data_len;
531 } else {
532 /*
533 * Adding new P2P IE header takes 6 extra bytes:
534 * - 2 byte IE header (1 byte IE id and 1 byte length)
535 * - 4 bytes of IE_VENDOR_TYPE are reduced from 255 below
536 */
537 *ie_len = p2p_buf_add_ie_hdr(buf);
538 remaining = 255 - 4;
539 }
540
541 if (remaining < sizeof(u32) + sizeof(u16) + sizeof(u8)) {
542 /*
543 * Split adv_id, config_methods, and svc_name_len between two
544 * IEs.
545 */
546 size_t front = remaining;
547 size_t back = sizeof(u32) + sizeof(u16) + sizeof(u8) - front;
548 u8 holder[sizeof(u32) + sizeof(u16) + sizeof(u8)];
549
550 WPA_PUT_LE32(holder, adv_id);
551 WPA_PUT_BE16(&holder[sizeof(u32)], config_methods);
552 holder[sizeof(u32) + sizeof(u16)] = svc_len;
553
554 if (front)
555 wpabuf_put_data(buf, holder, front);
556
557 p2p_buf_update_ie_hdr(buf, *ie_len);
558 *ie_len = p2p_buf_add_ie_hdr(buf);
559
560 wpabuf_put_data(buf, &holder[front], back);
561 remaining = 255 - 4 - (sizeof(u32) + sizeof(u16) + sizeof(u8)) -
562 back;
563 } else {
564 wpabuf_put_le32(buf, adv_id);
565 wpabuf_put_be16(buf, config_methods);
566 wpabuf_put_u8(buf, svc_len);
567 remaining -= sizeof(adv_id) + sizeof(config_methods) +
568 sizeof(u8);
569 }
570
571 if (remaining < svc_len) {
572 /* split svc_name between two or three IEs */
573 size_t front = remaining;
574 size_t back = svc_len - front;
575
576 if (front)
577 wpabuf_put_data(buf, svc_name, front);
578
579 p2p_buf_update_ie_hdr(buf, *ie_len);
580 *ie_len = p2p_buf_add_ie_hdr(buf);
581
582 /* In rare cases, we must split across 3 attributes */
583 if (back > 255 - 4) {
584 wpabuf_put_data(buf, &svc_name[front], 255 - 4);
585 back -= 255 - 4;
586 front += 255 - 4;
587 p2p_buf_update_ie_hdr(buf, *ie_len);
588 *ie_len = p2p_buf_add_ie_hdr(buf);
589 }
590
591 wpabuf_put_data(buf, &svc_name[front], back);
592 remaining = 255 - 4 - back;
593 } else {
594 wpabuf_put_data(buf, svc_name, svc_len);
595 remaining -= svc_len;
596 }
597
598 p2p_buf_update_ie_hdr(buf, *ie_len);
599
600 /* set *ie_len to NULL if a new IE has to be added on the next call */
601 if (!remaining)
602 *ie_len = NULL;
603
604 /* set *pos to point to the next byte to update */
605 *pos = wpabuf_put(buf, 0);
606
607 *total_len += info_len;
608 WPA_PUT_LE16(attr_len, (u16) *total_len);
609 return 0;
610 }
611
612
p2p_buf_add_service_instance(struct wpabuf * buf,struct p2p_data * p2p,u8 hash_count,const u8 * hash,struct p2ps_advertisement * adv_list)613 void p2p_buf_add_service_instance(struct wpabuf *buf, struct p2p_data *p2p,
614 u8 hash_count, const u8 *hash,
615 struct p2ps_advertisement *adv_list)
616 {
617 struct p2ps_advertisement *adv;
618 int p2ps_wildcard;
619 size_t total_len;
620 struct wpabuf *tmp_buf = NULL;
621 u8 *pos, *attr_len, *ie_len = NULL;
622
623 if (!adv_list || !hash || !hash_count)
624 return;
625
626 wpa_hexdump(MSG_DEBUG, "P2PS: Probe Request service hash values",
627 hash, hash_count * P2PS_HASH_LEN);
628 p2ps_wildcard = p2ps_wildcard_hash(p2p, hash, hash_count) &&
629 p2p_wfa_service_adv(p2p);
630
631 /* Allocate temp buffer, allowing for overflow of 1 instance */
632 tmp_buf = wpabuf_alloc(MAX_SVC_ADV_IE_LEN + 256 + P2PS_HASH_LEN);
633 if (!tmp_buf)
634 return;
635
636 /*
637 * Attribute data can be split into a number of IEs. Start with the
638 * first IE and the attribute headers here.
639 */
640 ie_len = p2p_buf_add_ie_hdr(tmp_buf);
641
642 total_len = 0;
643
644 wpabuf_put_u8(tmp_buf, P2P_ATTR_ADVERTISED_SERVICE);
645 attr_len = wpabuf_put(tmp_buf, sizeof(u16));
646 WPA_PUT_LE16(attr_len, (u16) total_len);
647 p2p_buf_update_ie_hdr(tmp_buf, ie_len);
648 pos = wpabuf_put(tmp_buf, 0);
649
650 if (p2ps_wildcard) {
651 /* org.wi-fi.wfds match found */
652 p2p_buf_add_service_info(tmp_buf, p2p, 0, 0, P2PS_WILD_HASH_STR,
653 &ie_len, &pos, &total_len, attr_len);
654 }
655
656 /* add advertised service info of matching services */
657 for (adv = adv_list; adv && total_len <= MAX_SVC_ADV_LEN;
658 adv = adv->next) {
659 const u8 *test = hash;
660 u8 i;
661
662 for (i = 0; i < hash_count; i++) {
663 /* exact name hash match */
664 if (os_memcmp(test, adv->hash, P2PS_HASH_LEN) == 0 &&
665 p2p_buf_add_service_info(tmp_buf, p2p,
666 adv->id,
667 adv->config_methods,
668 adv->svc_name,
669 &ie_len, &pos,
670 &total_len,
671 attr_len))
672 break;
673
674 test += P2PS_HASH_LEN;
675 }
676 }
677
678 if (total_len)
679 wpabuf_put_buf(buf, tmp_buf);
680 wpabuf_free(tmp_buf);
681 }
682
683
p2p_buf_add_session_id(struct wpabuf * buf,u32 id,const u8 * mac)684 void p2p_buf_add_session_id(struct wpabuf *buf, u32 id, const u8 *mac)
685 {
686 if (!buf || !mac)
687 return;
688
689 /* Session ID Info */
690 wpabuf_put_u8(buf, P2P_ATTR_SESSION_ID);
691 wpabuf_put_le16(buf, (u16) (sizeof(u32) + ETH_ALEN));
692 wpabuf_put_le32(buf, id);
693 wpabuf_put_data(buf, mac, ETH_ALEN);
694 wpa_printf(MSG_DEBUG, "P2P: * Session ID Info (%x) " MACSTR,
695 id, MAC2STR(mac));
696 }
697
698
p2p_buf_add_feature_capability(struct wpabuf * buf,u16 len,const u8 * mask)699 void p2p_buf_add_feature_capability(struct wpabuf *buf, u16 len, const u8 *mask)
700 {
701 if (!buf || !len || !mask)
702 return;
703
704 /* Feature Capability */
705 wpabuf_put_u8(buf, P2P_ATTR_FEATURE_CAPABILITY);
706 wpabuf_put_le16(buf, len);
707 wpabuf_put_data(buf, mask, len);
708 wpa_printf(MSG_DEBUG, "P2P: * Feature Capability (%d)", len);
709 }
710
711
p2p_buf_add_persistent_group_info(struct wpabuf * buf,const u8 * dev_addr,const u8 * ssid,size_t ssid_len)712 void p2p_buf_add_persistent_group_info(struct wpabuf *buf, const u8 *dev_addr,
713 const u8 *ssid, size_t ssid_len)
714 {
715 /* P2P Group ID */
716 wpabuf_put_u8(buf, P2P_ATTR_PERSISTENT_GROUP);
717 wpabuf_put_le16(buf, ETH_ALEN + ssid_len);
718 wpabuf_put_data(buf, dev_addr, ETH_ALEN);
719 wpabuf_put_data(buf, ssid, ssid_len);
720 wpa_printf(MSG_DEBUG, "P2P: * P2P Group ID " MACSTR,
721 MAC2STR(dev_addr));
722 }
723
724
p2p_buf_add_pcea(struct wpabuf * buf,struct p2p_data * p2p)725 void p2p_buf_add_pcea(struct wpabuf *buf, struct p2p_data *p2p)
726 {
727 u8 *len;
728 u16 capability_info = 0;
729
730 /* P2P Capability Extension */
731 wpabuf_put_u8(buf, P2P_ATTR_CAPABILITY_EXTENSION);
732 /* Length to be filled */
733 len = wpabuf_put(buf, 2);
734
735 if (!p2p->cfg->p2p_6ghz_disable)
736 capability_info |= P2P_PCEA_6GHZ;
737
738 if (p2p->cfg->reg_info)
739 capability_info |= P2P_PCEA_REG_INFO;
740
741 if (p2p->cfg->dfs_owner)
742 capability_info |= P2P_PCEA_DFS_OWNER;
743
744 if (p2p->cfg->pairing_config.pairing_capable)
745 capability_info |= P2P_PCEA_PAIRING_CAPABLE;
746
747 if (p2p->cfg->pairing_config.enable_pairing_setup)
748 capability_info |= P2P_PCEA_PAIRING_SETUP_ENABLED;
749
750 if (p2p->cfg->pairing_config.enable_pairing_cache)
751 capability_info |= P2P_PCEA_PMK_CACHING;
752
753 if (p2p->cfg->pairing_config.pasn_type)
754 capability_info |= P2P_PCEA_PASN_TYPE;
755
756 if (p2p->cfg->twt_power_mgmt)
757 capability_info |= P2P_PCEA_TWT_POWER_MGMT;
758
759 /* Field length is (n-1), n in octets */
760 capability_info |= (2 - 1) & P2P_PCEA_LEN_MASK;
761 wpabuf_put_le16(buf, capability_info);
762
763 if (capability_info & P2P_PCEA_REG_INFO)
764 wpabuf_put_u8(buf, p2p->cfg->reg_info);
765
766 if (capability_info & P2P_PCEA_PASN_TYPE)
767 wpabuf_put_u8(buf, p2p->cfg->pairing_config.pasn_type);
768
769 /* Update attribute length */
770 WPA_PUT_LE16(len, (u8 *) wpabuf_put(buf, 0) - len - 2);
771
772 wpa_printf(MSG_DEBUG, "P2P: * Capability Extension info=0x%x",
773 capability_info);
774 }
775
776
p2p_buf_add_pbma(struct wpabuf * buf,u16 bootstrap,const u8 * cookie,size_t cookie_len,int comeback_after)777 void p2p_buf_add_pbma(struct wpabuf *buf, u16 bootstrap, const u8 *cookie,
778 size_t cookie_len, int comeback_after)
779 {
780 u8 *len;
781
782 /* P2P Pairing and Bootstrapping methods */
783 wpabuf_put_u8(buf, P2P_ATTR_PAIRING_AND_BOOTSTRAPPING);
784 /* Length to be filled */
785 len = wpabuf_put(buf, 2);
786
787 if (cookie && cookie_len) {
788 if (comeback_after)
789 wpabuf_put_le16(buf, comeback_after);
790 wpabuf_put_u8(buf, cookie_len);
791 wpabuf_put_data(buf, cookie, cookie_len);
792 }
793 wpabuf_put_le16(buf, bootstrap);
794
795 /* Update attribute length */
796 WPA_PUT_LE16(len, (u8 *) wpabuf_put(buf, 0) - len - 2);
797
798 wpa_printf(MSG_DEBUG, "P2P: * Bootstrapping method=0x%x",
799 bootstrap);
800 }
801
802
p2p_buf_add_dira(struct wpabuf * buf,struct p2p_data * p2p)803 void p2p_buf_add_dira(struct wpabuf *buf, struct p2p_data *p2p)
804 {
805 u8 *len;
806 struct p2p_id_key *dev_ik;
807
808 if (!p2p->cfg->pairing_config.pairing_capable ||
809 !p2p->cfg->pairing_config.enable_pairing_cache ||
810 !p2p->cfg->pairing_config.enable_pairing_verification)
811 return;
812
813 dev_ik = &p2p->pairing_info->dev_ik;
814 /* P2P DIRA */
815 wpabuf_put_u8(buf, P2P_ATTR_DEVICE_IDENTITY_RESOLUTION);
816 /* Length to be filled */
817 len = wpabuf_put(buf, 2);
818
819 wpabuf_put_u8(buf, dev_ik->cipher_version);
820 wpabuf_put_data(buf, dev_ik->dira_nonce, dev_ik->dira_nonce_len);
821 wpabuf_put_data(buf, dev_ik->dira_tag, dev_ik->dira_tag_len);
822
823 /* Update attribute length */
824 WPA_PUT_LE16(len, (u8 *) wpabuf_put(buf, 0) - len - 2);
825
826 wpa_printf(MSG_DEBUG, "P2P: * DIRA");
827 }
828
829
p2p_add_wps_string(struct wpabuf * buf,enum wps_attribute attr,const char * val)830 static int p2p_add_wps_string(struct wpabuf *buf, enum wps_attribute attr,
831 const char *val)
832 {
833 size_t len;
834
835 len = val ? os_strlen(val) : 0;
836 if (wpabuf_tailroom(buf) < 4 + len)
837 return -1;
838 wpabuf_put_be16(buf, attr);
839 #ifndef CONFIG_WPS_STRICT
840 if (len == 0) {
841 /*
842 * Some deployed WPS implementations fail to parse zeor-length
843 * attributes. As a workaround, send a space character if the
844 * device attribute string is empty.
845 */
846 if (wpabuf_tailroom(buf) < 3)
847 return -1;
848 wpabuf_put_be16(buf, 1);
849 wpabuf_put_u8(buf, ' ');
850 return 0;
851 }
852 #endif /* CONFIG_WPS_STRICT */
853 wpabuf_put_be16(buf, len);
854 if (val)
855 wpabuf_put_data(buf, val, len);
856 return 0;
857 }
858
859
p2p_build_wps_ie(struct p2p_data * p2p,struct wpabuf * buf,int pw_id,int all_attr)860 int p2p_build_wps_ie(struct p2p_data *p2p, struct wpabuf *buf, int pw_id,
861 int all_attr)
862 {
863 u8 *len;
864 int i;
865
866 if (wpabuf_tailroom(buf) < 6)
867 return -1;
868 wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
869 len = wpabuf_put(buf, 1);
870 wpabuf_put_be32(buf, WPS_DEV_OUI_WFA);
871
872 if (wps_build_version(buf) < 0)
873 return -1;
874
875 if (all_attr) {
876 if (wpabuf_tailroom(buf) < 5)
877 return -1;
878 wpabuf_put_be16(buf, ATTR_WPS_STATE);
879 wpabuf_put_be16(buf, 1);
880 wpabuf_put_u8(buf, WPS_STATE_NOT_CONFIGURED);
881 }
882
883 if (pw_id >= 0) {
884 if (wpabuf_tailroom(buf) < 6)
885 return -1;
886 /* Device Password ID */
887 wpabuf_put_be16(buf, ATTR_DEV_PASSWORD_ID);
888 wpabuf_put_be16(buf, 2);
889 wpa_printf(MSG_DEBUG, "P2P: WPS IE Device Password ID: %d",
890 pw_id);
891 wpabuf_put_be16(buf, pw_id);
892 }
893
894 if (all_attr) {
895 if (wpabuf_tailroom(buf) < 5)
896 return -1;
897 wpabuf_put_be16(buf, ATTR_RESPONSE_TYPE);
898 wpabuf_put_be16(buf, 1);
899 wpabuf_put_u8(buf, WPS_RESP_ENROLLEE_INFO);
900
901 if (wps_build_uuid_e(buf, p2p->cfg->uuid) < 0 ||
902 p2p_add_wps_string(buf, ATTR_MANUFACTURER,
903 p2p->cfg->manufacturer) < 0 ||
904 p2p_add_wps_string(buf, ATTR_MODEL_NAME,
905 p2p->cfg->model_name) < 0 ||
906 p2p_add_wps_string(buf, ATTR_MODEL_NUMBER,
907 p2p->cfg->model_number) < 0 ||
908 p2p_add_wps_string(buf, ATTR_SERIAL_NUMBER,
909 p2p->cfg->serial_number) < 0)
910 return -1;
911
912 if (wpabuf_tailroom(buf) < 4 + WPS_DEV_TYPE_LEN)
913 return -1;
914 wpabuf_put_be16(buf, ATTR_PRIMARY_DEV_TYPE);
915 wpabuf_put_be16(buf, WPS_DEV_TYPE_LEN);
916 wpabuf_put_data(buf, p2p->cfg->pri_dev_type, WPS_DEV_TYPE_LEN);
917
918 if (p2p_add_wps_string(buf, ATTR_DEV_NAME, p2p->cfg->dev_name)
919 < 0)
920 return -1;
921
922 if (wpabuf_tailroom(buf) < 6)
923 return -1;
924 wpabuf_put_be16(buf, ATTR_CONFIG_METHODS);
925 wpabuf_put_be16(buf, 2);
926 wpabuf_put_be16(buf, p2p->cfg->config_methods);
927 }
928
929 if (wps_build_wfa_ext(buf, 0, NULL, 0, 0) < 0)
930 return -1;
931
932 if (all_attr && p2p->cfg->num_sec_dev_types) {
933 if (wpabuf_tailroom(buf) <
934 4 + WPS_DEV_TYPE_LEN * p2p->cfg->num_sec_dev_types)
935 return -1;
936 wpabuf_put_be16(buf, ATTR_SECONDARY_DEV_TYPE_LIST);
937 wpabuf_put_be16(buf, WPS_DEV_TYPE_LEN *
938 p2p->cfg->num_sec_dev_types);
939 wpabuf_put_data(buf, p2p->cfg->sec_dev_type,
940 WPS_DEV_TYPE_LEN *
941 p2p->cfg->num_sec_dev_types);
942 }
943
944 /* Add the WPS vendor extensions */
945 for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) {
946 if (p2p->wps_vendor_ext[i] == NULL)
947 break;
948 if (wpabuf_tailroom(buf) <
949 4 + wpabuf_len(p2p->wps_vendor_ext[i]))
950 continue;
951 wpabuf_put_be16(buf, ATTR_VENDOR_EXT);
952 wpabuf_put_be16(buf, wpabuf_len(p2p->wps_vendor_ext[i]));
953 wpabuf_put_buf(buf, p2p->wps_vendor_ext[i]);
954 }
955
956 p2p_buf_update_ie_hdr(buf, len);
957
958 return 0;
959 }
960
961
p2p_encaps_ie(const struct wpabuf * subelems,u32 ie_type)962 struct wpabuf * p2p_encaps_ie(const struct wpabuf *subelems, u32 ie_type)
963 {
964 struct wpabuf *ie;
965 const u8 *pos, *end;
966 size_t len;
967
968 if (!subelems)
969 return NULL;
970
971 len = wpabuf_len(subelems) + 1000;
972
973 ie = wpabuf_alloc(len);
974 if (!ie)
975 return NULL;
976
977 pos = wpabuf_head(subelems);
978 end = pos + wpabuf_len(subelems);
979
980 while (end > pos) {
981 size_t frag_len = end - pos;
982
983 if (frag_len > 251)
984 frag_len = 251;
985 wpabuf_put_u8(ie, WLAN_EID_VENDOR_SPECIFIC);
986 wpabuf_put_u8(ie, 4 + frag_len);
987 wpabuf_put_be32(ie, ie_type);
988 wpabuf_put_data(ie, pos, frag_len);
989 pos += frag_len;
990 }
991
992 return ie;
993 }
994