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