~ubuntu-branches/ubuntu/vivid/wpasupplicant/vivid

« back to all changes in this revision

Viewing changes to wpa_supplicant/wpa_cli.c

  • Committer: Bazaar Package Importer
  • Author(s): Kel Modderman
  • Date: 2008-03-12 20:03:04 UTC
  • mfrom: (1.1.10 upstream)
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20080312200304-4331y9wj46pdd34z
Tags: 0.6.3-1
* New upstream release.
* Drop patches applied upstream:
  - debian/patches/30_wpa_gui_qt4_eventhistoryui_rework.patch
  - debian/patches/31_wpa_gui_qt4_eventhistory_always_scrollbar.patch
  - debian/patches/32_wpa_gui_qt4_eventhistory_scroll_with_events.patch
  - debian/patches/40_dbus_ssid_data.patch
* Tidy up the clean target of debian/rules. Now that the madwifi headers are
  handled differently we no longer need to do any cleanup.
* Fix formatting error in debian/ifupdown/wpa_action.8 to make lintian
  quieter.
* Add patch to fix formatting errors in manpages build from sgml source. Use
  <emphasis> tags to hightlight keywords instead of surrounding them in
  strong quotes.
  - debian/patches/41_manpage_format_fixes.patch
* wpasupplicant binary package no longer suggests pcscd, guessnet, iproute
  or wireless-tools, nor does it recommend dhcp3-client. These are not
  needed.
* Add debian/patches/10_silence_siocsiwauth_icotl_failure.patch to disable
  ioctl failure messages that occur under normal conditions.
* Cherry pick two upstream git commits concerning the dbus interface:
  - debian/patches/11_avoid_dbus_version_namespace.patch
  - debian/patches/12_fix_potential_use_after_free.patch
* Add debian/patches/42_manpage_explain_available_drivers.patch to explain
  that not all of the driver backends are available in the provided
  wpa_supplicant binary, and that the canonical list of supported driver
  backends can be retrieved from the wpa_supplicant -h (help) output.
  (Closes: #466910)
* Add debian/patches/20_wpa_gui_qt4_disable_link_prl.patch to remove
  link_prl CONFIG compile flag added by qmake-qt4 >= 4.3.4-2 to avoid excess
  linking.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * WPA Supplicant - command line interface for wpa_supplicant daemon
 
3
 * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License version 2 as
 
7
 * published by the Free Software Foundation.
 
8
 *
 
9
 * Alternatively, this software may be distributed under the terms of BSD
 
10
 * license.
 
11
 *
 
12
 * See README and COPYING for more details.
 
13
 */
 
14
 
 
15
#include "includes.h"
 
16
 
 
17
#ifdef CONFIG_CTRL_IFACE
 
18
 
 
19
#ifdef CONFIG_CTRL_IFACE_UNIX
 
20
#include <dirent.h>
 
21
#endif /* CONFIG_CTRL_IFACE_UNIX */
 
22
#ifdef CONFIG_READLINE
 
23
#include <readline/readline.h>
 
24
#include <readline/history.h>
 
25
#endif /* CONFIG_READLINE */
 
26
 
 
27
#include "wpa_ctrl.h"
 
28
#include "common.h"
 
29
#include "version.h"
 
30
 
 
31
 
 
32
static const char *wpa_cli_version =
 
33
"wpa_cli v" VERSION_STR "\n"
 
34
"Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi> and contributors";
 
35
 
 
36
 
 
37
static const char *wpa_cli_license =
 
38
"This program is free software. You can distribute it and/or modify it\n"
 
39
"under the terms of the GNU General Public License version 2.\n"
 
40
"\n"
 
41
"Alternatively, this software may be distributed under the terms of the\n"
 
42
"BSD license. See README and COPYING for more details.\n";
 
43
 
 
44
static const char *wpa_cli_full_license =
 
45
"This program is free software; you can redistribute it and/or modify\n"
 
46
"it under the terms of the GNU General Public License version 2 as\n"
 
47
"published by the Free Software Foundation.\n"
 
48
"\n"
 
49
"This program is distributed in the hope that it will be useful,\n"
 
50
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
 
51
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
 
52
"GNU General Public License for more details.\n"
 
53
"\n"
 
54
"You should have received a copy of the GNU General Public License\n"
 
55
"along with this program; if not, write to the Free Software\n"
 
56
"Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\n"
 
57
"\n"
 
58
"Alternatively, this software may be distributed under the terms of the\n"
 
59
"BSD license.\n"
 
60
"\n"
 
61
"Redistribution and use in source and binary forms, with or without\n"
 
62
"modification, are permitted provided that the following conditions are\n"
 
63
"met:\n"
 
64
"\n"
 
65
"1. Redistributions of source code must retain the above copyright\n"
 
66
"   notice, this list of conditions and the following disclaimer.\n"
 
67
"\n"
 
68
"2. Redistributions in binary form must reproduce the above copyright\n"
 
69
"   notice, this list of conditions and the following disclaimer in the\n"
 
70
"   documentation and/or other materials provided with the distribution.\n"
 
71
"\n"
 
72
"3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
 
73
"   names of its contributors may be used to endorse or promote products\n"
 
74
"   derived from this software without specific prior written permission.\n"
 
75
"\n"
 
76
"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
 
77
"\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
 
78
"LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
 
79
"A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
 
80
"OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
 
81
"SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
 
82
"LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
 
83
"DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
 
84
"THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
 
85
"(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
 
86
"OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
 
87
"\n";
 
88
 
 
89
static const char *commands_help =
 
90
"commands:\n"
 
91
"  status [verbose] = get current WPA/EAPOL/EAP status\n"
 
92
"  mib = get MIB variables (dot1x, dot11)\n"
 
93
"  help = show this usage help\n"
 
94
"  interface [ifname] = show interfaces/select interface\n"
 
95
"  level <debug level> = change debug level\n"
 
96
"  license = show full wpa_cli license\n"
 
97
"  logoff = IEEE 802.1X EAPOL state machine logoff\n"
 
98
"  logon = IEEE 802.1X EAPOL state machine logon\n"
 
99
"  set = set variables (shows list of variables when run without arguments)\n"
 
100
"  pmksa = show PMKSA cache\n"
 
101
"  reassociate = force reassociation\n"
 
102
"  reconfigure = force wpa_supplicant to re-read its configuration file\n"
 
103
"  preauthenticate <BSSID> = force preauthentication\n"
 
104
"  identity <network id> <identity> = configure identity for an SSID\n"
 
105
"  password <network id> <password> = configure password for an SSID\n"
 
106
"  new_password <network id> <password> = change password for an SSID\n"
 
107
"  pin <network id> <pin> = configure pin for an SSID\n"
 
108
"  otp <network id> <password> = configure one-time-password for an SSID\n"
 
109
"  passphrase <network id> <passphrase> = configure private key passphrase\n"
 
110
"    for an SSID\n"
 
111
"  bssid <network id> <BSSID> = set preferred BSSID for an SSID\n"
 
112
"  list_networks = list configured networks\n"
 
113
"  select_network <network id> = select a network (disable others)\n"
 
114
"  enable_network <network id> = enable a network\n"
 
115
"  disable_network <network id> = disable a network\n"
 
116
"  add_network = add a network\n"
 
117
"  remove_network <network id> = remove a network\n"
 
118
"  set_network <network id> <variable> <value> = set network variables "
 
119
"(shows\n"
 
120
"    list of variables when run without arguments)\n"
 
121
"  get_network <network id> <variable> = get network variables\n"
 
122
"  save_config = save the current configuration\n"
 
123
"  disconnect = disconnect and wait for reassociate/reconnect command before\n "
 
124
"    connecting\n"
 
125
"  reconnect = like reassociate, but only takes effect if already "
 
126
"disconnected\n"
 
127
"  scan = request new BSS scan\n"
 
128
"  scan_results = get latest scan results\n"
 
129
"  bss <<idx> | <bssid>> = get detailed scan result info\n"
 
130
"  get_capability <eap/pairwise/group/key_mgmt/proto/auth_alg> = "
 
131
"get capabilies\n"
 
132
"  ap_scan <value> = set ap_scan parameter\n"
 
133
"  stkstart <addr> = request STK negotiation with <addr>\n"
 
134
"  ft_ds <addr> = request over-the-DS FT with <addr>\n"
 
135
"  terminate = terminate wpa_supplicant\n"
 
136
"  quit = exit wpa_cli\n";
 
137
 
 
138
static struct wpa_ctrl *ctrl_conn;
 
139
static int wpa_cli_quit = 0;
 
140
static int wpa_cli_attached = 0;
 
141
static int wpa_cli_connected = 0;
 
142
static int wpa_cli_last_id = 0;
 
143
static const char *ctrl_iface_dir = "/var/run/wpa_supplicant";
 
144
static char *ctrl_ifname = NULL;
 
145
static const char *pid_file = NULL;
 
146
static const char *action_file = NULL;
 
147
 
 
148
 
 
149
static void usage(void)
 
150
{
 
151
        printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
 
152
               "[-a<action file>] \\\n"
 
153
               "        [-P<pid file>] [-g<global ctrl>]  [command..]\n"
 
154
               "  -h = help (show this usage text)\n"
 
155
               "  -v = shown version information\n"
 
156
               "  -a = run in daemon mode executing the action file based on "
 
157
               "events from\n"
 
158
               "       wpa_supplicant\n"
 
159
               "  -B = run a daemon in the background\n"
 
160
               "  default path: /var/run/wpa_supplicant\n"
 
161
               "  default interface: first interface found in socket path\n"
 
162
               "%s",
 
163
               commands_help);
 
164
}
 
