wpa_cli工具的使用方法及分析

2 篇文章 0 订阅
0 篇文章 0 订阅

wpa_cli 的使用方法

在Android中有wpa_cli工具能够直接可wpa_supplicant通讯。能够查看一些wifi的信息。
使用方法:wpa_cli -i wlan0 -p /data/misc/wifi/sockets

wpa_cli源码分析

int main(int argc, char *argv[])
{
···
	for (;;) {
		c = getopt(argc, argv, "a:Bg:G:hi:p:P:s:v");
		if (c < 0)
			break;
		switch (c) {
		case 'a':
			action_file = optarg;
			break;
		case 'B':
			daemonize = 1;
			break;
		case 'g':
			global = optarg;
			break;
		case 'G':
			ping_interval = atoi(optarg);
			break;
		case 'h':
			usage();
			return 0;
		case 'v':
			printf("%s\n", wpa_cli_version);
			return 0;
		case 'i':
			os_free(ctrl_ifname);
			ctrl_ifname = os_strdup(optarg);
			break;
		case 'p':
			ctrl_iface_dir = optarg;
			break;
		case 'P':
			pid_file = optarg;
			break;
		case 's':
			client_socket_dir = optarg;
			break;
		default:
			usage();
			return -1;
		}
	}
	···
	if (interactive) {
		wpa_cli_interactive();
	}
	···
···
}

在main函数里面主要就是从命令行中读取参数。之后就是调用wpa_cli_interactive进行建立与supplicant通信的socket,通过读取stdin中的命令与用户进行交互。

static void wpa_cli_interactive(void)
{
	printf("\nInteractive mode\n\n");

	eloop_register_timeout(0, 0, try_connection, NULL, NULL);
	eloop_run();
	eloop_cancel_timeout(try_connection, NULL, NULL);

	cli_txt_list_flush(&p2p_peers);
	cli_txt_list_flush(&p2p_groups);
	cli_txt_list_flush(&bsses);
	cli_txt_list_flush(&ifnames);
	cli_txt_list_flush(&networks);
	if (edit_started)
		edit_deinit(hfile, wpa_cli_edit_filter_history_cb);
	os_free(hfile);
	eloop_cancel_timeout(wpa_cli_ping, NULL, NULL);
	wpa_cli_close_connection();
}

在这个函数里面就是注册try_connection。time到后就可以执行。这里面时间为0,也就是马上执行。
继续对try_connection函数进行分析

static void try_connection(void *eloop_ctx, void *timeout_ctx)
{
···
	if (!wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
	···
	}
	···
···
done:
	start_edit();
}

这里面就是打开socket用来与wpa_supplicant进行通讯,之后调用start_edit()函数

static void start_edit(void)
{
···
	if (edit_init(wpa_cli_edit_cmd_cb, wpa_cli_edit_eof_cb,
		      wpa_cli_edit_completion_cb, NULL, hfile, ps) < 0) {
		eloop_terminate();
		return;
	}
···
}

这里面注册了三个callback函数:

  1. wpa_cli_edit_cmd_cb。查找用户输入命令对应的函数,找到后执行,就是将用户指令发送个supplicant
  2. wpa_cli_edit_eof_cb,用户交互完毕之后调用。用来结束wpa_cli进程
  3. wpa_cli_edit_completion_cb,用户输入完毕调用函数。

下面主要分析wpa_cli_edit_cmd_cb函数。

static void wpa_cli_edit_cmd_cb(void *ctx, char *cmd)
{
	char *argv[max_args];
	int argc;
	argc = tokenize_cmd(cmd, argv);
	if (argc)
		wpa_request(ctrl_conn, argc, argv);
}

这个函数就是获得用户输入的命令,之后调用wpa_request进行处理。

static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
{
	···
	cmd = wpa_cli_commands;
	while (cmd->cmd) {
		if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
		{
			match = cmd;
			if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
				/* we have an exact match */
				count = 1;
				break;
			}
			count++;
		}
		cmd++;
	}
	···
	ret = match->handler(ctrl, argc - 1, &argv[1]);
}

这个函数里面主要就进行了上述的两个工作:
1.查找用户输入命令对应的函数
2.调用对应函数的handler

那么handler是如何定义的呢?
通过源码可以找到这些command都对应一个函数。这些函数都被封装到一个机构题里面。结构体内容如下:

