xref: /aosp_15_r20/external/wpa_supplicant_8/src/p2p/p2p_build.c (revision 03f9172ca588f91df233974f4258bab95191f931)
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