165
 
 
166
 
 
167
static struct wpa_ctrl * wpa_cli_open_connection(const char *ifname)
 
168
{
 
169
#if defined(CONFIG_CTRL_IFACE_UDP) || defined(CONFIG_CTRL_IFACE_NAMED_PIPE)
 
170
        ctrl_conn = wpa_ctrl_open(ifname);
 
171
        return ctrl_conn;
 
172
#else /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
 
173
        char *cfile;
 
174
        int flen, res;
 
175
 
 
176
        if (ifname == NULL)
 
177
                return NULL;
 
178
 
 
179
        flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
 
180
        cfile = os_malloc(flen);
 
181
        if (cfile == NULL)
 
182
                return NULL;
 
183
        res = os_snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ifname);
 
184
        if (res < 0 || res >= flen) {
 
185
                os_free(cfile);
 
186
                return NULL;
 
187
        }
 
188
 
 
189
        ctrl_conn = wpa_ctrl_open(cfile);
 
190
        os_free(cfile);
 
191
        return ctrl_conn;
 
192
#endif /* CONFIG_CTRL_IFACE_UDP || CONFIG_CTRL_IFACE_NAMED_PIPE */
 
193
}
 
194
 
 
195
 
 
196
static void wpa_cli_close_connection(void)
 
197
{
 
198
        if (ctrl_conn == NULL)
 
199
                return;
 
200
 
 
201
        if (wpa_cli_attached) {
 
202
                wpa_ctrl_detach(ctrl_conn);
 
203
                wpa_cli_attached = 0;
 
204
        }
 
205
        wpa_ctrl_close(ctrl_conn);
 
206
        ctrl_conn = NULL;
 
207
}
 
208
 
 
209
 
 
210
static void wpa_cli_msg_cb(char *msg, size_t len)
 
211
{
 
212
        printf("%s\n", msg);
 
213
}
 
214
 
 
215
 
 
216
static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
 
217
{
 
218
        char buf[2048];
 
219
        size_t len;
 
220
        int ret;
 
221
 
 
222
        if (ctrl_conn == NULL) {
 
223
                printf("Not connected to wpa_supplicant - command dropped.\n");
 
224
                return -1;
 
225
        }
 
226
        len = sizeof(buf) - 1;
 
227
        ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
 
228
                               wpa_cli_msg_cb);
 
229
        if (ret == -2) {
 
230
                printf("'%s' command timed out.\n", cmd);
 
231
                return -2;
 
232
        } else if (ret < 0) {
 
233
                printf("'%s' command failed.\n", cmd);
 
234
                return -1;
 
235
        }
 
236
        if (print) {
 
237
                buf[len] = '\0';
 
238
                printf("%s", buf);
 
239
        }
 
240
        return 0;
 
241
}
 
242
 
 
243
 
 
244
static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
 
245
{
 
246
        return _wpa_ctrl_command(ctrl, cmd, 1);
 
247
}
 
248
 
 
249
 
 
250
static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
 
251
{
 
252
        int verbose = argc > 0 && os_strcmp(argv[0], "verbose") == 0;
 
253
        return wpa_ctrl_command(ctrl, verbose ? "STATUS-VERBOSE" : "STATUS");
 
254
}
 
255
 
 
256
 
 
257
static int wpa_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
 
258
{
 
259
        return wpa_ctrl_command(ctrl, "PING");
 
260
}
 
261
 
 
262
 
 
263
static int wpa_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
 
264
{
 
265
        return wpa_ctrl_command(ctrl, "MIB");
 
266
}
 
267
 
 
268
 
 
269
static int wpa_cli_cmd_pmksa(struct wpa_ctrl *ctrl, int argc, char *argv[])
 
270
{
 
271
        return wpa_ctrl_command(ctrl, "PMKSA");
 
272
}
 
273
 
 
274
 
 
275
static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
 
276
{
 
277
        printf("%s", commands_help);
 
278
        return 0;
 
279
}
 
280
 
 
281
 
 
282
static int wpa_cli_cmd_license(struct wpa_ctrl *ctrl, int argc, char *argv[])
 
283
{
 
284
        printf("%s\n\n%s\n", wpa_cli_version, wpa_cli_full_license);
 
285
        return 0;
 
286
}
 
287
 
 
288
 
 
289
static int wpa_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
 
290
{
 
291
        wpa_cli_quit = 1;
 
292
        return 0;
 
293
}
 
294
 
 
295
 
 
296
static void wpa_cli_show_variables(void)
 
297
{
 
298
        printf("set variables:\n"
 
299
               "  EAPOL::heldPeriod (EAPOL state machine held period, "
 
300
               "in seconds)\n"
 
301
               "  EAPOL::authPeriod (EAPOL state machine authentication "
 
302
               "period, in seconds)\n"
 
303
               "  EAPOL::startPeriod (EAPOL state machine start period, in "
 
304
               "seconds)\n"
 
305
               "  EAPOL::maxStart (EAPOL state machine maximum start "
 
306
               "attempts)\n");
 
307
        printf("  dot11RSNAConfigPMKLifetime (WPA/WPA2 PMK lifetime in "
 
308
               "seconds)\n"
 
309
               "  dot11RSNAConfigPMKReauthThreshold (WPA/WPA2 reauthentication"
 
310
               " threshold\n\tpercentage)\n"
 
311
               "  dot11RSNAConfigSATimeout (WPA/WPA2 timeout for completing "
 
312
               "security\n\tassociation in seconds)\n");
 
313
}
 
314
 
 
315
 
 
316
static int wpa_cli_cmd_set(struct wpa_ctrl *ctrl, int argc, char *argv[])
 
317
{
 
318
        char cmd[256];
 
319
        int res;
 
320
 
 
321
        if (argc == 0) {
 
322
                wpa_cli_show_variables();
 
323
                return 0;
 
324
        }
 
325
 
 
326
        if (argc != 2) {
 
327
                printf("Invalid SET command: needs two arguments (variable "
 
328
                       "name and value)\n");
 
329
                return -1;
 
330
        }
 
331
 
 
332
        res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]);
 
333
        if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
 
334
                printf("Too long SET command.\n");
 
335
                return -1;
 
336
        }
 
337
        return wpa_ctrl_command(ctrl, cmd);
 
338
}
 
339
 
 
340
 
 
341
static int wpa_cli_cmd_logoff(struct wpa_ctrl *ctrl, int argc, char *argv[])
 
342
{
 
343
        return wpa_ctrl_command(ctrl, "LOGOFF");
 
344
}
 
345
 
 
346
 
 
347
static int wpa_cli_cmd_logon(struct wpa_ctrl *ctrl, int argc, char *argv[])
 
348
{
 
349
        return wpa_ctrl_command(ctrl, "LOGON");
 
350
}
 
351
 
 
352
 
 
353
static int wpa_cli_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
 
354
                                   char *argv[])
 
355
{
 
356
        return wpa_ctrl_command(ctrl, "REASSOCIATE");
 
357
}
 
358
 
 
359
 
 
360
static int wpa_cli_cmd_preauthenticate(struct wpa_ctrl *ctrl, int argc,
 
361
                                       char *argv[])
 
362
{
 
363
        char cmd[256];
 
364
        int res;
 
365
 
 
366
        if (argc != 1) {
 
367
                printf("Invalid PREAUTH command: needs one argument "
 
368
                       "(BSSID)\n");
 
369
                return -1;
 
370
        }
 
371
 
 
372
        res = os_snprintf(cmd, sizeof(cmd), "PREAUTH %s", argv[0]);
 
373
        if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
 
374
                printf("Too long PREAUTH command.\n");
 
375
                return -1;
 
376
        }
 
