2 * wlantest control interface
3 * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
15 #include "utils/includes.h"
18 #include "utils/common.h"
19 #include "utils/eloop.h"
20 #include "common/defs.h"
21 #include "common/version.h"
22 #include "common/ieee802_11_defs.h"
24 #include "wlantest_ctrl.h"
27 static u8 * attr_get(u8 *buf, size_t buflen, enum wlantest_ctrl_attr attr,
32 while (pos + 8 <= buf + buflen) {
33 enum wlantest_ctrl_attr a;
35 a = WPA_GET_BE32(pos);
37 alen = WPA_GET_BE32(pos);
39 if (pos + alen > buf + buflen) {
40 wpa_printf(MSG_DEBUG, "Invalid control message "
55 static u8 * attr_get_macaddr(u8 *buf, size_t buflen,
56 enum wlantest_ctrl_attr attr)
60 addr = attr_get(buf, buflen, attr, &addr_len);
61 if (addr && addr_len != ETH_ALEN)
67 static int attr_get_int(u8 *buf, size_t buflen, enum wlantest_ctrl_attr attr)
71 pos = attr_get(buf, buflen, attr, &len);
72 if (pos == NULL || len != 4)
74 return WPA_GET_BE32(pos);
78 static u8 * attr_add_str(u8 *pos, u8 *end, enum wlantest_ctrl_attr attr,
81 size_t len = os_strlen(str);
83 if (pos == NULL || end - pos < 8 + len)
85 WPA_PUT_BE32(pos, attr);
87 WPA_PUT_BE32(pos, len);
89 os_memcpy(pos, str, len);
95 static u8 * attr_add_be32(u8 *pos, u8 *end, enum wlantest_ctrl_attr attr,
98 if (pos == NULL || end - pos < 12)
100 WPA_PUT_BE32(pos, attr);
102 WPA_PUT_BE32(pos, 4);
104 WPA_PUT_BE32(pos, val);
110 static void ctrl_disconnect(struct wlantest *wt, int sock)
113 wpa_printf(MSG_DEBUG, "Disconnect control interface connection %d",
115 for (i = 0; i < MAX_CTRL_CONNECTIONS; i++) {
116 if (wt->ctrl_socks[i] == sock) {
117 close(wt->ctrl_socks[i]);
118 eloop_unregister_read_sock(wt->ctrl_socks[i]);
119 wt->ctrl_socks[i] = -1;
126 static void ctrl_send(struct wlantest *wt, int sock, const u8 *buf,
129 if (send(sock, buf, len, 0) < 0) {
130 wpa_printf(MSG_INFO, "send(ctrl): %s", strerror(errno));
131 ctrl_disconnect(wt, sock);
136 static void ctrl_send_simple(struct wlantest *wt, int sock,
137 enum wlantest_ctrl_cmd cmd)
140 WPA_PUT_BE32(buf, cmd);
141 ctrl_send(wt, sock, buf, sizeof(buf));
145 static void ctrl_list_bss(struct wlantest *wt, int sock)
147 u8 buf[WLANTEST_CTRL_MAX_RESP_LEN], *pos, *len;
148 struct wlantest_bss *bss;
151 WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
153 WPA_PUT_BE32(pos, WLANTEST_ATTR_BSSID);
155 len = pos; /* to be filled */
158 dl_list_for_each(bss, &wt->bss, struct wlantest_bss, list) {
159 if (pos + ETH_ALEN > buf + WLANTEST_CTRL_MAX_RESP_LEN)
161 os_memcpy(pos, bss->bssid, ETH_ALEN);
165 WPA_PUT_BE32(len, pos - len - 4);
166 ctrl_send(wt, sock, buf, pos - buf);
170 static void ctrl_list_sta(struct wlantest *wt, int sock, u8 *cmd, size_t clen)
172 u8 buf[WLANTEST_CTRL_MAX_RESP_LEN], *pos, *len;
175 struct wlantest_bss *bss;
176 struct wlantest_sta *sta;
178 bssid = attr_get(cmd, clen, WLANTEST_ATTR_BSSID, &bssid_len);
179 if (bssid == NULL || bssid_len != ETH_ALEN) {
180 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
184 bss = bss_find(wt, bssid);
186 ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
191 WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
193 WPA_PUT_BE32(pos, WLANTEST_ATTR_STA_ADDR);
195 len = pos; /* to be filled */
198 dl_list_for_each(sta, &bss->sta, struct wlantest_sta, list) {
199 if (pos + ETH_ALEN > buf + WLANTEST_CTRL_MAX_RESP_LEN)
201 os_memcpy(pos, sta->addr, ETH_ALEN);
205 WPA_PUT_BE32(len, pos - len - 4);
206 ctrl_send(wt, sock, buf, pos - buf);
210 static void ctrl_flush(struct wlantest *wt, int sock)
212 wpa_printf(MSG_DEBUG, "Drop all collected BSS data");
214 ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
218 static void ctrl_clear_sta_counters(struct wlantest *wt, int sock, u8 *cmd,
223 struct wlantest_bss *bss;
224 struct wlantest_sta *sta;
226 addr = attr_get(cmd, clen, WLANTEST_ATTR_BSSID, &addr_len);
227 if (addr == NULL || addr_len != ETH_ALEN) {
228 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
232 bss = bss_find(wt, addr);
234 ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
238 addr = attr_get(cmd, clen, WLANTEST_ATTR_STA_ADDR, &addr_len);
239 if (addr == NULL || addr_len != ETH_ALEN) {
240 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
244 sta = sta_find(bss, addr);
246 ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
250 os_memset(sta->counters, 0, sizeof(sta->counters));
251 ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
255 static void ctrl_clear_bss_counters(struct wlantest *wt, int sock, u8 *cmd,
260 struct wlantest_bss *bss;
262 addr = attr_get(cmd, clen, WLANTEST_ATTR_BSSID, &addr_len);
263 if (addr == NULL || addr_len != ETH_ALEN) {
264 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
268 bss = bss_find(wt, addr);
270 ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
274 os_memset(bss->counters, 0, sizeof(bss->counters));
275 ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
279 static void ctrl_get_sta_counter(struct wlantest *wt, int sock, u8 *cmd,
284 struct wlantest_bss *bss;
285 struct wlantest_sta *sta;
287 u8 buf[4 + 12], *end, *pos;
289 addr = attr_get(cmd, clen, WLANTEST_ATTR_BSSID, &addr_len);
290 if (addr == NULL || addr_len != ETH_ALEN) {
291 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
295 bss = bss_find(wt, addr);
297 ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
301 addr = attr_get(cmd, clen, WLANTEST_ATTR_STA_ADDR, &addr_len);
302 if (addr == NULL || addr_len != ETH_ALEN) {
303 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
307 sta = sta_find(bss, addr);
309 ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
313 addr = attr_get(cmd, clen, WLANTEST_ATTR_STA_COUNTER, &addr_len);
314 if (addr == NULL || addr_len != 4) {
315 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
318 counter = WPA_GET_BE32(addr);
319 if (counter >= NUM_WLANTEST_STA_COUNTER) {
320 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
325 end = buf + sizeof(buf);
326 WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
328 pos = attr_add_be32(pos, end, WLANTEST_ATTR_COUNTER,
329 sta->counters[counter]);
330 ctrl_send(wt, sock, buf, pos - buf);
334 static void ctrl_get_bss_counter(struct wlantest *wt, int sock, u8 *cmd,
339 struct wlantest_bss *bss;
341 u8 buf[4 + 12], *end, *pos;
343 addr = attr_get(cmd, clen, WLANTEST_ATTR_BSSID, &addr_len);
344 if (addr == NULL || addr_len != ETH_ALEN) {
345 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
349 bss = bss_find(wt, addr);
351 ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
355 addr = attr_get(cmd, clen, WLANTEST_ATTR_BSS_COUNTER, &addr_len);
356 if (addr == NULL || addr_len != 4) {
357 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
360 counter = WPA_GET_BE32(addr);
361 if (counter >= NUM_WLANTEST_BSS_COUNTER) {
362 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
367 end = buf + sizeof(buf);
368 WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
370 pos = attr_add_be32(pos, end, WLANTEST_ATTR_COUNTER,
371 bss->counters[counter]);
372 ctrl_send(wt, sock, buf, pos - buf);
376 static void build_mgmt_hdr(struct ieee80211_mgmt *mgmt,
377 struct wlantest_bss *bss, struct wlantest_sta *sta,
378 int sender_ap, int stype)
380 os_memset(mgmt, 0, 24);
381 mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, stype);
384 os_memcpy(mgmt->da, sta->addr, ETH_ALEN);
386 os_memset(mgmt->da, 0xff, ETH_ALEN);
387 os_memcpy(mgmt->sa, bss->bssid, ETH_ALEN);
389 os_memcpy(mgmt->da, bss->bssid, ETH_ALEN);
390 os_memcpy(mgmt->sa, sta->addr, ETH_ALEN);
392 os_memcpy(mgmt->bssid, bss->bssid, ETH_ALEN);
396 static int ctrl_inject_auth(struct wlantest *wt, struct wlantest_bss *bss,
397 struct wlantest_sta *sta, int sender_ap,
398 enum wlantest_inject_protection prot)
400 struct ieee80211_mgmt mgmt;
402 if (prot != WLANTEST_INJECT_NORMAL &&
403 prot != WLANTEST_INJECT_UNPROTECTED)
404 return -1; /* Authentication frame is never protected */
406 return -1; /* No broadcast Authentication frames */
409 wpa_printf(MSG_INFO, "INJECT: Auth " MACSTR " -> " MACSTR,
410 MAC2STR(bss->bssid), MAC2STR(sta->addr));
412 wpa_printf(MSG_INFO, "INJECT: Auth " MACSTR " -> " MACSTR,
413 MAC2STR(sta->addr), MAC2STR(bss->bssid));
414 build_mgmt_hdr(&mgmt, bss, sta, sender_ap, WLAN_FC_STYPE_AUTH);
416 mgmt.u.auth.auth_alg = host_to_le16(WLAN_AUTH_OPEN);
417 mgmt.u.auth.auth_transaction = host_to_le16(1);
418 mgmt.u.auth.status_code = host_to_le16(WLAN_STATUS_SUCCESS);
420 return wlantest_inject(wt, bss, sta, (u8 *) &mgmt, 24 + 6,
421 WLANTEST_INJECT_UNPROTECTED);
425 static int ctrl_inject_assocreq(struct wlantest *wt, struct wlantest_bss *bss,
426 struct wlantest_sta *sta, int sender_ap,
427 enum wlantest_inject_protection prot)
430 struct ieee80211_mgmt *mgmt;
433 if (prot != WLANTEST_INJECT_NORMAL &&
434 prot != WLANTEST_INJECT_UNPROTECTED)
435 return -1; /* Association Request frame is never protected */
437 return -1; /* No broadcast Association Request frames */
439 return -1; /* No Association Request frame sent by AP */
440 if (sta->assocreq_ies == NULL) {
441 wpa_printf(MSG_INFO, "INJECT: No previous (Re)Association "
442 "Request available for " MACSTR,
447 wpa_printf(MSG_INFO, "INJECT: AssocReq " MACSTR " -> " MACSTR,
448 MAC2STR(sta->addr), MAC2STR(bss->bssid));
449 buf = os_malloc(sizeof(*mgmt) + sta->assocreq_ies_len);
452 mgmt = (struct ieee80211_mgmt *) buf;
454 build_mgmt_hdr(mgmt, bss, sta, sender_ap, WLAN_FC_STYPE_ASSOC_REQ);
456 mgmt->u.assoc_req.capab_info = host_to_le16(sta->assocreq_capab_info);
457 mgmt->u.assoc_req.listen_interval =
458 host_to_le16(sta->assocreq_listen_int);
459 os_memcpy(mgmt->u.assoc_req.variable, sta->assocreq_ies,
460 sta->assocreq_ies_len);
462 ret = wlantest_inject(wt, bss, sta, buf,
463 24 + 4 + sta->assocreq_ies_len,
464 WLANTEST_INJECT_UNPROTECTED);
470 static int ctrl_inject_reassocreq(struct wlantest *wt,
471 struct wlantest_bss *bss,
472 struct wlantest_sta *sta, int sender_ap,
473 enum wlantest_inject_protection prot)
476 struct ieee80211_mgmt *mgmt;
479 if (prot != WLANTEST_INJECT_NORMAL &&
480 prot != WLANTEST_INJECT_UNPROTECTED)
481 return -1; /* Reassociation Request frame is never protected */
483 return -1; /* No broadcast Reassociation Request frames */
485 return -1; /* No Reassociation Request frame sent by AP */
486 if (sta->assocreq_ies == NULL) {
487 wpa_printf(MSG_INFO, "INJECT: No previous (Re)Association "
488 "Request available for " MACSTR,
493 wpa_printf(MSG_INFO, "INJECT: ReassocReq " MACSTR " -> " MACSTR,
494 MAC2STR(sta->addr), MAC2STR(bss->bssid));
495 buf = os_malloc(sizeof(*mgmt) + sta->assocreq_ies_len);
498 mgmt = (struct ieee80211_mgmt *) buf;
500 build_mgmt_hdr(mgmt, bss, sta, sender_ap, WLAN_FC_STYPE_REASSOC_REQ);
502 mgmt->u.reassoc_req.capab_info =
503 host_to_le16(sta->assocreq_capab_info);
504 mgmt->u.reassoc_req.listen_interval =
505 host_to_le16(sta->assocreq_listen_int);
506 os_memcpy(mgmt->u.reassoc_req.current_ap, bss->bssid, ETH_ALEN);
507 os_memcpy(mgmt->u.reassoc_req.variable, sta->assocreq_ies,
508 sta->assocreq_ies_len);
510 ret = wlantest_inject(wt, bss, sta, buf,
511 24 + 10 + sta->assocreq_ies_len,
512 WLANTEST_INJECT_UNPROTECTED);
518 static int ctrl_inject_deauth(struct wlantest *wt, struct wlantest_bss *bss,
519 struct wlantest_sta *sta, int sender_ap,
520 enum wlantest_inject_protection prot)
522 struct ieee80211_mgmt mgmt;
526 wpa_printf(MSG_INFO, "INJECT: Deauth " MACSTR " -> "
528 MAC2STR(bss->bssid), MAC2STR(sta->addr));
530 wpa_printf(MSG_INFO, "INJECT: Deauth " MACSTR
531 " -> broadcast", MAC2STR(bss->bssid));
533 wpa_printf(MSG_INFO, "INJECT: Deauth " MACSTR " -> " MACSTR,
534 MAC2STR(sta->addr), MAC2STR(bss->bssid));
535 build_mgmt_hdr(&mgmt, bss, sta, sender_ap, WLAN_FC_STYPE_DEAUTH);
537 mgmt.u.deauth.reason_code = host_to_le16(WLAN_REASON_UNSPECIFIED);
539 return wlantest_inject(wt, bss, sta, (u8 *) &mgmt, 24 + 2, prot);
543 static int ctrl_inject_disassoc(struct wlantest *wt, struct wlantest_bss *bss,
544 struct wlantest_sta *sta, int sender_ap,
545 enum wlantest_inject_protection prot)
547 struct ieee80211_mgmt mgmt;
551 wpa_printf(MSG_INFO, "INJECT: Disassoc " MACSTR " -> "
553 MAC2STR(bss->bssid), MAC2STR(sta->addr));
555 wpa_printf(MSG_INFO, "INJECT: Disassoc " MACSTR
556 " -> broadcast", MAC2STR(bss->bssid));
558 wpa_printf(MSG_INFO, "INJECT: Disassoc " MACSTR " -> " MACSTR,
559 MAC2STR(sta->addr), MAC2STR(bss->bssid));
560 build_mgmt_hdr(&mgmt, bss, sta, sender_ap, WLAN_FC_STYPE_DISASSOC);
562 mgmt.u.disassoc.reason_code = host_to_le16(WLAN_REASON_UNSPECIFIED);
564 return wlantest_inject(wt, bss, sta, (u8 *) &mgmt, 24 + 2, prot);
568 static int ctrl_inject_saqueryreq(struct wlantest *wt,
569 struct wlantest_bss *bss,
570 struct wlantest_sta *sta, int sender_ap,
571 enum wlantest_inject_protection prot)
573 struct ieee80211_mgmt mgmt;
576 return -1; /* No broadcast SA Query frames */
579 wpa_printf(MSG_INFO, "INJECT: SA Query Request " MACSTR " -> "
580 MACSTR, MAC2STR(bss->bssid), MAC2STR(sta->addr));
582 wpa_printf(MSG_INFO, "INJECT: SA Query Request " MACSTR " -> "
583 MACSTR, MAC2STR(sta->addr), MAC2STR(bss->bssid));
584 build_mgmt_hdr(&mgmt, bss, sta, sender_ap, WLAN_FC_STYPE_ACTION);
586 mgmt.u.action.category = WLAN_ACTION_SA_QUERY;
587 mgmt.u.action.u.sa_query_req.action = WLAN_SA_QUERY_REQUEST;
588 mgmt.u.action.u.sa_query_req.trans_id[0] = 0x12;
589 mgmt.u.action.u.sa_query_req.trans_id[1] = 0x34;
590 os_memcpy(sender_ap ? sta->ap_sa_query_tr : sta->sta_sa_query_tr,
591 mgmt.u.action.u.sa_query_req.trans_id,
592 WLAN_SA_QUERY_TR_ID_LEN);
593 return wlantest_inject(wt, bss, sta, (u8 *) &mgmt, 24 + 4, prot);
597 static void ctrl_inject(struct wlantest *wt, int sock, u8 *cmd, size_t clen)
599 u8 *bssid, *sta_addr;
600 struct wlantest_bss *bss;
601 struct wlantest_sta *sta;
602 int frame, sender_ap, prot;
605 bssid = attr_get_macaddr(cmd, clen, WLANTEST_ATTR_BSSID);
606 sta_addr = attr_get_macaddr(cmd, clen, WLANTEST_ATTR_STA_ADDR);
607 frame = attr_get_int(cmd, clen, WLANTEST_ATTR_INJECT_FRAME);
608 sender_ap = attr_get_int(cmd, clen, WLANTEST_ATTR_INJECT_SENDER_AP);
611 prot = attr_get_int(cmd, clen, WLANTEST_ATTR_INJECT_PROTECTION);
612 if (bssid == NULL || sta_addr == NULL || frame < 0 || prot < 0) {
613 wpa_printf(MSG_INFO, "Invalid inject command parameters");
614 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
618 bss = bss_find(wt, bssid);
620 wpa_printf(MSG_INFO, "BSS not found for inject command");
621 ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
625 if (is_broadcast_ether_addr(sta_addr)) {
627 wpa_printf(MSG_INFO, "Invalid broadcast inject "
628 "command without sender_ap set");
629 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
633 sta = sta_find(bss, sta_addr);
635 wpa_printf(MSG_INFO, "Station not found for inject "
637 ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
643 case WLANTEST_FRAME_AUTH:
644 ret = ctrl_inject_auth(wt, bss, sta, sender_ap, prot);
646 case WLANTEST_FRAME_ASSOCREQ:
647 ret = ctrl_inject_assocreq(wt, bss, sta, sender_ap, prot);
649 case WLANTEST_FRAME_REASSOCREQ:
650 ret = ctrl_inject_reassocreq(wt, bss, sta, sender_ap, prot);
652 case WLANTEST_FRAME_DEAUTH:
653 ret = ctrl_inject_deauth(wt, bss, sta, sender_ap, prot);
655 case WLANTEST_FRAME_DISASSOC:
656 ret = ctrl_inject_disassoc(wt, bss, sta, sender_ap, prot);
658 case WLANTEST_FRAME_SAQUERYREQ:
659 ret = ctrl_inject_saqueryreq(wt, bss, sta, sender_ap, prot);
662 wpa_printf(MSG_INFO, "Unsupported inject command frame %d",
664 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
669 wpa_printf(MSG_INFO, "Failed to inject frame");
671 wpa_printf(MSG_INFO, "Frame injected successfully");
672 ctrl_send_simple(wt, sock, ret == 0 ? WLANTEST_CTRL_SUCCESS :
673 WLANTEST_CTRL_FAILURE);
677 static void ctrl_version(struct wlantest *wt, int sock)
679 u8 buf[WLANTEST_CTRL_MAX_RESP_LEN], *pos;
682 WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
684 pos = attr_add_str(pos, buf + sizeof(buf), WLANTEST_ATTR_VERSION,
686 ctrl_send(wt, sock, buf, pos - buf);
690 static void ctrl_add_passphrase(struct wlantest *wt, int sock, u8 *cmd,
695 struct wlantest_passphrase *p, *pa;
698 passphrase = attr_get(cmd, clen, WLANTEST_ATTR_PASSPHRASE, &len);
699 if (passphrase == NULL || len < 8 || len > 63) {
700 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
704 p = os_zalloc(sizeof(*p));
706 ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
709 os_memcpy(p->passphrase, passphrase, len);
710 wpa_printf(MSG_INFO, "Add passphrase '%s'", p->passphrase);
712 bssid = attr_get_macaddr(cmd, clen, WLANTEST_ATTR_BSSID);
714 os_memcpy(p->bssid, bssid, ETH_ALEN);
715 wpa_printf(MSG_INFO, "Limit passphrase for BSSID " MACSTR,
719 dl_list_for_each(pa, &wt->passphrase, struct wlantest_passphrase, list)
721 if (os_strcmp(p->passphrase, pa->passphrase) == 0 &&
722 os_memcmp(p->bssid, pa->bssid, ETH_ALEN) == 0) {
723 wpa_printf(MSG_INFO, "Passphrase was already known");
731 struct wlantest_bss *bss;
732 dl_list_add(&wt->passphrase, &p->list);
733 dl_list_for_each(bss, &wt->bss, struct wlantest_bss, list) {
735 os_memcmp(p->bssid, bss->bssid, ETH_ALEN) != 0)
737 bss_add_pmk_from_passphrase(bss, p->passphrase);
741 ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
745 static void info_print_proto(char *buf, size_t len, int proto)
750 os_snprintf(buf, len, "OPEN");
757 if (proto & WPA_PROTO_WPA)
758 pos += os_snprintf(pos, end - pos, "%sWPA",
759 pos == buf ? "" : " ");
760 if (proto & WPA_PROTO_RSN)
761 pos += os_snprintf(pos, end - pos, "%sWPA2",
762 pos == buf ? "" : " ");
766 static void info_print_cipher(char *buf, size_t len, int cipher)
771 os_snprintf(buf, len, "N/A");
778 if (cipher & WPA_CIPHER_NONE)
779 pos += os_snprintf(pos, end - pos, "%sNONE",
780 pos == buf ? "" : " ");
781 if (cipher & WPA_CIPHER_WEP40)
782 pos += os_snprintf(pos, end - pos, "%sWEP40",
783 pos == buf ? "" : " ");
784 if (cipher & WPA_CIPHER_WEP104)
785 pos += os_snprintf(pos, end - pos, "%sWEP104",
786 pos == buf ? "" : " ");
787 if (cipher & WPA_CIPHER_TKIP)
788 pos += os_snprintf(pos, end - pos, "%sTKIP",
789 pos == buf ? "" : " ");
790 if (cipher & WPA_CIPHER_CCMP)
791 pos += os_snprintf(pos, end - pos, "%sCCMP",
792 pos == buf ? "" : " ");
793 if (cipher & WPA_CIPHER_AES_128_CMAC)
794 pos += os_snprintf(pos, end - pos, "%sBIP",
795 pos == buf ? "" : " ");
799 static void info_print_key_mgmt(char *buf, size_t len, int key_mgmt)
804 os_snprintf(buf, len, "N/A");
811 if (key_mgmt & WPA_KEY_MGMT_IEEE8021X)
812 pos += os_snprintf(pos, end - pos, "%sEAP",
813 pos == buf ? "" : " ");
814 if (key_mgmt & WPA_KEY_MGMT_PSK)
815 pos += os_snprintf(pos, end - pos, "%sPSK",
816 pos == buf ? "" : " ");
817 if (key_mgmt & WPA_KEY_MGMT_WPA_NONE)
818 pos += os_snprintf(pos, end - pos, "%sWPA-NONE",
819 pos == buf ? "" : " ");
820 if (key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X)
821 pos += os_snprintf(pos, end - pos, "%sFT-EAP",
822 pos == buf ? "" : " ");
823 if (key_mgmt & WPA_KEY_MGMT_FT_PSK)
824 pos += os_snprintf(pos, end - pos, "%sFT-PSK",
825 pos == buf ? "" : " ");
826 if (key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256)
827 pos += os_snprintf(pos, end - pos, "%sEAP-SHA256",
828 pos == buf ? "" : " ");
829 if (key_mgmt & WPA_KEY_MGMT_PSK_SHA256)
830 pos += os_snprintf(pos, end - pos, "%sPSK-SHA256",
831 pos == buf ? "" : " ");
835 static void info_print_rsn_capab(char *buf, size_t len, int capab)
842 if (capab & WPA_CAPABILITY_PREAUTH)
843 pos += os_snprintf(pos, end - pos, "%sPREAUTH",
844 pos == buf ? "" : " ");
845 if (capab & WPA_CAPABILITY_NO_PAIRWISE)
846 pos += os_snprintf(pos, end - pos, "%sNO_PAIRWISE",
847 pos == buf ? "" : " ");
848 if (capab & WPA_CAPABILITY_MFPR)
849 pos += os_snprintf(pos, end - pos, "%sMFPR",
850 pos == buf ? "" : " ");
851 if (capab & WPA_CAPABILITY_MFPC)
852 pos += os_snprintf(pos, end - pos, "%sMFPC",
853 pos == buf ? "" : " ");
854 if (capab & WPA_CAPABILITY_PEERKEY_ENABLED)
855 pos += os_snprintf(pos, end - pos, "%sPEERKEY",
856 pos == buf ? "" : " ");
860 static void info_print_state(char *buf, size_t len, int state)
864 os_strlcpy(buf, "NOT-AUTH", len);
867 os_strlcpy(buf, "AUTH", len);
870 os_strlcpy(buf, "AUTH+ASSOC", len);
876 static void ctrl_info_sta(struct wlantest *wt, int sock, u8 *cmd, size_t clen)
880 struct wlantest_bss *bss;
881 struct wlantest_sta *sta;
882 enum wlantest_sta_info info;
883 u8 buf[4 + 108], *end, *pos;
886 addr = attr_get(cmd, clen, WLANTEST_ATTR_BSSID, &addr_len);
887 if (addr == NULL || addr_len != ETH_ALEN) {
888 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
892 bss = bss_find(wt, addr);
894 ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
898 addr = attr_get(cmd, clen, WLANTEST_ATTR_STA_ADDR, &addr_len);
899 if (addr == NULL || addr_len != ETH_ALEN) {
900 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
904 sta = sta_find(bss, addr);
906 ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
910 addr = attr_get(cmd, clen, WLANTEST_ATTR_STA_INFO, &addr_len);
911 if (addr == NULL || addr_len != 4) {
912 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
915 info = WPA_GET_BE32(addr);
919 case WLANTEST_STA_INFO_PROTO:
920 info_print_proto(resp, sizeof(resp), sta->proto);
922 case WLANTEST_STA_INFO_PAIRWISE:
923 info_print_cipher(resp, sizeof(resp), sta->pairwise_cipher);
925 case WLANTEST_STA_INFO_KEY_MGMT:
926 info_print_key_mgmt(resp, sizeof(resp), sta->key_mgmt);
928 case WLANTEST_STA_INFO_RSN_CAPAB:
929 info_print_rsn_capab(resp, sizeof(resp), sta->rsn_capab);
931 case WLANTEST_STA_INFO_STATE:
932 info_print_state(resp, sizeof(resp), sta->state);
935 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
940 end = buf + sizeof(buf);
941 WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
943 pos = attr_add_str(pos, end, WLANTEST_ATTR_INFO, resp);
944 ctrl_send(wt, sock, buf, pos - buf);
948 static void ctrl_info_bss(struct wlantest *wt, int sock, u8 *cmd, size_t clen)
952 struct wlantest_bss *bss;
953 enum wlantest_bss_info info;
954 u8 buf[4 + 108], *end, *pos;
957 addr = attr_get(cmd, clen, WLANTEST_ATTR_BSSID, &addr_len);
958 if (addr == NULL || addr_len != ETH_ALEN) {
959 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
963 bss = bss_find(wt, addr);
965 ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
969 addr = attr_get(cmd, clen, WLANTEST_ATTR_BSS_INFO, &addr_len);
970 if (addr == NULL || addr_len != 4) {
971 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
974 info = WPA_GET_BE32(addr);
978 case WLANTEST_BSS_INFO_PROTO:
979 info_print_proto(resp, sizeof(resp), bss->proto);
981 case WLANTEST_BSS_INFO_PAIRWISE:
982 info_print_cipher(resp, sizeof(resp), bss->pairwise_cipher);
984 case WLANTEST_BSS_INFO_GROUP:
985 info_print_cipher(resp, sizeof(resp), bss->group_cipher);
987 case WLANTEST_BSS_INFO_GROUP_MGMT:
988 info_print_cipher(resp, sizeof(resp), bss->mgmt_group_cipher);
990 case WLANTEST_BSS_INFO_KEY_MGMT:
991 info_print_key_mgmt(resp, sizeof(resp), bss->key_mgmt);
993 case WLANTEST_BSS_INFO_RSN_CAPAB:
994 info_print_rsn_capab(resp, sizeof(resp), bss->rsn_capab);
997 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
1002 end = buf + sizeof(buf);
1003 WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
1005 pos = attr_add_str(pos, end, WLANTEST_ATTR_INFO, resp);
1006 ctrl_send(wt, sock, buf, pos - buf);
1010 static void ctrl_read(int sock, void *eloop_ctx, void *sock_ctx)
1012 struct wlantest *wt = eloop_ctx;
1013 u8 buf[WLANTEST_CTRL_MAX_CMD_LEN];
1015 enum wlantest_ctrl_cmd cmd;
1017 wpa_printf(MSG_EXCESSIVE, "New control interface message from %d",
1019 len = recv(sock, buf, sizeof(buf), 0);
1021 wpa_printf(MSG_INFO, "recv(ctrl): %s", strerror(errno));
1022 ctrl_disconnect(wt, sock);
1026 ctrl_disconnect(wt, sock);
1031 wpa_printf(MSG_INFO, "Too short control interface command "
1033 ctrl_disconnect(wt, sock);
1036 cmd = WPA_GET_BE32(buf);
1037 wpa_printf(MSG_EXCESSIVE, "Control interface command %d from %d",
1041 case WLANTEST_CTRL_PING:
1042 ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
1044 case WLANTEST_CTRL_TERMINATE:
1045 ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
1048 case WLANTEST_CTRL_LIST_BSS:
1049 ctrl_list_bss(wt, sock);
1051 case WLANTEST_CTRL_LIST_STA:
1052 ctrl_list_sta(wt, sock, buf + 4, len - 4);
1054 case WLANTEST_CTRL_FLUSH:
1055 ctrl_flush(wt, sock);
1057 case WLANTEST_CTRL_CLEAR_STA_COUNTERS:
1058 ctrl_clear_sta_counters(wt, sock, buf + 4, len - 4);
1060 case WLANTEST_CTRL_CLEAR_BSS_COUNTERS:
1061 ctrl_clear_bss_counters(wt, sock, buf + 4, len - 4);
1063 case WLANTEST_CTRL_GET_STA_COUNTER:
1064 ctrl_get_sta_counter(wt, sock, buf + 4, len - 4);
1066 case WLANTEST_CTRL_GET_BSS_COUNTER:
1067 ctrl_get_bss_counter(wt, sock, buf + 4, len - 4);
1069 case WLANTEST_CTRL_INJECT:
1070 ctrl_inject(wt, sock, buf + 4, len - 4);
1072 case WLANTEST_CTRL_VERSION:
1073 ctrl_version(wt, sock);
1075 case WLANTEST_CTRL_ADD_PASSPHRASE:
1076 ctrl_add_passphrase(wt, sock, buf + 4, len - 4);
1078 case WLANTEST_CTRL_INFO_STA:
1079 ctrl_info_sta(wt, sock, buf + 4, len - 4);
1081 case WLANTEST_CTRL_INFO_BSS:
1082 ctrl_info_bss(wt, sock, buf + 4, len - 4);
1085 ctrl_send_simple(wt, sock, WLANTEST_CTRL_UNKNOWN_CMD);
1091 static void ctrl_connect(int sock, void *eloop_ctx, void *sock_ctx)
1093 struct wlantest *wt = eloop_ctx;
1096 conn = accept(sock, NULL, NULL);
1098 wpa_printf(MSG_INFO, "accept(ctrl): %s", strerror(errno));
1101 wpa_printf(MSG_MSGDUMP, "New control interface connection %d", conn);
1103 for (i = 0; i < MAX_CTRL_CONNECTIONS; i++) {
1104 if (wt->ctrl_socks[i] < 0)
1108 if (i == MAX_CTRL_CONNECTIONS) {
1109 wpa_printf(MSG_INFO, "No room for new control connection");
1114 wt->ctrl_socks[i] = conn;
1115 eloop_register_read_sock(conn, ctrl_read, wt, NULL);
1119 int ctrl_init(struct wlantest *wt)
1121 struct sockaddr_un addr;
1123 wt->ctrl_sock = socket(AF_UNIX, SOCK_SEQPACKET, 0);
1124 if (wt->ctrl_sock < 0) {
1125 wpa_printf(MSG_ERROR, "socket: %s", strerror(errno));
1129 os_memset(&addr, 0, sizeof(addr));
1130 addr.sun_family = AF_UNIX;
1131 os_strlcpy(addr.sun_path + 1, WLANTEST_SOCK_NAME,
1132 sizeof(addr.sun_path) - 1);
1133 if (bind(wt->ctrl_sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
1134 wpa_printf(MSG_ERROR, "bind: %s", strerror(errno));
1135 close(wt->ctrl_sock);
1140 if (listen(wt->ctrl_sock, 5) < 0) {
1141 wpa_printf(MSG_ERROR, "listen: %s", strerror(errno));
1142 close(wt->ctrl_sock);
1147 if (eloop_register_read_sock(wt->ctrl_sock, ctrl_connect, wt, NULL)) {
1148 close(wt->ctrl_sock);
1157 void ctrl_deinit(struct wlantest *wt)
1161 if (wt->ctrl_sock < 0)
1164 for (i = 0; i < MAX_CTRL_CONNECTIONS; i++) {
1165 if (wt->ctrl_socks[i] >= 0) {
1166 close(wt->ctrl_socks[i]);
1167 eloop_unregister_read_sock(wt->ctrl_socks[i]);
1168 wt->ctrl_socks[i] = -1;
1172 eloop_unregister_read_sock(wt->ctrl_sock);
1173 close(wt->ctrl_sock);