1 /*
2  * WPA Supplicant - Scanning
3  * Copyright (c) 2003-2019, Jouni Malinen <j@w1.fi>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8 
9 #include "utils/includes.h"
10 
11 #include "utils/common.h"
12 #include "common/ieee802_11_defs.h"
13 #include "wpa_supplicant_i.h"
14 #include "drivers/driver.h"
15 #include "common/ieee802_11_common.h"
16 #include "bss.h"
17 #include "scan.h"
18 
19 /**
20  * wpa_supplicant_req_scan - Schedule a scan for neighboring access points
21  * @wpa_s: Pointer to wpa_supplicant data
22  * @sec: Number of seconds after which to scan
23  * @usec: Number of microseconds after which to scan
24  *
25  * This function is used to schedule a scan for neighboring access points after
26  * the specified time.
27  */
wpa_supplicant_req_scan(struct wpa_supplicant * wpa_s,int sec,int usec)28 void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec)
29 {
30 	int ret;
31 	struct wpa_driver_scan_params *params;
32 
33 	os_sleep(sec, usec);
34 
35 	if (wpa_s->scanning) {
36 		wpa_dbg(wpa_s, MSG_DEBUG, "Already scanning - Return");
37 		return;
38 	}
39 	params = os_zalloc(sizeof(*params));
40 
41 	if (!params) {
42 		wpa_printf(MSG_ERROR, "Memory allocation failed");
43 		return;
44 	}
45 	if (wpa_s->wnm_mode) {
46 		/* Use the same memory */
47 		params->ssids[0].ssid = wpa_s->current_bss->ssid;
48 		params->ssids[0].ssid_len = wpa_s->current_bss->ssid_len;
49 		params->num_ssids = 1;
50 	}
51 	if (!is_zero_ether_addr(wpa_s->next_scan_bssid)) {
52 		/* Use the same memory */
53 		params->bssid = wpa_s->next_scan_bssid;
54 	}
55 
56 	if (wpa_s->next_scan_chan)
57 		params->channel = wpa_s->next_scan_chan;
58 
59 	wpa_s->scan_reason = REASON_WNM_BSS_TRANS_REQ;
60 	ret = wpa_supplicant_trigger_scan(wpa_s, params);
61 
62 	os_free(params);
63 
64 	if (ret < 0) {
65 		wpa_printf(MSG_ERROR, "Failed to issue scan - Return");
66 		return;
67 	}
68 }
69 
70 /**
71  * wpa_scan_get_ie - Fetch a specified information element from a scan result
72  * @res: Scan result entry
73  * @ie: Information element identitifier (WLAN_EID_*)
74  * Returns: Pointer to the information element (id field) or %NULL if not found
75  *
76  * This function returns the first matching information element in the scan
77  * result.
78  */
wpa_scan_get_ie(const struct wpa_scan_res * res,u8 ie)79 const u8 * wpa_scan_get_ie(const struct wpa_scan_res *res, u8 ie)
80 {
81 	size_t ie_len = res->ie_len;
82 
83 	/* Use the Beacon frame IEs if res->ie_len is not available */
84 	if (!ie_len)
85 		ie_len = res->beacon_ie_len;
86 
87 	return get_ie((const u8 *) (res + 1), ie_len, ie);
88 }
89 
wpa_scan_free_params(struct wpa_driver_scan_params * params)90 void wpa_scan_free_params(struct wpa_driver_scan_params *params)
91 {
92 	if (params == NULL)
93 		return;
94 
95 	os_free((u8 *) params->bssid);
96 
97 	os_free(params);
98 }
99