377
        return wpa_ctrl_command(ctrl, cmd);
 
378
}
 
379
 
 
380
 
 
381
static int wpa_cli_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
 
382
{
 
383
        char cmd[256];
 
384
        int res;
 
385
 
 
386
        if (argc != 1) {
 
387
                printf("Invalid AP_SCAN command: needs one argument (ap_scan "
 
388
                       "value)\n");
 
389
                return -1;
 
390
        }
 
391
        res = os_snprintf(cmd, sizeof(cmd), "AP_SCAN %s", argv[0]);
 
392
        if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
 
393
                printf("Too long AP_SCAN command.\n");
 
394
                return -1;
 
395
        }
 
396
        return wpa_ctrl_command(ctrl, cmd);
 
397
}
 
398
 
 
399
 
 
400
static int wpa_cli_cmd_stkstart(struct wpa_ctrl *ctrl, int argc,
 
401
                                char *argv[])
 
402
{
 
403
        char cmd[256];
 
404
        int res;
 
405
 
 
406
        if (argc != 1) {
 
407
                printf("Invalid STKSTART command: needs one argument "
 
408
                       "(Peer STA MAC address)\n");
 
409
                return -1;
 
410
        }
 
411
 
 
412
        res = os_snprintf(cmd, sizeof(cmd), "STKSTART %s", argv[0]);
 
413
        if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
 
414
                printf("Too long STKSTART command.\n");
 
415
                return -1;
 
416
        }
 
417
        return wpa_ctrl_command(ctrl, cmd);
 
418
}
 
419
 
 
420
 
 
421
static int wpa_cli_cmd_ft_ds(struct wpa_ctrl *ctrl, int argc, char *argv[])
 
422
{
 
423
        char cmd[256];
 
424
        int res;
 
425
 
 
426
        if (argc != 1) {
 
427
                printf("Invalid FT_DS command: needs one argument "
 
428
                       "(Target AP MAC address)\n");
 
429
                return -1;
 
430
        }
 
431
 
 
432
        res = os_snprintf(cmd, sizeof(cmd), "FT_DS %s", argv[0]);
 
433
        if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
 
434
                printf("Too long FT_DS command.\n");
 
435
                return -1;
 
436
        }
 
437
        return wpa_ctrl_command(ctrl, cmd);
 
438
}
 
439
 
 
440
 
 
441
static int wpa_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
 
442
{
 
443
        char cmd[256];
 
444
        int res;
 
445
 
 
446
        if (argc != 1) {
 
447
                printf("Invalid LEVEL command: needs one argument (debug "
 
448
                       "level)\n");
 
449
                return -1;
 
450
        }
 
451
        res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
 
452
        if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
 
453
                printf("Too long LEVEL command.\n");
 
454
                return -1;
 
455
        }
 
456
        return wpa_ctrl_command(ctrl, cmd);
 
457
}
 
458
 
 
459
 
 
460
static int wpa_cli_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
 
461
{
 
462
        char cmd[256], *pos, *end;
 
463
        int i, ret;
 
464
 
 
465
        if (argc < 2) {
 
466
                printf("Invalid IDENTITY command: needs two arguments "
 
467
                       "(network id and identity)\n");
 
468
                return -1;
 
469
        }
 
470
 
 
471
        end = cmd + sizeof(cmd);
 
472
        pos = cmd;
 
473
        ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
 
474
                          argv[0], argv[1]);
 
475
        if (ret < 0 || ret >= end - pos) {
 
476
                printf("Too long IDENTITY command.\n");
 
477
                return -1;
 
478
        }
 
479
        pos += ret;
 
480
        for (i = 2; i < argc; i++) {
 
481
                ret = os_snprintf(pos, end - pos, " %s", argv[i]);
 
482
                if (ret < 0 || ret >= end - pos) {
 
483
                        printf("Too long IDENTITY command.\n");
 
484
                        return -1;
 
485
                }
 
486
                pos += ret;
 
487
        }
 
488
 
 
489
        return wpa_ctrl_command(ctrl, cmd);
 
490
}
 
491
 
 
492
 
 
493
static int wpa_cli_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
 
494
{
 
495
        char cmd[256], *pos, *end;
 
496
        int i, ret;
 
497
 
 
498
        if (argc < 2) {
 
499
                printf("Invalid PASSWORD command: needs two arguments "
 
500
                       "(network id and password)\n");
 
501
                return -1;
 
502
        }
 
503
 
 
504
        end = cmd + sizeof(cmd);
 
505
        pos = cmd;
 
506
        ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
 
507
                          argv[0], argv[1]);
 
508
        if (ret < 0 || ret >= end - pos) {
 
509
                printf("Too long PASSWORD command.\n");
 
510
                return -1;
 
511
        }
 
512
        pos += ret;
 
513
        for (i = 2; i < argc; i++) {
 
514
                ret = os_snprintf(pos, end - pos, " %s", argv[i]);
 
515
                if (ret < 0 || ret >= end - pos) {
 
516
                        printf("Too long PASSWORD command.\n");
 
517
                        return -1;
 
518
                }
 
519
                pos += ret;
 
520
        }
 
521
 
 
522
        return wpa_ctrl_command(ctrl, cmd);
 
523
}
 
524
 
 
525
 
 
526
static int wpa_cli_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
 
527
                                    char *argv[])
 
528
{
 
529
        char cmd[256], *pos, *end;
 
530
        int i, ret;
 
531
 
 
532
        if (argc < 2) {
 
533
                printf("Invalid NEW_PASSWORD command: needs two arguments "
 
534
                       "(network id and password)\n");
 
535
                return -1;
 
536
        }
 
537
 
 
538
        end = cmd + sizeof(cmd);
 
539
        pos = cmd;
 
540
        ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
 
541
                          argv[0], argv[1]);
 
542
        if (ret < 0 || ret >= end - pos) {
 
543
                printf("Too long NEW_PASSWORD command.\n");
 
544
                return -1;
 
545
        }
 
546
        pos += ret;
 
547
        for (i = 2; i < argc; i++) {
 
548
                ret = os_snprintf(pos, end - pos, " %s", argv[i]);
 
549
                if (ret < 0 || ret >= end - pos) {
 
550
                        printf("Too long NEW_PASSWORD command.\n");
 
551
                        return -1;
 
552
                }
 
553
                pos += ret;
 
554
        }
 
555
 
 
556
        return wpa_ctrl_command(ctrl, cmd);
 
557
}
 
558
 
 
559
 
 
560
static int wpa_cli_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
 
561
{
 
562
        char cmd[256], *pos, *end;
 
563
        int i, ret;
 
564
 
 
565
        if (argc < 2) {
 
566
                printf("Invalid PIN command: needs two arguments "
 
567
                       "(network id and pin)\n");
 
568
                return -1;
 
569
        }
 
570
 
 
571
        end = cmd + sizeof(cmd);
 
572
        pos = cmd;
 
573
        ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
 
574
                          argv[0], argv[1]);
 
575
        if (ret < 0 || ret >= end - pos) {
 
576
                printf("Too long PIN command.\n");
 
577
                return -1;
 
578
        }
 
579
        pos += ret;
 
580
        for (i = 2; i < argc; i++) {
 
581
                ret = os_snprintf(pos, end - pos, " %s", argv[i]);
 
582
                if (ret < 0 || ret >= end - pos) {
 
583
                        printf("Too long PIN command.\n");
 
584
                        return -1;
 
585
                }
 
586
                pos += ret;
 
587
        }
 
588
        return wpa_ctrl_command(ctrl, cmd);
 
589
}
 
590
 
 
591
 
 
592
static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
 
593
{
 
594
        char cmd[256], *pos, *end;
 
595
        int i, ret;
 
596
 
 
597
        if (argc < 2) {
 
598
                printf("Invalid OTP command: needs two arguments (network "
 
599
                       "id and password)\n");
 
600
                return -1;
 
601
        }
 
602
 
 
603
        end = cmd + sizeof(cmd);
 
604
        pos = cmd;
 
605
        ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "OTP-%s:%s",
 
606
                          argv[0], argv[1]);
 
607
        if (ret < 0 || ret >= end - pos) {
 
608
                printf("Too long OTP command.\n");
 
609
                return -1;
 
610
        }
 
611
        pos += ret;
 
612
        for (i = 2; i < argc; i++) {
 
613
                ret = os_snprintf(pos, end - pos, " %s", argv[i]);
 
614
                if (ret < 0 || ret >= end - pos) {
 
615
                        printf("Too long OTP command.\n");
 
616
                        return -1;
 
617
                }
 
618
                pos += ret;
 
619
        }
 
