Preparations for v0.7.1 release
[libeap.git] / hostapd / hostapd_cli.c
1 /*
2  * hostapd - command line interface for hostapd daemon
3  * Copyright (c) 2004-2010, 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 #include <dirent.h>
17
18 #include "common/wpa_ctrl.h"
19 #include "common.h"
20 #include "common/version.h"
21
22
23 static const char *hostapd_cli_version =
24 "hostapd_cli v" VERSION_STR "\n"
25 "Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi> and contributors";
26
27
28 static const char *hostapd_cli_license =
29 "This program is free software. You can distribute it and/or modify it\n"
30 "under the terms of the GNU General Public License version 2.\n"
31 "\n"
32 "Alternatively, this software may be distributed under the terms of the\n"
33 "BSD license. See README and COPYING for more details.\n";
34
35 static const char *hostapd_cli_full_license =
36 "This program is free software; you can redistribute it and/or modify\n"
37 "it under the terms of the GNU General Public License version 2 as\n"
38 "published by the Free Software Foundation.\n"
39 "\n"
40 "This program is distributed in the hope that it will be useful,\n"
41 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
42 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
43 "GNU General Public License for more details.\n"
44 "\n"
45 "You should have received a copy of the GNU General Public License\n"
46 "along with this program; if not, write to the Free Software\n"
47 "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\n"
48 "\n"
49 "Alternatively, this software may be distributed under the terms of the\n"
50 "BSD license.\n"
51 "\n"
52 "Redistribution and use in source and binary forms, with or without\n"
53 "modification, are permitted provided that the following conditions are\n"
54 "met:\n"
55 "\n"
56 "1. Redistributions of source code must retain the above copyright\n"
57 "   notice, this list of conditions and the following disclaimer.\n"
58 "\n"
59 "2. Redistributions in binary form must reproduce the above copyright\n"
60 "   notice, this list of conditions and the following disclaimer in the\n"
61 "   documentation and/or other materials provided with the distribution.\n"
62 "\n"
63 "3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
64 "   names of its contributors may be used to endorse or promote products\n"
65 "   derived from this software without specific prior written permission.\n"
66 "\n"
67 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
68 "\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
69 "LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
70 "A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
71 "OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
72 "SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
73 "LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
74 "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
75 "THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
76 "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
77 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
78 "\n";
79
80 static const char *commands_help =
81 "Commands:\n"
82 "   mib                  get MIB variables (dot1x, dot11, radius)\n"
83 "   sta <addr>           get MIB variables for one station\n"
84 "   all_sta              get MIB variables for all stations\n"
85 "   new_sta <addr>       add a new station\n"
86 #ifdef CONFIG_IEEE80211W
87 "   sa_query <addr>      send SA Query to a station\n"
88 #endif /* CONFIG_IEEE80211W */
89 #ifdef CONFIG_WPS
90 "   wps_pin <uuid> <pin> [timeout]  add WPS Enrollee PIN (Device Password)\n"
91 "   wps_pbc              indicate button pushed to initiate PBC\n"
92 #ifdef CONFIG_WPS_OOB
93 "   wps_oob <type> <path> <method>  use WPS with out-of-band (UFD)\n"
94 #endif /* CONFIG_WPS_OOB */
95 #endif /* CONFIG_WPS */
96 "   help                 show this usage help\n"
97 "   interface [ifname]   show interfaces/select interface\n"
98 "   level <debug level>  change debug level\n"
99 "   license              show full hostapd_cli license\n"
100 "   quit                 exit hostapd_cli\n";
101
102 static struct wpa_ctrl *ctrl_conn;
103 static int hostapd_cli_quit = 0;
104 static int hostapd_cli_attached = 0;
105 static const char *ctrl_iface_dir = "/var/run/hostapd";
106 static char *ctrl_ifname = NULL;
107 static int ping_interval = 5;
108
109
110 static void usage(void)
111 {
112         fprintf(stderr, "%s\n", hostapd_cli_version);
113         fprintf(stderr, 
114                 "\n"    
115                 "usage: hostapd_cli [-p<path>] [-i<ifname>] [-hv] "
116                 "[-G<ping interval>] \\\n"
117                 "        [command..]\n"
118                 "\n"
119                 "Options:\n"
120                 "   -h           help (show this usage text)\n"
121                 "   -v           shown version information\n"
122                 "   -p<path>     path to find control sockets (default: "
123                 "/var/run/hostapd)\n"
124                 "   -i<ifname>   Interface to listen on (default: first "
125                 "interface found in the\n"
126                 "                socket path)\n\n"
127                 "%s",
128                 commands_help);
129 }
130
131
132 static struct wpa_ctrl * hostapd_cli_open_connection(const char *ifname)
133 {
134         char *cfile;
135         int flen;
136
137         if (ifname == NULL)
138                 return NULL;
139
140         flen = strlen(ctrl_iface_dir) + strlen(ifname) + 2;
141         cfile = malloc(flen);
142         if (cfile == NULL)
143                 return NULL;
144         snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ifname);
145
146         ctrl_conn = wpa_ctrl_open(cfile);
147         free(cfile);
148         return ctrl_conn;
149 }
150
151
152 static void hostapd_cli_close_connection(void)
153 {
154         if (ctrl_conn == NULL)
155                 return;
156
157         if (hostapd_cli_attached) {
158                 wpa_ctrl_detach(ctrl_conn);
159                 hostapd_cli_attached = 0;
160         }
161         wpa_ctrl_close(ctrl_conn);
162         ctrl_conn = NULL;
163 }
164
165
166 static void hostapd_cli_msg_cb(char *msg, size_t len)
167 {
168         printf("%s\n", msg);
169 }
170
171
172 static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
173 {
174         char buf[4096];
175         size_t len;
176         int ret;
177
178         if (ctrl_conn == NULL) {
179                 printf("Not connected to hostapd - command dropped.\n");
180                 return -1;
181         }
182         len = sizeof(buf) - 1;
183         ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
184                                hostapd_cli_msg_cb);
185         if (ret == -2) {
186                 printf("'%s' command timed out.\n", cmd);
187                 return -2;
188         } else if (ret < 0) {
189                 printf("'%s' command failed.\n", cmd);
190                 return -1;
191         }
192         if (print) {
193                 buf[len] = '\0';
194                 printf("%s", buf);
195         }
196         return 0;
197 }
198
199
200 static inline int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
201 {
202         return _wpa_ctrl_command(ctrl, cmd, 1);
203 }
204
205
206 static int hostapd_cli_cmd_ping(struct wpa_ctrl *ctrl, int argc, char *argv[])
207 {
208         return wpa_ctrl_command(ctrl, "PING");
209 }
210
211
212 static int hostapd_cli_cmd_mib(struct wpa_ctrl *ctrl, int argc, char *argv[])
213 {
214         return wpa_ctrl_command(ctrl, "MIB");
215 }
216
217
218 static int hostapd_cli_cmd_sta(struct wpa_ctrl *ctrl, int argc, char *argv[])
219 {
220         char buf[64];
221         if (argc != 1) {
222                 printf("Invalid 'sta' command - exactly one argument, STA "
223                        "address, is required.\n");
224                 return -1;
225         }
226         snprintf(buf, sizeof(buf), "STA %s", argv[0]);
227         return wpa_ctrl_command(ctrl, buf);
228 }
229
230
231 static int hostapd_cli_cmd_new_sta(struct wpa_ctrl *ctrl, int argc,
232                                    char *argv[])
233 {
234         char buf[64];
235         if (argc != 1) {
236                 printf("Invalid 'new_sta' command - exactly one argument, STA "
237                        "address, is required.\n");
238                 return -1;
239         }
240         snprintf(buf, sizeof(buf), "NEW_STA %s", argv[0]);
241         return wpa_ctrl_command(ctrl, buf);
242 }
243
244
245 #ifdef CONFIG_IEEE80211W
246 static int hostapd_cli_cmd_sa_query(struct wpa_ctrl *ctrl, int argc,
247                                     char *argv[])
248 {
249         char buf[64];
250         if (argc != 1) {
251                 printf("Invalid 'sa_query' command - exactly one argument, "
252                        "STA address, is required.\n");
253                 return -1;
254         }
255         snprintf(buf, sizeof(buf), "SA_QUERY %s", argv[0]);
256         return wpa_ctrl_command(ctrl, buf);
257 }
258 #endif /* CONFIG_IEEE80211W */
259
260
261 #ifdef CONFIG_WPS
262 static int hostapd_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc,
263                                    char *argv[])
264 {
265         char buf[64];
266         if (argc < 2) {
267                 printf("Invalid 'wps_pin' command - at least two arguments, "
268                        "UUID and PIN, are required.\n");
269                 return -1;
270         }
271         if (argc > 2)
272                 snprintf(buf, sizeof(buf), "WPS_PIN %s %s %s",
273                          argv[0], argv[1], argv[2]);
274         else
275                 snprintf(buf, sizeof(buf), "WPS_PIN %s %s", argv[0], argv[1]);
276         return wpa_ctrl_command(ctrl, buf);
277 }
278
279
280 static int hostapd_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc,
281                                    char *argv[])
282 {
283         return wpa_ctrl_command(ctrl, "WPS_PBC");
284 }
285
286
287 #ifdef CONFIG_WPS_OOB
288 static int hostapd_cli_cmd_wps_oob(struct wpa_ctrl *ctrl, int argc,
289                                    char *argv[])
290 {
291         char cmd[256];
292         int res;
293
294         if (argc != 3 && argc != 4) {
295                 printf("Invalid WPS_OOB command: need three or four "
296                        "arguments:\n"
297                        "- DEV_TYPE: use 'ufd' or 'nfc'\n"
298                        "- PATH: path of OOB device like '/mnt'\n"
299                        "- METHOD: OOB method 'pin-e' or 'pin-r', "
300                        "'cred'\n"
301                        "- DEV_NAME: (only for NFC) device name like "
302                        "'pn531'\n");
303                 return -1;
304         }
305
306         if (argc == 3)
307                 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s",
308                                   argv[0], argv[1], argv[2]);
309         else
310                 res = os_snprintf(cmd, sizeof(cmd), "WPS_OOB %s %s %s %s",
311                                   argv[0], argv[1], argv[2], argv[3]);
312         if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
313                 printf("Too long WPS_OOB command.\n");
314                 return -1;
315         }
316         return wpa_ctrl_command(ctrl, cmd);
317 }
318 #endif /* CONFIG_WPS_OOB */
319 #endif /* CONFIG_WPS */
320
321
322 static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
323                                 char *addr, size_t addr_len)
324 {
325         char buf[4096], *pos;
326         size_t len;
327         int ret;
328
329         if (ctrl_conn == NULL) {
330                 printf("Not connected to hostapd - command dropped.\n");
331                 return -1;
332         }
333         len = sizeof(buf) - 1;
334         ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
335                                hostapd_cli_msg_cb);
336         if (ret == -2) {
337                 printf("'%s' command timed out.\n", cmd);
338                 return -2;
339         } else if (ret < 0) {
340                 printf("'%s' command failed.\n", cmd);
341                 return -1;
342         }
343
344         buf[len] = '\0';
345         if (memcmp(buf, "FAIL", 4) == 0)
346                 return -1;
347         printf("%s", buf);
348
349         pos = buf;
350         while (*pos != '\0' && *pos != '\n')
351                 pos++;
352         *pos = '\0';
353         os_strlcpy(addr, buf, addr_len);
354         return 0;
355 }
356
357
358 static int hostapd_cli_cmd_all_sta(struct wpa_ctrl *ctrl, int argc,
359                                    char *argv[])
360 {
361         char addr[32], cmd[64];
362
363         if (wpa_ctrl_command_sta(ctrl, "STA-FIRST", addr, sizeof(addr)))
364                 return 0;
365         do {
366                 snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
367         } while (wpa_ctrl_command_sta(ctrl, cmd, addr, sizeof(addr)) == 0);
368
369         return -1;
370 }
371
372
373 static int hostapd_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
374 {
375         printf("%s", commands_help);
376         return 0;
377 }
378
379
380 static int hostapd_cli_cmd_license(struct wpa_ctrl *ctrl, int argc,
381                                    char *argv[])
382 {
383         printf("%s\n\n%s\n", hostapd_cli_version, hostapd_cli_full_license);
384         return 0;
385 }
386
387
388 static int hostapd_cli_cmd_quit(struct wpa_ctrl *ctrl, int argc, char *argv[])
389 {
390         hostapd_cli_quit = 1;
391         return 0;
392 }
393
394
395 static int hostapd_cli_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
396 {
397         char cmd[256];
398         if (argc != 1) {
399                 printf("Invalid LEVEL command: needs one argument (debug "
400                        "level)\n");
401                 return 0;
402         }
403         snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
404         return wpa_ctrl_command(ctrl, cmd);
405 }
406
407
408 static void hostapd_cli_list_interfaces(struct wpa_ctrl *ctrl)
409 {
410         struct dirent *dent;
411         DIR *dir;
412
413         dir = opendir(ctrl_iface_dir);
414         if (dir == NULL) {
415                 printf("Control interface directory '%s' could not be "
416                        "openned.\n", ctrl_iface_dir);
417                 return;
418         }
419
420         printf("Available interfaces:\n");
421         while ((dent = readdir(dir))) {
422                 if (strcmp(dent->d_name, ".") == 0 ||
423                     strcmp(dent->d_name, "..") == 0)
424                         continue;
425                 printf("%s\n", dent->d_name);
426         }
427         closedir(dir);
428 }
429
430
431 static int hostapd_cli_cmd_interface(struct wpa_ctrl *ctrl, int argc,
432                                      char *argv[])
433 {
434         if (argc < 1) {
435                 hostapd_cli_list_interfaces(ctrl);
436                 return 0;
437         }
438
439         hostapd_cli_close_connection();
440         free(ctrl_ifname);
441         ctrl_ifname = strdup(argv[0]);
442
443         if (hostapd_cli_open_connection(ctrl_ifname)) {
444                 printf("Connected to interface '%s.\n", ctrl_ifname);
445                 if (wpa_ctrl_attach(ctrl_conn) == 0) {
446                         hostapd_cli_attached = 1;
447                 } else {
448                         printf("Warning: Failed to attach to "
449                                "hostapd.\n");
450                 }
451         } else {
452                 printf("Could not connect to interface '%s' - re-trying\n",
453                         ctrl_ifname);
454         }
455         return 0;
456 }
457
458
459 struct hostapd_cli_cmd {
460         const char *cmd;
461         int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
462 };
463
464 static struct hostapd_cli_cmd hostapd_cli_commands[] = {
465         { "ping", hostapd_cli_cmd_ping },
466         { "mib", hostapd_cli_cmd_mib },
467         { "sta", hostapd_cli_cmd_sta },
468         { "all_sta", hostapd_cli_cmd_all_sta },
469         { "new_sta", hostapd_cli_cmd_new_sta },
470 #ifdef CONFIG_IEEE80211W
471         { "sa_query", hostapd_cli_cmd_sa_query },
472 #endif /* CONFIG_IEEE80211W */
473 #ifdef CONFIG_WPS
474         { "wps_pin", hostapd_cli_cmd_wps_pin },
475         { "wps_pbc", hostapd_cli_cmd_wps_pbc },
476 #ifdef CONFIG_WPS_OOB
477         { "wps_oob", hostapd_cli_cmd_wps_oob },
478 #endif /* CONFIG_WPS_OOB */
479 #endif /* CONFIG_WPS */
480         { "help", hostapd_cli_cmd_help },
481         { "interface", hostapd_cli_cmd_interface },
482         { "level", hostapd_cli_cmd_level },
483         { "license", hostapd_cli_cmd_license },
484         { "quit", hostapd_cli_cmd_quit },
485         { NULL, NULL }
486 };
487
488
489 static void wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
490 {
491         struct hostapd_cli_cmd *cmd, *match = NULL;
492         int count;
493
494         count = 0;
495         cmd = hostapd_cli_commands;
496         while (cmd->cmd) {
497                 if (strncasecmp(cmd->cmd, argv[0], strlen(argv[0])) == 0) {
498                         match = cmd;
499                         count++;
500                 }
501                 cmd++;
502         }
503
504         if (count > 1) {
505                 printf("Ambiguous command '%s'; possible commands:", argv[0]);
506                 cmd = hostapd_cli_commands;
507                 while (cmd->cmd) {
508                         if (strncasecmp(cmd->cmd, argv[0], strlen(argv[0])) ==
509                             0) {
510                                 printf(" %s", cmd->cmd);
511                         }
512                         cmd++;
513                 }
514                 printf("\n");
515         } else if (count == 0) {
516                 printf("Unknown command '%s'\n", argv[0]);
517         } else {
518                 match->handler(ctrl, argc - 1, &argv[1]);
519         }
520 }
521
522
523 static void hostapd_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read)
524 {
525         int first = 1;
526         if (ctrl_conn == NULL)
527                 return;
528         while (wpa_ctrl_pending(ctrl)) {
529                 char buf[256];
530                 size_t len = sizeof(buf) - 1;
531                 if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
532                         buf[len] = '\0';
533                         if (in_read && first)
534                                 printf("\n");
535                         first = 0;
536                         printf("%s\n", buf);
537                 } else {
538                         printf("Could not read pending message.\n");
539                         break;
540                 }
541         }
542 }
543
544
545 static void hostapd_cli_interactive(void)
546 {
547         const int max_args = 10;
548         char cmd[256], *res, *argv[max_args], *pos;
549         int argc;
550
551         printf("\nInteractive mode\n\n");
552
553         do {
554                 hostapd_cli_recv_pending(ctrl_conn, 0);
555                 printf("> ");
556                 alarm(ping_interval);
557                 res = fgets(cmd, sizeof(cmd), stdin);
558                 alarm(0);
559                 if (res == NULL)
560                         break;
561                 pos = cmd;
562                 while (*pos != '\0') {
563                         if (*pos == '\n') {
564                                 *pos = '\0';
565                                 break;
566                         }
567                         pos++;
568                 }
569                 argc = 0;
570                 pos = cmd;
571                 for (;;) {
572                         while (*pos == ' ')
573                                 pos++;
574                         if (*pos == '\0')
575                                 break;
576                         argv[argc] = pos;
577                         argc++;
578                         if (argc == max_args)
579                                 break;
580                         while (*pos != '\0' && *pos != ' ')
581                                 pos++;
582                         if (*pos == ' ')
583                                 *pos++ = '\0';
584                 }
585                 if (argc)
586                         wpa_request(ctrl_conn, argc, argv);
587         } while (!hostapd_cli_quit);
588 }
589
590
591 static void hostapd_cli_terminate(int sig)
592 {
593         hostapd_cli_close_connection();
594         exit(0);
595 }
596
597
598 static void hostapd_cli_alarm(int sig)
599 {
600         if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) {
601                 printf("Connection to hostapd lost - trying to reconnect\n");
602                 hostapd_cli_close_connection();
603         }
604         if (!ctrl_conn) {
605                 ctrl_conn = hostapd_cli_open_connection(ctrl_ifname);
606                 if (ctrl_conn) {
607                         printf("Connection to hostapd re-established\n");
608                         if (wpa_ctrl_attach(ctrl_conn) == 0) {
609                                 hostapd_cli_attached = 1;
610                         } else {
611                                 printf("Warning: Failed to attach to "
612                                        "hostapd.\n");
613                         }
614                 }
615         }
616         if (ctrl_conn)
617                 hostapd_cli_recv_pending(ctrl_conn, 1);
618         alarm(ping_interval);
619 }
620
621
622 int main(int argc, char *argv[])
623 {
624         int interactive;
625         int warning_displayed = 0;
626         int c;
627
628         if (os_program_init())
629                 return -1;
630
631         for (;;) {
632                 c = getopt(argc, argv, "hG:i:p:v");
633                 if (c < 0)
634                         break;
635                 switch (c) {
636                 case 'G':
637                         ping_interval = atoi(optarg);
638                         break;
639                 case 'h':
640                         usage();
641                         return 0;
642                 case 'v':
643                         printf("%s\n", hostapd_cli_version);
644                         return 0;
645                 case 'i':
646                         free(ctrl_ifname);
647                         ctrl_ifname = strdup(optarg);
648                         break;
649                 case 'p':
650                         ctrl_iface_dir = optarg;
651                         break;
652                 default:
653                         usage();
654                         return -1;
655                 }
656         }
657
658         interactive = argc == optind;
659
660         if (interactive) {
661                 printf("%s\n\n%s\n\n", hostapd_cli_version,
662                        hostapd_cli_license);
663         }
664
665         for (;;) {
666                 if (ctrl_ifname == NULL) {
667                         struct dirent *dent;
668                         DIR *dir = opendir(ctrl_iface_dir);
669                         if (dir) {
670                                 while ((dent = readdir(dir))) {
671                                         if (strcmp(dent->d_name, ".") == 0 ||
672                                             strcmp(dent->d_name, "..") == 0)
673                                                 continue;
674                                         printf("Selected interface '%s'\n",
675                                                dent->d_name);
676                                         ctrl_ifname = strdup(dent->d_name);
677                                         break;
678                                 }
679                                 closedir(dir);
680                         }
681                 }
682                 ctrl_conn = hostapd_cli_open_connection(ctrl_ifname);
683                 if (ctrl_conn) {
684                         if (warning_displayed)
685                                 printf("Connection established.\n");
686                         break;
687                 }
688
689                 if (!interactive) {
690                         perror("Failed to connect to hostapd - "
691                                "wpa_ctrl_open");
692                         return -1;
693                 }
694
695                 if (!warning_displayed) {
696                         printf("Could not connect to hostapd - re-trying\n");
697                         warning_displayed = 1;
698                 }
699                 sleep(1);
700                 continue;
701         }
702
703         signal(SIGINT, hostapd_cli_terminate);
704         signal(SIGTERM, hostapd_cli_terminate);
705         signal(SIGALRM, hostapd_cli_alarm);
706
707         if (interactive) {
708                 if (wpa_ctrl_attach(ctrl_conn) == 0) {
709                         hostapd_cli_attached = 1;
710                 } else {
711                         printf("Warning: Failed to attach to hostapd.\n");
712                 }
713                 hostapd_cli_interactive();
714         } else
715                 wpa_request(ctrl_conn, argc - optind, &argv[optind]);
716
717         free(ctrl_ifname);
718         hostapd_cli_close_connection();
719         os_program_deinit();
720         return 0;
721 }