Add EAPOL_REAUTH hostapd command to trigger EAPOL reauthentication
[mech_eap.git] / hostapd / ctrl_iface.c
1 /*
2  * hostapd / UNIX domain socket -based control interface
3  * Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8
9 #include "utils/includes.h"
10
11 #ifndef CONFIG_NATIVE_WINDOWS
12
13 #ifdef CONFIG_TESTING_OPTIONS
14 #include <net/ethernet.h>
15 #include <netinet/ip.h>
16 #endif /* CONFIG_TESTING_OPTIONS */
17
18 #include <sys/un.h>
19 #include <sys/stat.h>
20 #include <stddef.h>
21
22 #include "utils/common.h"
23 #include "utils/eloop.h"
24 #include "common/version.h"
25 #include "common/ieee802_11_defs.h"
26 #include "crypto/tls.h"
27 #include "drivers/driver.h"
28 #include "eapol_auth/eapol_auth_sm.h"
29 #include "radius/radius_client.h"
30 #include "radius/radius_server.h"
31 #include "l2_packet/l2_packet.h"
32 #include "ap/hostapd.h"
33 #include "ap/ap_config.h"
34 #include "ap/ieee802_1x.h"
35 #include "ap/wpa_auth.h"
36 #include "ap/ieee802_11.h"
37 #include "ap/sta_info.h"
38 #include "ap/wps_hostapd.h"
39 #include "ap/ctrl_iface_ap.h"
40 #include "ap/ap_drv_ops.h"
41 #include "ap/hs20.h"
42 #include "ap/wnm_ap.h"
43 #include "ap/wpa_auth.h"
44 #include "ap/beacon.h"
45 #include "wps/wps_defs.h"
46 #include "wps/wps.h"
47 #include "config_file.h"
48 #include "ctrl_iface.h"
49
50
51 struct wpa_ctrl_dst {
52         struct wpa_ctrl_dst *next;
53         struct sockaddr_un addr;
54         socklen_t addrlen;
55         int debug_level;
56         int errors;
57 };
58
59
60 static void hostapd_ctrl_iface_send(struct hostapd_data *hapd, int level,
61                                     const char *buf, size_t len);
62
63
64 static int hostapd_ctrl_iface_attach(struct hostapd_data *hapd,
65                                      struct sockaddr_un *from,
66                                      socklen_t fromlen)
67 {
68         struct wpa_ctrl_dst *dst;
69
70         dst = os_zalloc(sizeof(*dst));
71         if (dst == NULL)
72                 return -1;
73         os_memcpy(&dst->addr, from, sizeof(struct sockaddr_un));
74         dst->addrlen = fromlen;
75         dst->debug_level = MSG_INFO;
76         dst->next = hapd->ctrl_dst;
77         hapd->ctrl_dst = dst;
78         wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor attached",
79                     (u8 *) from->sun_path,
80                     fromlen - offsetof(struct sockaddr_un, sun_path));
81         return 0;
82 }
83
84
85 static int hostapd_ctrl_iface_detach(struct hostapd_data *hapd,
86                                      struct sockaddr_un *from,
87                                      socklen_t fromlen)
88 {
89         struct wpa_ctrl_dst *dst, *prev = NULL;
90
91         dst = hapd->ctrl_dst;
92         while (dst) {
93                 if (fromlen == dst->addrlen &&
94                     os_memcmp(from->sun_path, dst->addr.sun_path,
95                               fromlen - offsetof(struct sockaddr_un, sun_path))
96                     == 0) {
97                         wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor detached",
98                                     (u8 *) from->sun_path,
99                                     fromlen -
100                                     offsetof(struct sockaddr_un, sun_path));
101                         if (prev == NULL)
102                                 hapd->ctrl_dst = dst->next;
103                         else
104                                 prev->next = dst->next;
105                         os_free(dst);
106                         return 0;
107                 }
108                 prev = dst;
109                 dst = dst->next;
110         }
111         return -1;
112 }
113
114
115 static int hostapd_ctrl_iface_level(struct hostapd_data *hapd,
116                                     struct sockaddr_un *from,
117                                     socklen_t fromlen,
118                                     char *level)
119 {
120         struct wpa_ctrl_dst *dst;
121
122         wpa_printf(MSG_DEBUG, "CTRL_IFACE LEVEL %s", level);
123
124         dst = hapd->ctrl_dst;
125         while (dst) {
126                 if (fromlen == dst->addrlen &&
127                     os_memcmp(from->sun_path, dst->addr.sun_path,
128                               fromlen - offsetof(struct sockaddr_un, sun_path))
129                     == 0) {
130                         wpa_hexdump(MSG_DEBUG, "CTRL_IFACE changed monitor "
131                                     "level", (u8 *) from->sun_path, fromlen -
132                                     offsetof(struct sockaddr_un, sun_path));
133                         dst->debug_level = atoi(level);
134                         return 0;
135                 }
136                 dst = dst->next;
137         }
138
139         return -1;
140 }
141
142
143 static int hostapd_ctrl_iface_new_sta(struct hostapd_data *hapd,
144                                       const char *txtaddr)
145 {
146         u8 addr[ETH_ALEN];
147         struct sta_info *sta;
148
149         wpa_printf(MSG_DEBUG, "CTRL_IFACE NEW_STA %s", txtaddr);
150
151         if (hwaddr_aton(txtaddr, addr))
152                 return -1;
153
154         sta = ap_get_sta(hapd, addr);
155         if (sta)
156                 return 0;
157
158         wpa_printf(MSG_DEBUG, "Add new STA " MACSTR " based on ctrl_iface "
159                    "notification", MAC2STR(addr));
160         sta = ap_sta_add(hapd, addr);
161         if (sta == NULL)
162                 return -1;
163
164         hostapd_new_assoc_sta(hapd, sta, 0);
165         return 0;
166 }
167
168
169 #ifdef CONFIG_IEEE80211W
170 #ifdef NEED_AP_MLME
171 static int hostapd_ctrl_iface_sa_query(struct hostapd_data *hapd,
172                                        const char *txtaddr)
173 {
174         u8 addr[ETH_ALEN];
175         u8 trans_id[WLAN_SA_QUERY_TR_ID_LEN];
176
177         wpa_printf(MSG_DEBUG, "CTRL_IFACE SA_QUERY %s", txtaddr);
178
179         if (hwaddr_aton(txtaddr, addr) ||
180             os_get_random(trans_id, WLAN_SA_QUERY_TR_ID_LEN) < 0)
181                 return -1;
182
183         ieee802_11_send_sa_query_req(hapd, addr, trans_id);
184
185         return 0;
186 }
187 #endif /* NEED_AP_MLME */
188 #endif /* CONFIG_IEEE80211W */
189
190
191 #ifdef CONFIG_WPS
192 static int hostapd_ctrl_iface_wps_pin(struct hostapd_data *hapd, char *txt)
193 {
194         char *pin = os_strchr(txt, ' ');
195         char *timeout_txt;
196         int timeout;
197         u8 addr_buf[ETH_ALEN], *addr = NULL;
198         char *pos;
199
200         if (pin == NULL)
201                 return -1;
202         *pin++ = '\0';
203
204         timeout_txt = os_strchr(pin, ' ');
205         if (timeout_txt) {
206                 *timeout_txt++ = '\0';
207                 timeout = atoi(timeout_txt);
208                 pos = os_strchr(timeout_txt, ' ');
209                 if (pos) {
210                         *pos++ = '\0';
211                         if (hwaddr_aton(pos, addr_buf) == 0)
212                                 addr = addr_buf;
213                 }
214         } else
215                 timeout = 0;
216
217         return hostapd_wps_add_pin(hapd, addr, txt, pin, timeout);
218 }
219
220
221 static int hostapd_ctrl_iface_wps_check_pin(
222         struct hostapd_data *hapd, char *cmd, char *buf, size_t buflen)
223 {
224         char pin[9];
225         size_t len;
226         char *pos;
227         int ret;
228
229         wpa_hexdump_ascii_key(MSG_DEBUG, "WPS_CHECK_PIN",
230                               (u8 *) cmd, os_strlen(cmd));
231         for (pos = cmd, len = 0; *pos != '\0'; pos++) {
232                 if (*pos < '0' || *pos > '9')
233                         continue;
234                 pin[len++] = *pos;
235                 if (len == 9) {
236                         wpa_printf(MSG_DEBUG, "WPS: Too long PIN");
237                         return -1;
238                 }
239         }
240         if (len != 4 && len != 8) {
241                 wpa_printf(MSG_DEBUG, "WPS: Invalid PIN length %d", (int) len);
242                 return -1;
243         }
244         pin[len] = '\0';
245
246         if (len == 8) {
247                 unsigned int pin_val;
248                 pin_val = atoi(pin);
249                 if (!wps_pin_valid(pin_val)) {
250                         wpa_printf(MSG_DEBUG, "WPS: Invalid checksum digit");
251                         ret = os_snprintf(buf, buflen, "FAIL-CHECKSUM\n");
252                         if (os_snprintf_error(buflen, ret))
253                                 return -1;
254                         return ret;
255                 }
256         }
257
258         ret = os_snprintf(buf, buflen, "%s", pin);
259         if (os_snprintf_error(buflen, ret))
260                 return -1;
261
262         return ret;
263 }
264
265
266 #ifdef CONFIG_WPS_NFC
267 static int hostapd_ctrl_iface_wps_nfc_tag_read(struct hostapd_data *hapd,
268                                                char *pos)
269 {
270         size_t len;
271         struct wpabuf *buf;
272         int ret;
273
274         len = os_strlen(pos);
275         if (len & 0x01)
276                 return -1;
277         len /= 2;
278
279         buf = wpabuf_alloc(len);
280         if (buf == NULL)
281                 return -1;
282         if (hexstr2bin(pos, wpabuf_put(buf, len), len) < 0) {
283                 wpabuf_free(buf);
284                 return -1;
285         }
286
287         ret = hostapd_wps_nfc_tag_read(hapd, buf);
288         wpabuf_free(buf);
289
290         return ret;
291 }
292
293
294 static int hostapd_ctrl_iface_wps_nfc_config_token(struct hostapd_data *hapd,
295                                                    char *cmd, char *reply,
296                                                    size_t max_len)
297 {
298         int ndef;
299         struct wpabuf *buf;
300         int res;
301
302         if (os_strcmp(cmd, "WPS") == 0)
303                 ndef = 0;
304         else if (os_strcmp(cmd, "NDEF") == 0)
305                 ndef = 1;
306         else
307                 return -1;
308
309         buf = hostapd_wps_nfc_config_token(hapd, ndef);
310         if (buf == NULL)
311                 return -1;
312
313         res = wpa_snprintf_hex_uppercase(reply, max_len, wpabuf_head(buf),
314                                          wpabuf_len(buf));
315         reply[res++] = '\n';
316         reply[res] = '\0';
317
318         wpabuf_free(buf);
319
320         return res;
321 }
322
323
324 static int hostapd_ctrl_iface_wps_nfc_token_gen(struct hostapd_data *hapd,
325                                                 char *reply, size_t max_len,
326                                                 int ndef)
327 {
328         struct wpabuf *buf;
329         int res;
330
331         buf = hostapd_wps_nfc_token_gen(hapd, ndef);
332         if (buf == NULL)
333                 return -1;
334
335         res = wpa_snprintf_hex_uppercase(reply, max_len, wpabuf_head(buf),
336                                          wpabuf_len(buf));
337         reply[res++] = '\n';
338         reply[res] = '\0';
339
340         wpabuf_free(buf);
341
342         return res;
343 }
344
345
346 static int hostapd_ctrl_iface_wps_nfc_token(struct hostapd_data *hapd,
347                                             char *cmd, char *reply,
348                                             size_t max_len)
349 {
350         if (os_strcmp(cmd, "WPS") == 0)
351                 return hostapd_ctrl_iface_wps_nfc_token_gen(hapd, reply,
352                                                             max_len, 0);
353
354         if (os_strcmp(cmd, "NDEF") == 0)
355                 return hostapd_ctrl_iface_wps_nfc_token_gen(hapd, reply,
356                                                             max_len, 1);
357
358         if (os_strcmp(cmd, "enable") == 0)
359                 return hostapd_wps_nfc_token_enable(hapd);
360
361         if (os_strcmp(cmd, "disable") == 0) {
362                 hostapd_wps_nfc_token_disable(hapd);
363                 return 0;
364         }
365
366         return -1;
367 }
368
369
370 static int hostapd_ctrl_iface_nfc_get_handover_sel(struct hostapd_data *hapd,
371                                                    char *cmd, char *reply,
372                                                    size_t max_len)
373 {
374         struct wpabuf *buf;
375         int res;
376         char *pos;
377         int ndef;
378
379         pos = os_strchr(cmd, ' ');
380         if (pos == NULL)
381                 return -1;
382         *pos++ = '\0';
383
384         if (os_strcmp(cmd, "WPS") == 0)
385                 ndef = 0;
386         else if (os_strcmp(cmd, "NDEF") == 0)
387                 ndef = 1;
388         else
389                 return -1;
390
391         if (os_strcmp(pos, "WPS-CR") == 0)
392                 buf = hostapd_wps_nfc_hs_cr(hapd, ndef);
393         else
394                 buf = NULL;
395         if (buf == NULL)
396                 return -1;
397
398         res = wpa_snprintf_hex_uppercase(reply, max_len, wpabuf_head(buf),
399                                          wpabuf_len(buf));
400         reply[res++] = '\n';
401         reply[res] = '\0';
402
403         wpabuf_free(buf);
404
405         return res;
406 }
407
408
409 static int hostapd_ctrl_iface_nfc_report_handover(struct hostapd_data *hapd,
410                                                   char *cmd)
411 {
412         size_t len;
413         struct wpabuf *req, *sel;
414         int ret;
415         char *pos, *role, *type, *pos2;
416
417         role = cmd;
418         pos = os_strchr(role, ' ');
419         if (pos == NULL)
420                 return -1;
421         *pos++ = '\0';
422
423         type = pos;
424         pos = os_strchr(type, ' ');
425         if (pos == NULL)
426                 return -1;
427         *pos++ = '\0';
428
429         pos2 = os_strchr(pos, ' ');
430         if (pos2 == NULL)
431                 return -1;
432         *pos2++ = '\0';
433
434         len = os_strlen(pos);
435         if (len & 0x01)
436                 return -1;
437         len /= 2;
438
439         req = wpabuf_alloc(len);
440         if (req == NULL)
441                 return -1;
442         if (hexstr2bin(pos, wpabuf_put(req, len), len) < 0) {
443                 wpabuf_free(req);
444                 return -1;
445         }
446
447         len = os_strlen(pos2);
448         if (len & 0x01) {
449                 wpabuf_free(req);
450                 return -1;
451         }
452         len /= 2;
453
454         sel = wpabuf_alloc(len);
455         if (sel == NULL) {
456                 wpabuf_free(req);
457                 return -1;
458         }
459         if (hexstr2bin(pos2, wpabuf_put(sel, len), len) < 0) {
460                 wpabuf_free(req);
461                 wpabuf_free(sel);
462                 return -1;
463         }
464
465         if (os_strcmp(role, "RESP") == 0 && os_strcmp(type, "WPS") == 0) {
466                 ret = hostapd_wps_nfc_report_handover(hapd, req, sel);
467         } else {
468                 wpa_printf(MSG_DEBUG, "NFC: Unsupported connection handover "
469                            "reported: role=%s type=%s", role, type);
470                 ret = -1;
471         }
472         wpabuf_free(req);
473         wpabuf_free(sel);
474
475         return ret;
476 }
477
478 #endif /* CONFIG_WPS_NFC */
479
480
481 static int hostapd_ctrl_iface_wps_ap_pin(struct hostapd_data *hapd, char *txt,
482                                          char *buf, size_t buflen)
483 {
484         int timeout = 300;
485         char *pos;
486         const char *pin_txt;
487
488         pos = os_strchr(txt, ' ');
489         if (pos)
490                 *pos++ = '\0';
491
492         if (os_strcmp(txt, "disable") == 0) {
493                 hostapd_wps_ap_pin_disable(hapd);
494                 return os_snprintf(buf, buflen, "OK\n");
495         }
496
497         if (os_strcmp(txt, "random") == 0) {
498                 if (pos)
499                         timeout = atoi(pos);
500                 pin_txt = hostapd_wps_ap_pin_random(hapd, timeout);
501                 if (pin_txt == NULL)
502                         return -1;
503                 return os_snprintf(buf, buflen, "%s", pin_txt);
504         }
505
506         if (os_strcmp(txt, "get") == 0) {
507                 pin_txt = hostapd_wps_ap_pin_get(hapd);
508                 if (pin_txt == NULL)
509                         return -1;
510                 return os_snprintf(buf, buflen, "%s", pin_txt);
511         }
512
513         if (os_strcmp(txt, "set") == 0) {
514                 char *pin;
515                 if (pos == NULL)
516                         return -1;
517                 pin = pos;
518                 pos = os_strchr(pos, ' ');
519                 if (pos) {
520                         *pos++ = '\0';
521                         timeout = atoi(pos);
522                 }
523                 if (os_strlen(pin) > buflen)
524                         return -1;
525                 if (hostapd_wps_ap_pin_set(hapd, pin, timeout) < 0)
526                         return -1;
527                 return os_snprintf(buf, buflen, "%s", pin);
528         }
529
530         return -1;
531 }
532
533
534 static int hostapd_ctrl_iface_wps_config(struct hostapd_data *hapd, char *txt)
535 {
536         char *pos;
537         char *ssid, *auth, *encr = NULL, *key = NULL;
538
539         ssid = txt;
540         pos = os_strchr(txt, ' ');
541         if (!pos)
542                 return -1;
543         *pos++ = '\0';
544
545         auth = pos;
546         pos = os_strchr(pos, ' ');
547         if (pos) {
548                 *pos++ = '\0';
549                 encr = pos;
550                 pos = os_strchr(pos, ' ');
551                 if (pos) {
552                         *pos++ = '\0';
553                         key = pos;
554                 }
555         }
556
557         return hostapd_wps_config_ap(hapd, ssid, auth, encr, key);
558 }
559
560
561 static const char * pbc_status_str(enum pbc_status status)
562 {
563         switch (status) {
564         case WPS_PBC_STATUS_DISABLE:
565                 return "Disabled";
566         case WPS_PBC_STATUS_ACTIVE:
567                 return "Active";
568         case WPS_PBC_STATUS_TIMEOUT:
569                 return "Timed-out";
570         case WPS_PBC_STATUS_OVERLAP:
571                 return "Overlap";
572         default:
573                 return "Unknown";
574         }
575 }
576
577
578 static int hostapd_ctrl_iface_wps_get_status(struct hostapd_data *hapd,
579                                              char *buf, size_t buflen)
580 {
581         int ret;
582         char *pos, *end;
583
584         pos = buf;
585         end = buf + buflen;
586
587         ret = os_snprintf(pos, end - pos, "PBC Status: %s\n",
588                           pbc_status_str(hapd->wps_stats.pbc_status));
589
590         if (os_snprintf_error(end - pos, ret))
591                 return pos - buf;
592         pos += ret;
593
594         ret = os_snprintf(pos, end - pos, "Last WPS result: %s\n",
595                           (hapd->wps_stats.status == WPS_STATUS_SUCCESS ?
596                            "Success":
597                            (hapd->wps_stats.status == WPS_STATUS_FAILURE ?
598                             "Failed" : "None")));
599
600         if (os_snprintf_error(end - pos, ret))
601                 return pos - buf;
602         pos += ret;
603
604         /* If status == Failure - Add possible Reasons */
605         if(hapd->wps_stats.status == WPS_STATUS_FAILURE &&
606            hapd->wps_stats.failure_reason > 0) {
607                 ret = os_snprintf(pos, end - pos,
608                                   "Failure Reason: %s\n",
609                                   wps_ei_str(hapd->wps_stats.failure_reason));
610
611                 if (os_snprintf_error(end - pos, ret))
612                         return pos - buf;
613                 pos += ret;
614         }
615
616         if (hapd->wps_stats.status) {
617                 ret = os_snprintf(pos, end - pos, "Peer Address: " MACSTR "\n",
618                                   MAC2STR(hapd->wps_stats.peer_addr));
619
620                 if (os_snprintf_error(end - pos, ret))
621                         return pos - buf;
622                 pos += ret;
623         }
624
625         return pos - buf;
626 }
627
628 #endif /* CONFIG_WPS */
629
630 #ifdef CONFIG_HS20
631
632 static int hostapd_ctrl_iface_hs20_wnm_notif(struct hostapd_data *hapd,
633                                              const char *cmd)
634 {
635         u8 addr[ETH_ALEN];
636         const char *url;
637
638         if (hwaddr_aton(cmd, addr))
639                 return -1;
640         url = cmd + 17;
641         if (*url == '\0') {
642                 url = NULL;
643         } else {
644                 if (*url != ' ')
645                         return -1;
646                 url++;
647                 if (*url == '\0')
648                         url = NULL;
649         }
650
651         return hs20_send_wnm_notification(hapd, addr, 1, url);
652 }
653
654
655 static int hostapd_ctrl_iface_hs20_deauth_req(struct hostapd_data *hapd,
656                                               const char *cmd)
657 {
658         u8 addr[ETH_ALEN];
659         int code, reauth_delay, ret;
660         const char *pos;
661         size_t url_len;
662         struct wpabuf *req;
663
664         /* <STA MAC Addr> <Code(0/1)> <Re-auth-Delay(sec)> [URL] */
665         if (hwaddr_aton(cmd, addr))
666                 return -1;
667
668         pos = os_strchr(cmd, ' ');
669         if (pos == NULL)
670                 return -1;
671         pos++;
672         code = atoi(pos);
673
674         pos = os_strchr(pos, ' ');
675         if (pos == NULL)
676                 return -1;
677         pos++;
678         reauth_delay = atoi(pos);
679
680         url_len = 0;
681         pos = os_strchr(pos, ' ');
682         if (pos) {
683                 pos++;
684                 url_len = os_strlen(pos);
685         }
686
687         req = wpabuf_alloc(4 + url_len);
688         if (req == NULL)
689                 return -1;
690         wpabuf_put_u8(req, code);
691         wpabuf_put_le16(req, reauth_delay);
692         wpabuf_put_u8(req, url_len);
693         if (pos)
694                 wpabuf_put_data(req, pos, url_len);
695
696         wpa_printf(MSG_DEBUG, "HS 2.0: Send WNM-Notification to " MACSTR
697                    " to indicate imminent deauthentication (code=%d "
698                    "reauth_delay=%d)", MAC2STR(addr), code, reauth_delay);
699         ret = hs20_send_wnm_notification_deauth_req(hapd, addr, req);
700         wpabuf_free(req);
701         return ret;
702 }
703
704 #endif /* CONFIG_HS20 */
705
706
707 #ifdef CONFIG_INTERWORKING
708
709 static int hostapd_ctrl_iface_set_qos_map_set(struct hostapd_data *hapd,
710                                               const char *cmd)
711 {
712         u8 qos_map_set[16 + 2 * 21], count = 0;
713         const char *pos = cmd;
714         int val, ret;
715
716         for (;;) {
717                 if (count == sizeof(qos_map_set)) {
718                         wpa_printf(MSG_ERROR, "Too many qos_map_set parameters");
719                         return -1;
720                 }
721
722                 val = atoi(pos);
723                 if (val < 0 || val > 255) {
724                         wpa_printf(MSG_INFO, "Invalid QoS Map Set");
725                         return -1;
726                 }
727
728                 qos_map_set[count++] = val;
729                 pos = os_strchr(pos, ',');
730                 if (!pos)
731                         break;
732                 pos++;
733         }
734
735         if (count < 16 || count & 1) {
736                 wpa_printf(MSG_INFO, "Invalid QoS Map Set");
737                 return -1;
738         }
739
740         ret = hostapd_drv_set_qos_map(hapd, qos_map_set, count);
741         if (ret) {
742                 wpa_printf(MSG_INFO, "Failed to set QoS Map Set");
743                 return -1;
744         }
745
746         os_memcpy(hapd->conf->qos_map_set, qos_map_set, count);
747         hapd->conf->qos_map_set_len = count;
748
749         return 0;
750 }
751
752
753 static int hostapd_ctrl_iface_send_qos_map_conf(struct hostapd_data *hapd,
754                                                 const char *cmd)
755 {
756         u8 addr[ETH_ALEN];
757         struct sta_info *sta;
758         struct wpabuf *buf;
759         u8 *qos_map_set = hapd->conf->qos_map_set;
760         u8 qos_map_set_len = hapd->conf->qos_map_set_len;
761         int ret;
762
763         if (!qos_map_set_len) {
764                 wpa_printf(MSG_INFO, "QoS Map Set is not set");
765                 return -1;
766         }
767
768         if (hwaddr_aton(cmd, addr))
769                 return -1;
770
771         sta = ap_get_sta(hapd, addr);
772         if (sta == NULL) {
773                 wpa_printf(MSG_DEBUG, "Station " MACSTR " not found "
774                            "for QoS Map Configuration message",
775                            MAC2STR(addr));
776                 return -1;
777         }
778
779         if (!sta->qos_map_enabled) {
780                 wpa_printf(MSG_DEBUG, "Station " MACSTR " did not indicate "
781                            "support for QoS Map", MAC2STR(addr));
782                 return -1;
783         }
784
785         buf = wpabuf_alloc(2 + 2 + qos_map_set_len);
786         if (buf == NULL)
787                 return -1;
788
789         wpabuf_put_u8(buf, WLAN_ACTION_QOS);
790         wpabuf_put_u8(buf, QOS_QOS_MAP_CONFIG);
791
792         /* QoS Map Set Element */
793         wpabuf_put_u8(buf, WLAN_EID_QOS_MAP_SET);
794         wpabuf_put_u8(buf, qos_map_set_len);
795         wpabuf_put_data(buf, qos_map_set, qos_map_set_len);
796
797         ret = hostapd_drv_send_action(hapd, hapd->iface->freq, 0, addr,
798                                       wpabuf_head(buf), wpabuf_len(buf));
799         wpabuf_free(buf);
800
801         return ret;
802 }
803
804 #endif /* CONFIG_INTERWORKING */
805
806
807 #ifdef CONFIG_WNM
808
809 static int hostapd_ctrl_iface_disassoc_imminent(struct hostapd_data *hapd,
810                                                 const char *cmd)
811 {
812         u8 addr[ETH_ALEN];
813         int disassoc_timer;
814         struct sta_info *sta;
815
816         if (hwaddr_aton(cmd, addr))
817                 return -1;
818         if (cmd[17] != ' ')
819                 return -1;
820         disassoc_timer = atoi(cmd + 17);
821
822         sta = ap_get_sta(hapd, addr);
823         if (sta == NULL) {
824                 wpa_printf(MSG_DEBUG, "Station " MACSTR
825                            " not found for disassociation imminent message",
826                            MAC2STR(addr));
827                 return -1;
828         }
829
830         return wnm_send_disassoc_imminent(hapd, sta, disassoc_timer);
831 }
832
833
834 static int hostapd_ctrl_iface_ess_disassoc(struct hostapd_data *hapd,
835                                            const char *cmd)
836 {
837         u8 addr[ETH_ALEN];
838         const char *url, *timerstr;
839         int disassoc_timer;
840         struct sta_info *sta;
841
842         if (hwaddr_aton(cmd, addr))
843                 return -1;
844
845         sta = ap_get_sta(hapd, addr);
846         if (sta == NULL) {
847                 wpa_printf(MSG_DEBUG, "Station " MACSTR
848                            " not found for ESS disassociation imminent message",
849                            MAC2STR(addr));
850                 return -1;
851         }
852
853         timerstr = cmd + 17;
854         if (*timerstr != ' ')
855                 return -1;
856         timerstr++;
857         disassoc_timer = atoi(timerstr);
858         if (disassoc_timer < 0 || disassoc_timer > 65535)
859                 return -1;
860
861         url = os_strchr(timerstr, ' ');
862         if (url == NULL)
863                 return -1;
864         url++;
865
866         return wnm_send_ess_disassoc_imminent(hapd, sta, url, disassoc_timer);
867 }
868
869
870 static int hostapd_ctrl_iface_bss_tm_req(struct hostapd_data *hapd,
871                                          const char *cmd)
872 {
873         u8 addr[ETH_ALEN];
874         const char *pos, *end;
875         int disassoc_timer = 0;
876         struct sta_info *sta;
877         u8 req_mode = 0, valid_int = 0x01;
878         u8 bss_term_dur[12];
879         char *url = NULL;
880         int ret;
881         u8 nei_rep[1000];
882         u8 *nei_pos = nei_rep;
883
884         if (hwaddr_aton(cmd, addr)) {
885                 wpa_printf(MSG_DEBUG, "Invalid STA MAC address");
886                 return -1;
887         }
888
889         sta = ap_get_sta(hapd, addr);
890         if (sta == NULL) {
891                 wpa_printf(MSG_DEBUG, "Station " MACSTR
892                            " not found for BSS TM Request message",
893                            MAC2STR(addr));
894                 return -1;
895         }
896
897         pos = os_strstr(cmd, " disassoc_timer=");
898         if (pos) {
899                 pos += 16;
900                 disassoc_timer = atoi(pos);
901                 if (disassoc_timer < 0 || disassoc_timer > 65535) {
902                         wpa_printf(MSG_DEBUG, "Invalid disassoc_timer");
903                         return -1;
904                 }
905         }
906
907         pos = os_strstr(cmd, " valid_int=");
908         if (pos) {
909                 pos += 11;
910                 valid_int = atoi(pos);
911         }
912
913         pos = os_strstr(cmd, " bss_term=");
914         if (pos) {
915                 pos += 10;
916                 req_mode |= WNM_BSS_TM_REQ_BSS_TERMINATION_INCLUDED;
917                 /* TODO: TSF configurable/learnable */
918                 bss_term_dur[0] = 4; /* Subelement ID */
919                 bss_term_dur[1] = 10; /* Length */
920                 os_memset(bss_term_dur, 2, 8);
921                 end = os_strchr(pos, ',');
922                 if (end == NULL) {
923                         wpa_printf(MSG_DEBUG, "Invalid bss_term data");
924                         return -1;
925                 }
926                 end++;
927                 WPA_PUT_LE16(&bss_term_dur[10], atoi(end));
928         }
929
930
931         /*
932          * BSS Transition Candidate List Entries - Neighbor Report elements
933          * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
934          * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
935          */
936         pos = cmd;
937         while (pos) {
938                 u8 *nei_start;
939                 long int val;
940                 char *endptr, *tmp;
941
942                 pos = os_strstr(pos, " neighbor=");
943                 if (!pos)
944                         break;
945                 if (nei_pos + 15 > nei_rep + sizeof(nei_rep)) {
946                         wpa_printf(MSG_DEBUG,
947                                    "Not enough room for additional neighbor");
948                         return -1;
949                 }
950                 pos += 10;
951
952                 nei_start = nei_pos;
953                 *nei_pos++ = WLAN_EID_NEIGHBOR_REPORT;
954                 nei_pos++; /* length to be filled in */
955
956                 if (hwaddr_aton(pos, nei_pos)) {
957                         wpa_printf(MSG_DEBUG, "Invalid BSSID");
958                         return -1;
959                 }
960                 nei_pos += ETH_ALEN;
961                 pos += 17;
962                 if (*pos != ',') {
963                         wpa_printf(MSG_DEBUG, "Missing BSSID Information");
964                         return -1;
965                 }
966                 pos++;
967
968                 val = strtol(pos, &endptr, 0);
969                 WPA_PUT_LE32(nei_pos, val);
970                 nei_pos += 4;
971                 if (*endptr != ',') {
972                         wpa_printf(MSG_DEBUG, "Missing Operating Class");
973                         return -1;
974                 }
975                 pos = endptr + 1;
976
977                 *nei_pos++ = atoi(pos); /* Operating Class */
978                 pos = os_strchr(pos, ',');
979                 if (pos == NULL) {
980                         wpa_printf(MSG_DEBUG, "Missing Channel Number");
981                         return -1;
982                 }
983                 pos++;
984
985                 *nei_pos++ = atoi(pos); /* Channel Number */
986                 pos = os_strchr(pos, ',');
987                 if (pos == NULL) {
988                         wpa_printf(MSG_DEBUG, "Missing PHY Type");
989                         return -1;
990                 }
991                 pos++;
992
993                 *nei_pos++ = atoi(pos); /* PHY Type */
994                 end = os_strchr(pos, ' ');
995                 tmp = os_strchr(pos, ',');
996                 if (tmp && (!end || tmp < end)) {
997                         /* Optional Subelements (hexdump) */
998                         size_t len;
999
1000                         pos = tmp + 1;
1001                         end = os_strchr(pos, ' ');
1002                         if (end)
1003                                 len = end - pos;
1004                         else
1005                                 len = os_strlen(pos);
1006                         if (nei_pos + len / 2 > nei_rep + sizeof(nei_rep)) {
1007                                 wpa_printf(MSG_DEBUG,
1008                                            "Not enough room for neighbor subelements");
1009                                 return -1;
1010                         }
1011                         if (len & 0x01 ||
1012                             hexstr2bin(pos, nei_pos, len / 2) < 0) {
1013                                 wpa_printf(MSG_DEBUG,
1014                                            "Invalid neighbor subelement info");
1015                                 return -1;
1016                         }
1017                         nei_pos += len / 2;
1018                         pos = end;
1019                 }
1020
1021                 nei_start[1] = nei_pos - nei_start - 2;
1022         }
1023
1024         pos = os_strstr(cmd, " url=");
1025         if (pos) {
1026                 size_t len;
1027                 pos += 5;
1028                 end = os_strchr(pos, ' ');
1029                 if (end)
1030                         len = end - pos;
1031                 else
1032                         len = os_strlen(pos);
1033                 url = os_malloc(len + 1);
1034                 if (url == NULL)
1035                         return -1;
1036                 os_memcpy(url, pos, len);
1037                 url[len] = '\0';
1038                 req_mode |= WNM_BSS_TM_REQ_ESS_DISASSOC_IMMINENT;
1039         }
1040
1041         if (os_strstr(cmd, " pref=1"))
1042                 req_mode |= WNM_BSS_TM_REQ_PREF_CAND_LIST_INCLUDED;
1043         if (os_strstr(cmd, " abridged=1"))
1044                 req_mode |= WNM_BSS_TM_REQ_ABRIDGED;
1045         if (os_strstr(cmd, " disassoc_imminent=1"))
1046                 req_mode |= WNM_BSS_TM_REQ_DISASSOC_IMMINENT;
1047
1048         ret = wnm_send_bss_tm_req(hapd, sta, req_mode, disassoc_timer,
1049                                   valid_int, bss_term_dur, url,
1050                                   nei_pos > nei_rep ? nei_rep : NULL,
1051                                   nei_pos - nei_rep);
1052         os_free(url);
1053         return ret;
1054 }
1055
1056 #endif /* CONFIG_WNM */
1057
1058
1059 static int hostapd_ctrl_iface_get_config(struct hostapd_data *hapd,
1060                                          char *buf, size_t buflen)
1061 {
1062         int ret;
1063         char *pos, *end;
1064
1065         pos = buf;
1066         end = buf + buflen;
1067
1068         ret = os_snprintf(pos, end - pos, "bssid=" MACSTR "\n"
1069                           "ssid=%s\n",
1070                           MAC2STR(hapd->own_addr),
1071                           wpa_ssid_txt(hapd->conf->ssid.ssid,
1072                                        hapd->conf->ssid.ssid_len));
1073         if (os_snprintf_error(end - pos, ret))
1074                 return pos - buf;
1075         pos += ret;
1076
1077 #ifdef CONFIG_WPS
1078         ret = os_snprintf(pos, end - pos, "wps_state=%s\n",
1079                           hapd->conf->wps_state == 0 ? "disabled" :
1080                           (hapd->conf->wps_state == 1 ? "not configured" :
1081                            "configured"));
1082         if (os_snprintf_error(end - pos, ret))
1083                 return pos - buf;
1084         pos += ret;
1085
1086         if (hapd->conf->wps_state && hapd->conf->wpa &&
1087             hapd->conf->ssid.wpa_passphrase) {
1088                 ret = os_snprintf(pos, end - pos, "passphrase=%s\n",
1089                                   hapd->conf->ssid.wpa_passphrase);
1090                 if (os_snprintf_error(end - pos, ret))
1091                         return pos - buf;
1092                 pos += ret;
1093         }
1094
1095         if (hapd->conf->wps_state && hapd->conf->wpa &&
1096             hapd->conf->ssid.wpa_psk &&
1097             hapd->conf->ssid.wpa_psk->group) {
1098                 char hex[PMK_LEN * 2 + 1];
1099                 wpa_snprintf_hex(hex, sizeof(hex),
1100                                  hapd->conf->ssid.wpa_psk->psk, PMK_LEN);
1101                 ret = os_snprintf(pos, end - pos, "psk=%s\n", hex);
1102                 if (os_snprintf_error(end - pos, ret))
1103                         return pos - buf;
1104                 pos += ret;
1105         }
1106 #endif /* CONFIG_WPS */
1107
1108         if (hapd->conf->wpa && hapd->conf->wpa_key_mgmt) {
1109                 ret = os_snprintf(pos, end - pos, "key_mgmt=");
1110                 if (os_snprintf_error(end - pos, ret))
1111                         return pos - buf;
1112                 pos += ret;
1113
1114                 if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) {
1115                         ret = os_snprintf(pos, end - pos, "WPA-PSK ");
1116                         if (os_snprintf_error(end - pos, ret))
1117                                 return pos - buf;
1118                         pos += ret;
1119                 }
1120                 if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X) {
1121                         ret = os_snprintf(pos, end - pos, "WPA-EAP ");
1122                         if (os_snprintf_error(end - pos, ret))
1123                                 return pos - buf;
1124                         pos += ret;
1125                 }
1126 #ifdef CONFIG_IEEE80211R
1127                 if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_PSK) {
1128                         ret = os_snprintf(pos, end - pos, "FT-PSK ");
1129                         if (os_snprintf_error(end - pos, ret))
1130                                 return pos - buf;
1131                         pos += ret;
1132                 }
1133                 if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) {
1134                         ret = os_snprintf(pos, end - pos, "FT-EAP ");
1135                         if (os_snprintf_error(end - pos, ret))
1136                                 return pos - buf;
1137                         pos += ret;
1138                 }
1139 #ifdef CONFIG_SAE
1140                 if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_SAE) {
1141                         ret = os_snprintf(pos, end - pos, "FT-SAE ");
1142                         if (os_snprintf_error(end - pos, ret))
1143                                 return pos - buf;
1144                         pos += ret;
1145                 }
1146 #endif /* CONFIG_SAE */
1147 #endif /* CONFIG_IEEE80211R */
1148 #ifdef CONFIG_IEEE80211W
1149                 if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK_SHA256) {
1150                         ret = os_snprintf(pos, end - pos, "WPA-PSK-SHA256 ");
1151                         if (os_snprintf_error(end - pos, ret))
1152                                 return pos - buf;
1153                         pos += ret;
1154                 }
1155                 if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) {
1156                         ret = os_snprintf(pos, end - pos, "WPA-EAP-SHA256 ");
1157                         if (os_snprintf_error(end - pos, ret))
1158                                 return pos - buf;
1159                         pos += ret;
1160                 }
1161 #endif /* CONFIG_IEEE80211W */
1162 #ifdef CONFIG_SAE
1163                 if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_SAE) {
1164                         ret = os_snprintf(pos, end - pos, "SAE ");
1165                         if (os_snprintf_error(end - pos, ret))
1166                                 return pos - buf;
1167                         pos += ret;
1168                 }
1169 #endif /* CONFIG_SAE */
1170                 if (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
1171                         ret = os_snprintf(pos, end - pos, "WPA-EAP-SUITE-B ");
1172                         if (os_snprintf_error(end - pos, ret))
1173                                 return pos - buf;
1174                         pos += ret;
1175                 }
1176                 if (hapd->conf->wpa_key_mgmt &
1177                     WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) {
1178                         ret = os_snprintf(pos, end - pos,
1179                                           "WPA-EAP-SUITE-B-192 ");
1180                         if (os_snprintf_error(end - pos, ret))
1181                                 return pos - buf;
1182                         pos += ret;
1183                 }
1184
1185                 ret = os_snprintf(pos, end - pos, "\n");
1186                 if (os_snprintf_error(end - pos, ret))
1187                         return pos - buf;
1188                 pos += ret;
1189         }
1190
1191         if (hapd->conf->wpa) {
1192                 ret = os_snprintf(pos, end - pos, "group_cipher=%s\n",
1193                                   wpa_cipher_txt(hapd->conf->wpa_group));
1194                 if (os_snprintf_error(end - pos, ret))
1195                         return pos - buf;
1196                 pos += ret;
1197         }
1198
1199         if ((hapd->conf->wpa & WPA_PROTO_RSN) && hapd->conf->rsn_pairwise) {
1200                 ret = os_snprintf(pos, end - pos, "rsn_pairwise_cipher=");
1201                 if (os_snprintf_error(end - pos, ret))
1202                         return pos - buf;
1203                 pos += ret;
1204
1205                 ret = wpa_write_ciphers(pos, end, hapd->conf->rsn_pairwise,
1206                                         " ");
1207                 if (ret < 0)
1208                         return pos - buf;
1209                 pos += ret;
1210
1211                 ret = os_snprintf(pos, end - pos, "\n");
1212                 if (os_snprintf_error(end - pos, ret))
1213                         return pos - buf;
1214                 pos += ret;
1215         }
1216
1217         if ((hapd->conf->wpa & WPA_PROTO_WPA) && hapd->conf->wpa_pairwise) {
1218                 ret = os_snprintf(pos, end - pos, "wpa_pairwise_cipher=");
1219                 if (os_snprintf_error(end - pos, ret))
1220                         return pos - buf;
1221                 pos += ret;
1222
1223                 ret = wpa_write_ciphers(pos, end, hapd->conf->wpa_pairwise,
1224                                         " ");
1225                 if (ret < 0)
1226                         return pos - buf;
1227                 pos += ret;
1228
1229                 ret = os_snprintf(pos, end - pos, "\n");
1230                 if (os_snprintf_error(end - pos, ret))
1231                         return pos - buf;
1232                 pos += ret;
1233         }
1234
1235         return pos - buf;
1236 }
1237
1238
1239 static int hostapd_ctrl_iface_set(struct hostapd_data *hapd, char *cmd)
1240 {
1241         char *value;
1242         int ret = 0;
1243
1244         value = os_strchr(cmd, ' ');
1245         if (value == NULL)
1246                 return -1;
1247         *value++ = '\0';
1248
1249         wpa_printf(MSG_DEBUG, "CTRL_IFACE SET '%s'='%s'", cmd, value);
1250         if (0) {
1251 #ifdef CONFIG_WPS_TESTING
1252         } else if (os_strcasecmp(cmd, "wps_version_number") == 0) {
1253                 long int val;
1254                 val = strtol(value, NULL, 0);
1255                 if (val < 0 || val > 0xff) {
1256                         ret = -1;
1257                         wpa_printf(MSG_DEBUG, "WPS: Invalid "
1258                                    "wps_version_number %ld", val);
1259                 } else {
1260                         wps_version_number = val;
1261                         wpa_printf(MSG_DEBUG, "WPS: Testing - force WPS "
1262                                    "version %u.%u",
1263                                    (wps_version_number & 0xf0) >> 4,
1264                                    wps_version_number & 0x0f);
1265                         hostapd_wps_update_ie(hapd);
1266                 }
1267         } else if (os_strcasecmp(cmd, "wps_testing_dummy_cred") == 0) {
1268                 wps_testing_dummy_cred = atoi(value);
1269                 wpa_printf(MSG_DEBUG, "WPS: Testing - dummy_cred=%d",
1270                            wps_testing_dummy_cred);
1271         } else if (os_strcasecmp(cmd, "wps_corrupt_pkhash") == 0) {
1272                 wps_corrupt_pkhash = atoi(value);
1273                 wpa_printf(MSG_DEBUG, "WPS: Testing - wps_corrupt_pkhash=%d",
1274                            wps_corrupt_pkhash);
1275 #endif /* CONFIG_WPS_TESTING */
1276 #ifdef CONFIG_INTERWORKING
1277         } else if (os_strcasecmp(cmd, "gas_frag_limit") == 0) {
1278                 int val = atoi(value);
1279                 if (val <= 0)
1280                         ret = -1;
1281                 else
1282                         hapd->gas_frag_limit = val;
1283 #endif /* CONFIG_INTERWORKING */
1284 #ifdef CONFIG_TESTING_OPTIONS
1285         } else if (os_strcasecmp(cmd, "ext_mgmt_frame_handling") == 0) {
1286                 hapd->ext_mgmt_frame_handling = atoi(value);
1287         } else if (os_strcasecmp(cmd, "ext_eapol_frame_io") == 0) {
1288                 hapd->ext_eapol_frame_io = atoi(value);
1289 #endif /* CONFIG_TESTING_OPTIONS */
1290         } else {
1291                 struct sta_info *sta;
1292                 int vlan_id;
1293
1294                 ret = hostapd_set_iface(hapd->iconf, hapd->conf, cmd, value);
1295                 if (ret)
1296                         return ret;
1297
1298                 if (os_strcasecmp(cmd, "deny_mac_file") == 0) {
1299                         for (sta = hapd->sta_list; sta; sta = sta->next) {
1300                                 if (hostapd_maclist_found(
1301                                             hapd->conf->deny_mac,
1302                                             hapd->conf->num_deny_mac, sta->addr,
1303                                             &vlan_id) &&
1304                                     (!vlan_id || vlan_id == sta->vlan_id))
1305                                         ap_sta_disconnect(
1306                                                 hapd, sta, sta->addr,
1307                                                 WLAN_REASON_UNSPECIFIED);
1308                         }
1309                 } else if (hapd->conf->macaddr_acl == DENY_UNLESS_ACCEPTED &&
1310                            os_strcasecmp(cmd, "accept_mac_file") == 0) {
1311                         for (sta = hapd->sta_list; sta; sta = sta->next) {
1312                                 if (!hostapd_maclist_found(
1313                                             hapd->conf->accept_mac,
1314                                             hapd->conf->num_accept_mac,
1315                                             sta->addr, &vlan_id) ||
1316                                     (vlan_id && vlan_id != sta->vlan_id))
1317                                         ap_sta_disconnect(
1318                                                 hapd, sta, sta->addr,
1319                                                 WLAN_REASON_UNSPECIFIED);
1320                         }
1321                 }
1322         }
1323
1324         return ret;
1325 }
1326
1327
1328 static int hostapd_ctrl_iface_get(struct hostapd_data *hapd, char *cmd,
1329                                   char *buf, size_t buflen)
1330 {
1331         int res;
1332
1333         wpa_printf(MSG_DEBUG, "CTRL_IFACE GET '%s'", cmd);
1334
1335         if (os_strcmp(cmd, "version") == 0) {
1336                 res = os_snprintf(buf, buflen, "%s", VERSION_STR);
1337                 if (os_snprintf_error(buflen, res))
1338                         return -1;
1339                 return res;
1340         } else if (os_strcmp(cmd, "tls_library") == 0) {
1341                 res = tls_get_library_version(buf, buflen);
1342                 if (os_snprintf_error(buflen, res))
1343                         return -1;
1344                 return res;
1345         }
1346
1347         return -1;
1348 }
1349
1350
1351 static int hostapd_ctrl_iface_enable(struct hostapd_iface *iface)
1352 {
1353         if (hostapd_enable_iface(iface) < 0) {
1354                 wpa_printf(MSG_ERROR, "Enabling of interface failed");
1355                 return -1;
1356         }
1357         return 0;
1358 }
1359
1360
1361 static int hostapd_ctrl_iface_reload(struct hostapd_iface *iface)
1362 {
1363         if (hostapd_reload_iface(iface) < 0) {
1364                 wpa_printf(MSG_ERROR, "Reloading of interface failed");
1365                 return -1;
1366         }
1367         return 0;
1368 }
1369
1370
1371 static int hostapd_ctrl_iface_disable(struct hostapd_iface *iface)
1372 {
1373         if (hostapd_disable_iface(iface) < 0) {
1374                 wpa_printf(MSG_ERROR, "Disabling of interface failed");
1375                 return -1;
1376         }
1377         return 0;
1378 }
1379
1380
1381 #ifdef CONFIG_TESTING_OPTIONS
1382
1383 static int hostapd_ctrl_iface_radar(struct hostapd_data *hapd, char *cmd)
1384 {
1385         union wpa_event_data data;
1386         char *pos, *param;
1387         enum wpa_event_type event;
1388
1389         wpa_printf(MSG_DEBUG, "RADAR TEST: %s", cmd);
1390
1391         os_memset(&data, 0, sizeof(data));
1392
1393         param = os_strchr(cmd, ' ');
1394         if (param == NULL)
1395                 return -1;
1396         *param++ = '\0';
1397
1398         if (os_strcmp(cmd, "DETECTED") == 0)
1399                 event = EVENT_DFS_RADAR_DETECTED;
1400         else if (os_strcmp(cmd, "CAC-FINISHED") == 0)
1401                 event = EVENT_DFS_CAC_FINISHED;
1402         else if (os_strcmp(cmd, "CAC-ABORTED") == 0)
1403                 event = EVENT_DFS_CAC_ABORTED;
1404         else if (os_strcmp(cmd, "NOP-FINISHED") == 0)
1405                 event = EVENT_DFS_NOP_FINISHED;
1406         else {
1407                 wpa_printf(MSG_DEBUG, "Unsupported RADAR test command: %s",
1408                            cmd);
1409                 return -1;
1410         }
1411
1412         pos = os_strstr(param, "freq=");
1413         if (pos)
1414                 data.dfs_event.freq = atoi(pos + 5);
1415
1416         pos = os_strstr(param, "ht_enabled=1");
1417         if (pos)
1418                 data.dfs_event.ht_enabled = 1;
1419
1420         pos = os_strstr(param, "chan_offset=");
1421         if (pos)
1422                 data.dfs_event.chan_offset = atoi(pos + 12);
1423
1424         pos = os_strstr(param, "chan_width=");
1425         if (pos)
1426                 data.dfs_event.chan_width = atoi(pos + 11);
1427
1428         pos = os_strstr(param, "cf1=");
1429         if (pos)
1430                 data.dfs_event.cf1 = atoi(pos + 4);
1431
1432         pos = os_strstr(param, "cf2=");
1433         if (pos)
1434                 data.dfs_event.cf2 = atoi(pos + 4);
1435
1436         wpa_supplicant_event(hapd, event, &data);
1437
1438         return 0;
1439 }
1440
1441
1442 static int hostapd_ctrl_iface_mgmt_tx(struct hostapd_data *hapd, char *cmd)
1443 {
1444         size_t len;
1445         u8 *buf;
1446         int res;
1447
1448         wpa_printf(MSG_DEBUG, "External MGMT TX: %s", cmd);
1449
1450         len = os_strlen(cmd);
1451         if (len & 1)
1452                 return -1;
1453         len /= 2;
1454
1455         buf = os_malloc(len);
1456         if (buf == NULL)
1457                 return -1;
1458
1459         if (hexstr2bin(cmd, buf, len) < 0) {
1460                 os_free(buf);
1461                 return -1;
1462         }
1463
1464         res = hostapd_drv_send_mlme(hapd, buf, len, 0);
1465         os_free(buf);
1466         return res;
1467 }
1468
1469
1470 static int hostapd_ctrl_iface_eapol_rx(struct hostapd_data *hapd, char *cmd)
1471 {
1472         char *pos;
1473         u8 src[ETH_ALEN], *buf;
1474         int used;
1475         size_t len;
1476
1477         wpa_printf(MSG_DEBUG, "External EAPOL RX: %s", cmd);
1478
1479         pos = cmd;
1480         used = hwaddr_aton2(pos, src);
1481         if (used < 0)
1482                 return -1;
1483         pos += used;
1484         while (*pos == ' ')
1485                 pos++;
1486
1487         len = os_strlen(pos);
1488         if (len & 1)
1489                 return -1;
1490         len /= 2;
1491
1492         buf = os_malloc(len);
1493         if (buf == NULL)
1494                 return -1;
1495
1496         if (hexstr2bin(pos, buf, len) < 0) {
1497                 os_free(buf);
1498                 return -1;
1499         }
1500
1501         ieee802_1x_receive(hapd, src, buf, len);
1502         os_free(buf);
1503
1504         return 0;
1505 }
1506
1507
1508 static u16 ipv4_hdr_checksum(const void *buf, size_t len)
1509 {
1510         size_t i;
1511         u32 sum = 0;
1512         const u16 *pos = buf;
1513
1514         for (i = 0; i < len / 2; i++)
1515                 sum += *pos++;
1516
1517         while (sum >> 16)
1518                 sum = (sum & 0xffff) + (sum >> 16);
1519
1520         return sum ^ 0xffff;
1521 }
1522
1523
1524 #define HWSIM_PACKETLEN 1500
1525 #define HWSIM_IP_LEN (HWSIM_PACKETLEN - sizeof(struct ether_header))
1526
1527 void hostapd_data_test_rx(void *ctx, const u8 *src_addr, const u8 *buf,
1528                           size_t len)
1529 {
1530         struct hostapd_data *hapd = ctx;
1531         const struct ether_header *eth;
1532         struct iphdr ip;
1533         const u8 *pos;
1534         unsigned int i;
1535
1536         if (len != HWSIM_PACKETLEN)
1537                 return;
1538
1539         eth = (const struct ether_header *) buf;
1540         os_memcpy(&ip, eth + 1, sizeof(ip));
1541         pos = &buf[sizeof(*eth) + sizeof(ip)];
1542
1543         if (ip.ihl != 5 || ip.version != 4 ||
1544             ntohs(ip.tot_len) != HWSIM_IP_LEN)
1545                 return;
1546
1547         for (i = 0; i < HWSIM_IP_LEN - sizeof(ip); i++) {
1548                 if (*pos != (u8) i)
1549                         return;
1550                 pos++;
1551         }
1552
1553         wpa_msg(hapd->msg_ctx, MSG_INFO, "DATA-TEST-RX " MACSTR " " MACSTR,
1554                 MAC2STR(eth->ether_dhost), MAC2STR(eth->ether_shost));
1555 }
1556
1557
1558 static int hostapd_ctrl_iface_data_test_config(struct hostapd_data *hapd,
1559                                                char *cmd)
1560 {
1561         int enabled = atoi(cmd);
1562         char *pos;
1563         const char *ifname;
1564
1565         if (!enabled) {
1566                 if (hapd->l2_test) {
1567                         l2_packet_deinit(hapd->l2_test);
1568                         hapd->l2_test = NULL;
1569                         wpa_dbg(hapd->msg_ctx, MSG_DEBUG,
1570                                 "test data: Disabled");
1571                 }
1572                 return 0;
1573         }
1574
1575         if (hapd->l2_test)
1576                 return 0;
1577
1578         pos = os_strstr(cmd, " ifname=");
1579         if (pos)
1580                 ifname = pos + 8;
1581         else
1582                 ifname = hapd->conf->iface;
1583
1584         hapd->l2_test = l2_packet_init(ifname, hapd->own_addr,
1585                                         ETHERTYPE_IP, hostapd_data_test_rx,
1586                                         hapd, 1);
1587         if (hapd->l2_test == NULL)
1588                 return -1;
1589
1590         wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "test data: Enabled");
1591
1592         return 0;
1593 }
1594
1595
1596 static int hostapd_ctrl_iface_data_test_tx(struct hostapd_data *hapd, char *cmd)
1597 {
1598         u8 dst[ETH_ALEN], src[ETH_ALEN];
1599         char *pos;
1600         int used;
1601         long int val;
1602         u8 tos;
1603         u8 buf[2 + HWSIM_PACKETLEN];
1604         struct ether_header *eth;
1605         struct iphdr *ip;
1606         u8 *dpos;
1607         unsigned int i;
1608
1609         if (hapd->l2_test == NULL)
1610                 return -1;
1611
1612         /* format: <dst> <src> <tos> */
1613
1614         pos = cmd;
1615         used = hwaddr_aton2(pos, dst);
1616         if (used < 0)
1617                 return -1;
1618         pos += used;
1619         while (*pos == ' ')
1620                 pos++;
1621         used = hwaddr_aton2(pos, src);
1622         if (used < 0)
1623                 return -1;
1624         pos += used;
1625
1626         val = strtol(pos, NULL, 0);
1627         if (val < 0 || val > 0xff)
1628                 return -1;
1629         tos = val;
1630
1631         eth = (struct ether_header *) &buf[2];
1632         os_memcpy(eth->ether_dhost, dst, ETH_ALEN);
1633         os_memcpy(eth->ether_shost, src, ETH_ALEN);
1634         eth->ether_type = htons(ETHERTYPE_IP);
1635         ip = (struct iphdr *) (eth + 1);
1636         os_memset(ip, 0, sizeof(*ip));
1637         ip->ihl = 5;
1638         ip->version = 4;
1639         ip->ttl = 64;
1640         ip->tos = tos;
1641         ip->tot_len = htons(HWSIM_IP_LEN);
1642         ip->protocol = 1;
1643         ip->saddr = htonl(192U << 24 | 168 << 16 | 1 << 8 | 1);
1644         ip->daddr = htonl(192U << 24 | 168 << 16 | 1 << 8 | 2);
1645         ip->check = ipv4_hdr_checksum(ip, sizeof(*ip));
1646         dpos = (u8 *) (ip + 1);
1647         for (i = 0; i < HWSIM_IP_LEN - sizeof(*ip); i++)
1648                 *dpos++ = i;
1649
1650         if (l2_packet_send(hapd->l2_test, dst, ETHERTYPE_IP, &buf[2],
1651                            HWSIM_PACKETLEN) < 0)
1652                 return -1;
1653
1654         wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "test data: TX dst=" MACSTR
1655                 " src=" MACSTR " tos=0x%x", MAC2STR(dst), MAC2STR(src), tos);
1656
1657         return 0;
1658 }
1659
1660
1661 static int hostapd_ctrl_iface_data_test_frame(struct hostapd_data *hapd,
1662                                               char *cmd)
1663 {
1664         u8 *buf;
1665         struct ether_header *eth;
1666         struct l2_packet_data *l2 = NULL;
1667         size_t len;
1668         u16 ethertype;
1669         int res = -1;
1670         const char *ifname = hapd->conf->iface;
1671
1672         if (os_strncmp(cmd, "ifname=", 7) == 0) {
1673                 cmd += 7;
1674                 ifname = cmd;
1675                 cmd = os_strchr(cmd, ' ');
1676                 if (cmd == NULL)
1677                         return -1;
1678                 *cmd++ = '\0';
1679         }
1680
1681         len = os_strlen(cmd);
1682         if (len & 1 || len < ETH_HLEN * 2)
1683                 return -1;
1684         len /= 2;
1685
1686         buf = os_malloc(len);
1687         if (buf == NULL)
1688                 return -1;
1689
1690         if (hexstr2bin(cmd, buf, len) < 0)
1691                 goto done;
1692
1693         eth = (struct ether_header *) buf;
1694         ethertype = ntohs(eth->ether_type);
1695
1696         l2 = l2_packet_init(ifname, hapd->own_addr, ethertype,
1697                             hostapd_data_test_rx, hapd, 1);
1698         if (l2 == NULL)
1699                 goto done;
1700
1701         res = l2_packet_send(l2, eth->ether_dhost, ethertype, buf, len);
1702         wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "test data: TX frame res=%d", res);
1703 done:
1704         if (l2)
1705                 l2_packet_deinit(l2);
1706         os_free(buf);
1707
1708         return res < 0 ? -1 : 0;
1709 }
1710
1711
1712 static int hostapd_ctrl_test_alloc_fail(struct hostapd_data *hapd, char *cmd)
1713 {
1714 #ifdef WPA_TRACE_BFD
1715         extern char wpa_trace_fail_func[256];
1716         extern unsigned int wpa_trace_fail_after;
1717         char *pos;
1718
1719         wpa_trace_fail_after = atoi(cmd);
1720         pos = os_strchr(cmd, ':');
1721         if (pos) {
1722                 pos++;
1723                 os_strlcpy(wpa_trace_fail_func, pos,
1724                            sizeof(wpa_trace_fail_func));
1725         } else {
1726                 wpa_trace_fail_after = 0;
1727         }
1728
1729         return 0;
1730 #else /* WPA_TRACE_BFD */
1731         return -1;
1732 #endif /* WPA_TRACE_BFD */
1733 }
1734
1735
1736 static int hostapd_ctrl_get_alloc_fail(struct hostapd_data *hapd,
1737                                        char *buf, size_t buflen)
1738 {
1739 #ifdef WPA_TRACE_BFD
1740         extern char wpa_trace_fail_func[256];
1741         extern unsigned int wpa_trace_fail_after;
1742
1743         return os_snprintf(buf, buflen, "%u:%s", wpa_trace_fail_after,
1744                            wpa_trace_fail_func);
1745 #else /* WPA_TRACE_BFD */
1746         return -1;
1747 #endif /* WPA_TRACE_BFD */
1748 }
1749
1750
1751 static int hostapd_ctrl_test_fail(struct hostapd_data *hapd, char *cmd)
1752 {
1753 #ifdef WPA_TRACE_BFD
1754         extern char wpa_trace_test_fail_func[256];
1755         extern unsigned int wpa_trace_test_fail_after;
1756         char *pos;
1757
1758         wpa_trace_test_fail_after = atoi(cmd);
1759         pos = os_strchr(cmd, ':');
1760         if (pos) {
1761                 pos++;
1762                 os_strlcpy(wpa_trace_test_fail_func, pos,
1763                            sizeof(wpa_trace_test_fail_func));
1764         } else {
1765                 wpa_trace_test_fail_after = 0;
1766         }
1767
1768         return 0;
1769 #else /* WPA_TRACE_BFD */
1770         return -1;
1771 #endif /* WPA_TRACE_BFD */
1772 }
1773
1774
1775 static int hostapd_ctrl_get_fail(struct hostapd_data *hapd,
1776                                  char *buf, size_t buflen)
1777 {
1778 #ifdef WPA_TRACE_BFD
1779         extern char wpa_trace_test_fail_func[256];
1780         extern unsigned int wpa_trace_test_fail_after;
1781
1782         return os_snprintf(buf, buflen, "%u:%s", wpa_trace_test_fail_after,
1783                            wpa_trace_test_fail_func);
1784 #else /* WPA_TRACE_BFD */
1785         return -1;
1786 #endif /* WPA_TRACE_BFD */
1787 }
1788
1789 #endif /* CONFIG_TESTING_OPTIONS */
1790
1791
1792 static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
1793                                           char *pos)
1794 {
1795 #ifdef NEED_AP_MLME
1796         struct csa_settings settings;
1797         int ret;
1798         unsigned int i;
1799
1800         ret = hostapd_parse_csa_settings(pos, &settings);
1801         if (ret)
1802                 return ret;
1803
1804         for (i = 0; i < iface->num_bss; i++) {
1805                 ret = hostapd_switch_channel(iface->bss[i], &settings);
1806                 if (ret) {
1807                         /* FIX: What do we do if CSA fails in the middle of
1808                          * submitting multi-BSS CSA requests? */
1809                         return ret;
1810                 }
1811         }
1812
1813         return 0;
1814 #else /* NEED_AP_MLME */
1815         return -1;
1816 #endif /* NEED_AP_MLME */
1817 }
1818
1819
1820 static int hostapd_ctrl_iface_mib(struct hostapd_data *hapd, char *reply,
1821                                   int reply_size, const char *param)
1822 {
1823 #ifdef RADIUS_SERVER
1824         if (os_strcmp(param, "radius_server") == 0) {
1825                 return radius_server_get_mib(hapd->radius_srv, reply,
1826                                              reply_size);
1827         }
1828 #endif /* RADIUS_SERVER */
1829         return -1;
1830 }
1831
1832
1833 static int hostapd_ctrl_iface_vendor(struct hostapd_data *hapd, char *cmd,
1834                                      char *buf, size_t buflen)
1835 {
1836         int ret;
1837         char *pos;
1838         u8 *data = NULL;
1839         unsigned int vendor_id, subcmd;
1840         struct wpabuf *reply;
1841         size_t data_len = 0;
1842
1843         /* cmd: <vendor id> <subcommand id> [<hex formatted data>] */
1844         vendor_id = strtoul(cmd, &pos, 16);
1845         if (!isblank(*pos))
1846                 return -EINVAL;
1847
1848         subcmd = strtoul(pos, &pos, 10);
1849
1850         if (*pos != '\0') {
1851                 if (!isblank(*pos++))
1852                         return -EINVAL;
1853                 data_len = os_strlen(pos);
1854         }
1855
1856         if (data_len) {
1857                 data_len /= 2;
1858                 data = os_malloc(data_len);
1859                 if (!data)
1860                         return -ENOBUFS;
1861
1862                 if (hexstr2bin(pos, data, data_len)) {
1863                         wpa_printf(MSG_DEBUG,
1864                                    "Vendor command: wrong parameter format");
1865                         os_free(data);
1866                         return -EINVAL;
1867                 }
1868         }
1869
1870         reply = wpabuf_alloc((buflen - 1) / 2);
1871         if (!reply) {
1872                 os_free(data);
1873                 return -ENOBUFS;
1874         }
1875
1876         ret = hostapd_drv_vendor_cmd(hapd, vendor_id, subcmd, data, data_len,
1877                                      reply);
1878
1879         if (ret == 0)
1880                 ret = wpa_snprintf_hex(buf, buflen, wpabuf_head_u8(reply),
1881                                        wpabuf_len(reply));
1882
1883         wpabuf_free(reply);
1884         os_free(data);
1885
1886         return ret;
1887 }
1888
1889
1890 static int hostapd_ctrl_iface_eapol_reauth(struct hostapd_data *hapd,
1891                                            const char *cmd)
1892 {
1893         u8 addr[ETH_ALEN];
1894         struct sta_info *sta;
1895
1896         if (hwaddr_aton(cmd, addr))
1897                 return -1;
1898
1899         sta = ap_get_sta(hapd, addr);
1900         if (!sta || !sta->eapol_sm)
1901                 return -1;
1902
1903         eapol_auth_reauthenticate(sta->eapol_sm);
1904         return 0;
1905 }
1906
1907
1908 static void hostapd_ctrl_iface_receive(int sock, void *eloop_ctx,
1909                                        void *sock_ctx)
1910 {
1911         struct hostapd_data *hapd = eloop_ctx;
1912         char buf[4096];
1913         int res;
1914         struct sockaddr_un from;
1915         socklen_t fromlen = sizeof(from);
1916         char *reply;
1917         const int reply_size = 4096;
1918         int reply_len;
1919         int level = MSG_DEBUG;
1920
1921         res = recvfrom(sock, buf, sizeof(buf) - 1, 0,
1922                        (struct sockaddr *) &from, &fromlen);
1923         if (res < 0) {
1924                 wpa_printf(MSG_ERROR, "recvfrom(ctrl_iface): %s",
1925                            strerror(errno));
1926                 return;
1927         }
1928         buf[res] = '\0';
1929         if (os_strcmp(buf, "PING") == 0)
1930                 level = MSG_EXCESSIVE;
1931         wpa_hexdump_ascii(level, "RX ctrl_iface", (u8 *) buf, res);
1932
1933         reply = os_malloc(reply_size);
1934         if (reply == NULL) {
1935                 if (sendto(sock, "FAIL\n", 5, 0, (struct sockaddr *) &from,
1936                            fromlen) < 0) {
1937                         wpa_printf(MSG_DEBUG, "CTRL: sendto failed: %s",
1938                                    strerror(errno));
1939                 }
1940                 return;
1941         }
1942
1943         os_memcpy(reply, "OK\n", 3);
1944         reply_len = 3;
1945
1946         if (os_strcmp(buf, "PING") == 0) {
1947                 os_memcpy(reply, "PONG\n", 5);
1948                 reply_len = 5;
1949         } else if (os_strncmp(buf, "RELOG", 5) == 0) {
1950                 if (wpa_debug_reopen_file() < 0)
1951                         reply_len = -1;
1952         } else if (os_strcmp(buf, "STATUS") == 0) {
1953                 reply_len = hostapd_ctrl_iface_status(hapd, reply,
1954                                                       reply_size);
1955         } else if (os_strcmp(buf, "STATUS-DRIVER") == 0) {
1956                 reply_len = hostapd_drv_status(hapd, reply, reply_size);
1957         } else if (os_strcmp(buf, "MIB") == 0) {
1958                 reply_len = ieee802_11_get_mib(hapd, reply, reply_size);
1959                 if (reply_len >= 0) {
1960                         res = wpa_get_mib(hapd->wpa_auth, reply + reply_len,
1961                                           reply_size - reply_len);
1962                         if (res < 0)
1963                                 reply_len = -1;
1964                         else
1965                                 reply_len += res;
1966                 }
1967                 if (reply_len >= 0) {
1968                         res = ieee802_1x_get_mib(hapd, reply + reply_len,
1969                                                  reply_size - reply_len);
1970                         if (res < 0)
1971                                 reply_len = -1;
1972                         else
1973                                 reply_len += res;
1974                 }
1975 #ifndef CONFIG_NO_RADIUS
1976                 if (reply_len >= 0) {
1977                         res = radius_client_get_mib(hapd->radius,
1978                                                     reply + reply_len,
1979                                                     reply_size - reply_len);
1980                         if (res < 0)
1981                                 reply_len = -1;
1982                         else
1983                                 reply_len += res;
1984                 }
1985 #endif /* CONFIG_NO_RADIUS */
1986         } else if (os_strncmp(buf, "MIB ", 4) == 0) {
1987                 reply_len = hostapd_ctrl_iface_mib(hapd, reply, reply_size,
1988                                                    buf + 4);
1989         } else if (os_strcmp(buf, "STA-FIRST") == 0) {
1990                 reply_len = hostapd_ctrl_iface_sta_first(hapd, reply,
1991                                                          reply_size);
1992         } else if (os_strncmp(buf, "STA ", 4) == 0) {
1993                 reply_len = hostapd_ctrl_iface_sta(hapd, buf + 4, reply,
1994                                                    reply_size);
1995         } else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) {
1996                 reply_len = hostapd_ctrl_iface_sta_next(hapd, buf + 9, reply,
1997                                                         reply_size);
1998         } else if (os_strcmp(buf, "ATTACH") == 0) {
1999                 if (hostapd_ctrl_iface_attach(hapd, &from, fromlen))
2000                         reply_len = -1;
2001         } else if (os_strcmp(buf, "DETACH") == 0) {
2002                 if (hostapd_ctrl_iface_detach(hapd, &from, fromlen))
2003                         reply_len = -1;
2004         } else if (os_strncmp(buf, "LEVEL ", 6) == 0) {
2005                 if (hostapd_ctrl_iface_level(hapd, &from, fromlen,
2006                                                     buf + 6))
2007                         reply_len = -1;
2008         } else if (os_strncmp(buf, "NEW_STA ", 8) == 0) {
2009                 if (hostapd_ctrl_iface_new_sta(hapd, buf + 8))
2010                         reply_len = -1;
2011         } else if (os_strncmp(buf, "DEAUTHENTICATE ", 15) == 0) {
2012                 if (hostapd_ctrl_iface_deauthenticate(hapd, buf + 15))
2013                         reply_len = -1;
2014         } else if (os_strncmp(buf, "DISASSOCIATE ", 13) == 0) {
2015                 if (hostapd_ctrl_iface_disassociate(hapd, buf + 13))
2016                         reply_len = -1;
2017         } else if (os_strcmp(buf, "STOP_AP") == 0) {
2018                 if (hostapd_ctrl_iface_stop_ap(hapd))
2019                         reply_len = -1;
2020 #ifdef CONFIG_IEEE80211W
2021 #ifdef NEED_AP_MLME
2022         } else if (os_strncmp(buf, "SA_QUERY ", 9) == 0) {
2023                 if (hostapd_ctrl_iface_sa_query(hapd, buf + 9))
2024                         reply_len = -1;
2025 #endif /* NEED_AP_MLME */
2026 #endif /* CONFIG_IEEE80211W */
2027 #ifdef CONFIG_WPS
2028         } else if (os_strncmp(buf, "WPS_PIN ", 8) == 0) {
2029                 if (hostapd_ctrl_iface_wps_pin(hapd, buf + 8))
2030                         reply_len = -1;
2031         } else if (os_strncmp(buf, "WPS_CHECK_PIN ", 14) == 0) {
2032                 reply_len = hostapd_ctrl_iface_wps_check_pin(
2033                         hapd, buf + 14, reply, reply_size);
2034         } else if (os_strcmp(buf, "WPS_PBC") == 0) {
2035                 if (hostapd_wps_button_pushed(hapd, NULL))
2036                         reply_len = -1;
2037         } else if (os_strcmp(buf, "WPS_CANCEL") == 0) {
2038                 if (hostapd_wps_cancel(hapd))
2039                         reply_len = -1;
2040         } else if (os_strncmp(buf, "WPS_AP_PIN ", 11) == 0) {
2041                 reply_len = hostapd_ctrl_iface_wps_ap_pin(hapd, buf + 11,
2042                                                           reply, reply_size);
2043         } else if (os_strncmp(buf, "WPS_CONFIG ", 11) == 0) {
2044                 if (hostapd_ctrl_iface_wps_config(hapd, buf + 11) < 0)
2045                         reply_len = -1;
2046         } else if (os_strncmp(buf, "WPS_GET_STATUS", 13) == 0) {
2047                 reply_len = hostapd_ctrl_iface_wps_get_status(hapd, reply,
2048                                                               reply_size);
2049 #ifdef CONFIG_WPS_NFC
2050         } else if (os_strncmp(buf, "WPS_NFC_TAG_READ ", 17) == 0) {
2051                 if (hostapd_ctrl_iface_wps_nfc_tag_read(hapd, buf + 17))
2052                         reply_len = -1;
2053         } else if (os_strncmp(buf, "WPS_NFC_CONFIG_TOKEN ", 21) == 0) {
2054                 reply_len = hostapd_ctrl_iface_wps_nfc_config_token(
2055                         hapd, buf + 21, reply, reply_size);
2056         } else if (os_strncmp(buf, "WPS_NFC_TOKEN ", 14) == 0) {
2057                 reply_len = hostapd_ctrl_iface_wps_nfc_token(
2058                         hapd, buf + 14, reply, reply_size);
2059         } else if (os_strncmp(buf, "NFC_GET_HANDOVER_SEL ", 21) == 0) {
2060                 reply_len = hostapd_ctrl_iface_nfc_get_handover_sel(
2061                         hapd, buf + 21, reply, reply_size);
2062         } else if (os_strncmp(buf, "NFC_REPORT_HANDOVER ", 20) == 0) {
2063                 if (hostapd_ctrl_iface_nfc_report_handover(hapd, buf + 20))
2064                         reply_len = -1;
2065 #endif /* CONFIG_WPS_NFC */
2066 #endif /* CONFIG_WPS */
2067 #ifdef CONFIG_INTERWORKING
2068         } else if (os_strncmp(buf, "SET_QOS_MAP_SET ", 16) == 0) {
2069                 if (hostapd_ctrl_iface_set_qos_map_set(hapd, buf + 16))
2070                         reply_len = -1;
2071         } else if (os_strncmp(buf, "SEND_QOS_MAP_CONF ", 18) == 0) {
2072                 if (hostapd_ctrl_iface_send_qos_map_conf(hapd, buf + 18))
2073                         reply_len = -1;
2074 #endif /* CONFIG_INTERWORKING */
2075 #ifdef CONFIG_HS20
2076         } else if (os_strncmp(buf, "HS20_WNM_NOTIF ", 15) == 0) {
2077                 if (hostapd_ctrl_iface_hs20_wnm_notif(hapd, buf + 15))
2078                         reply_len = -1;
2079         } else if (os_strncmp(buf, "HS20_DEAUTH_REQ ", 16) == 0) {
2080                 if (hostapd_ctrl_iface_hs20_deauth_req(hapd, buf + 16))
2081                         reply_len = -1;
2082 #endif /* CONFIG_HS20 */
2083 #ifdef CONFIG_WNM
2084         } else if (os_strncmp(buf, "DISASSOC_IMMINENT ", 18) == 0) {
2085                 if (hostapd_ctrl_iface_disassoc_imminent(hapd, buf + 18))
2086                         reply_len = -1;
2087         } else if (os_strncmp(buf, "ESS_DISASSOC ", 13) == 0) {
2088                 if (hostapd_ctrl_iface_ess_disassoc(hapd, buf + 13))
2089                         reply_len = -1;
2090         } else if (os_strncmp(buf, "BSS_TM_REQ ", 11) == 0) {
2091                 if (hostapd_ctrl_iface_bss_tm_req(hapd, buf + 11))
2092                         reply_len = -1;
2093 #endif /* CONFIG_WNM */
2094         } else if (os_strcmp(buf, "GET_CONFIG") == 0) {
2095                 reply_len = hostapd_ctrl_iface_get_config(hapd, reply,
2096                                                           reply_size);
2097         } else if (os_strncmp(buf, "SET ", 4) == 0) {
2098                 if (hostapd_ctrl_iface_set(hapd, buf + 4))
2099                         reply_len = -1;
2100         } else if (os_strncmp(buf, "GET ", 4) == 0) {
2101                 reply_len = hostapd_ctrl_iface_get(hapd, buf + 4, reply,
2102                                                    reply_size);
2103         } else if (os_strncmp(buf, "ENABLE", 6) == 0) {
2104                 if (hostapd_ctrl_iface_enable(hapd->iface))
2105                         reply_len = -1;
2106         } else if (os_strncmp(buf, "RELOAD", 6) == 0) {
2107                 if (hostapd_ctrl_iface_reload(hapd->iface))
2108                         reply_len = -1;
2109         } else if (os_strncmp(buf, "DISABLE", 7) == 0) {
2110                 if (hostapd_ctrl_iface_disable(hapd->iface))
2111                         reply_len = -1;
2112         } else if (os_strcmp(buf, "UPDATE_BEACON") == 0) {
2113                 if (ieee802_11_set_beacon(hapd))
2114                         reply_len = -1;
2115 #ifdef CONFIG_TESTING_OPTIONS
2116         } else if (os_strncmp(buf, "RADAR ", 6) == 0) {
2117                 if (hostapd_ctrl_iface_radar(hapd, buf + 6))
2118                         reply_len = -1;
2119         } else if (os_strncmp(buf, "MGMT_TX ", 8) == 0) {
2120                 if (hostapd_ctrl_iface_mgmt_tx(hapd, buf + 8))
2121                         reply_len = -1;
2122         } else if (os_strncmp(buf, "EAPOL_RX ", 9) == 0) {
2123                 if (hostapd_ctrl_iface_eapol_rx(hapd, buf + 9) < 0)
2124                         reply_len = -1;
2125         } else if (os_strncmp(buf, "DATA_TEST_CONFIG ", 17) == 0) {
2126                 if (hostapd_ctrl_iface_data_test_config(hapd, buf + 17) < 0)
2127                         reply_len = -1;
2128         } else if (os_strncmp(buf, "DATA_TEST_TX ", 13) == 0) {
2129                 if (hostapd_ctrl_iface_data_test_tx(hapd, buf + 13) < 0)
2130                         reply_len = -1;
2131         } else if (os_strncmp(buf, "DATA_TEST_FRAME ", 16) == 0) {
2132                 if (hostapd_ctrl_iface_data_test_frame(hapd, buf + 16) < 0)
2133                         reply_len = -1;
2134         } else if (os_strncmp(buf, "TEST_ALLOC_FAIL ", 16) == 0) {
2135                 if (hostapd_ctrl_test_alloc_fail(hapd, buf + 16) < 0)
2136                         reply_len = -1;
2137         } else if (os_strcmp(buf, "GET_ALLOC_FAIL") == 0) {
2138                 reply_len = hostapd_ctrl_get_alloc_fail(hapd, reply,
2139                                                         reply_size);
2140         } else if (os_strncmp(buf, "TEST_FAIL ", 10) == 0) {
2141                 if (hostapd_ctrl_test_fail(hapd, buf + 10) < 0)
2142                         reply_len = -1;
2143         } else if (os_strcmp(buf, "GET_FAIL") == 0) {
2144                 reply_len = hostapd_ctrl_get_fail(hapd, reply, reply_size);
2145 #endif /* CONFIG_TESTING_OPTIONS */
2146         } else if (os_strncmp(buf, "CHAN_SWITCH ", 12) == 0) {
2147                 if (hostapd_ctrl_iface_chan_switch(hapd->iface, buf + 12))
2148                         reply_len = -1;
2149         } else if (os_strncmp(buf, "VENDOR ", 7) == 0) {
2150                 reply_len = hostapd_ctrl_iface_vendor(hapd, buf + 7, reply,
2151                                                       reply_size);
2152         } else if (os_strcmp(buf, "ERP_FLUSH") == 0) {
2153                 ieee802_1x_erp_flush(hapd);
2154 #ifdef RADIUS_SERVER
2155                 radius_server_erp_flush(hapd->radius_srv);
2156 #endif /* RADIUS_SERVER */
2157         } else if (os_strncmp(buf, "EAPOL_REAUTH ", 13) == 0) {
2158                 if (hostapd_ctrl_iface_eapol_reauth(hapd, buf + 13))
2159                         reply_len = -1;
2160         } else {
2161                 os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
2162                 reply_len = 16;
2163         }
2164
2165         if (reply_len < 0) {
2166                 os_memcpy(reply, "FAIL\n", 5);
2167                 reply_len = 5;
2168         }
2169         if (sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from,
2170                    fromlen) < 0) {
2171                 wpa_printf(MSG_DEBUG, "CTRL: sendto failed: %s",
2172                            strerror(errno));
2173         }
2174         os_free(reply);
2175 }
2176
2177
2178 static char * hostapd_ctrl_iface_path(struct hostapd_data *hapd)
2179 {
2180         char *buf;
2181         size_t len;
2182
2183         if (hapd->conf->ctrl_interface == NULL)
2184                 return NULL;
2185
2186         len = os_strlen(hapd->conf->ctrl_interface) +
2187                 os_strlen(hapd->conf->iface) + 2;
2188         buf = os_malloc(len);
2189         if (buf == NULL)
2190                 return NULL;
2191
2192         os_snprintf(buf, len, "%s/%s",
2193                     hapd->conf->ctrl_interface, hapd->conf->iface);
2194         buf[len - 1] = '\0';
2195         return buf;
2196 }
2197
2198
2199 static void hostapd_ctrl_iface_msg_cb(void *ctx, int level,
2200                                       enum wpa_msg_type type,
2201                                       const char *txt, size_t len)
2202 {
2203         struct hostapd_data *hapd = ctx;
2204         if (hapd == NULL)
2205                 return;
2206         hostapd_ctrl_iface_send(hapd, level, txt, len);
2207 }
2208
2209
2210 int hostapd_ctrl_iface_init(struct hostapd_data *hapd)
2211 {
2212         struct sockaddr_un addr;
2213         int s = -1;
2214         char *fname = NULL;
2215
2216         if (hapd->ctrl_sock > -1) {
2217                 wpa_printf(MSG_DEBUG, "ctrl_iface already exists!");
2218                 return 0;
2219         }
2220
2221         if (hapd->conf->ctrl_interface == NULL)
2222                 return 0;
2223
2224         if (mkdir(hapd->conf->ctrl_interface, S_IRWXU | S_IRWXG) < 0) {
2225                 if (errno == EEXIST) {
2226                         wpa_printf(MSG_DEBUG, "Using existing control "
2227                                    "interface directory.");
2228                 } else {
2229                         wpa_printf(MSG_ERROR, "mkdir[ctrl_interface]: %s",
2230                                    strerror(errno));
2231                         goto fail;
2232                 }
2233         }
2234
2235         if (hapd->conf->ctrl_interface_gid_set &&
2236             chown(hapd->conf->ctrl_interface, -1,
2237                   hapd->conf->ctrl_interface_gid) < 0) {
2238                 wpa_printf(MSG_ERROR, "chown[ctrl_interface]: %s",
2239                            strerror(errno));
2240                 return -1;
2241         }
2242
2243         if (!hapd->conf->ctrl_interface_gid_set &&
2244             hapd->iface->interfaces->ctrl_iface_group &&
2245             chown(hapd->conf->ctrl_interface, -1,
2246                   hapd->iface->interfaces->ctrl_iface_group) < 0) {
2247                 wpa_printf(MSG_ERROR, "chown[ctrl_interface]: %s",
2248                            strerror(errno));
2249                 return -1;
2250         }
2251
2252 #ifdef ANDROID
2253         /*
2254          * Android is using umask 0077 which would leave the control interface
2255          * directory without group access. This breaks things since Wi-Fi
2256          * framework assumes that this directory can be accessed by other
2257          * applications in the wifi group. Fix this by adding group access even
2258          * if umask value would prevent this.
2259          */
2260         if (chmod(hapd->conf->ctrl_interface, S_IRWXU | S_IRWXG) < 0) {
2261                 wpa_printf(MSG_ERROR, "CTRL: Could not chmod directory: %s",
2262                            strerror(errno));
2263                 /* Try to continue anyway */
2264         }
2265 #endif /* ANDROID */
2266
2267         if (os_strlen(hapd->conf->ctrl_interface) + 1 +
2268             os_strlen(hapd->conf->iface) >= sizeof(addr.sun_path))
2269                 goto fail;
2270
2271         s = socket(PF_UNIX, SOCK_DGRAM, 0);
2272         if (s < 0) {
2273                 wpa_printf(MSG_ERROR, "socket(PF_UNIX): %s", strerror(errno));
2274                 goto fail;
2275         }
2276
2277         os_memset(&addr, 0, sizeof(addr));
2278 #ifdef __FreeBSD__
2279         addr.sun_len = sizeof(addr);
2280 #endif /* __FreeBSD__ */
2281         addr.sun_family = AF_UNIX;
2282         fname = hostapd_ctrl_iface_path(hapd);
2283         if (fname == NULL)
2284                 goto fail;
2285         os_strlcpy(addr.sun_path, fname, sizeof(addr.sun_path));
2286         if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
2287                 wpa_printf(MSG_DEBUG, "ctrl_iface bind(PF_UNIX) failed: %s",
2288                            strerror(errno));
2289                 if (connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
2290                         wpa_printf(MSG_DEBUG, "ctrl_iface exists, but does not"
2291                                    " allow connections - assuming it was left"
2292                                    "over from forced program termination");
2293                         if (unlink(fname) < 0) {
2294                                 wpa_printf(MSG_ERROR,
2295                                            "Could not unlink existing ctrl_iface socket '%s': %s",
2296                                            fname, strerror(errno));
2297                                 goto fail;
2298                         }
2299                         if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) <
2300                             0) {
2301                                 wpa_printf(MSG_ERROR,
2302                                            "hostapd-ctrl-iface: bind(PF_UNIX): %s",
2303                                            strerror(errno));
2304                                 goto fail;
2305                         }
2306                         wpa_printf(MSG_DEBUG, "Successfully replaced leftover "
2307                                    "ctrl_iface socket '%s'", fname);
2308                 } else {
2309                         wpa_printf(MSG_INFO, "ctrl_iface exists and seems to "
2310                                    "be in use - cannot override it");
2311                         wpa_printf(MSG_INFO, "Delete '%s' manually if it is "
2312                                    "not used anymore", fname);
2313                         os_free(fname);
2314                         fname = NULL;
2315                         goto fail;
2316                 }
2317         }
2318
2319         if (hapd->conf->ctrl_interface_gid_set &&
2320             chown(fname, -1, hapd->conf->ctrl_interface_gid) < 0) {
2321                 wpa_printf(MSG_ERROR, "chown[ctrl_interface/ifname]: %s",
2322                            strerror(errno));
2323                 goto fail;
2324         }
2325
2326         if (!hapd->conf->ctrl_interface_gid_set &&
2327             hapd->iface->interfaces->ctrl_iface_group &&
2328             chown(fname, -1, hapd->iface->interfaces->ctrl_iface_group) < 0) {
2329                 wpa_printf(MSG_ERROR, "chown[ctrl_interface/ifname]: %s",
2330                            strerror(errno));
2331                 goto fail;
2332         }
2333
2334         if (chmod(fname, S_IRWXU | S_IRWXG) < 0) {
2335                 wpa_printf(MSG_ERROR, "chmod[ctrl_interface/ifname]: %s",
2336                            strerror(errno));
2337                 goto fail;
2338         }
2339         os_free(fname);
2340
2341         hapd->ctrl_sock = s;
2342         if (eloop_register_read_sock(s, hostapd_ctrl_iface_receive, hapd,
2343                                      NULL) < 0) {
2344                 hostapd_ctrl_iface_deinit(hapd);
2345                 return -1;
2346         }
2347         hapd->msg_ctx = hapd;
2348         wpa_msg_register_cb(hostapd_ctrl_iface_msg_cb);
2349
2350         return 0;
2351
2352 fail:
2353         if (s >= 0)
2354                 close(s);
2355         if (fname) {
2356                 unlink(fname);
2357                 os_free(fname);
2358         }
2359         return -1;
2360 }
2361
2362
2363 void hostapd_ctrl_iface_deinit(struct hostapd_data *hapd)
2364 {
2365         struct wpa_ctrl_dst *dst, *prev;
2366
2367         if (hapd->ctrl_sock > -1) {
2368                 char *fname;
2369                 eloop_unregister_read_sock(hapd->ctrl_sock);
2370                 close(hapd->ctrl_sock);
2371                 hapd->ctrl_sock = -1;
2372                 fname = hostapd_ctrl_iface_path(hapd);
2373                 if (fname)
2374                         unlink(fname);
2375                 os_free(fname);
2376
2377                 if (hapd->conf->ctrl_interface &&
2378                     rmdir(hapd->conf->ctrl_interface) < 0) {
2379                         if (errno == ENOTEMPTY) {
2380                                 wpa_printf(MSG_DEBUG, "Control interface "
2381                                            "directory not empty - leaving it "
2382                                            "behind");
2383                         } else {
2384                                 wpa_printf(MSG_ERROR,
2385                                            "rmdir[ctrl_interface=%s]: %s",
2386                                            hapd->conf->ctrl_interface,
2387                                            strerror(errno));
2388                         }
2389                 }
2390         }
2391
2392         dst = hapd->ctrl_dst;
2393         hapd->ctrl_dst = NULL;
2394         while (dst) {
2395                 prev = dst;
2396                 dst = dst->next;
2397                 os_free(prev);
2398         }
2399
2400 #ifdef CONFIG_TESTING_OPTIONS
2401         l2_packet_deinit(hapd->l2_test);
2402         hapd->l2_test = NULL;
2403 #endif /* CONFIG_TESTING_OPTIONS */
2404 }
2405
2406
2407 static int hostapd_ctrl_iface_add(struct hapd_interfaces *interfaces,
2408                                   char *buf)
2409 {
2410         if (hostapd_add_iface(interfaces, buf) < 0) {
2411                 wpa_printf(MSG_ERROR, "Adding interface %s failed", buf);
2412                 return -1;
2413         }
2414         return 0;
2415 }
2416
2417
2418 static int hostapd_ctrl_iface_remove(struct hapd_interfaces *interfaces,
2419                                      char *buf)
2420 {
2421         if (hostapd_remove_iface(interfaces, buf) < 0) {
2422                 wpa_printf(MSG_ERROR, "Removing interface %s failed", buf);
2423                 return -1;
2424         }
2425         return 0;
2426 }
2427
2428
2429 static void hostapd_ctrl_iface_flush(struct hapd_interfaces *interfaces)
2430 {
2431 #ifdef CONFIG_WPS_TESTING
2432         wps_version_number = 0x20;
2433         wps_testing_dummy_cred = 0;
2434         wps_corrupt_pkhash = 0;
2435 #endif /* CONFIG_WPS_TESTING */
2436 }
2437
2438
2439 static void hostapd_global_ctrl_iface_receive(int sock, void *eloop_ctx,
2440                                               void *sock_ctx)
2441 {
2442         void *interfaces = eloop_ctx;
2443         char buf[256];
2444         int res;
2445         struct sockaddr_un from;
2446         socklen_t fromlen = sizeof(from);
2447         char reply[24];
2448         int reply_len;
2449
2450         res = recvfrom(sock, buf, sizeof(buf) - 1, 0,
2451                        (struct sockaddr *) &from, &fromlen);
2452         if (res < 0) {
2453                 wpa_printf(MSG_ERROR, "recvfrom(ctrl_iface): %s",
2454                            strerror(errno));
2455                 return;
2456         }
2457         buf[res] = '\0';
2458         wpa_printf(MSG_DEBUG, "Global ctrl_iface command: %s", buf);
2459
2460         os_memcpy(reply, "OK\n", 3);
2461         reply_len = 3;
2462
2463         if (os_strcmp(buf, "PING") == 0) {
2464                 os_memcpy(reply, "PONG\n", 5);
2465                 reply_len = 5;
2466         } else if (os_strncmp(buf, "RELOG", 5) == 0) {
2467                 if (wpa_debug_reopen_file() < 0)
2468                         reply_len = -1;
2469         } else if (os_strcmp(buf, "FLUSH") == 0) {
2470                 hostapd_ctrl_iface_flush(interfaces);
2471         } else if (os_strncmp(buf, "ADD ", 4) == 0) {
2472                 if (hostapd_ctrl_iface_add(interfaces, buf + 4) < 0)
2473                         reply_len = -1;
2474         } else if (os_strncmp(buf, "REMOVE ", 7) == 0) {
2475                 if (hostapd_ctrl_iface_remove(interfaces, buf + 7) < 0)
2476                         reply_len = -1;
2477 #ifdef CONFIG_MODULE_TESTS
2478         } else if (os_strcmp(buf, "MODULE_TESTS") == 0) {
2479                 int hapd_module_tests(void);
2480                 if (hapd_module_tests() < 0)
2481                         reply_len = -1;
2482 #endif /* CONFIG_MODULE_TESTS */
2483         } else {
2484                 wpa_printf(MSG_DEBUG, "Unrecognized global ctrl_iface command "
2485                            "ignored");
2486                 reply_len = -1;
2487         }
2488
2489         if (reply_len < 0) {
2490                 os_memcpy(reply, "FAIL\n", 5);
2491                 reply_len = 5;
2492         }
2493
2494         if (sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from,
2495                    fromlen) < 0) {
2496                 wpa_printf(MSG_DEBUG, "CTRL: sendto failed: %s",
2497                            strerror(errno));
2498         }
2499 }
2500
2501
2502 static char * hostapd_global_ctrl_iface_path(struct hapd_interfaces *interface)
2503 {
2504         char *buf;
2505         size_t len;
2506
2507         if (interface->global_iface_path == NULL)
2508                 return NULL;
2509
2510         len = os_strlen(interface->global_iface_path) +
2511                 os_strlen(interface->global_iface_name) + 2;
2512         buf = os_malloc(len);
2513         if (buf == NULL)
2514                 return NULL;
2515
2516         os_snprintf(buf, len, "%s/%s", interface->global_iface_path,
2517                     interface->global_iface_name);
2518         buf[len - 1] = '\0';
2519         return buf;
2520 }
2521
2522
2523 int hostapd_global_ctrl_iface_init(struct hapd_interfaces *interface)
2524 {
2525         struct sockaddr_un addr;
2526         int s = -1;
2527         char *fname = NULL;
2528
2529         if (interface->global_iface_path == NULL) {
2530                 wpa_printf(MSG_DEBUG, "ctrl_iface not configured!");
2531                 return 0;
2532         }
2533
2534         if (mkdir(interface->global_iface_path, S_IRWXU | S_IRWXG) < 0) {
2535                 if (errno == EEXIST) {
2536                         wpa_printf(MSG_DEBUG, "Using existing control "
2537                                    "interface directory.");
2538                 } else {
2539                         wpa_printf(MSG_ERROR, "mkdir[ctrl_interface]: %s",
2540                                    strerror(errno));
2541                         goto fail;
2542                 }
2543         } else if (interface->ctrl_iface_group &&
2544                    chown(interface->global_iface_path, -1,
2545                          interface->ctrl_iface_group) < 0) {
2546                 wpa_printf(MSG_ERROR, "chown[ctrl_interface]: %s",
2547                            strerror(errno));
2548                 goto fail;
2549         }
2550
2551         if (os_strlen(interface->global_iface_path) + 1 +
2552             os_strlen(interface->global_iface_name) >= sizeof(addr.sun_path))
2553                 goto fail;
2554
2555         s = socket(PF_UNIX, SOCK_DGRAM, 0);
2556         if (s < 0) {
2557                 wpa_printf(MSG_ERROR, "socket(PF_UNIX): %s", strerror(errno));
2558                 goto fail;
2559         }
2560
2561         os_memset(&addr, 0, sizeof(addr));
2562 #ifdef __FreeBSD__
2563         addr.sun_len = sizeof(addr);
2564 #endif /* __FreeBSD__ */
2565         addr.sun_family = AF_UNIX;
2566         fname = hostapd_global_ctrl_iface_path(interface);
2567         if (fname == NULL)
2568                 goto fail;
2569         os_strlcpy(addr.sun_path, fname, sizeof(addr.sun_path));
2570         if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
2571                 wpa_printf(MSG_DEBUG, "ctrl_iface bind(PF_UNIX) failed: %s",
2572                            strerror(errno));
2573                 if (connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
2574                         wpa_printf(MSG_DEBUG, "ctrl_iface exists, but does not"
2575                                    " allow connections - assuming it was left"
2576                                    "over from forced program termination");
2577                         if (unlink(fname) < 0) {
2578                                 wpa_printf(MSG_ERROR,
2579                                            "Could not unlink existing ctrl_iface socket '%s': %s",
2580                                            fname, strerror(errno));
2581                                 goto fail;
2582                         }
2583                         if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) <
2584                             0) {
2585                                 wpa_printf(MSG_ERROR, "bind(PF_UNIX): %s",
2586                                            strerror(errno));
2587                                 goto fail;
2588                         }
2589                         wpa_printf(MSG_DEBUG, "Successfully replaced leftover "
2590                                    "ctrl_iface socket '%s'", fname);
2591                 } else {
2592                         wpa_printf(MSG_INFO, "ctrl_iface exists and seems to "
2593                                    "be in use - cannot override it");
2594                         wpa_printf(MSG_INFO, "Delete '%s' manually if it is "
2595                                    "not used anymore", fname);
2596                         os_free(fname);
2597                         fname = NULL;
2598                         goto fail;
2599                 }
2600         }
2601
2602         if (interface->ctrl_iface_group &&
2603             chown(fname, -1, interface->ctrl_iface_group) < 0) {
2604                 wpa_printf(MSG_ERROR, "chown[ctrl_interface]: %s",
2605                            strerror(errno));
2606                 goto fail;
2607         }
2608
2609         if (chmod(fname, S_IRWXU | S_IRWXG) < 0) {
2610                 wpa_printf(MSG_ERROR, "chmod[ctrl_interface/ifname]: %s",
2611                            strerror(errno));
2612                 goto fail;
2613         }
2614         os_free(fname);
2615
2616         interface->global_ctrl_sock = s;
2617         eloop_register_read_sock(s, hostapd_global_ctrl_iface_receive,
2618                                  interface, NULL);
2619
2620         return 0;
2621
2622 fail:
2623         if (s >= 0)
2624                 close(s);
2625         if (fname) {
2626                 unlink(fname);
2627                 os_free(fname);
2628         }
2629         return -1;
2630 }
2631
2632
2633 void hostapd_global_ctrl_iface_deinit(struct hapd_interfaces *interfaces)
2634 {
2635         char *fname = NULL;
2636
2637         if (interfaces->global_ctrl_sock > -1) {
2638                 eloop_unregister_read_sock(interfaces->global_ctrl_sock);
2639                 close(interfaces->global_ctrl_sock);
2640                 interfaces->global_ctrl_sock = -1;
2641                 fname = hostapd_global_ctrl_iface_path(interfaces);
2642                 if (fname) {
2643                         unlink(fname);
2644                         os_free(fname);
2645                 }
2646
2647                 if (interfaces->global_iface_path &&
2648                     rmdir(interfaces->global_iface_path) < 0) {
2649                         if (errno == ENOTEMPTY) {
2650                                 wpa_printf(MSG_DEBUG, "Control interface "
2651                                            "directory not empty - leaving it "
2652                                            "behind");
2653                         } else {
2654                                 wpa_printf(MSG_ERROR,
2655                                            "rmdir[ctrl_interface=%s]: %s",
2656                                            interfaces->global_iface_path,
2657                                            strerror(errno));
2658                         }
2659                 }
2660                 os_free(interfaces->global_iface_path);
2661                 interfaces->global_iface_path = NULL;
2662         }
2663 }
2664
2665
2666 static void hostapd_ctrl_iface_send(struct hostapd_data *hapd, int level,
2667                                     const char *buf, size_t len)
2668 {
2669         struct wpa_ctrl_dst *dst, *next;
2670         struct msghdr msg;
2671         int idx;
2672         struct iovec io[2];
2673         char levelstr[10];
2674
2675         dst = hapd->ctrl_dst;
2676         if (hapd->ctrl_sock < 0 || dst == NULL)
2677                 return;
2678
2679         os_snprintf(levelstr, sizeof(levelstr), "<%d>", level);
2680         io[0].iov_base = levelstr;
2681         io[0].iov_len = os_strlen(levelstr);
2682         io[1].iov_base = (char *) buf;
2683         io[1].iov_len = len;
2684         os_memset(&msg, 0, sizeof(msg));
2685         msg.msg_iov = io;
2686         msg.msg_iovlen = 2;
2687
2688         idx = 0;
2689         while (dst) {
2690                 next = dst->next;
2691                 if (level >= dst->debug_level) {
2692                         wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor send",
2693                                     (u8 *) dst->addr.sun_path, dst->addrlen -
2694                                     offsetof(struct sockaddr_un, sun_path));
2695                         msg.msg_name = &dst->addr;
2696                         msg.msg_namelen = dst->addrlen;
2697                         if (sendmsg(hapd->ctrl_sock, &msg, 0) < 0) {
2698                                 int _errno = errno;
2699                                 wpa_printf(MSG_INFO, "CTRL_IFACE monitor[%d]: "
2700                                            "%d - %s",
2701                                            idx, errno, strerror(errno));
2702                                 dst->errors++;
2703                                 if (dst->errors > 10 || _errno == ENOENT) {
2704                                         hostapd_ctrl_iface_detach(
2705                                                 hapd, &dst->addr,
2706                                                 dst->addrlen);
2707                                 }
2708                         } else
2709                                 dst->errors = 0;
2710                 }
2711                 idx++;
2712                 dst = next;
2713         }
2714 }
2715
2716 #endif /* CONFIG_NATIVE_WINDOWS */