620
 
 
621
        return wpa_ctrl_command(ctrl, cmd);
 
622
}
 
623
 
 
624
 
 
625
static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
 
626
                                  char *argv[])
 
627
{
 
628
        char cmd[256], *pos, *end;
 
629
        int i, ret;
 
630
 
 
631
        if (argc < 2) {
 
632
                printf("Invalid PASSPHRASE command: needs two arguments "
 
633
                       "(network id and passphrase)\n");
 
634
                return -1;
 
635
        }
 
636
 
 
637
        end = cmd + sizeof(cmd);
 
638
        pos = cmd;
 
639
        ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
 
640
                          argv[0], argv[1]);
 
641
        if (ret < 0 || ret >= end - pos) {
 
642
                printf("Too long PASSPHRASE command.\n");
 
643
                return -1;
 
644
        }
 
645
        pos += ret;
 
646
        for (i = 2; i < argc; i++) {
 
647
                ret = os_snprintf(pos, end - pos, " %s", argv[i]);
 
648
                if (ret < 0 || ret >= end - pos) {
 
649
                        printf("Too long PASSPHRASE command.\n");
 
650
                        return -1;
 
651
                }
 
652
                pos += ret;
 
653
        }
 
654
 
 
655
        return wpa_ctrl_command(ctrl, cmd);
 
656
}
 
657
 
 
658
 
 
659
static int wpa_cli_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
 
660
{
 
661
        char cmd[256], *pos, *end;
 
662
        int i, ret;
 
663
 
 
664
        if (argc < 2) {
 
665
                printf("Invalid BSSID command: needs two arguments (network "
 
666
                       "id and BSSID)\n");
 
667
                return -1;
 
668
        }
 
669
 
 
670
        end = cmd + sizeof(cmd);
 
671
        pos = cmd;
 
672
        ret = os_snprintf(pos, end - pos, "BSSID");
 
673
        if (ret < 0 || ret >= end - pos) {
 
674
                printf("Too long BSSID command.\n");
 
675
                return -1;
 
676
        }
 
677
        pos += ret;
 
678
        for (i = 0; i < argc; i++) {
 
679
                ret = os_snprintf(pos, end - pos, " %s", argv[i]);
 
680
                if (ret < 0 || ret >= end - pos) {
 
681
                        printf("Too long BSSID command.\n");
 
682
                        return -1;
 
683
                }
 
684
                pos += ret;
 
685
        }
 
686
 
 
687
        return wpa_ctrl_command(ctrl, cmd);
 
688
}
 
689
 
 
690
 
 
691
static int wpa_cli_cmd_list_networks(struct wpa_ctrl *ctrl, int argc,
 
692
                                     char *argv[])
 
693
{
 
694
        return wpa_ctrl_command(ctrl, "LIST_NETWORKS");
 
695
}
 
696
 
 
697
 
 
698
static int wpa_cli_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
 
699
                                      char *argv[])
 
700
{
 
701
        char cmd[32];
 
702
        int res;
 
703
 
 
704
        if (argc < 1) {
 
705
                printf("Invalid SELECT_NETWORK command: needs one argument "
 
706
                       "(network id)\n");
 
707
                return -1;
 
708
        }
 
709
 
 
710
        res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
 
711
        if (res < 0 || (size_t) res >= sizeof(cmd))
 
712
                return -1;
 
713
        cmd[sizeof(cmd) - 1] = '\0';
 
714
 
 
715
        return wpa_ctrl_command(ctrl, cmd);
 
716
}
 
717
 
 
718
 
 
719
static int wpa_cli_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
 
720
                                      char *argv[])
 
721
{
 
722
        char cmd[32];
 
723
        int res;
 
724
 
 
725
        if (argc < 1) {
 
726
                printf("Invalid ENABLE_NETWORK command: needs one argument "
 
727
                       "(network id)\n");
 
728
                return -1;
 
729
        }
 
730
 
 
731
        res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
 
732
        if (res < 0 || (size_t) res >= sizeof(cmd))
 
733
                return -1;
 
734
        cmd[sizeof(cmd) - 1] = '\0';
 
735
 
 
736
        return wpa_ctrl_command(ctrl, cmd);
 
737
}
 
738
 
 
739
 
 
740
static int wpa_cli_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
 
741
                                       char *argv[])
 
742
{
 
743
        char cmd[32];
 
744
        int res;
 
745
 
 
746
        if (argc < 1) {
 
747
                printf("Invalid DISABLE_NETWORK command: needs one argument "
 
748
                       "(network id)\n");
 
749
                return -1;
 
750
        }
 
751
 
 
752
        res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
 
753
        if (res < 0 || (size_t) res >= sizeof(cmd))
 
754
                return -1;
 
755
        cmd[sizeof(cmd) - 1] = '\0';
 
756
 
 
757
        return wpa_ctrl_command(ctrl, cmd);
 
758
}
 
759
 
 
760
 
 
761
static int wpa_cli_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
 
762
                                   char *argv[])
 
763
{
 
764
        return wpa_ctrl_command(ctrl, "ADD_NETWORK");
 
765
}
 
766
 
 
767
 
 
768
static int wpa_cli_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
 
769
                                      char *argv[])
 
770
{
 
771
        char cmd[32];
 
772
        int res;
 
773
 
 
774
        if (argc < 1) {
 
775
                printf("Invalid REMOVE_NETWORK command: needs one argument "
 
776
                       "(network id)\n");
 
777
                return -1;
 
778
        }
 
779
 
 
780
        res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
 
781
        if (res < 0 || (size_t) res >= sizeof(cmd))
 
782
                return -1;
 
783
        cmd[sizeof(cmd) - 1] = '\0';
 
784
 
 
785
        return wpa_ctrl_command(ctrl, cmd);
 
786
}
 
787
 
 
788
 
 
789
static void wpa_cli_show_network_variables(void)
 
790
{
 
791
        printf("set_network variables:\n"
 
792
               "  ssid (network name, SSID)\n"
 
793
               "  psk (WPA passphrase or pre-shared key)\n"
 
794
               "  key_mgmt (key management protocol)\n"
 
795
               "  identity (EAP identity)\n"
 
796
               "  password (EAP password)\n"
 
797
               "  ...\n"
 
798
               "\n"
 
799
               "Note: Values are entered in the same format as the "
 
800
               "configuration file is using,\n"
 
801
               "i.e., strings values need to be inside double quotation "
 
802
               "marks.\n"
 
803
               "For example: set_network 1 ssid \"network name\"\n"
 
804
               "\n"
 
805
               "Please see wpa_supplicant.conf documentation for full list "
 
806
               "of\navailable variables.\n");
 
807
}
 
808
 
 
809
 
 
810
static int wpa_cli_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
 
811
                                   char *argv[])
 
812
{
 
813
        char cmd[256];
 
814
        int res;
 
815
 
 
816
        if (argc == 0) {
 
817
                wpa_cli_show_network_variables();
 
818
                return 0;
 
819
        }
 
820
 
 
821
        if (argc != 3) {
 
822
                printf("Invalid SET_NETWORK command: needs three arguments\n"
 
823
                       "(network id, variable name, and value)\n");
 
824
                return -1;
 
825
        }
 
826
 
 
827
        res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
 
828
                          argv[0], argv[1], argv[2]);
 
829
        if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
 
830
                printf("Too long SET_NETWORK command.\n");
 
831
                return -1;
 
832
        }
 
833
        return wpa_ctrl_command(ctrl, cmd);
 
834
}
 
835
 
 
836
 
 
837
static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
 
838
                                   char *argv[])
 
839
{
 
840
        char cmd[256];
 
841
        int res;
 
842
 
 
843
        if (argc == 0) {
 
844
                wpa_cli_show_network_variables();
 
845
                return 0;
 
846
        }
 
847
 
 
848
        if (argc != 2) {
 
849
                printf("Invalid GET_NETWORK command: needs two arguments\n"
 
850
                       "(network id and variable name)\n");
 
851
                return -1;
 
852
        }
 
853
 
 
854
        res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
 
855
                          argv[0], argv[1]);
 
856
        if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
 
857
                printf("Too long GET_NETWORK command.\n");
 
858
                return -1;
 
859
        }
 
860
        return wpa_ctrl_command(ctrl, cmd);
 
861
}
 
862
 
 
863
 
 
864
static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
 
865
                                  char *argv[])
 
866
{
 
867
        return wpa_ctrl_command(ctrl, "DISCONNECT");
 
868
}
 