static const struct wpa_cli_cmd wpa_cli_commands[] = {
	{ "status", wpa_cli_cmd_status, NULL,
	  cli_cmd_flag_none,
	  "[verbose] = get current WPA/EAPOL/EAP status" },
	{ "ifname", wpa_cli_cmd_ifname, NULL,
	  cli_cmd_flag_none,
	  "= get current interface name" },
	{ "ping", wpa_cli_cmd_ping, NULL,
	  cli_cmd_flag_none,
	  "= pings wpa_supplicant" },
	{ "relog", wpa_cli_cmd_relog, NULL,
	  cli_cmd_flag_none,
	  "= re-open log-file (allow rolling logs)" },
	{ "note", wpa_cli_cmd_note, NULL,
	  cli_cmd_flag_none,
	  "<text> = add a note to wpa_supplicant debug log" },
	{ "mib", wpa_cli_cmd_mib, NULL,
	  cli_cmd_flag_none,
	  "= get MIB variables (dot1x, dot11)" },
	{ "help", wpa_cli_cmd_help, wpa_cli_complete_help,
	  cli_cmd_flag_none,
	  "[command] = show usage help" },
	{ "interface", wpa_cli_cmd_interface, NULL,
	  cli_cmd_flag_none,
	  "[ifname] = show interfaces/select interface" },
	{ "level", wpa_cli_cmd_level, NULL,
	  cli_cmd_flag_none,
	  "<debug level> = change debug level" },
	{ "license", wpa_cli_cmd_license, NULL,
	  cli_cmd_flag_none,
	  "= show full wpa_cli license" },
	{ "quit", wpa_cli_cmd_quit, NULL,
	  cli_cmd_flag_none,
	  "= exit wpa_cli" },
	{ "set", wpa_cli_cmd_set, wpa_cli_complete_set,
	  cli_cmd_flag_none,
	  "= set variables (shows list of variables when run without "
	  "arguments)" },
	{ "dump", wpa_cli_cmd_dump, NULL,
	  cli_cmd_flag_none,
	  "= dump config variables" },
	{ "get", wpa_cli_cmd_get, wpa_cli_complete_get,
	  cli_cmd_flag_none,
	  "<name> = get information" },
	{ "logon", wpa_cli_cmd_logon, NULL,
	  cli_cmd_flag_none,
	  "= IEEE 802.1X EAPOL state machine logon" },
	{ "logoff", wpa_cli_cmd_logoff, NULL,
	  cli_cmd_flag_none,
	  "= IEEE 802.1X EAPOL state machine logoff" },
	{ "pmksa", wpa_cli_cmd_pmksa, NULL,
	  cli_cmd_flag_none,
	  "= show PMKSA cache" },
	{ "pmksa_flush", wpa_cli_cmd_pmksa_flush, NULL,
	  cli_cmd_flag_none,
	  "= flush PMKSA cache entries" },
	{ "reassociate", wpa_cli_cmd_reassociate, NULL,
	  cli_cmd_flag_none,
	  "= force reassociation" },
	{ "reattach", wpa_cli_cmd_reattach, NULL,
	  cli_cmd_flag_none,
	  "= force reassociation back to the same BSS" },
	{ "preauthenticate", wpa_cli_cmd_preauthenticate, wpa_cli_complete_bss,
	  cli_cmd_flag_none,
	  "<BSSID> = force preauthentication" },
	{ "identity", wpa_cli_cmd_identity, NULL,
	  cli_cmd_flag_none,
	  "<network id> <identity> = configure identity for an SSID" },
	{ "password", wpa_cli_cmd_password, NULL,
	  cli_cmd_flag_sensitive,
	  "<network id> <password> = configure password for an SSID" },
	{ "new_password", wpa_cli_cmd_new_password, NULL,
	  cli_cmd_flag_sensitive,
	  "<network id> <password> = change password for an SSID" },
	{ "pin", wpa_cli_cmd_pin, NULL,
	  cli_cmd_flag_sensitive,
	  "<network id> <pin> = configure pin for an SSID" },
	{ "otp", wpa_cli_cmd_otp, NULL,
	  cli_cmd_flag_sensitive,
	  "<network id> <password> = configure one-time-password for an SSID"
	},
	{ "passphrase", wpa_cli_cmd_passphrase, NULL,
	  cli_cmd_flag_sensitive,
	  "<network id> <passphrase> = configure private key passphrase\n"
	  "  for an SSID" },
	{ "sim", wpa_cli_cmd_sim, NULL,
	  cli_cmd_flag_sensitive,
	  "<network id> <pin> = report SIM operation result" },
	{ "bssid", wpa_cli_cmd_bssid, NULL,
	  cli_cmd_flag_none,
	  "<network id> <BSSID> = set preferred BSSID for an SSID" },
	{ "blacklist", wpa_cli_cmd_blacklist, wpa_cli_complete_bss,
	  cli_cmd_flag_none,
	  "<BSSID> = add a BSSID to the blacklist\n"
	  "blacklist clear = clear the blacklist\n"
	  "blacklist = display the blacklist" },
	{ "log_level", wpa_cli_cmd_log_level, NULL,
	  cli_cmd_flag_none,
	  "<level> [<timestamp>] = update the log level/timestamp\n"
	  "log_level = display the current log level and log options" },
	{ "list_networks", wpa_cli_cmd_list_networks, NULL,
	  cli_cmd_flag_none,
	  "= list configured networks" },
	{ "select_network", wpa_cli_cmd_select_network,
	  wpa_cli_complete_network_id,
	  cli_cmd_flag_none,
	  "<network id> = select a network (disable others)" },
	{ "enable_network", wpa_cli_cmd_enable_network,
	  wpa_cli_complete_network_id,
	  cli_cmd_flag_none,
	  "<network id> = enable a network" },
	{ "disable_network", wpa_cli_cmd_disable_network,
	  wpa_cli_complete_network_id,
	  cli_cmd_flag_none,
	  "<network id> = disable a network" },
	{ "add_network", wpa_cli_cmd_add_network, NULL,
	  cli_cmd_flag_none,
	  "= add a network" },
	{ "remove_network", wpa_cli_cmd_remove_network,
	  wpa_cli_complete_network_id,
	  cli_cmd_flag_none,
	  "<network id> = remove a network" },
	{ "set_network", wpa_cli_cmd_set_network, wpa_cli_complete_network,
	  cli_cmd_flag_sensitive,
	  "<network id> <variable> <value> = set network variables (shows\n"
	  "  list of variables when run without arguments)" },
	{ "get_network", wpa_cli_cmd_get_network, wpa_cli_complete_network,
	  cli_cmd_flag_none,
	  "<network id> <variable> = get network variables" },
	{ "dup_network", wpa_cli_cmd_dup_network, wpa_cli_complete_dup_network,
	  cli_cmd_flag_none,
	  "<src network id> <dst network id> <variable> = duplicate network variables"
	},
	{ "list_creds", wpa_cli_cmd_list_creds, NULL,
	  cli_cmd_flag_none,
	  "= list configured credentials" },
	{ "add_cred", wpa_cli_cmd_add_cred, NULL,
	  cli_cmd_flag_none,
	  "= add a credential" },
	{ "remove_cred", wpa_cli_cmd_remove_cred, NULL,
	  cli_cmd_flag_none,
	  "<cred id> = remove a credential" },
	{ "set_cred", wpa_cli_cmd_set_cred, NULL,
	  cli_cmd_flag_sensitive,
	  "<cred id> <variable> <value> = set credential variables" },
	{ "get_cred", wpa_cli_cmd_get_cred, NULL,
	  cli_cmd_flag_none,
	  "<cred id> <variable> = get credential variables" },
	{ "save_config", wpa_cli_cmd_save_config, NULL,
	  cli_cmd_flag_none,
	  "= save the current configuration" },
	{ "disconnect", wpa_cli_cmd_disconnect, NULL,
	  cli_cmd_flag_none,
	  "= disconnect and wait for reassociate/reconnect command before\n"
	  "  connecting" },
	{ "reconnect", wpa_cli_cmd_reconnect, NULL,
	  cli_cmd_flag_none,
	  "= like reassociate, but only takes effect if already disconnected"
	},
	{ "scan", wpa_cli_cmd_scan, NULL,
	  cli_cmd_flag_none,
	  "= request new BSS scan" },
	{ "scan_results", wpa_cli_cmd_scan_results, NULL,
	  cli_cmd_flag_none,
	  "= get latest scan results" },
	{ "bss", wpa_cli_cmd_bss, wpa_cli_complete_bss,
	  cli_cmd_flag_none,
	  "<<idx> | <bssid>> = get detailed scan result info" },
	{ "get_capability", wpa_cli_cmd_get_capability, NULL,
	  cli_cmd_flag_none,
	  "<eap/pairwise/group/key_mgmt/proto/auth_alg/channels/freq/modes> "
	  "= get capabilities" },
	{ "reconfigure", wpa_cli_cmd_reconfigure, NULL,
	  cli_cmd_flag_none,
	  "= force wpa_supplicant to re-read its configuration file" },
	{ "terminate", wpa_cli_cmd_terminate, NULL,
	  cli_cmd_flag_none,
	  "= terminate wpa_supplicant" },
	{ "interface_add", wpa_cli_cmd_interface_add, NULL,
	  cli_cmd_flag_none,
	  "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
	  "  <bridge_name> = adds new interface, all parameters but <ifname>\n"
	  "  are optional" },
	{ "interface_remove", wpa_cli_cmd_interface_remove, NULL,
	  cli_cmd_flag_none,
	  "<ifname> = removes the interface" },
	{ "interface_list", wpa_cli_cmd_interface_list, NULL,
	  cli_cmd_flag_none,
	  "= list available interfaces" },
	{ "ap_scan", wpa_cli_cmd_ap_scan, NULL,
	  cli_cmd_flag_none,
	  "<value> = set ap_scan parameter" },
	{ "scan_interval", wpa_cli_cmd_scan_interval, NULL,
	  cli_cmd_flag_none,
	  "<value> = set scan_interval parameter (in seconds)" },
	{ "bss_expire_age", wpa_cli_cmd_bss_expire_age, NULL,
	  cli_cmd_flag_none,
	  "<value> = set BSS expiration age parameter" },
	{ "bss_expire_count", wpa_cli_cmd_bss_expire_count, NULL,
	  cli_cmd_flag_none,
	  "<value> = set BSS expiration scan count parameter" },
	{ "bss_flush", wpa_cli_cmd_bss_flush, NULL,
	  cli_cmd_flag_none,
	  "<value> = set BSS flush age (0 by default)" },
	{ "stkstart", wpa_cli_cmd_stkstart, NULL,
	  cli_cmd_flag_none,
	  "<addr> = request STK negotiation with <addr>" },
	{ "ft_ds", wpa_cli_cmd_ft_ds, wpa_cli_complete_bss,
	  cli_cmd_flag_none,
	  "<addr> = request over-the-DS FT with <addr>" },
	{ "wps_pbc", wpa_cli_cmd_wps_pbc, wpa_cli_complete_bss,
	  cli_cmd_flag_none,
	  "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
	{ "wps_pin", wpa_cli_cmd_wps_pin, wpa_cli_complete_bss,
	  cli_cmd_flag_sensitive,
	  "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
	  "hardcoded)" },
	{ "wps_check_pin", wpa_cli_cmd_wps_check_pin, NULL,
	  cli_cmd_flag_sensitive,
	  "<PIN> = verify PIN checksum" },
	{ "wps_cancel", wpa_cli_cmd_wps_cancel, NULL, cli_cmd_flag_none,
	  "Cancels the pending WPS operation" },
#ifdef CONFIG_WPS_NFC
	{ "wps_nfc", wpa_cli_cmd_wps_nfc, wpa_cli_complete_bss,
	  cli_cmd_flag_none,
	  "[BSSID] = start Wi-Fi Protected Setup: NFC" },
	{ "wps_nfc_config_token", wpa_cli_cmd_wps_nfc_config_token, NULL,
	  cli_cmd_flag_none,
	  "<WPS|NDEF> = build configuration token" },
	{ "wps_nfc_token", wpa_cli_cmd_wps_nfc_token, NULL,
	  cli_cmd_flag_none,
	  "<WPS|NDEF> = create password token" },
	{ "wps_nfc_tag_read", wpa_cli_cmd_wps_nfc_tag_read, NULL,
	  cli_cmd_flag_sensitive,
	  "<hexdump of payload> = report read NFC tag with WPS data" },
	{ "nfc_get_handover_req", wpa_cli_cmd_nfc_get_handover_req, NULL,
	  cli_cmd_flag_none,
	  "<NDEF> <WPS> = create NFC handover request" },
	{ "nfc_get_handover_sel", wpa_cli_cmd_nfc_get_handover_sel, NULL,
	  cli_cmd_flag_none,
	  "<NDEF> <WPS> = create NFC handover select" },
	{ "nfc_report_handover", wpa_cli_cmd_nfc_report_handover, NULL,
	  cli_cmd_flag_none,
	  "<role> <type> <hexdump of req> <hexdump of sel> = report completed "
	  "NFC handover" },
#endif /* CONFIG_WPS_NFC */
	{ "wps_reg", wpa_cli_cmd_wps_reg, wpa_cli_complete_bss,
	  cli_cmd_flag_sensitive,
	  "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
	{ "wps_ap_pin", wpa_cli_cmd_wps_ap_pin, NULL,
	  cli_cmd_flag_sensitive,
	  "[params..] = enable/disable AP PIN" },
	{ "wps_er_start", wpa_cli_cmd_wps_er_start, NULL,
	  cli_cmd_flag_none,
	  "[IP address] = start Wi-Fi Protected Setup External Registrar" },
	{ "wps_er_stop", wpa_cli_cmd_wps_er_stop, NULL,
	  cli_cmd_flag_none,
	  "= stop Wi-Fi Protected Setup External Registrar" },
	{ "wps_er_pin", wpa_cli_cmd_wps_er_pin, NULL,
	  cli_cmd_flag_sensitive,
	  "<UUID> <PIN> = add an Enrollee PIN to External Registrar" },
	{ "wps_er_pbc", wpa_cli_cmd_wps_er_pbc, NULL,
	  cli_cmd_flag_none,
	  "<UUID> = accept an Enrollee PBC using External Registrar" },
	{ "wps_er_learn", wpa_cli_cmd_wps_er_learn, NULL,
	  cli_cmd_flag_sensitive,
	  "<UUID> <PIN> = learn AP configuration" },
	{ "wps_er_set_config", wpa_cli_cmd_wps_er_set_config, NULL,
	  cli_cmd_flag_none,
	  "<UUID> <network id> = set AP configuration for enrolling" },
	{ "wps_er_config", wpa_cli_cmd_wps_er_config, NULL,
	  cli_cmd_flag_sensitive,
	  "<UUID> <PIN> <SSID> <auth> <encr> <key> = configure AP" },
#ifdef CONFIG_WPS_NFC
	{ "wps_er_nfc_config_token", wpa_cli_cmd_wps_er_nfc_config_token, NULL,
	  cli_cmd_flag_none,
	  "<WPS/NDEF> <UUID> = build NFC configuration token" },
#endif /* CONFIG_WPS_NFC */
	{ "ibss_rsn", wpa_cli_cmd_ibss_rsn, NULL,
	  cli_cmd_flag_none,
	  "<addr> = request RSN authentication with <addr> in IBSS" },
#ifdef CONFIG_AP
	{ "sta", wpa_cli_cmd_sta, NULL,
	  cli_cmd_flag_none,
	  "<addr> = get information about an associated station (AP)" },
	{ "all_sta", wpa_cli_cmd_all_sta, NULL,
	  cli_cmd_flag_none,
	  "= get information about all associated stations (AP)" },
	{ "deauthenticate", wpa_cli_cmd_deauthenticate, NULL,
	  cli_cmd_flag_none,
	  "<addr> = deauthenticate a station" },
	{ "disassociate", wpa_cli_cmd_disassociate, NULL,
	  cli_cmd_flag_none,
	  "<addr> = disassociate a station" },
	{ "chan_switch", wpa_cli_cmd_chanswitch, NULL,
	  cli_cmd_flag_none,
	  "<cs_count> <freq> [sec_channel_offset=] [center_freq1=]"
	  " [center_freq2=] [bandwidth=] [blocktx] [ht|vht]"
	  " = CSA parameters" },
#endif /* CONFIG_AP */
	{ "suspend", wpa_cli_cmd_suspend, NULL, cli_cmd_flag_none,
	  "= notification of suspend/hibernate" },
	{ "resume", wpa_cli_cmd_resume, NULL, cli_cmd_flag_none,
	  "= notification of resume/thaw" },
#ifdef CONFIG_TESTING_OPTIONS
	{ "drop_sa", wpa_cli_cmd_drop_sa, NULL, cli_cmd_flag_none,
	  "= drop SA without deauth/disassoc (test command)" },
#endif /* CONFIG_TESTING_OPTIONS */
	{ "roam", wpa_cli_cmd_roam, wpa_cli_complete_bss,
	  cli_cmd_flag_none,
	  "<addr> = roam to the specified BSS" },
#ifdef CONFIG_MESH
	{ "mesh_interface_add", wpa_cli_cmd_mesh_interface_add, NULL,
	  cli_cmd_flag_none,
	  "[ifname] = Create a new mesh interface" },
	{ "mesh_group_add", wpa_cli_cmd_mesh_group_add, NULL,
	  cli_cmd_flag_none,
	  "<network id> = join a mesh network (disable others)" },
	{ "mesh_group_remove", wpa_cli_cmd_mesh_group_remove, NULL,
	  cli_cmd_flag_none,
	  "<ifname> = Remove mesh group interface" },
#endif /* CONFIG_MESH */
#ifdef CONFIG_P2P
	{ "p2p_find", wpa_cli_cmd_p2p_find, wpa_cli_complete_p2p_find,
	  cli_cmd_flag_none,
	  "[timeout] [type=*] = find P2P Devices for up-to timeout seconds" },
	{ "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, NULL, cli_cmd_flag_none,
	  "= stop P2P Devices search" },
	{ "p2p_asp_provision", wpa_cli_cmd_p2p_asp_provision, NULL,
	  cli_cmd_flag_none,
	  "<addr> adv_id=<adv_id> conncap=<conncap> [info=<infodata>] = provision with a P2P ASP Device" },
	{ "p2p_asp_provision_resp", wpa_cli_cmd_p2p_asp_provision_resp, NULL,
	  cli_cmd_flag_none,
	  "<addr> adv_id=<adv_id> [role<conncap>] [info=<infodata>] = provision with a P2P ASP Device" },
	{ "p2p_connect", wpa_cli_cmd_p2p_connect, wpa_cli_complete_p2p_connect,
	  cli_cmd_flag_none,
	  "<addr> <\"pbc\"|PIN> [ht40] = connect to a P2P Device" },
	{ "p2p_listen", wpa_cli_cmd_p2p_listen, NULL, cli_cmd_flag_none,
	  "[timeout] = listen for P2P Devices for up-to timeout seconds" },
	{ "p2p_group_remove", wpa_cli_cmd_p2p_group_remove,
	  wpa_cli_complete_p2p_group_remove, cli_cmd_flag_none,
	  "<ifname> = remove P2P group interface (terminate group if GO)" },
	{ "p2p_group_add", wpa_cli_cmd_p2p_group_add, NULL, cli_cmd_flag_none,
	  "[ht40] = add a new P2P group (local end as GO)" },
	{ "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc,
	  wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
	  "<addr> <method> = request provisioning discovery" },
	{ "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase, NULL,
	  cli_cmd_flag_none,
	  "= get the passphrase for a group (GO only)" },
	{ "p2p_serv_disc_req", wpa_cli_cmd_p2p_serv_disc_req,
	  wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
	  "<addr> <TLVs> = schedule service discovery request" },
	{ "p2p_serv_disc_cancel_req", wpa_cli_cmd_p2p_serv_disc_cancel_req,
	  NULL, cli_cmd_flag_none,
	  "<id> = cancel pending service discovery request" },
	{ "p2p_serv_disc_resp", wpa_cli_cmd_p2p_serv_disc_resp, NULL,
	  cli_cmd_flag_none,
	  "<freq> <addr> <dialog token> <TLVs> = service discovery response" },
	{ "p2p_service_update", wpa_cli_cmd_p2p_service_update, NULL,
	  cli_cmd_flag_none,
	  "= indicate change in local services" },
	{ "p2p_serv_disc_external", wpa_cli_cmd_p2p_serv_disc_external, NULL,
	  cli_cmd_flag_none,
	  "<external> = set external processing of service discovery" },
	{ "p2p_service_flush", wpa_cli_cmd_p2p_service_flush, NULL,
	  cli_cmd_flag_none,
	  "= remove all stored service entries" },
	{ "p2p_service_add", wpa_cli_cmd_p2p_service_add, NULL,
	  cli_cmd_flag_none,
	  "<bonjour|upnp|asp> <query|version> <response|service> = add a local "
	  "service" },
	{ "p2p_service_rep", wpa_cli_cmd_p2p_service_rep, NULL,
	  cli_cmd_flag_none,
	  "asp <auto> <adv_id> <svc_state> <svc_string> [<svc_info>] = replace "
	  "local ASP service" },
	{ "p2p_service_del", wpa_cli_cmd_p2p_service_del, NULL,
	  cli_cmd_flag_none,
	  "<bonjour|upnp> <query|version> [|service] = remove a local "
	  "service" },
	{ "p2p_reject", wpa_cli_cmd_p2p_reject, wpa_cli_complete_p2p_peer,
	  cli_cmd_flag_none,
	  "<addr> = reject connection attempts from a specific peer" },
	{ "p2p_invite", wpa_cli_cmd_p2p_invite, NULL,
	  cli_cmd_flag_none,
	  "<cmd> [peer=addr] = invite peer" },
	{ "p2p_peers", wpa_cli_cmd_p2p_peers, NULL, cli_cmd_flag_none,
	  "[discovered] = list known (optionally, only fully discovered) P2P "
	  "peers" },
	{ "p2p_peer", wpa_cli_cmd_p2p_peer, wpa_cli_complete_p2p_peer,
	  cli_cmd_flag_none,
	  "<address> = show information about known P2P peer" },
	{ "p2p_set", wpa_cli_cmd_p2p_set, wpa_cli_complete_p2p_set,
	  cli_cmd_flag_none,
	  "<field> <value> = set a P2P parameter" },
	{ "p2p_flush", wpa_cli_cmd_p2p_flush, NULL, cli_cmd_flag_none,
	  "= flush P2P state" },
	{ "p2p_cancel", wpa_cli_cmd_p2p_cancel, NULL, cli_cmd_flag_none,
	  "= cancel P2P group formation" },
	{ "p2p_unauthorize", wpa_cli_cmd_p2p_unauthorize,
	  wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
	  "<address> = unauthorize a peer" },
	{ "p2p_presence_req", wpa_cli_cmd_p2p_presence_req, NULL,
	  cli_cmd_flag_none,
	  "[<duration> <interval>] [<duration> <interval>] = request GO "
	  "presence" },
	{ "p2p_ext_listen", wpa_cli_cmd_p2p_ext_listen, NULL,
	  cli_cmd_flag_none,
	  "[<period> <interval>] = set extended listen timing" },
	{ "p2p_remove_client", wpa_cli_cmd_p2p_remove_client,
	  wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
	  "<address|iface=address> = remove a peer from all groups" },
#endif /* CONFIG_P2P */
#ifdef CONFIG_WIFI_DISPLAY
	{ "wfd_subelem_set", wpa_cli_cmd_wfd_subelem_set, NULL,
	  cli_cmd_flag_none,
	  "<subelem> [contents] = set Wi-Fi Display subelement" },
	{ "wfd_subelem_get", wpa_cli_cmd_wfd_subelem_get, NULL,
	  cli_cmd_flag_none,
	  "<subelem> = get Wi-Fi Display subelement" },
#endif /* CONFIG_WIFI_DISPLAY */
#ifdef CONFIG_INTERWORKING
	{ "fetch_anqp", wpa_cli_cmd_fetch_anqp, NULL, cli_cmd_flag_none,
	  "= fetch ANQP information for all APs" },
	{ "stop_fetch_anqp", wpa_cli_cmd_stop_fetch_anqp, NULL,
	  cli_cmd_flag_none,
	  "= stop fetch_anqp operation" },
	{ "interworking_select", wpa_cli_cmd_interworking_select, NULL,
	  cli_cmd_flag_none,
	  "[auto] = perform Interworking network selection" },
	{ "interworking_connect", wpa_cli_cmd_interworking_connect,
	  wpa_cli_complete_bss, cli_cmd_flag_none,
	  "<BSSID> = connect using Interworking credentials" },
	{ "interworking_add_network", wpa_cli_cmd_interworking_add_network,
	  wpa_cli_complete_bss, cli_cmd_flag_none,
	  "<BSSID> = connect using Interworking credentials" },
	{ "anqp_get", wpa_cli_cmd_anqp_get, wpa_cli_complete_bss,
	  cli_cmd_flag_none,
	  "<addr> <info id>[,<info id>]... = request ANQP information" },
	{ "gas_request", wpa_cli_cmd_gas_request, wpa_cli_complete_bss,
	  cli_cmd_flag_none,
	  "<addr> <AdvProtoID> [QueryReq] = GAS request" },
	{ "gas_response_get", wpa_cli_cmd_gas_response_get,
	  wpa_cli_complete_bss, cli_cmd_flag_none,
	  "<addr> <dialog token> [start,len] = Fetch last GAS response" },
#endif /* CONFIG_INTERWORKING */
#ifdef CONFIG_HS20
	{ "hs20_anqp_get", wpa_cli_cmd_hs20_anqp_get, wpa_cli_complete_bss,
	  cli_cmd_flag_none,
	  "<addr> <subtype>[,<subtype>]... = request HS 2.0 ANQP information"
	},
	{ "nai_home_realm_list", wpa_cli_cmd_get_nai_home_realm_list,
	  wpa_cli_complete_bss, cli_cmd_flag_none,
	  "<addr> <home realm> = get HS20 nai home realm list" },
	{ "hs20_icon_request", wpa_cli_cmd_hs20_icon_request,
	  wpa_cli_complete_bss, cli_cmd_flag_none,
	  "<addr> <icon name> = get Hotspot 2.0 OSU icon" },
	{ "fetch_osu", wpa_cli_cmd_fetch_osu, NULL, cli_cmd_flag_none,
	  "= fetch OSU provider information from all APs" },
	{ "cancel_fetch_osu", wpa_cli_cmd_cancel_fetch_osu, NULL,
	  cli_cmd_flag_none,
	  "= cancel fetch_osu command" },
#endif /* CONFIG_HS20 */
	{ "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, NULL,
	  cli_cmd_flag_none,
	  "<0/1> = disable/enable automatic reconnection" },
	{ "tdls_discover", wpa_cli_cmd_tdls_discover, NULL,
	  cli_cmd_flag_none,
	  "<addr> = request TDLS discovery with <addr>" },
	{ "tdls_setup", wpa_cli_cmd_tdls_setup, NULL,
	  cli_cmd_flag_none,
	  "<addr> = request TDLS setup with <addr>" },
	{ "tdls_teardown", wpa_cli_cmd_tdls_teardown, NULL,
	  cli_cmd_flag_none,
	  "<addr> = tear down TDLS with <addr>" },
	{ "tdls_link_status", wpa_cli_cmd_tdls_link_status, NULL,
	  cli_cmd_flag_none,
	  "<addr> = TDLS link status with <addr>" },
	{ "wmm_ac_addts", wpa_cli_cmd_wmm_ac_addts, NULL,
	  cli_cmd_flag_none,
	  "<uplink/downlink/bidi> <tsid=0..7> <up=0..7> [nominal_msdu_size=#] "
	  "[mean_data_rate=#] [min_phy_rate=#] [sba=#] [fixed_nominal_msdu] "
	  "= add WMM-AC traffic stream" },
	{ "wmm_ac_delts", wpa_cli_cmd_wmm_ac_delts, NULL,
	  cli_cmd_flag_none,
	  "<tsid> = delete WMM-AC traffic stream" },
	{ "wmm_ac_status", wpa_cli_cmd_wmm_ac_status, NULL,
	  cli_cmd_flag_none,
	  "= show status for Wireless Multi-Media Admission-Control" },
	{ "tdls_chan_switch", wpa_cli_cmd_tdls_chan_switch, NULL,
	  cli_cmd_flag_none,
	  "<addr> <oper class> <freq> [sec_channel_offset=] [center_freq1=] "
	  "[center_freq2=] [bandwidth=] [ht|vht] = enable channel switching "
	  "with TDLS peer" },
	{ "tdls_cancel_chan_switch", wpa_cli_cmd_tdls_cancel_chan_switch, NULL,
	  cli_cmd_flag_none,
	  "<addr> = disable channel switching with TDLS peer <addr>" },
	{ "signal_poll", wpa_cli_cmd_signal_poll, NULL,
	  cli_cmd_flag_none,
	  "= get signal parameters" },
	{ "pktcnt_poll", wpa_cli_cmd_pktcnt_poll, NULL,
	  cli_cmd_flag_none,
	  "= get TX/RX packet counters" },
	{ "reauthenticate", wpa_cli_cmd_reauthenticate, NULL,
	  cli_cmd_flag_none,
	  "= trigger IEEE 802.1X/EAPOL reauthentication" },
#ifdef CONFIG_AUTOSCAN
	{ "autoscan", wpa_cli_cmd_autoscan, NULL, cli_cmd_flag_none,
	  "[params] = Set or unset (if none) autoscan parameters" },
#endif /* CONFIG_AUTOSCAN */
#ifdef CONFIG_WNM
	{ "wnm_sleep", wpa_cli_cmd_wnm_sleep, NULL, cli_cmd_flag_none,
	  "<enter/exit> [interval=#] = enter/exit WNM-Sleep mode" },
	{ "wnm_bss_query", wpa_cli_cmd_wnm_bss_query, NULL, cli_cmd_flag_none,
	  "<query reason> = Send BSS Transition Management Query" },
#endif /* CONFIG_WNM */
	{ "raw", wpa_cli_cmd_raw, NULL, cli_cmd_flag_sensitive,
	  "<params..> = Sent unprocessed command" },
	{ "flush", wpa_cli_cmd_flush, NULL, cli_cmd_flag_none,
	  "= flush wpa_supplicant state" },
#ifdef ANDROID
	{ "driver", wpa_cli_cmd_driver, NULL, cli_cmd_flag_none,
	  "<command> = driver private commands" },
#endif /* ANDROID */
	{ "radio_work", wpa_cli_cmd_radio_work, NULL, cli_cmd_flag_none,
	  "= radio_work <show/add/done>" },
	{ "vendor", wpa_cli_cmd_vendor, NULL, cli_cmd_flag_none,
	  "<vendor id> <command id> [<hex formatted command argument>] = Send vendor command"
	},
	{ "neighbor_rep_request",
	  wpa_cli_cmd_neighbor_rep_request, NULL, cli_cmd_flag_none,
	  "[ssid=<SSID>] = Trigger request to AP for neighboring AP report "
	  "(with optional given SSID, default: current SSID)"
	},
	{ "erp_flush", wpa_cli_cmd_erp_flush, NULL, cli_cmd_flag_none,
	  "= flush ERP keys" },
	{ "mac_rand_scan",
	  wpa_cli_cmd_mac_rand_scan, NULL, cli_cmd_flag_none,
	  "<scan|sched|pno|all> enable=<0/1> [addr=mac-address "
	  "mask=mac-address-mask] = scan MAC randomization"
	},
	{ NULL, NULL, NULL, cli_cmd_flag_none, NULL }
};

用户输入命令之后就是从这个列表中查找对应的函数的。
这里面以status命令为例看一下

static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
{
	if (argc > 0 && os_strcmp(argv[0], "verbose") == 0)
		return wpa_ctrl_command(ctrl, "STATUS-VERBOSE");
	if (argc > 0 && os_strcmp(argv[0], "wps") == 0)
		return wpa_ctrl_command(ctrl, "STATUS-WPS");
	if (argc > 0 && os_strcmp(argv[0], "driver") == 0)
		return wpa_ctrl_command(ctrl, "STATUS-DRIVER");
	return wpa_ctrl_command(ctrl, "STATUS");
}

最终会调用到

int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd, size_t cmd_len,
		     char *reply, size_t *reply_len,
		     void (*msg_cb)(char *msg, size_t len))
{
	DWORD written;
	DWORD readlen = *reply_len;

	if (!WriteFile(ctrl->pipe, cmd, cmd_len, &written, NULL))
		return -1;

	if (!ReadFile(ctrl->pipe, reply, *reply_len, &readlen, NULL))
		return -1;
	*reply_len = readlen;

	return 0;
}

就是把命令写入到已经与supplicant连接上的socket里面。

以上就是Wpa_cli的流程分析。
通过上述的分析,能够理解上层应用是如何与supplicant建立起连接的,以及命令是如何发送个supplicant的。

Android 中的wifi.c中也是与wpa_supplicant建立socket,之后将命令发送给wpa_supplicant的。

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值