12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811 |
- /*
- * WPA Supplicant - command line interface for wpa_supplicant daemon
- * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
- */
- #include "includes.h"
- #ifdef CONFIG_CTRL_IFACE
- #ifdef CONFIG_CTRL_IFACE_UNIX
- #include <dirent.h>
- #endif /* CONFIG_CTRL_IFACE_UNIX */
- #ifdef CONFIG_READLINE
- #include <readline/readline.h>
- #include <readline/history.h>
- #endif /* CONFIG_READLINE */
- #include "wpa_ctrl.h"
- #include "common.h"
- #include "version.h"
- static const char *wpa_cli_version =
- "wpa_cli v" VERSION_STR "\n"
- "Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi> and contributors";
- static const char *wpa_cli_license =
- "This program is free software. You can distribute it and/or modify it\n"
- "under the terms of the GNU General Public License version 2.\n"
- "\n"
- "Alternatively, this software may be distributed under the terms of the\n"
- "BSD license. See README and COPYING for more details.\n";
- static const char *wpa_cli_full_license =
- "This program is free software; you can redistribute it and/or modify\n"
- "it under the terms of the GNU General Public License version 2 as\n"
- "published by the Free Software Foundation.\n"
- "\n"
- "This program is distributed in the hope that it will be useful,\n"
- "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
- "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
- "GNU General Public License for more details.\n"
- "\n"
- "You should have received a copy of the GNU General Public License\n"
- "along with this program; if not, write to the Free Software\n"
- "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n"
- "\n"
- "Alternatively, this software may be distributed under the terms of the\n"
- "BSD license.\n"
- "\n"
- "Redistribution and use in source and binary forms, with or without\n"
- "modification, are permitted provided that the following conditions are\n"
- "met:\n"
- "\n"
- "1. Redistributions of source code must retain the above copyright\n"
- " notice, this list of conditions and the following disclaimer.\n"
- "\n"
- "2. Redistributions in binary form must reproduce the above copyright\n"
- " notice, this list of conditions and the following disclaimer in the\n"
- " documentation and/or other materials provided with the distribution.\n"
- "\n"
- "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
- " names of its contributors may be used to endorse or promote products\n"
- " derived from this software without specific prior written permission.\n"
- "\n"
- "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
- "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
- "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
- "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
- "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
- "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
- "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
- "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
- "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
- "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
- "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
- "\n";
- static const char *commands_help =
- "commands:\n"
- " status [verbose] = get current WPA/EAPOL/EAP status\n"
- " mib = get MIB variables (dot1x, dot11)\n"
- " help = show this usage help\n"
- " interface [ifname] = show interfaces/select interface\n"
- " level <debug level> = change debug level\n"
- " license = show full wpa_cli license\n"
- " logoff = IEEE 802.1X EAPOL state machine logoff\n"
- " logon = IEEE 802.1X EAPOL state machine logon\n"
- " set = set variables (shows list of variables when run without arguments)\n"
- " pmksa = show PMKSA cache\n"
- " reassociate = force reassociation\n"
- " reconfigure = force wpa_supplicant to re-read its configuration file\n"
- " preauthenticate <BSSID> = force preauthentication\n"
- " identity <network id> <identity> = configure identity for an SSID\n"
- " password <network id> <password> = configure password for an SSID\n"
- " new_password <network id> <password> = change password for an SSID\n"
- " pin <network id> <pin> = configure pin for an SSID\n"
- " otp <network id> <password> = configure one-time-password for an SSID\n"
- " passphrase <network id> <passphrase> = configure private key passphrase\n"
- " for an SSID\n"
- " bssid <network id> <BSSID> = set preferred BSSID for an SSID\n"
- " list_networks = list configured networks\n"
- " select_network <network id> = select a network (disable others)\n"
- " enable_network <network id> = enable a network\n"
- " disable_network <network id> = disable a network\n"
- " add_network = add a network\n"
- " remove_network <network id> = remove a network\n"
- " set_network <network id> <variable> <value> = set network variables "
- "(shows\n"
- " list of variables when run without arguments)\n"
- " get_network <network id> <variable> = get network variables\n"
- " save_config = save the current configuration\n"
- " disconnect = disconnect and wait for reassociate/reconnect command before\n "
- " connecting\n"
- " reconnect = like reassociate, but only takes effect if already "
- "disconnected\n"
- " scan = request new BSS scan\n"
- " scan_results = get latest scan results\n"
- " bss <<idx> | <bssid>> = get detailed scan result info\n"
- " get_capability <eap/pairwise/group/key_mgmt/proto/auth_alg> = "
- "get capabilies\n"
- " ap_scan <value> = set ap_scan parameter\n"
- " stkstart <addr> = request STK negotiation with <addr>\n"
- " ft_ds <addr> = request over-the-DS FT with <addr>\n"
- " wps_pbc [BSSID] = start Wi-Fi Protected Setup: Push Button Configuration\n"
- " wps_pin <BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
- "hardcoded)\n"
- " wps_reg <BSSID> <AP PIN> = start WPS Registrar to configure an AP\n"
- " terminate = terminate wpa_supplicant\n"
- " quit = exit wpa_cli\n";
- static struct wpa_ctrl *ctrl_conn;
- static int wpa_cli_quit = 0;
- static int wpa_cli_attached = 0;
- static int wpa_cli_connected = 0;
- static int wpa_cli_last_id = 0;
- static const char *ctrl_iface_dir = "/var/run/wpa_supplicant";
- static char *ctrl_ifname = NULL;
- static const char *pid_file = NULL;
- static const char *action_file = NULL;
- static void usage(void)
- {
- printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
- "[-a<action file>] \\\n"
- " [-P<pid file>] [-g<global ctrl>] [command..]\n"
- " -h = help (show this usage text)\n"
- " -v = shown version information\n"
- " -a = run in daemon mode executing the action file based on "
- "events from\n"
- " wpa_supplicant\n"
- " -B = run a daemon in the background\n"
- " default path: /var/run/wpa_supplicant\n"
- " default interface: first interface found in socket path\n"
- "%s",
- commands_help);
- }
- static struct wpa_ctrl * wpa_cli_open_connection(const char *ifname)
- {
- #if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
- ctrl_conn = wpa_ctrl_open(ifname);
- return ctrl_conn;
- #else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
- char *cfile;
- int flen, res;
- if (ifname == NULL)
- return NULL;
- flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
- cfile = os_malloc(flen);
- if (cfile == NULL)
- return NULL;
- res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ifname);
- if (res < 0 || res >= flen) {
- os_free(cfile);
- return NULL;
- }
- ctrl_conn = wpa_ctrl_open(cfile);
- os_free(cfile);
- return ctrl_conn;
- #endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
- }
- static void wpa_cli_close_connection(void)
- {
- if (ctrl_conn == NULL)
- return;
- if (wpa_cli_attached) {
- wpa_ctrl_detach(ctrl_conn);
- wpa_cli_attached = 0;
- }
- wpa_ctrl_close(ctrl_conn);
- ctrl_conn = NULL;
- }
- static void wpa_cli_msg_cb(char *msg, size_t len)
- {
- printf("%s\n", msg);
- }
- static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
- {
- char buf[2048];
- size_t len;
- int ret;
- if (ctrl_conn == NULL) {
- printf("Not connected to wpa_supplicant - command dropped.\n");
- return -1;
- }
- len = sizeof(buf) - 1;
- ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
- wpa_cli_msg_cb);
- if (ret == -2) {
- printf("'%s' command timed out.\n", cmd);
- return -2;
- } else if (ret < 0) {
- printf("'%s' command failed.\n", cmd);
- return -1;
- }
- if (print) {
- buf[len] = '\0';
- printf("%s", buf);
- }
- return 0;
- }
- static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
- {
- return _wpa_ctrl_command(ctrl, cmd, 1);
- }
- static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
- {
- int verbose = argc > 0 && os_strcmp(argv[0], "verbose") == 0;
- return wpa_ctrl_command(ctrl, verbose ? "STATUS-VERBOSE" : "STATUS");
- }
- static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
- {
- return wpa_ctrl_command(ctrl, "PING");
- }
- static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
- {
- return wpa_ctrl_command(ctrl, "MIB");
- }
- static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
- {
- return wpa_ctrl_command(ctrl, "PMKSA");
- }
- static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
- {
- printf("%s", commands_help);
- return 0;
- }
- static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
- {
- printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
- return 0;
- }
- static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
- {
- wpa_cli_quit = 1;
- return 0;
- }
- static void wpa_cli_show_variables(void)
- {
- printf("set variables:\n"
- " EAPOL::heldPeriod (EAPOL state machine held period, "
- "in seconds)\n"
- " EAPOL::authPeriod (EAPOL state machine authentication "
- "period, in seconds)\n"
- " EAPOL::startPeriod (EAPOL state machine start period, in "
- "seconds)\n"
- " EAPOL::maxStart (EAPOL state machine maximum start "
- "attempts)\n");
- printf(" dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
- "seconds)\n"
- " dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
- " threshold\n\tpercentage)\n"
- " dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
- "security\n\tassociation in seconds)\n");
- }
- static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
- {
- char cmd[256];
- int res;
- if (argc == 0) {
- wpa_cli_show_variables();
- return 0;
- }
- if (argc != 2) {
- printf("Invalid SET command: needs two arguments (variable "
- "name and value)\n");
- return -1;
- }
- res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]);
- if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
- printf("Too long SET command.\n");
- return -1;
- }
- return wpa_ctrl_command(ctrl, cmd);
- }
- static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
- {
- return wpa_ctrl_command(ctrl, "LOGOFF");
- }
- static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
- {
- return wpa_ctrl_command(ctrl, "LOGON");
- }
- static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
- {
- return wpa_ctrl_command(ctrl, "REASSOCIATE");
- }
- static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
- {
- char cmd[256];
- int res;
- if (argc != 1) {
- printf("Invalid PREAUTH command: needs one argument "
- "(BSSID)\n");
- return -1;
- }
- res = os_snprintf(cmd, sizeof(cmd), "PREAUTH %s", argv[0]);
- if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
- printf("Too long PREAUTH command.\n");
- return -1;
- }
- return wpa_ctrl_command(ctrl, cmd);
- }
- static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
- {
- char cmd[256];
- int res;
- if (argc != 1) {
- printf("Invalid AP_SCAN command: needs one argument (ap_scan "
- "value)\n");
- return -1;
- }
- res = os_snprintf(cmd, sizeof(cmd), "AP_SCAN %s", argv[0]);
- if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
- printf("Too long AP_SCAN command.\n");
- return -1;
- }
- return wpa_ctrl_command(ctrl, cmd);
- }
- static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
- {
- char cmd[256];
- int res;
- if (argc != 1) {
- printf("Invalid STKSTART command: needs one argument "
- "(Peer STA MAC address)\n");
- return -1;
- }
- res = os_snprintf(cmd, sizeof(cmd), "STKSTART %s", argv[0]);
- if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
- printf("Too long STKSTART command.\n");
- return -1;
- }
- return wpa_ctrl_command(ctrl, cmd);
- }
- static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
- {
- char cmd[256];
- int res;
- if (argc != 1) {
- printf("Invalid FT_DS command: needs one argument "
- "(Target AP MAC address)\n");
- return -1;
- }
- res = os_snprintf(cmd, sizeof(cmd), "FT_DS %s", argv[0]);
- if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
- printf("Too long FT_DS command.\n");
- return -1;
- }
- return wpa_ctrl_command(ctrl, cmd);
- }
- static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
- {
- char cmd[256];
- int res;
- if (argc == 0) {
- /* Any BSSID */
- return wpa_ctrl_command(ctrl, "WPS_PBC");
- }
- /* Specific BSSID */
- res = os_snprintf(cmd, sizeof(cmd), "WPS_PBC %s", argv[0]);
- if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
- printf("Too long WPS_PBC command.\n");
- return -1;
- }
- return wpa_ctrl_command(ctrl, cmd);
- }
- static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
- {
- char cmd[256];
- int res;
- if (argc == 0) {
- printf("Invalid WPS_PIN command: need one or two arguments:\n"
- "- BSSID: use 'any' to select any\n"
- "- PIN: optional, used only with devices that have no "
- "display\n");
- return -1;
- }
- if (argc == 1) {
- /* Use dynamically generated PIN (returned as reply) */
- res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s", argv[0]);
- if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
- printf("Too long WPS_PIN command.\n");
- return -1;
- }
- return wpa_ctrl_command(ctrl, cmd);
- }
- /* Use hardcoded PIN from a label */
- res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s", argv[0], argv[1]);
- if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
- printf("Too long WPS_PIN command.\n");
- return -1;
- }
- return wpa_ctrl_command(ctrl, cmd);
- }
- static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
- {
- char cmd[256];
- int res;
- if (argc != 2) {
- printf("Invalid WPS_REG command: need two arguments:\n"
- "- BSSID: use 'any' to select any\n"
- "- AP PIN\n");
- return -1;
- }
- res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s", argv[0], argv[1]);
- if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
- printf("Too long WPS_REG command.\n");
- return -1;
- }
- return wpa_ctrl_command(ctrl, cmd);
- }
- static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
- {
- char cmd[256];
- int res;
- if (argc != 1) {
- printf("Invalid LEVEL command: needs one argument (debug "
- "level)\n");
- return -1;
- }
- res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
- if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
- printf("Too long LEVEL command.\n");
- return -1;
- }
- return wpa_ctrl_command(ctrl, cmd);
- }
- static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
- {
- char cmd[256], *pos, *end;
- int i, ret;
- if (argc < 2) {
- printf("Invalid IDENTITY command: needs two arguments "
- "(network id and identity)\n");
- return -1;
- }
- end = cmd + sizeof(cmd);
- pos = cmd;
- ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
- argv[0], argv[1]);
- if (ret < 0 || ret >= end - pos) {
- printf("Too long IDENTITY command.\n");
- return -1;
- }
- pos += ret;
- for (i = 2; i < argc; i++) {
- ret = os_snprintf(pos, end - pos, " %s", argv[i]);
- if (ret < 0 || ret >= end - pos) {
- printf("Too long IDENTITY command.\n");
- return -1;
- }
- pos += ret;
- }
- return wpa_ctrl_command(ctrl, cmd);
- }
- static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
- {
- char cmd[256], *pos, *end;
- int i, ret;
- if (argc < 2) {
- printf("Invalid PASSWORD command: needs two arguments "
- "(network id and password)\n");
- return -1;
- }
- end = cmd + sizeof(cmd);
- pos = cmd;
- ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
- argv[0], argv[1]);
- if (ret < 0 || ret >= end - pos) {
- printf("Too long PASSWORD command.\n");
- return -1;
- }
- pos += ret;
- for (i = 2; i < argc; i++) {
- ret = os_snprintf(pos, end - pos, " %s", argv[i]);
- if (ret < 0 || ret >= end - pos) {
- printf("Too long PASSWORD command.\n");
- return -1;
- }
- pos += ret;
- }
- return wpa_ctrl_command(ctrl, cmd);
- }
- static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
- {
- char cmd[256], *pos, *end;
- int i, ret;
- if (argc < 2) {
- printf("Invalid NEW_PASSWORD command: needs two arguments "
- "(network id and password)\n");
- return -1;
- }
- end = cmd + sizeof(cmd);
- pos = cmd;
- ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
- argv[0], argv[1]);
- if (ret < 0 || ret >= end - pos) {
- printf("Too long NEW_PASSWORD command.\n");
- return -1;
- }
- pos += ret;
- for (i = 2; i < argc; i++) {
- ret = os_snprintf(pos, end - pos, " %s", argv[i]);
- if (ret < 0 || ret >= end - pos) {
- printf("Too long NEW_PASSWORD command.\n");
- return -1;
- }
- pos += ret;
- }
- return wpa_ctrl_command(ctrl, cmd);
- }
- static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
- {
- char cmd[256], *pos, *end;
- int i, ret;
- if (argc < 2) {
- printf("Invalid PIN command: needs two arguments "
- "(network id and pin)\n");
- return -1;
- }
- end = cmd + sizeof(cmd);
- pos = cmd;
- ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
- argv[0], argv[1]);
- if (ret < 0 || ret >= end - pos) {
- printf("Too long PIN command.\n");
- return -1;
- }
- pos += ret;
- for (i = 2; i < argc; i++) {
- ret = os_snprintf(pos, end - pos, " %s", argv[i]);
- if (ret < 0 || ret >= end - pos) {
- printf("Too long PIN command.\n");
- return -1;
- }
- pos += ret;
- }
- return wpa_ctrl_command(ctrl, cmd);
- }
- static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
- {
- char cmd[256], *pos, *end;
- int i, ret;
- if (argc < 2) {
- printf("Invalid OTP command: needs two arguments (network "
- "id and password)\n");
- return -1;
- }
- end = cmd + sizeof(cmd);
- pos = cmd;
- ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
- argv[0], argv[1]);
- if (ret < 0 || ret >= end - pos) {
- printf("Too long OTP command.\n");
- return -1;
- }
- pos += ret;
- for (i = 2; i < argc; i++) {
- ret = os_snprintf(pos, end - pos, " %s", argv[i]);
- if (ret < 0 || ret >= end - pos) {
- printf("Too long OTP command.\n");
- return -1;
- }
- pos += ret;
- }
- return wpa_ctrl_command(ctrl, cmd);
- }
- static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
- {
- char cmd[256], *pos, *end;
- int i, ret;
- if (argc < 2) {
- printf("Invalid PASSPHRASE command: needs two arguments "
- "(network id and passphrase)\n");
- return -1;
- }
- end = cmd + sizeof(cmd);
- pos = cmd;
- ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
- argv[0], argv[1]);
- if (ret < 0 || ret >= end - pos) {
- printf("Too long PASSPHRASE command.\n");
- return -1;
- }
- pos += ret;
- for (i = 2; i < argc; i++) {
- ret = os_snprintf(pos, end - pos, " %s", argv[i]);
- if (ret < 0 || ret >= end - pos) {
- printf("Too long PASSPHRASE command.\n");
- return -1;
- }
- pos += ret;
- }
- return wpa_ctrl_command(ctrl, cmd);
- }
- static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
- {
- char cmd[256], *pos, *end;
- int i, ret;
- if (argc < 2) {
- printf("Invalid BSSID command: needs two arguments (network "
- "id and BSSID)\n");
- return -1;
- }
- end = cmd + sizeof(cmd);
- pos = cmd;
- ret = os_snprintf(pos, end - pos, "BSSID");
- if (ret < 0 || ret >= end - pos) {
- printf("Too long BSSID command.\n");
- return -1;
- }
- pos += ret;
- for (i = 0; i < argc; i++) {
- ret = os_snprintf(pos, end - pos, " %s", argv[i]);
- if (ret < 0 || ret >= end - pos) {
- printf("Too long BSSID command.\n");
- return -1;
- }
- pos += ret;
- }
- return wpa_ctrl_command(ctrl, cmd);
- }
- static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
- {
- return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
- }
- static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
- {
- char cmd[32];
- int res;
- if (argc < 1) {
- printf("Invalid SELECT_NETWORK command: needs one argument "
- "(network id)\n");
- return -1;
- }
- res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
- if (res < 0 || (size_t) res >= sizeof(cmd))
- return -1;
- cmd[sizeof(cmd) - 1] = '\0';
- return wpa_ctrl_command(ctrl, cmd);
- }
- static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
- {
- char cmd[32];
- int res;
- if (argc < 1) {
- printf("Invalid ENABLE_NETWORK command: needs one argument "
- "(network id)\n");
- return -1;
- }
- res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
- if (res < 0 || (size_t) res >= sizeof(cmd))
- return -1;
- cmd[sizeof(cmd) - 1] = '\0';
- return wpa_ctrl_command(ctrl, cmd);
- }
- static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
- {
- char cmd[32];
- int res;
- if (argc < 1) {
- printf("Invalid DISABLE_NETWORK command: needs one argument "
- "(network id)\n");
- return -1;
- }
- res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
- if (res < 0 || (size_t) res >= sizeof(cmd))
- return -1;
- cmd[sizeof(cmd) - 1] = '\0';
- return wpa_ctrl_command(ctrl, cmd);
- }
- static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
- {
- return wpa_ctrl_command(ctrl, "ADD_NETWORK");
- }
- static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
- {
- char cmd[32];
- int res;
- if (argc < 1) {
- printf("Invalid REMOVE_NETWORK command: needs one argument "
- "(network id)\n");
- return -1;
- }
- res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
- if (res < 0 || (size_t) res >= sizeof(cmd))
- return -1;
- cmd[sizeof(cmd) - 1] = '\0';
- return wpa_ctrl_command(ctrl, cmd);
- }
- static void wpa_cli_show_network_variables(void)
- {
- printf("set_network variables:\n"
- " ssid (network name, SSID)\n"
- " psk (WPA passphrase or pre-shared key)\n"
- " key_mgmt (key management protocol)\n"
- " identity (EAP identity)\n"
- " password (EAP password)\n"
- " ...\n"
- "\n"
- "Note: Values are entered in the same format as the "
- "configuration file is using,\n"
- "i.e., strings values need to be inside double quotation "
- "marks.\n"
- "For example: set_network 1 ssid \"network name\"\n"
- "\n"
- "Please see wpa_supplicant.conf documentation for full list "
- "of\navailable variables.\n");
- }
- static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
- {
- char cmd[256];
- int res;
- if (argc == 0) {
- wpa_cli_show_network_variables();
- return 0;
- }
- if (argc != 3) {
- printf("Invalid SET_NETWORK command: needs three arguments\n"
- "(network id, variable name, and value)\n");
- return -1;
- }
- res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
- argv[0], argv[1], argv[2]);
- if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
- printf("Too long SET_NETWORK command.\n");
- return -1;
- }
- return wpa_ctrl_command(ctrl, cmd);
- }
- static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
- {
- char cmd[256];
- int res;
- if (argc == 0) {
- wpa_cli_show_network_variables();
- return 0;
- }
- if (argc != 2) {
- printf("Invalid GET_NETWORK command: needs two arguments\n"
- "(network id and variable name)\n");
- return -1;
- }
- res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
- argv[0], argv[1]);
- if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
- printf("Too long GET_NETWORK command.\n");
- return -1;
- }
- return wpa_ctrl_command(ctrl, cmd);
- }
- static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
- {
- return wpa_ctrl_command(ctrl, "DISCONNECT");
- }
- static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
- {
- return wpa_ctrl_command(ctrl, "RECONNECT");
- }
- static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
- {
- return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
- }
- static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
- {
- return wpa_ctrl_command(ctrl, "SCAN");
- }
- static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
- {
- return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
- }
- static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
- {
- char cmd[64];
- int res;
- if (argc != 1) {
- printf("Invalid BSS command: need one argument (index or "
- "BSSID)\n");
- return -1;
- }
- res = os_snprintf(cmd, sizeof(cmd), "BSS %s", argv[0]);
- if (res < 0 || (size_t) res >= sizeof(cmd))
- return -1;
- cmd[sizeof(cmd) - 1] = '\0';
- return wpa_ctrl_command(ctrl, cmd);
- }
- static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
- {
- char cmd[64];
- int res;
- if (argc < 1 || argc > 2) {
- printf("Invalid GET_CAPABILITY command: need either one or "
- "two arguments\n");
- return -1;
- }
- if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
- printf("Invalid GET_CAPABILITY command: second argument, "
- "if any, must be 'strict'\n");
- return -1;
- }
- res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
- (argc == 2) ? " strict" : "");
- if (res < 0 || (size_t) res >= sizeof(cmd))
- return -1;
- cmd[sizeof(cmd) - 1] = '\0';
- return wpa_ctrl_command(ctrl, cmd);
- }
- static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
- {
- printf("Available interfaces:\n");
- return wpa_ctrl_command(ctrl, "INTERFACES");
- }
- static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
- {
- if (argc < 1) {
- wpa_cli_list_interfaces(ctrl);
- return 0;
- }
- wpa_cli_close_connection();
- os_free(ctrl_ifname);
- ctrl_ifname = os_strdup(argv[0]);
- if (wpa_cli_open_connection(ctrl_ifname)) {
- printf("Connected to interface '%s.\n", ctrl_ifname);
- if (wpa_ctrl_attach(ctrl_conn) == 0) {
- wpa_cli_attached = 1;
- } else {
- printf("Warning: Failed to attach to "
- "wpa_supplicant.\n");
- }
- } else {
- printf("Could not connect to interface '%s' - re-trying\n",
- ctrl_ifname);
- }
- return 0;
- }
- static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
- {
- return wpa_ctrl_command(ctrl, "RECONFIGURE");
- }
- static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
- {
- return wpa_ctrl_command(ctrl, "TERMINATE");
- }
- static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
- {
- char cmd[256];
- int res;
- if (argc < 1) {
- printf("Invalid INTERFACE_ADD command: needs at least one "
- "argument (interface name)\n"
- "All arguments: ifname confname driver ctrl_interface "
- "driver_param bridge_name\n");
- return -1;
- }
- /*
- * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
- * <driver_param>TAB<bridge_name>
- */
- res = os_snprintf(cmd, sizeof(cmd),
- "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
- argv[0],
- argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
- argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
- argc > 5 ? argv[5] : "");
- if (res < 0 || (size_t) res >= sizeof(cmd))
- return -1;
- cmd[sizeof(cmd) - 1] = '\0';
- return wpa_ctrl_command(ctrl, cmd);
- }
- static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
- {
- char cmd[128];
- int res;
- if (argc != 1) {
- printf("Invalid INTERFACE_REMOVE command: needs one argument "
- "(interface name)\n");
- return -1;
- }
- res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
- if (res < 0 || (size_t) res >= sizeof(cmd))
- return -1;
- cmd[sizeof(cmd) - 1] = '\0';
- return wpa_ctrl_command(ctrl, cmd);
- }
- static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
- char *argv[])
- {
- return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
- }
- struct wpa_cli_cmd {
- const char *cmd;
- int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
- };
- static struct wpa_cli_cmd wpa_cli_commands[] = {
- { "status", wpa_cli_cmd_status },
- { "ping", wpa_cli_cmd_ping },
- { "mib", wpa_cli_cmd_mib },
- { "help", wpa_cli_cmd_help },
- { "interface", wpa_cli_cmd_interface },
- { "level", wpa_cli_cmd_level },
- { "license", wpa_cli_cmd_license },
- { "quit", wpa_cli_cmd_quit },
- { "set", wpa_cli_cmd_set },
- { "logon", wpa_cli_cmd_logon },
- { "logoff", wpa_cli_cmd_logoff },
- { "pmksa", wpa_cli_cmd_pmksa },
- { "reassociate", wpa_cli_cmd_reassociate },
- { "preauthenticate", wpa_cli_cmd_preauthenticate },
- { "identity", wpa_cli_cmd_identity },
- { "password", wpa_cli_cmd_password },
- { "new_password", wpa_cli_cmd_new_password },
- { "pin", wpa_cli_cmd_pin },
- { "otp", wpa_cli_cmd_otp },
- { "passphrase", wpa_cli_cmd_passphrase },
- { "bssid", wpa_cli_cmd_bssid },
- { "list_networks", wpa_cli_cmd_list_networks },
- { "select_network", wpa_cli_cmd_select_network },
- { "enable_network", wpa_cli_cmd_enable_network },
- { "disable_network", wpa_cli_cmd_disable_network },
- { "add_network", wpa_cli_cmd_add_network },
- { "remove_network", wpa_cli_cmd_remove_network },
- { "set_network", wpa_cli_cmd_set_network },
- { "get_network", wpa_cli_cmd_get_network },
- { "save_config", wpa_cli_cmd_save_config },
- { "disconnect", wpa_cli_cmd_disconnect },
- { "reconnect", wpa_cli_cmd_reconnect },
- { "scan", wpa_cli_cmd_scan },
- { "scan_results", wpa_cli_cmd_scan_results },
- { "bss", wpa_cli_cmd_bss },
- { "get_capability", wpa_cli_cmd_get_capability },
- { "reconfigure", wpa_cli_cmd_reconfigure },
- { "terminate", wpa_cli_cmd_terminate },
- { "interface_add", wpa_cli_cmd_interface_add },
- { "interface_remove", wpa_cli_cmd_interface_remove },
- { "interface_list", wpa_cli_cmd_interface_list },
- { "ap_scan", wpa_cli_cmd_ap_scan },
- { "stkstart", wpa_cli_cmd_stkstart },
- { "ft_ds", wpa_cli_cmd_ft_ds },
- { "wps_pbc", wpa_cli_cmd_wps_pbc },
- { "wps_pin", wpa_cli_cmd_wps_pin },
- { "wps_reg", wpa_cli_cmd_wps_reg },
- { NULL, NULL }
- };
- static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
- {
- struct wpa_cli_cmd *cmd, *match = NULL;
- int count;
- int ret = 0;
- count = 0;
- 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++;
- }
- if (count > 1) {
- printf("Ambiguous command '%s'; possible commands:", argv[0]);
- cmd = wpa_cli_commands;
- while (cmd->cmd) {
- if (os_strncasecmp(cmd->cmd, argv[0],
- os_strlen(argv[0])) == 0) {
- printf(" %s", cmd->cmd);
- }
- cmd++;
- }
- printf("\n");
- ret = 1;
- } else if (count == 0) {
- printf("Unknown command '%s'\n", argv[0]);
- ret = 1;
- } else {
- ret = match->handler(ctrl, argc - 1, &argv[1]);
- }
- return ret;
- }
- static int str_match(const char *a, const char *b)
- {
- return os_strncmp(a, b, os_strlen(b)) == 0;
- }
- static int wpa_cli_exec(const char *program, const char *arg1,
- const char *arg2)
- {
- char *cmd;
- size_t len;
- int res;
- int ret = 0;
- len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
- cmd = os_malloc(len);
- if (cmd == NULL)
- return -1;
- res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
- if (res < 0 || (size_t) res >= len) {
- os_free(cmd);
- return -1;
- }
- cmd[len - 1] = '\0';
- #ifndef _WIN32_WCE
- if (system(cmd) < 0)
- ret = -1;
- #endif /* _WIN32_WCE */
- os_free(cmd);
- return ret;
- }
- static void wpa_cli_action_process(const char *msg)
- {
- const char *pos;
- char *copy = NULL, *id, *pos2;
- pos = msg;
- if (*pos == '<') {
- /* skip priority */
- pos = os_strchr(pos, '>');
- if (pos)
- pos++;
- else
- pos = msg;
- }
- if (str_match(pos, WPA_EVENT_CONNECTED)) {
- int new_id = -1;
- os_unsetenv("WPA_ID");
- os_unsetenv("WPA_ID_STR");
- os_unsetenv("WPA_CTRL_DIR");
- pos = os_strstr(pos, "[id=");
- if (pos)
- copy = os_strdup(pos + 4);
- if (copy) {
- pos2 = id = copy;
- while (*pos2 && *pos2 != ' ')
- pos2++;
- *pos2++ = '\0';
- new_id = atoi(id);
- os_setenv("WPA_ID", id, 1);
- while (*pos2 && *pos2 != '=')
- pos2++;
- if (*pos2 == '=')
- pos2++;
- id = pos2;
- while (*pos2 && *pos2 != ']')
- pos2++;
- *pos2 = '\0';
- os_setenv("WPA_ID_STR", id, 1);
- os_free(copy);
- }
- os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
- if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
- wpa_cli_connected = 1;
- wpa_cli_last_id = new_id;
- wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
- }
- } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
- if (wpa_cli_connected) {
- wpa_cli_connected = 0;
- wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
- }
- } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
- printf("wpa_supplicant is terminating - stop monitoring\n");
- wpa_cli_quit = 1;
- }
- }
- #ifndef CONFIG_ANSI_C_EXTRA
- static void wpa_cli_action_cb(char *msg, size_t len)
- {
- wpa_cli_action_process(msg);
- }
- #endif /* CONFIG_ANSI_C_EXTRA */
- static void wpa_cli_reconnect(void)
- {
- wpa_cli_close_connection();
- ctrl_conn = wpa_cli_open_connection(ctrl_ifname);
- if (ctrl_conn) {
- printf("Connection to wpa_supplicant re-established\n");
- if (wpa_ctrl_attach(ctrl_conn) == 0) {
- wpa_cli_attached = 1;
- } else {
- printf("Warning: Failed to attach to "
- "wpa_supplicant.\n");
- }
- }
- }
- static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
- int action_monitor)
- {
- int first = 1;
- if (ctrl_conn == NULL) {
- wpa_cli_reconnect();
- return;
- }
- while (wpa_ctrl_pending(ctrl) > 0) {
- char buf[256];
- size_t len = sizeof(buf) - 1;
- if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
- buf[len] = '\0';
- if (action_monitor)
- wpa_cli_action_process(buf);
- else {
- if (in_read && first)
- printf("\n");
- first = 0;
- printf("%s\n", buf);
- }
- } else {
- printf("Could not read pending message.\n");
- break;
- }
- }
- if (wpa_ctrl_pending(ctrl) < 0) {
- printf("Connection to wpa_supplicant lost - trying to "
- "reconnect\n");
- wpa_cli_reconnect();
- }
- }
- #ifdef CONFIG_READLINE
- static char * wpa_cli_cmd_gen(const char *text, int state)
- {
- static int i, len;
- const char *cmd;
- if (state == 0) {
- i = 0;
- len = os_strlen(text);
- }
- while ((cmd = wpa_cli_commands[i].cmd)) {
- i++;
- if (os_strncasecmp(cmd, text, len) == 0)
- return os_strdup(cmd);
- }
- return NULL;
- }
- static char * wpa_cli_dummy_gen(const char *text, int state)
- {
- return NULL;
- }
- static char ** wpa_cli_completion(const char *text, int start, int end)
- {
- return rl_completion_matches(text, start == 0 ?
- wpa_cli_cmd_gen : wpa_cli_dummy_gen);
- }
- #endif /* CONFIG_READLINE */
- static void wpa_cli_interactive(void)
- {
- #define max_args 10
- char cmdbuf[256], *cmd, *argv[max_args], *pos;
- int argc;
- #ifdef CONFIG_READLINE
- char *home, *hfile = NULL;
- #endif /* CONFIG_READLINE */
- printf("\nInteractive mode\n\n");
- #ifdef CONFIG_READLINE
- rl_attempted_completion_function = wpa_cli_completion;
- home = getenv("HOME");
- if (home) {
- const char *fname = ".wpa_cli_history";
- int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
- hfile = os_malloc(hfile_len);
- if (hfile) {
- int res;
- res = os_snprintf(hfile, hfile_len, "%s/%s", home,
- fname);
- if (res >= 0 && res < hfile_len) {
- hfile[hfile_len - 1] = '\0';
- read_history(hfile);
- stifle_history(100);
- }
- }
- }
- #endif /* CONFIG_READLINE */
- do {
- wpa_cli_recv_pending(ctrl_conn, 0, 0);
- #ifndef CONFIG_NATIVE_WINDOWS
- alarm(1);
- #endif /* CONFIG_NATIVE_WINDOWS */
- #ifdef CONFIG_READLINE
- cmd = readline("> ");
- if (cmd && *cmd) {
- HIST_ENTRY *h;
- while (next_history())
- ;
- h = previous_history();
- if (h == NULL || os_strcmp(cmd, h->line) != 0)
- add_history(cmd);
- next_history();
- }
- #else /* CONFIG_READLINE */
- printf("> ");
- cmd = fgets(cmdbuf, sizeof(cmdbuf), stdin);
- #endif /* CONFIG_READLINE */
- #ifndef CONFIG_NATIVE_WINDOWS
- alarm(0);
- #endif /* CONFIG_NATIVE_WINDOWS */
- if (cmd == NULL)
- break;
- wpa_cli_recv_pending(ctrl_conn, 0, 0);
- pos = cmd;
- while (*pos != '\0') {
- if (*pos == '\n') {
- *pos = '\0';
- break;
- }
- pos++;
- }
- argc = 0;
- pos = cmd;
- for (;;) {
- while (*pos == ' ')
- pos++;
- if (*pos == '\0')
- break;
- argv[argc] = pos;
- argc++;
- if (argc == max_args)
- break;
- if (*pos == '"') {
- char *pos2 = os_strrchr(pos, '"');
- if (pos2)
- pos = pos2 + 1;
- }
- while (*pos != '\0' && *pos != ' ')
- pos++;
- if (*pos == ' ')
- *pos++ = '\0';
- }
- if (argc)
- wpa_request(ctrl_conn, argc, argv);
- if (cmd != cmdbuf)
- os_free(cmd);
- } while (!wpa_cli_quit);
- #ifdef CONFIG_READLINE
- if (hfile) {
- /* Save command history, excluding lines that may contain
- * passwords. */
- HIST_ENTRY *h;
- history_set_pos(0);
- h = next_history();
- while (h) {
- char *p = h->line;
- while (*p == ' ' || *p == '\t')
- p++;
- if (os_strncasecmp(p, "pa", 2) == 0 ||
- os_strncasecmp(p, "o", 1) == 0 ||
- os_strncasecmp(p, "n", 1)) {
- h = remove_history(where_history());
- if (h) {
- os_free(h->line);
- os_free(h->data);
- os_free(h);
- }
- h = current_history();
- } else {
- h = next_history();
- }
- }
- write_history(hfile);
- os_free(hfile);
- }
- #endif /* CONFIG_READLINE */
- }
- static void wpa_cli_action(struct wpa_ctrl *ctrl)
- {
- #ifdef CONFIG_ANSI_C_EXTRA
- /* TODO: ANSI C version(?) */
- printf("Action processing not supported in ANSI C build.\n");
- #else /* CONFIG_ANSI_C_EXTRA */
- fd_set rfds;
- int fd, res;
- struct timeval tv;
- char buf[256]; /* note: large enough to fit in unsolicited messages */
- size_t len;
- fd = wpa_ctrl_get_fd(ctrl);
- while (!wpa_cli_quit) {
- FD_ZERO(&rfds);
- FD_SET(fd, &rfds);
- tv.tv_sec = 2;
- tv.tv_usec = 0;
- res = select(fd + 1, &rfds, NULL, NULL, &tv);
- if (res < 0 && errno != EINTR) {
- perror("select");
- break;
- }
- if (FD_ISSET(fd, &rfds))
- wpa_cli_recv_pending(ctrl, 0, 1);
- else {
- /* verify that connection is still working */
- len = sizeof(buf) - 1;
- if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
- wpa_cli_action_cb) < 0 ||
- len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
- printf("wpa_supplicant did not reply to PING "
- "command - exiting\n");
- break;
- }
- }
- }
- #endif /* CONFIG_ANSI_C_EXTRA */
- }
- static void wpa_cli_cleanup(void)
- {
- wpa_cli_close_connection();
- if (pid_file)
- os_daemonize_terminate(pid_file);
- os_program_deinit();
- }
- static void wpa_cli_terminate(int sig)
- {
- wpa_cli_cleanup();
- exit(0);
- }
- #ifndef CONFIG_NATIVE_WINDOWS
- static void wpa_cli_alarm(int sig)
- {
- if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
- printf("Connection to wpa_supplicant lost - trying to "
- "reconnect\n");
- wpa_cli_close_connection();
- }
- if (!ctrl_conn)
- wpa_cli_reconnect();
- if (ctrl_conn)
- wpa_cli_recv_pending(ctrl_conn, 1, 0);
- alarm(1);
- }
- #endif /* CONFIG_NATIVE_WINDOWS */
- static char * wpa_cli_get_default_ifname(void)
- {
- char *ifname = NULL;
- #ifdef CONFIG_CTRL_IFACE_UNIX
- struct dirent *dent;
- DIR *dir = opendir(ctrl_iface_dir);
- if (!dir)
- return NULL;
- while ((dent = readdir(dir))) {
- #ifdef _DIRENT_HAVE_D_TYPE
- /*
- * Skip the file if it is not a socket. Also accept
- * DT_UNKNOWN (0) in case the C library or underlying
- * file system does not support d_type.
- */
- if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
- continue;
- #endif /* _DIRENT_HAVE_D_TYPE */
- if (os_strcmp(dent->d_name, ".") == 0 ||
- os_strcmp(dent->d_name, "..") == 0)
- continue;
- printf("Selected interface '%s'\n", dent->d_name);
- ifname = os_strdup(dent->d_name);
- break;
- }
- closedir(dir);
- #endif /* CONFIG_CTRL_IFACE_UNIX */
- #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
- char buf[2048], *pos;
- size_t len;
- struct wpa_ctrl *ctrl;
- int ret;
- ctrl = wpa_ctrl_open(NULL);
- if (ctrl == NULL)
- return NULL;
- len = sizeof(buf) - 1;
- ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
- if (ret >= 0) {
- buf[len] = '\0';
- pos = os_strchr(buf, '\n');
- if (pos)
- *pos = '\0';
- ifname = os_strdup(buf);
- }
- wpa_ctrl_close(ctrl);
- #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
- return ifname;
- }
- int main(int argc, char *argv[])
- {
- int interactive;
- int warning_displayed = 0;
- int c;
- int daemonize = 0;
- int ret = 0;
- const char *global = NULL;
- if (os_program_init())
- return -1;
- for (;;) {
- c = getopt(argc, argv, "a:Bg:hi:p:P:v");
- if (c < 0)
- break;
- switch (c) {
- case 'a':
- action_file = optarg;
- break;
- case 'B':
- daemonize = 1;
- break;
- case 'g':
- global = 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;
- default:
- usage();
- return -1;
- }
- }
- interactive = (argc == optind) && (action_file == NULL);
- if (interactive)
- printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
- if (global) {
- #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
- ctrl_conn = wpa_ctrl_open(NULL);
- #else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
- ctrl_conn = wpa_ctrl_open(global);
- #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
- if (ctrl_conn == NULL) {
- perror("Failed to connect to wpa_supplicant - "
- "wpa_ctrl_open");
- return -1;
- }
- }
- for (; !global;) {
- if (ctrl_ifname == NULL)
- ctrl_ifname = wpa_cli_get_default_ifname();
- ctrl_conn = wpa_cli_open_connection(ctrl_ifname);
- if (ctrl_conn) {
- if (warning_displayed)
- printf("Connection established.\n");
- break;
- }
- if (!interactive) {
- perror("Failed to connect to wpa_supplicant - "
- "wpa_ctrl_open");
- return -1;
- }
- if (!warning_displayed) {
- printf("Could not connect to wpa_supplicant - "
- "re-trying\n");
- warning_displayed = 1;
- }
- os_sleep(1, 0);
- continue;
- }
- #ifndef _WIN32_WCE
- signal(SIGINT, wpa_cli_terminate);
- signal(SIGTERM, wpa_cli_terminate);
- #endif /* _WIN32_WCE */
- #ifndef CONFIG_NATIVE_WINDOWS
- signal(SIGALRM, wpa_cli_alarm);
- #endif /* CONFIG_NATIVE_WINDOWS */
- if (interactive || action_file) {
- if (wpa_ctrl_attach(ctrl_conn) == 0) {
- wpa_cli_attached = 1;
- } else {
- printf("Warning: Failed to attach to "
- "wpa_supplicant.\n");
- if (!interactive)
- return -1;
- }
- }
- if (daemonize && os_daemonize(pid_file))
- return -1;
- if (interactive)
- wpa_cli_interactive();
- else if (action_file)
- wpa_cli_action(ctrl_conn);
- else
- ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
- os_free(ctrl_ifname);
- wpa_cli_cleanup();
- return ret;
- }
- #else /* CONFIG_CTRL_IFACE */
- int main(int argc, char *argv[])
- {
- printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
- return -1;
- }
- #endif /* CONFIG_CTRL_IFACE */
|