869
 
 
870
 
 
871
static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
 
872
                                  char *argv[])
 
873
{
 
874
        return wpa_ctrl_command(ctrl, "RECONNECT");
 
875
}
 
876
 
 
877
 
 
878
static int wpa_cli_cmd_save_config(struct wpa_ctrl *ctrl, int argc,
 
879
                                   char *argv[])
 
880
{
 
881
        return wpa_ctrl_command(ctrl, "SAVE_CONFIG");
 
882
}
 
883
 
 
884
 
 
885
static int wpa_cli_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
 
886
{
 
887
        return wpa_ctrl_command(ctrl, "SCAN");
 
888
}
 
889
 
 
890
 
 
891
static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
 
892
                                    char *argv[])
 
893
{
 
894
        return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
 
895
}
 
896
 
 
897
 
 
898
static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
 
899
{
 
900
        char cmd[64];
 
901
        int res;
 
902
 
 
903
        if (argc != 1) {
 
904
                printf("Invalid BSS command: need one argument (index or "
 
905
                       "BSSID)\n");
 
906
                return -1;
 
907
        }
 
908
 
 
909
        res = os_snprintf(cmd, sizeof(cmd), "BSS %s", argv[0]);
 
910
        if (res < 0 || (size_t) res >= sizeof(cmd))
 
911
                return -1;
 
912
        cmd[sizeof(cmd) - 1] = '\0';
 
913
 
 
914
        return wpa_ctrl_command(ctrl, cmd);
 
915
}
 
916
 
 
917
 
 
918
static int wpa_cli_cmd_get_capability(struct wpa_ctrl *ctrl, int argc,
 
919
                                      char *argv[])
 
920
{
 
921
        char cmd[64];
 
922
        int res;
 
923
 
 
924
        if (argc < 1 || argc > 2) {
 
925
                printf("Invalid GET_CAPABILITY command: need either one or "
 
926
                       "two arguments\n");
 
927
                return -1;
 
928
        }
 
929
 
 
930
        if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
 
931
                printf("Invalid GET_CAPABILITY command: second argument, "
 
932
                       "if any, must be 'strict'\n");
 
933
                return -1;
 
934
        }
 
935
 
 
936
        res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
 
937
                          (argc == 2) ? " strict" : "");
 
938
        if (res < 0 || (size_t) res >= sizeof(cmd))
 
939
                return -1;
 
940
        cmd[sizeof(cmd) - 1] = '\0';
 
941
 
 
942
        return wpa_ctrl_command(ctrl, cmd);
 
943
}
 
944
 
 
945
 
 
946
static int wpa_cli_list_interfaces(struct wpa_ctrl *ctrl)
 
947
{
 
948
        printf("Available interfaces:\n");
 
949
        return wpa_ctrl_command(ctrl, "INTERFACES");
 
950
}
 
951
 
 
952
 
 
953
static int wpa_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc, char *argv[])
 
954
{
 
955
        if (argc < 1) {
 
956
                wpa_cli_list_interfaces(ctrl);
 
957
                return 0;
 
958
        }
 
959
 
 
960
        wpa_cli_close_connection();
 
961
        os_free(ctrl_ifname);
 
962
        ctrl_ifname = os_strdup(argv[0]);
 
963
 
 
964
        if (wpa_cli_open_connection(ctrl_ifname)) {
 
965
                printf("Connected to interface '%s.\n", ctrl_ifname);
 
966
                if (wpa_ctrl_attach(ctrl_conn) == 0) {
 
967
                        wpa_cli_attached = 1;
 
968
                } else {
 
969
                        printf("Warning: Failed to attach to "
 
970
                               "wpa_supplicant.\n");
 
971
                }
 
972
        } else {
 
973
                printf("Could not connect to interface '%s' - re-trying\n",
 
974
                       ctrl_ifname);
 
975
        }
 
976
        return 0;
 
977
}
 
978
 
 
979
 
 
980
static int wpa_cli_cmd_reconfigure(struct wpa_ctrl *ctrl, int argc,
 
981
                                   char *argv[])
 
982
{
 
983
        return wpa_ctrl_command(ctrl, "RECONFIGURE");
 
984
}
 
985
 
 
986
 
 
987
static int wpa_cli_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
 
988
                                 char *argv[])
 
989
{
 
990
        return wpa_ctrl_command(ctrl, "TERMINATE");
 
991
}
 
992
 
 
993
 
 
994
static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
 
995
                                     char *argv[])
 
996
{
 
997
        char cmd[256];
 
998
        int res;
 
999
 
 
1000
        if (argc < 1) {
 
1001
                printf("Invalid INTERFACE_ADD command: needs at least one "
 
1002
                       "argument (interface name)\n"
 
1003
                       "All arguments: ifname confname driver ctrl_interface "
 
1004
                       "driver_param bridge_name\n");
 
1005
                return -1;
 
1006
        }
 
1007
 
 
1008
        /*
 
1009
         * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
 
1010
         * <driver_param>TAB<bridge_name>
 
1011
         */
 
1012
        res = os_snprintf(cmd, sizeof(cmd),
 
1013
                          "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
 
1014
                          argv[0],
 
1015
                          argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
 
1016
                          argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
 
1017
                          argc > 5 ? argv[5] : "");
 
1018
        if (res < 0 || (size_t) res >= sizeof(cmd))
 
1019
                return -1;
 
1020
        cmd[sizeof(cmd) - 1] = '\0';
 
1021
        return wpa_ctrl_command(ctrl, cmd);
 
1022
}
 
1023
 
 
1024
 
 
1025
static int wpa_cli_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
 
1026
                                        char *argv[])
 
1027
{
 
1028
        char cmd[128];
 
1029
        int res;
 
1030
 
 
1031
        if (argc != 1) {
 
1032
                printf("Invalid INTERFACE_REMOVE command: needs one argument "
 
1033
                       "(interface name)\n");
 
1034
                return -1;
 
1035
        }
 
1036
 
 
1037
        res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
 
1038
        if (res < 0 || (size_t) res >= sizeof(cmd))
 
1039
                return -1;
 
1040
        cmd[sizeof(cmd) - 1] = '\0';
 
1041
        return wpa_ctrl_command(ctrl, cmd);
 
1042
}
 
1043
 
 
1044
 
 
1045
struct wpa_cli_cmd {
 
1046
        const char *cmd;
 
1047
        int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
 
1048
};
 
1049
 
 
1050
static struct wpa_cli_cmd wpa_cli_commands[] = {
 
1051
        { "status", wpa_cli_cmd_status },
 
1052
        { "ping", wpa_cli_cmd_ping },
 
1053
        { "mib", wpa_cli_cmd_mib },
 
1054
        { "help", wpa_cli_cmd_help },
 
1055
        { "interface", wpa_cli_cmd_interface },
 
1056
        { "level", wpa_cli_cmd_level },
 
1057
        { "license", wpa_cli_cmd_license },
 
1058
        { "quit", wpa_cli_cmd_quit },
 
1059
        { "set", wpa_cli_cmd_set },
 
1060
        { "logon", wpa_cli_cmd_logon },
 
1061
        { "logoff", wpa_cli_cmd_logoff },
 
1062
        { "pmksa", wpa_cli_cmd_pmksa },
 
1063
        { "reassociate", wpa_cli_cmd_reassociate },
 
1064
        { "preauthenticate", wpa_cli_cmd_preauthenticate },
 
1065
        { "identity", wpa_cli_cmd_identity },
 
1066
        { "password", wpa_cli_cmd_password },
 
1067
        { "new_password", wpa_cli_cmd_new_password },
 
1068
        { "pin", wpa_cli_cmd_pin },
 
1069
        { "otp", wpa_cli_cmd_otp },
 
1070
        { "passphrase", wpa_cli_cmd_passphrase },
 
1071
        { "bssid", wpa_cli_cmd_bssid },
 
1072
        { "list_networks", wpa_cli_cmd_list_networks },
 
1073
        { "select_network", wpa_cli_cmd_select_network },
 
1074
        { "enable_network", wpa_cli_cmd_enable_network },
 
1075
        { "disable_network", wpa_cli_cmd_disable_network },
 
1076
        { "add_network", wpa_cli_cmd_add_network },
 
1077
        { "remove_network", wpa_cli_cmd_remove_network },
 
1078
        { "set_network", wpa_cli_cmd_set_network },
 
1079
        { "get_network", wpa_cli_cmd_get_network },
 
1080
        { "save_config", wpa_cli_cmd_save_config },
 
1081
        { "disconnect", wpa_cli_cmd_disconnect },
 
1082
        { "reconnect", wpa_cli_cmd_reconnect },
 
1083
        { "scan", wpa_cli_cmd_scan },
 
1084
        { "scan_results", wpa_cli_cmd_scan_results },
 
1085
        { "bss", wpa_cli_cmd_bss },
 
1086
        { "get_capability", wpa_cli_cmd_get_capability },
 
1087
        { "reconfigure", wpa_cli_cmd_reconfigure },
 
1088
        { "terminate", wpa_cli_cmd_terminate },
 
1089
        { "interface_add", wpa_cli_cmd_interface_add },
 
1090
        { "interface_remove", wpa_cli_cmd_interface_remove },
 
1091
        { "ap_scan", wpa_cli_cmd_ap_scan },
 
1092
        { "stkstart", wpa_cli_cmd_stkstart },
 
1093
        { "ft_ds", wpa_cli_cmd_ft_ds },
 
1094
        { NULL, NULL }
 
1095
};
 
