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 if (!wpa_s->current_bss) {
40 wpa_dbg(wpa_s, MSG_INFO, "Current BSS is null - Return");
41 return;
42 }
43 params = os_zalloc(sizeof(*params));
44
45 if (!params) {
46 wpa_printf(MSG_ERROR, "Memory allocation failed");
47 return;
48 }
49 #ifdef CONFIG_WNM
50 if (wpa_s->wnm_mode) {
51 /* Use the same memory */
52 params->ssids[0].ssid = wpa_s->current_bss->ssid;
53 params->ssids[0].ssid_len = wpa_s->current_bss->ssid_len;
54 params->num_ssids = 1;
55 }
56 #endif
57 if (!is_zero_ether_addr(wpa_s->next_scan_bssid)) {
58 /* Use the same memory */
59 params->bssid = wpa_s->next_scan_bssid;
60 }
61
62 if (wpa_s->next_scan_chan)
63 params->channel = wpa_s->next_scan_chan;
64
65 wpa_s->scan_reason = REASON_WNM_BSS_TRANS_REQ;
66 ret = wpa_supplicant_trigger_scan(wpa_s, params);
67
68 os_free(params);
69
70 if (ret < 0) {
71 wpa_printf(MSG_ERROR, "Failed to issue scan - Return");
72 return;
73 }
74 }
75
76 /**
77 * wpa_scan_get_ie - Fetch a specified information element from a scan result
78 * @res: Scan result entry
79 * @ie: Information element identitifier (WLAN_EID_*)
80 * Returns: Pointer to the information element (id field) or %NULL if not found
81 *
82 * This function returns the first matching information element in the scan
83 * result.
84 */
wpa_scan_get_ie(const struct wpa_scan_res * res,u8 ie)85 const u8 * wpa_scan_get_ie(const struct wpa_scan_res *res, u8 ie)
86 {
87 size_t ie_len = res->ie_len;
88
89 /* Use the Beacon frame IEs if res->ie_len is not available */
90 if (!ie_len)
91 ie_len = res->beacon_ie_len;
92
93 return get_ie((const u8 *) (res + 1), ie_len, ie);
94 }
95
wpa_scan_free_params(struct wpa_driver_scan_params * params)96 void wpa_scan_free_params(struct wpa_driver_scan_params *params)
97 {
98 if (params == NULL)
99 return;
100
101 os_free((u8 *) params->bssid);
102
103 os_free(params);
104 }
105