~ubuntu-branches/ubuntu/gutsy/wpasupplicant/gutsy

« back to all changes in this revision

Viewing changes to wpa_cli.c

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler, Alexander Sack
  • Date: 2007-08-26 16:06:57 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20070826160657-2m8pxoweuxe8f93t
Tags: 0.6.0+0.5.8-0ubuntu1
* New upstream release
* remove patch 11_erroneous_manpage_ref, applied upstream
* remove patch 25_wpas_dbus_unregister_iface_fix, applied upstream

[ Alexander Sack ]
* bumping upstream version to replace development version 0.6.0 with
  this package from stable release branch.
* attempt to fix wierd timeout and high latency issues by going
  back to stable upstream version (0.5.9) (LP: #140763,
  LP: #141233).

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