1096
 
 
1097
 
 
1098
static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
 
1099
{
 
1100
        struct wpa_cli_cmd *cmd, *match = NULL;
 
1101
        int count;
 
1102
        int ret = 0;
 
1103
 
 
1104
        count = 0;
 
1105
        cmd = wpa_cli_commands;
 
1106
        while (cmd->cmd) {
 
1107
                if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
 
1108
                {
 
1109
                        match = cmd;
 
1110
                        if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
 
1111
                                /* we have an exact match */
 
1112
                                count = 1;
 
1113
                                break;
 
1114
                        }
 
1115
                        count++;
 
1116
                }
 
1117
                cmd++;
 
1118
        }
 
1119
 
 
1120
        if (count > 1) {
 
1121
                printf("Ambiguous command '%s'; possible commands:", argv[0]);
 
1122
                cmd = wpa_cli_commands;
 
1123
                while (cmd->cmd) {
 
1124
                        if (os_strncasecmp(cmd->cmd, argv[0],
 
1125
                                           os_strlen(argv[0])) == 0) {
 
1126
                                printf(" %s", cmd->cmd);
 
1127
                        }
 
1128
                        cmd++;
 
1129
                }
 
1130
                printf("\n");
 
1131
                ret = 1;
 
1132
        } else if (count == 0) {
 
1133
                printf("Unknown command '%s'\n", argv[0]);
 
1134
                ret = 1;
 
1135
        } else {
 
1136
                ret = match->handler(ctrl, argc - 1, &argv[1]);
 
1137
        }
 
1138
 
 
1139
        return ret;
 
1140
}
 
1141
 
 
1142
 
 
1143
static int str_match(const char *a, const char *b)
 
1144
{
 
1145
        return os_strncmp(a, b, os_strlen(b)) == 0;
 
1146
}
 
1147
 
 
1148
 
 
1149
static int wpa_cli_exec(const char *program, const char *arg1,
 
1150
                        const char *arg2)
 
1151
{
 
1152
        char *cmd;
 
1153
        size_t len;
 
1154
        int res;
 
1155
 
 
1156
        len = os_strlen(program) + os_strlen(arg1) + os_strlen(arg2) + 3;
 
1157
        cmd = os_malloc(len);
 
1158
        if (cmd == NULL)
 
1159
                return -1;
 
1160
        res = os_snprintf(cmd, len, "%s %s %s", program, arg1, arg2);
 
1161
        if (res < 0 || (size_t) res >= len) {
 
1162
                os_free(cmd);
 
1163
                return -1;
 
1164
        }
 
1165
        cmd[len - 1] = '\0';
 
1166
#ifndef _WIN32_WCE
 
1167
        system(cmd);
 
1168
#endif /* _WIN32_WCE */
 
1169
        os_free(cmd);
 
1170
 
 
1171
        return 0;
 
1172
}
 
1173
 
 
1174
 
 
1175
static void wpa_cli_action_process(const char *msg)
 
1176
{
 
1177
        const char *pos;
 
1178
        char *copy = NULL, *id, *pos2;
 
1179
 
 
1180
        pos = msg;
 
1181
        if (*pos == '<') {
 
1182
                /* skip priority */
 
1183
                pos = os_strchr(pos, '>');
 
1184
                if (pos)
 
1185
                        pos++;
 
1186
                else
 
1187
                        pos = msg;
 
1188
        }
 
1189
 
 
1190
        if (str_match(pos, WPA_EVENT_CONNECTED)) {
 
1191
                int new_id = -1;
 
1192
                os_unsetenv("WPA_ID");
 
1193
                os_unsetenv("WPA_ID_STR");
 
1194
                os_unsetenv("WPA_CTRL_DIR");
 
1195
 
 
1196
                pos = os_strstr(pos, "[id=");
 
1197
                if (pos)
 
1198
                        copy = os_strdup(pos + 4);
 
1199
 
 
1200
                if (copy) {
 
1201
                        pos2 = id = copy;
 
1202
                        while (*pos2 && *pos2 != ' ')
 
1203
                                pos2++;
 
1204
                        *pos2++ = '\0';
 
1205
                        new_id = atoi(id);
 
1206
                        os_setenv("WPA_ID", id, 1);
 
1207
                        while (*pos2 && *pos2 != '=')
 
1208
                                pos2++;
 
1209
                        if (*pos2 == '=')
 
1210
                                pos2++;
 
1211
                        id = pos2;
 
1212
                        while (*pos2 && *pos2 != ']')
 
1213
                                pos2++;
 
1214
                        *pos2 = '\0';
 
1215
                        os_setenv("WPA_ID_STR", id, 1);
 
1216
                        os_free(copy);
 
1217
                }
 
1218
 
 
1219
                os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1);
 
1220
 
 
1221
                if (!wpa_cli_connected || new_id != wpa_cli_last_id) {
 
1222
                        wpa_cli_connected = 1;
 
1223
                        wpa_cli_last_id = new_id;
 
1224
                        wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED");
 
1225
                }
 
1226
        } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) {
 
1227
                if (wpa_cli_connected) {
 
1228
                        wpa_cli_connected = 0;
 
1229
                        wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED");
 
1230
                }
 
1231
        } else if (str_match(pos, WPA_EVENT_TERMINATING)) {
 
1232
                printf("wpa_supplicant is terminating - stop monitoring\n");
 
1233
                wpa_cli_quit = 1;
 
1234
        }
 
1235
}
 
1236
 
 
1237
 
 
1238
#ifndef CONFIG_ANSI_C_EXTRA
 
1239
static void wpa_cli_action_cb(char *msg, size_t len)
 
1240
{
 
1241
        wpa_cli_action_process(msg);
 
1242
}
 
1243
#endif /* CONFIG_ANSI_C_EXTRA */
 
1244
 
 
1245
 
 
1246
static void wpa_cli_reconnect(void)
 
1247
{
 
1248
        wpa_cli_close_connection();
 
1249
        ctrl_conn = wpa_cli_open_connection(ctrl_ifname);
 
1250
        if (ctrl_conn) {
 
1251
                printf("Connection to wpa_supplicant re-established\n");
 
1252
                if (wpa_ctrl_attach(ctrl_conn) == 0) {
 
1253
                        wpa_cli_attached = 1;
 
1254
                } else {
 
1255
                        printf("Warning: Failed to attach to "
 
1256
                               "wpa_supplicant.\n");
 
1257
                }
 
1258
        }
 
1259
}
 
1260
 
 
1261
 
 
1262
static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read,
 
1263
                                 int action_monitor)
 
1264
{
 
1265
        int first = 1;
 
1266
        if (ctrl_conn == NULL) {
 
1267
                wpa_cli_reconnect();
 
1268
                return;
 
1269
        }
 
1270
        while (wpa_ctrl_pending(ctrl) > 0) {
 
1271
                char buf[256];
 
1272
                size_t len = sizeof(buf) - 1;
 
1273
                if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
 
1274
                        buf[len] = '\0';
 
1275
                        if (action_monitor)
 
1276
                                wpa_cli_action_process(buf);
 
1277
                        else {
 
1278
                                if (in_read && first)
 
1279
                                        printf("\n");
 
1280
                                first = 0;
 
1281
                                printf("%s\n", buf);
 
1282
                        }
 
1283
                } else {
 
1284
                        printf("Could not read pending message.\n");
 
1285
                        break;
 
1286
                }
 
1287
        }
 
1288
 
 
1289
        if (wpa_ctrl_pending(ctrl) < 0) {
 
1290
                printf("Connection to wpa_supplicant lost - trying to "
 
1291
                       "reconnect\n");
 
1292
                wpa_cli_reconnect();
 
1293
        }
 
1294
}
 
1295
 
 
1296
 
 
1297
#ifdef CONFIG_READLINE
 
1298
static char * wpa_cli_cmd_gen(const char *text, int state)
 
1299
{
 
1300
        static int i, len;
 
1301
        const char *cmd;
 
1302
 
 
1303
        if (state == 0) {
 
1304
                i = 0;
 
1305
                len = os_strlen(text);
 
1306
        }
 
1307
 
 
1308
        while ((cmd = wpa_cli_commands[i].cmd)) {
 
1309
                i++;
 
1310
                if (os_strncasecmp(cmd, text, len) == 0)
 
1311
                        return os_strdup(cmd);
 
1312
        }
 
1313
 
 
1314
        return NULL;
 
1315
}
 
1316
 
 
1317
 
 
1318
static char * wpa_cli_dummy_gen(const char *text, int state)
 
1319
{
 
1320
        return NULL;
 
1321
}
 
1322
 
 
1323
 
 
1324
static char ** wpa_cli_completion(const char *text, int start, int end)
 
1325
{
 
1326
        return rl_completion_matches(text, start == 0 ?
 
1327
                                     wpa_cli_cmd_gen : wpa_cli_dummy_gen);
 
1328
}
 
1329
#endif /* CONFIG_READLINE */
 
1330
 
 
1331
 
 
1332
static void wpa_cli_interactive(void)
 
1333
{
 
1334
#define max_args 10
 
1335
        char cmdbuf[256], *cmd, *argv[max_args], *pos;
 
1336
        int argc;
 
1337
#ifdef CONFIG_READLINE
 
1338
        char *home, *hfile = NULL;
 
1339
#endif /* CONFIG_READLINE */
 
1340
 
 
1341
        printf("\nInteractive mode\n\n");
 
1342
 
 
1343
#ifdef CONFIG_READLINE
 
1344
        rl_attempted_completion_function = wpa_cli_completion;
 
1345
        home = getenv("HOME");
 
1346
        if (home) {
 
1347
                const char *fname = ".wpa_cli_history";
 
1348
                int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
 
1349
                hfile = os_malloc(hfile_len);
 
1350
                if (hfile) {
 
1351
                        int res;
 
1352
                        res = os_snprintf(hfile, hfile_len, "%s/%s", home,
 
1353
                                          fname);
 
1354
                        if (res >= 0 && res < hfile_len) {
 
1355
                                hfile[hfile_len - 1] = '\0';
 
1356
                                read_history(hfile);
 
1357
                                stifle_history(100);
 
1358
                        }
 
1359
                }
 
1360
        }
 
1361
#endif /* CONFIG_READLINE */
 
1362
 
 
1363
        do {
 
1364
                wpa_cli_recv_pending(ctrl_conn, 0, 0);
 
1365
#ifndef CONFIG_NATIVE_WINDOWS
 
1366
                alarm(1);
 
1367
#endif /* CONFIG_NATIVE_WINDOWS */
 
1368
#ifdef CONFIG_READLINE
 
1369
                cmd = readline("> ");
 
1370
                if (cmd && *cmd) {
 
1371
                        HIST_ENTRY *h;
 
1372
                        while (next_history())
 
1373
                                ;
 
1374
                        h = previous_history();
 
1375
                        if (h == NULL || os_strcmp(cmd, h->line) != 0)
 
1376
                                add_history(cmd);
 
1377
                        next_history();
 
1378
                }
 
1379
#else /* CONFIG_READLINE */
 
1380
                printf("> ");
 
1381
                cmd = fgets(cmdbuf, sizeof(cmdbuf), stdin);
 
1382
#endif /* CONFIG_READLINE */
 
1383
#ifndef CONFIG_NATIVE_WINDOWS
 
1384
                alarm(0);
 
1385
#endif /* CONFIG_NATIVE_WINDOWS */
 
1386
                if (cmd == NULL)
 
1387
                        break;
 
1388
                wpa_cli_recv_pending(ctrl_conn, 0, 0);
 
1389
                pos = cmd;
 
1390
                while (*pos != '\0') {
 
1391
                        if (*pos == '\n') {
 
1392
                                *pos = '\0';
 
1393
                                break;
 
1394
                        }
 
1395
                        pos++;
 
1396
                }
 
1397
                argc = 0;
 
1398
                pos = cmd;
 
1399
                for (;;) {
 
1400
                        while (*pos == ' ')
 
1401
                                pos++;
 
1402
                        if (*pos == '\0')
 
1403
                                break;
 
1404
                        argv[argc] = pos;
 
1405
                        argc++;
 
1406
                        if (argc == max_args)
 
1407
                                break;
 
1408
                        if (*pos == '"') {
 
1409
                                char *pos2 = os_strrchr(pos, '"');
 
1410
                                if (pos2)
 
1411
                                        pos = pos2 + 1;
 
1412
                        }
 
1413
                        while (*pos != '\0' && *pos != ' ')
 
1414
                                pos++;
 
1415
                        if (*pos == ' ')
 
1416
                                *pos++ = '\0';
 
1417
                }
 
1418
                if (argc)
 
1419
                        wpa_request(ctrl_conn, argc, argv);
 
1420
 
 
1421
                if (cmd != cmdbuf)
 
1422
                        os_free(cmd);
 
1423
        } while (!wpa_cli_quit);
 
1424
 
 
1425
#ifdef CONFIG_READLINE
 
1426
        if (hfile) {
 
1427
                /* Save command history, excluding lines that may contain
 
1428
                 * passwords. */
 
1429
                HIST_ENTRY *h;
 
1430
                history_set_pos(0);
 
1431
                h = next_history();
 
1432
                while (h) {
 
1433
                        char *p = h->line;
 
1434
                        while (*p == ' ' || *p == '\t')
 
1435
                                p++;
 
1436
                        if (os_strncasecmp(p, "pa", 2) == 0 ||
 
1437
                            os_strncasecmp(p, "o", 1) == 0 ||
 
1438
                            os_strncasecmp(p, "n", 1)) {
 
1439
                                h = remove_history(where_history());
 
1440
                                if (h) {
 
1441
                                        os_free(h->line);
 
1442
                                        os_free(h->data);
 
1443
                                        os_free(h);
 
1444
                                }
 
1445
                                h = current_history();
 
1446
                        } else {
 
1447
                                h = next_history();
 
1448
                        }
 
1449
                }
 
1450
                write_history(hfile);
 
1451
                os_free(hfile);
 
1452
        }
 
1453
#endif /* CONFIG_READLINE */
 
1454
}
 
1455
 
 
1456
 
 
1457
static void wpa_cli_action(struct wpa_ctrl *ctrl)
 
1458
{
 
1459
#ifdef CONFIG_ANSI_C_EXTRA
 
1460
        /* TODO: ANSI C version(?) */
 
1461
        printf("Action processing not supported in ANSI C build.\n");
 
1462
#else /* CONFIG_ANSI_C_EXTRA */
 
1463
        fd_set rfds;
 
1464
        int fd, res;
 
1465
        struct timeval tv;
 
1466
        char buf[256]; /* note: large enough to fit in unsolicited messages */
 
1467
        size_t len;
 
1468
 
 
1469
        fd = wpa_ctrl_get_fd(ctrl);
 
1470
 
 
1471
        while (!wpa_cli_quit) {
 
1472
                FD_ZERO(&rfds);
 
1473
                FD_SET(fd, &rfds);
 
1474
                tv.tv_sec = 2;
 
1475
                tv.tv_usec = 0;
 
1476
                res = select(fd + 1, &rfds, NULL, NULL, &tv);
 
1477
                if (res < 0 && errno != EINTR) {
 
1478
                        perror("select");
 
1479
                        break;
 
1480
                }
 
1481
 
 
1482
                if (FD_ISSET(fd, &rfds))
 
1483
                        wpa_cli_recv_pending(ctrl, 0, 1);
 
1484
                else {
 
1485
                        /* verify that connection is still working */
 
1486
                        len = sizeof(buf) - 1;
 
1487
                        if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len,
 
1488
                                             wpa_cli_action_cb) < 0 ||
 
1489
                            len < 4 || os_memcmp(buf, "PONG", 4) != 0) {
 
1490
                                printf("wpa_supplicant did not reply to PING "
 
1491
                                       "command - exiting\n");
 
1492
                                break;
 
1493
                        }
 
1494
                }
 
1495
        }
 
1496
#endif /* CONFIG_ANSI_C_EXTRA */
 
1497
}
 
1498
 
 
1499
 
 
1500
static void wpa_cli_cleanup(void)
 
1501
{
 
1502
        wpa_cli_close_connection();
 
1503
        if (pid_file)
 
1504
                os_daemonize_terminate(pid_file);
 
1505
 
 
1506
        os_program_deinit();
 
1507
}
 
1508
 
 
1509
static void wpa_cli_terminate(int sig)
 
1510
{
 
1511
        wpa_cli_cleanup();
 
1512
        exit(0);
 
1513
}
 
1514
 
 
1515
 
 
1516
#ifndef CONFIG_NATIVE_WINDOWS
 
1517
static void wpa_cli_alarm(int sig)
 
1518
{
 
1519
        if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
 
1520
                printf("Connection to wpa_supplicant lost - trying to "
 
1521
                       "reconnect\n");
 
1522
                wpa_cli_close_connection();
 
1523
        }
 
1524
        if (!ctrl_conn)
 
1525
                wpa_cli_reconnect();
 
1526
        if (ctrl_conn)
 
1527
                wpa_cli_recv_pending(ctrl_conn, 1, 0);
 
1528
        alarm(1);
 
1529
}
 
1530
#endif /* CONFIG_NATIVE_WINDOWS */
 
1531
 
 
1532
 
 
1533
static char * wpa_cli_get_default_ifname(void)
 
1534
{
 
1535
        char *ifname = NULL;
 
1536
 
 
1537
#ifdef CONFIG_CTRL_IFACE_UNIX
 
1538
        struct dirent *dent;
 
1539
        DIR *dir = opendir(ctrl_iface_dir);
 
1540
        if (!dir)
 
1541
                return NULL;
 
1542
        while ((dent = readdir(dir))) {
 
1543
#ifdef _DIRENT_HAVE_D_TYPE
 
1544
                /*
 
1545
                 * Skip the file if it is not a socket. Also accept
 
1546
                 * DT_UNKNOWN (0) in case the C library or underlying
 
1547
                 * file system does not support d_type.
 
1548
                 */
 
1549
                if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
 
1550
                        continue;
 
1551
#endif /* _DIRENT_HAVE_D_TYPE */
 
1552
                if (os_strcmp(dent->d_name, ".") == 0 ||
 
1553
                    os_strcmp(dent->d_name, "..") == 0)
 
1554
                        continue;
 
1555
                printf("Selected interface '%s'\n", dent->d_name);
 
1556
                ifname = os_strdup(dent->d_name);
 
1557
                break;
 
1558
        }
 
1559
        closedir(dir);
 
1560
#endif /* CONFIG_CTRL_IFACE_UNIX */
 
1561
 
 
1562
#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
 
1563
        char buf[2048], *pos;
 
1564
        size_t len;
 
1565
        struct wpa_ctrl *ctrl;
 
1566
        int ret;
 
1567
 
 
1568
        ctrl = wpa_ctrl_open(NULL);
 
1569
        if (ctrl == NULL)
 
1570
                return NULL;
 
1571
 
 
1572
        len = sizeof(buf) - 1;
 
1573
        ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf, &len, NULL);
 
1574
        if (ret >= 0) {
 
1575
                buf[len] = '\0';
 
1576
                pos = os_strchr(buf, '\n');
 
1577
                if (pos)
 
1578
                        *pos = '\0';
 
1579
                ifname = os_strdup(buf);
 
1580
        }
 
1581
        wpa_ctrl_close(ctrl);
 
1582
#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
 
1583
 
 
1584
        return ifname;
 
1585
}
 
1586
 
 
1587
 
 
1588
int main(int argc, char *argv[])
 
1589
{
 
1590
        int interactive;
 
1591
        int warning_displayed = 0;
 
1592
        int c;
 
1593
        int daemonize = 0;
 
1594
        int ret = 0;
 
1595
        const char *global = NULL;
 
1596
 
 
1597
        if (os_program_init())
 
1598
                return -1;
 
1599
 
 
1600
        for (;;) {
 
1601
                c = getopt(argc, argv, "a:Bg:hi:p:P:v");
 
1602
                if (c < 0)
 
1603
                        break;
 
1604
                switch (c) {
 
1605
                case 'a':
 
1606
                        action_file = optarg;
 
1607
                        break;
 
1608
                case 'B':
 
1609
                        daemonize = 1;
 
1610
                        break;
 
1611
                case 'g':
 
1612
                        global = optarg;
 
1613
                        break;
 
1614
                case 'h':
 
1615
                        usage();
 
1616
                        return 0;
 
1617
                case 'v':
 
1618
                        printf("%s\n", wpa_cli_version);
 
1619
                        return 0;
 
1620
                case 'i':
 
1621
                        os_free(ctrl_ifname);
 
1622
                        ctrl_ifname = os_strdup(optarg);
 
1623
                        break;
 
1624
                case 'p':
 
1625
                        ctrl_iface_dir = optarg;
 
1626
                        break;
 
1627
                case 'P':
 
1628
                        pid_file = optarg;
 
1629
                        break;
 
1630
                default:
 
1631
                        usage();
 
1632
                        return -1;
 
1633
                }
 
1634
        }
 
1635
 
 
1636
        interactive = (argc == optind) && (action_file == NULL);
 
1637
 
 
1638
        if (interactive)
 
1639
                printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license);
 
1640
 
 
1641
        if (global) {
 
1642
#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
 
1643
                ctrl_conn = wpa_ctrl_open(NULL);
 
1644
#else /* CONFIG_CTRL_IFACE_NAMED_PIPE */
 
1645
                ctrl_conn = wpa_ctrl_open(global);
 
1646
#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
 
1647
                if (ctrl_conn == NULL) {
 
1648
                        perror("Failed to connect to wpa_supplicant - "
 
1649
                               "wpa_ctrl_open");
 
1650
                        return -1;
 
1651
                }
 
1652
        }
 
1653
 
 
1654
        for (; !global;) {
 
1655
                if (ctrl_ifname == NULL)
 
1656
                        ctrl_ifname = wpa_cli_get_default_ifname();
 
1657
                ctrl_conn = wpa_cli_open_connection(ctrl_ifname);
 
1658
                if (ctrl_conn) {
 
1659
                        if (warning_displayed)
 
1660
                                printf("Connection established.\n");
 
1661
                        break;
 
1662
                }
 
1663
 
 
1664
                if (!interactive) {
 
1665
                        perror("Failed to connect to wpa_supplicant - "
 
1666
                               "wpa_ctrl_open");
 
1667
                        return -1;
 
1668
                }
 
1669
 
 
1670
                if (!warning_displayed) {
 
1671
                        printf("Could not connect to wpa_supplicant - "
 
1672
                               "re-trying\n");
 
1673
                        warning_displayed = 1;
 
1674
                }
 
1675
                os_sleep(1, 0);
 
1676
                continue;
 
1677
        }
 
1678
 
 
1679
#ifndef _WIN32_WCE
 
1680
        signal(SIGINT, wpa_cli_terminate);
 
1681
        signal(SIGTERM, wpa_cli_terminate);
 
1682
#endif /* _WIN32_WCE */
 
1683
#ifndef CONFIG_NATIVE_WINDOWS
 
1684
        signal(SIGALRM, wpa_cli_alarm);
 
1685
#endif /* CONFIG_NATIVE_WINDOWS */
 
1686
 
 
1687
        if (interactive || action_file) {
 
1688
                if (wpa_ctrl_attach(ctrl_conn) == 0) {
 
1689
                        wpa_cli_attached = 1;
 
1690
                } else {
 
1691
                        printf("Warning: Failed to attach to "
 
1692
                               "wpa_supplicant.\n");
 
1693
                        if (!interactive)
 
1694
                                return -1;
 
1695
                }
 
1696
        }
 
1697
 
 
1698
        if (daemonize && os_daemonize(pid_file))
 
1699
                return -1;
 
1700
 
 
1701
        if (interactive)
 
1702
                wpa_cli_interactive();
 
1703
        else if (action_file)
 
1704
                wpa_cli_action(ctrl_conn);
 
1705
        else
 
1706
                ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
 
1707
 
 
1708
        os_free(ctrl_ifname);
 
1709
        wpa_cli_cleanup();
 
1710
 
 
1711
        return ret;
 
1712
}
 
1713
 
 
1714
#else /* CONFIG_CTRL_IFACE */
 
1715
int main(int argc, char *argv[])
 
1716
{
 
1717
        printf("CONFIG_CTRL_IFACE not defined - wpa_cli disabled\n");
 
1718
        return -1;
 
1719
}
 
1720
#endif /* CONFIG_CTRL_IFACE */