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/version.h"
21 #include "common/ieee802_11_defs.h"
23 #include "wlantest_ctrl.h"
26 static u8 * attr_get(u8 *buf, size_t buflen, enum wlantest_ctrl_attr attr,
31 while (pos + 8 <= buf + buflen) {
32 enum wlantest_ctrl_attr a;
34 a = WPA_GET_BE32(pos);
36 alen = WPA_GET_BE32(pos);
38 if (pos + alen > buf + buflen) {
39 wpa_printf(MSG_DEBUG, "Invalid control message "
54 static u8 * attr_get_macaddr(u8 *buf, size_t buflen,
55 enum wlantest_ctrl_attr attr)
59 addr = attr_get(buf, buflen, attr, &addr_len);
60 if (addr && addr_len != ETH_ALEN)
66 static int attr_get_int(u8 *buf, size_t buflen, enum wlantest_ctrl_attr attr)
70 pos = attr_get(buf, buflen, attr, &len);
71 if (pos == NULL || len != 4)
73 return WPA_GET_BE32(pos);
77 static u8 * attr_add_str(u8 *pos, u8 *end, enum wlantest_ctrl_attr attr,
80 size_t len = os_strlen(str);
82 if (pos == NULL || end - pos < 8 + len)
84 WPA_PUT_BE32(pos, attr);
86 WPA_PUT_BE32(pos, len);
88 os_memcpy(pos, str, len);
94 static u8 * attr_add_be32(u8 *pos, u8 *end, enum wlantest_ctrl_attr attr,
97 if (pos == NULL || end - pos < 12)
99 WPA_PUT_BE32(pos, attr);
101 WPA_PUT_BE32(pos, 4);
103 WPA_PUT_BE32(pos, val);
109 static void ctrl_disconnect(struct wlantest *wt, int sock)
112 wpa_printf(MSG_DEBUG, "Disconnect control interface connection %d",
114 for (i = 0; i < MAX_CTRL_CONNECTIONS; i++) {
115 if (wt->ctrl_socks[i] == sock) {
116 close(wt->ctrl_socks[i]);
117 eloop_unregister_read_sock(wt->ctrl_socks[i]);
118 wt->ctrl_socks[i] = -1;
125 static void ctrl_send(struct wlantest *wt, int sock, const u8 *buf,
128 if (send(sock, buf, len, 0) < 0) {
129 wpa_printf(MSG_INFO, "send(ctrl): %s", strerror(errno));
130 ctrl_disconnect(wt, sock);
135 static void ctrl_send_simple(struct wlantest *wt, int sock,
136 enum wlantest_ctrl_cmd cmd)
139 WPA_PUT_BE32(buf, cmd);
140 ctrl_send(wt, sock, buf, sizeof(buf));
144 static void ctrl_list_bss(struct wlantest *wt, int sock)
146 u8 buf[WLANTEST_CTRL_MAX_RESP_LEN], *pos, *len;
147 struct wlantest_bss *bss;
150 WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
152 WPA_PUT_BE32(pos, WLANTEST_ATTR_BSSID);
154 len = pos; /* to be filled */
157 dl_list_for_each(bss, &wt->bss, struct wlantest_bss, list) {
158 if (pos + ETH_ALEN > buf + WLANTEST_CTRL_MAX_RESP_LEN)
160 os_memcpy(pos, bss->bssid, ETH_ALEN);
164 WPA_PUT_BE32(len, pos - len - 4);
165 ctrl_send(wt, sock, buf, pos - buf);
169 static void ctrl_list_sta(struct wlantest *wt, int sock, u8 *cmd, size_t clen)
171 u8 buf[WLANTEST_CTRL_MAX_RESP_LEN], *pos, *len;
174 struct wlantest_bss *bss;
175 struct wlantest_sta *sta;
177 bssid = attr_get(cmd, clen, WLANTEST_ATTR_BSSID, &bssid_len);
178 if (bssid == NULL || bssid_len != ETH_ALEN) {
179 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
183 bss = bss_find(wt, bssid);
185 ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
190 WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
192 WPA_PUT_BE32(pos, WLANTEST_ATTR_STA_ADDR);
194 len = pos; /* to be filled */
197 dl_list_for_each(sta, &bss->sta, struct wlantest_sta, list) {
198 if (pos + ETH_ALEN > buf + WLANTEST_CTRL_MAX_RESP_LEN)
200 os_memcpy(pos, sta->addr, ETH_ALEN);
204 WPA_PUT_BE32(len, pos - len - 4);
205 ctrl_send(wt, sock, buf, pos - buf);
209 static void ctrl_flush(struct wlantest *wt, int sock)
211 wpa_printf(MSG_DEBUG, "Drop all collected BSS data");
213 ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
217 static void ctrl_clear_sta_counters(struct wlantest *wt, int sock, u8 *cmd,
222 struct wlantest_bss *bss;
223 struct wlantest_sta *sta;
225 addr = attr_get(cmd, clen, WLANTEST_ATTR_BSSID, &addr_len);
226 if (addr == NULL || addr_len != ETH_ALEN) {
227 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
231 bss = bss_find(wt, addr);
233 ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
237 addr = attr_get(cmd, clen, WLANTEST_ATTR_STA_ADDR, &addr_len);
238 if (addr == NULL || addr_len != ETH_ALEN) {
239 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
243 sta = sta_find(bss, addr);
245 ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
249 os_memset(sta->counters, 0, sizeof(sta->counters));
250 ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
254 static void ctrl_clear_bss_counters(struct wlantest *wt, int sock, u8 *cmd,
259 struct wlantest_bss *bss;
261 addr = attr_get(cmd, clen, WLANTEST_ATTR_BSSID, &addr_len);
262 if (addr == NULL || addr_len != ETH_ALEN) {
263 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
267 bss = bss_find(wt, addr);
269 ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
273 os_memset(bss->counters, 0, sizeof(bss->counters));
274 ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
278 static void ctrl_get_sta_counter(struct wlantest *wt, int sock, u8 *cmd,
283 struct wlantest_bss *bss;
284 struct wlantest_sta *sta;
286 u8 buf[4 + 12], *end, *pos;
288 addr = attr_get(cmd, clen, WLANTEST_ATTR_BSSID, &addr_len);
289 if (addr == NULL || addr_len != ETH_ALEN) {
290 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
294 bss = bss_find(wt, addr);
296 ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
300 addr = attr_get(cmd, clen, WLANTEST_ATTR_STA_ADDR, &addr_len);
301 if (addr == NULL || addr_len != ETH_ALEN) {
302 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
306 sta = sta_find(bss, addr);
308 ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
312 addr = attr_get(cmd, clen, WLANTEST_ATTR_STA_COUNTER, &addr_len);
313 if (addr == NULL || addr_len != 4) {
314 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
317 counter = WPA_GET_BE32(addr);
318 if (counter >= NUM_WLANTEST_STA_COUNTER) {
319 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
324 end = buf + sizeof(buf);
325 WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
327 pos = attr_add_be32(pos, end, WLANTEST_ATTR_COUNTER,
328 sta->counters[counter]);
329 ctrl_send(wt, sock, buf, pos - buf);
333 static void ctrl_get_bss_counter(struct wlantest *wt, int sock, u8 *cmd,
338 struct wlantest_bss *bss;
340 u8 buf[4 + 12], *end, *pos;
342 addr = attr_get(cmd, clen, WLANTEST_ATTR_BSSID, &addr_len);
343 if (addr == NULL || addr_len != ETH_ALEN) {
344 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
348 bss = bss_find(wt, addr);
350 ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
354 addr = attr_get(cmd, clen, WLANTEST_ATTR_BSS_COUNTER, &addr_len);
355 if (addr == NULL || addr_len != 4) {
356 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
359 counter = WPA_GET_BE32(addr);
360 if (counter >= NUM_WLANTEST_BSS_COUNTER) {
361 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
366 end = buf + sizeof(buf);
367 WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
369 pos = attr_add_be32(pos, end, WLANTEST_ATTR_COUNTER,
370 bss->counters[counter]);
371 ctrl_send(wt, sock, buf, pos - buf);
375 static void build_mgmt_hdr(struct ieee80211_mgmt *mgmt,
376 struct wlantest_bss *bss, struct wlantest_sta *sta,
377 int sender_ap, int stype)
379 os_memset(mgmt, 0, 24);
380 mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, stype);
383 os_memcpy(mgmt->da, sta->addr, ETH_ALEN);
385 os_memset(mgmt->da, 0xff, ETH_ALEN);
386 os_memcpy(mgmt->sa, bss->bssid, ETH_ALEN);
388 os_memcpy(mgmt->da, bss->bssid, ETH_ALEN);
389 os_memcpy(mgmt->sa, sta->addr, ETH_ALEN);
391 os_memcpy(mgmt->bssid, bss->bssid, ETH_ALEN);
395 static int ctrl_inject_auth(struct wlantest *wt, struct wlantest_bss *bss,
396 struct wlantest_sta *sta, int sender_ap,
397 enum wlantest_inject_protection prot)
399 struct ieee80211_mgmt mgmt;
401 if (prot != WLANTEST_INJECT_NORMAL &&
402 prot != WLANTEST_INJECT_UNPROTECTED)
403 return -1; /* Authentication frame is never protected */
405 return -1; /* No broadcast Authentication frames */
408 wpa_printf(MSG_INFO, "INJECT: Auth " MACSTR " -> " MACSTR,
409 MAC2STR(bss->bssid), MAC2STR(sta->addr));
411 wpa_printf(MSG_INFO, "INJECT: Auth " MACSTR " -> " MACSTR,
412 MAC2STR(sta->addr), MAC2STR(bss->bssid));
413 build_mgmt_hdr(&mgmt, bss, sta, sender_ap, WLAN_FC_STYPE_AUTH);
415 mgmt.u.auth.auth_alg = host_to_le16(WLAN_AUTH_OPEN);
416 mgmt.u.auth.auth_transaction = host_to_le16(1);
417 mgmt.u.auth.status_code = host_to_le16(WLAN_STATUS_SUCCESS);
419 return wlantest_inject(wt, bss, sta, (u8 *) &mgmt, 24 + 6,
420 WLANTEST_INJECT_UNPROTECTED);
424 static int ctrl_inject_assocreq(struct wlantest *wt, struct wlantest_bss *bss,
425 struct wlantest_sta *sta, int sender_ap,
426 enum wlantest_inject_protection prot)
429 struct ieee80211_mgmt *mgmt;
432 if (prot != WLANTEST_INJECT_NORMAL &&
433 prot != WLANTEST_INJECT_UNPROTECTED)
434 return -1; /* Association Request frame is never protected */
436 return -1; /* No broadcast Association Request frames */
438 return -1; /* No Association Request frame sent by AP */
439 if (sta->assocreq_ies == NULL) {
440 wpa_printf(MSG_INFO, "INJECT: No previous (Re)Association "
441 "Request available for " MACSTR,
446 wpa_printf(MSG_INFO, "INJECT: AssocReq " MACSTR " -> " MACSTR,
447 MAC2STR(sta->addr), MAC2STR(bss->bssid));
448 buf = os_malloc(sizeof(*mgmt) + sta->assocreq_ies_len);
451 mgmt = (struct ieee80211_mgmt *) buf;
453 build_mgmt_hdr(mgmt, bss, sta, sender_ap, WLAN_FC_STYPE_ASSOC_REQ);
455 mgmt->u.assoc_req.capab_info = host_to_le16(sta->assocreq_capab_info);
456 mgmt->u.assoc_req.listen_interval =
457 host_to_le16(sta->assocreq_listen_int);
458 os_memcpy(mgmt->u.assoc_req.variable, sta->assocreq_ies,
459 sta->assocreq_ies_len);
461 ret = wlantest_inject(wt, bss, sta, buf,
462 24 + 4 + sta->assocreq_ies_len,
463 WLANTEST_INJECT_UNPROTECTED);
469 static int ctrl_inject_reassocreq(struct wlantest *wt,
470 struct wlantest_bss *bss,
471 struct wlantest_sta *sta, int sender_ap,
472 enum wlantest_inject_protection prot)
475 struct ieee80211_mgmt *mgmt;
478 if (prot != WLANTEST_INJECT_NORMAL &&
479 prot != WLANTEST_INJECT_UNPROTECTED)
480 return -1; /* Reassociation Request frame is never protected */
482 return -1; /* No broadcast Reassociation Request frames */
484 return -1; /* No Reassociation Request frame sent by AP */
485 if (sta->assocreq_ies == NULL) {
486 wpa_printf(MSG_INFO, "INJECT: No previous (Re)Association "
487 "Request available for " MACSTR,
492 wpa_printf(MSG_INFO, "INJECT: ReassocReq " MACSTR " -> " MACSTR,
493 MAC2STR(sta->addr), MAC2STR(bss->bssid));
494 buf = os_malloc(sizeof(*mgmt) + sta->assocreq_ies_len);
497 mgmt = (struct ieee80211_mgmt *) buf;
499 build_mgmt_hdr(mgmt, bss, sta, sender_ap, WLAN_FC_STYPE_REASSOC_REQ);
501 mgmt->u.reassoc_req.capab_info =
502 host_to_le16(sta->assocreq_capab_info);
503 mgmt->u.reassoc_req.listen_interval =
504 host_to_le16(sta->assocreq_listen_int);
505 os_memcpy(mgmt->u.reassoc_req.current_ap, bss->bssid, ETH_ALEN);
506 os_memcpy(mgmt->u.reassoc_req.variable, sta->assocreq_ies,
507 sta->assocreq_ies_len);
509 ret = wlantest_inject(wt, bss, sta, buf,
510 24 + 10 + sta->assocreq_ies_len,
511 WLANTEST_INJECT_UNPROTECTED);
517 static int ctrl_inject_deauth(struct wlantest *wt, struct wlantest_bss *bss,
518 struct wlantest_sta *sta, int sender_ap,
519 enum wlantest_inject_protection prot)
521 struct ieee80211_mgmt mgmt;
525 wpa_printf(MSG_INFO, "INJECT: Deauth " MACSTR " -> "
527 MAC2STR(bss->bssid), MAC2STR(sta->addr));
529 wpa_printf(MSG_INFO, "INJECT: Deauth " MACSTR
530 " -> broadcast", MAC2STR(bss->bssid));
532 wpa_printf(MSG_INFO, "INJECT: Deauth " MACSTR " -> " MACSTR,
533 MAC2STR(sta->addr), MAC2STR(bss->bssid));
534 build_mgmt_hdr(&mgmt, bss, sta, sender_ap, WLAN_FC_STYPE_DEAUTH);
536 mgmt.u.deauth.reason_code = host_to_le16(WLAN_REASON_UNSPECIFIED);
538 return wlantest_inject(wt, bss, sta, (u8 *) &mgmt, 24 + 2, prot);
542 static int ctrl_inject_disassoc(struct wlantest *wt, struct wlantest_bss *bss,
543 struct wlantest_sta *sta, int sender_ap,
544 enum wlantest_inject_protection prot)
546 struct ieee80211_mgmt mgmt;
550 wpa_printf(MSG_INFO, "INJECT: Disassoc " MACSTR " -> "
552 MAC2STR(bss->bssid), MAC2STR(sta->addr));
554 wpa_printf(MSG_INFO, "INJECT: Disassoc " MACSTR
555 " -> broadcast", MAC2STR(bss->bssid));
557 wpa_printf(MSG_INFO, "INJECT: Disassoc " MACSTR " -> " MACSTR,
558 MAC2STR(sta->addr), MAC2STR(bss->bssid));
559 build_mgmt_hdr(&mgmt, bss, sta, sender_ap, WLAN_FC_STYPE_DISASSOC);
561 mgmt.u.disassoc.reason_code = host_to_le16(WLAN_REASON_UNSPECIFIED);
563 return wlantest_inject(wt, bss, sta, (u8 *) &mgmt, 24 + 2, prot);
567 static int ctrl_inject_saqueryreq(struct wlantest *wt,
568 struct wlantest_bss *bss,
569 struct wlantest_sta *sta, int sender_ap,
570 enum wlantest_inject_protection prot)
572 struct ieee80211_mgmt mgmt;
575 return -1; /* No broadcast SA Query frames */
578 wpa_printf(MSG_INFO, "INJECT: SA Query Request " MACSTR " -> "
579 MACSTR, MAC2STR(bss->bssid), MAC2STR(sta->addr));
581 wpa_printf(MSG_INFO, "INJECT: SA Query Request " MACSTR " -> "
582 MACSTR, MAC2STR(sta->addr), MAC2STR(bss->bssid));
583 build_mgmt_hdr(&mgmt, bss, sta, sender_ap, WLAN_FC_STYPE_ACTION);
585 mgmt.u.action.category = WLAN_ACTION_SA_QUERY;
586 mgmt.u.action.u.sa_query_req.action = WLAN_SA_QUERY_REQUEST;
587 mgmt.u.action.u.sa_query_req.trans_id[0] = 0x12;
588 mgmt.u.action.u.sa_query_req.trans_id[1] = 0x34;
589 os_memcpy(sender_ap ? sta->ap_sa_query_tr : sta->sta_sa_query_tr,
590 mgmt.u.action.u.sa_query_req.trans_id,
591 WLAN_SA_QUERY_TR_ID_LEN);
592 return wlantest_inject(wt, bss, sta, (u8 *) &mgmt, 24 + 4, prot);
596 static void ctrl_inject(struct wlantest *wt, int sock, u8 *cmd, size_t clen)
598 u8 *bssid, *sta_addr;
599 struct wlantest_bss *bss;
600 struct wlantest_sta *sta;
601 int frame, sender_ap, prot;
604 bssid = attr_get_macaddr(cmd, clen, WLANTEST_ATTR_BSSID);
605 sta_addr = attr_get_macaddr(cmd, clen, WLANTEST_ATTR_STA_ADDR);
606 frame = attr_get_int(cmd, clen, WLANTEST_ATTR_INJECT_FRAME);
607 sender_ap = attr_get_int(cmd, clen, WLANTEST_ATTR_INJECT_SENDER_AP);
610 prot = attr_get_int(cmd, clen, WLANTEST_ATTR_INJECT_PROTECTION);
611 if (bssid == NULL || sta_addr == NULL || frame < 0 || prot < 0) {
612 wpa_printf(MSG_INFO, "Invalid inject command parameters");
613 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
617 bss = bss_find(wt, bssid);
619 wpa_printf(MSG_INFO, "BSS not found for inject command");
620 ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
624 if (is_broadcast_ether_addr(sta_addr)) {
626 wpa_printf(MSG_INFO, "Invalid broadcast inject "
627 "command without sender_ap set");
628 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
632 sta = sta_find(bss, sta_addr);
634 wpa_printf(MSG_INFO, "Station not found for inject "
636 ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
642 case WLANTEST_FRAME_AUTH:
643 ret = ctrl_inject_auth(wt, bss, sta, sender_ap, prot);
645 case WLANTEST_FRAME_ASSOCREQ:
646 ret = ctrl_inject_assocreq(wt, bss, sta, sender_ap, prot);
648 case WLANTEST_FRAME_REASSOCREQ:
649 ret = ctrl_inject_reassocreq(wt, bss, sta, sender_ap, prot);
651 case WLANTEST_FRAME_DEAUTH:
652 ret = ctrl_inject_deauth(wt, bss, sta, sender_ap, prot);
654 case WLANTEST_FRAME_DISASSOC:
655 ret = ctrl_inject_disassoc(wt, bss, sta, sender_ap, prot);
657 case WLANTEST_FRAME_SAQUERYREQ:
658 ret = ctrl_inject_saqueryreq(wt, bss, sta, sender_ap, prot);
661 wpa_printf(MSG_INFO, "Unsupported inject command frame %d",
663 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
668 wpa_printf(MSG_INFO, "Failed to inject frame");
670 wpa_printf(MSG_INFO, "Frame injected successfully");
671 ctrl_send_simple(wt, sock, ret == 0 ? WLANTEST_CTRL_SUCCESS :
672 WLANTEST_CTRL_FAILURE);
676 static void ctrl_version(struct wlantest *wt, int sock)
678 u8 buf[WLANTEST_CTRL_MAX_RESP_LEN], *pos;
681 WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
683 pos = attr_add_str(pos, buf + sizeof(buf), WLANTEST_ATTR_VERSION,
685 ctrl_send(wt, sock, buf, pos - buf);
689 static void ctrl_add_passphrase(struct wlantest *wt, int sock, u8 *cmd,
694 struct wlantest_passphrase *p, *pa;
697 passphrase = attr_get(cmd, clen, WLANTEST_ATTR_PASSPHRASE, &len);
698 if (passphrase == NULL || len < 8 || len > 63) {
699 ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
703 p = os_zalloc(sizeof(*p));
705 ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
708 os_memcpy(p->passphrase, passphrase, len);
709 wpa_printf(MSG_INFO, "Add passphrase '%s'", p->passphrase);
711 bssid = attr_get_macaddr(cmd, clen, WLANTEST_ATTR_BSSID);
713 os_memcpy(p->bssid, bssid, ETH_ALEN);
714 wpa_printf(MSG_INFO, "Limit passphrase for BSSID " MACSTR,
718 dl_list_for_each(pa, &wt->passphrase, struct wlantest_passphrase, list)
720 if (os_strcmp(p->passphrase, pa->passphrase) == 0 &&
721 os_memcmp(p->bssid, pa->bssid, ETH_ALEN) == 0) {
722 wpa_printf(MSG_INFO, "Passphrase was already known");
730 dl_list_add(&wt->passphrase, &p->list);
732 ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
736 static void ctrl_read(int sock, void *eloop_ctx, void *sock_ctx)
738 struct wlantest *wt = eloop_ctx;
739 u8 buf[WLANTEST_CTRL_MAX_CMD_LEN];
741 enum wlantest_ctrl_cmd cmd;
743 wpa_printf(MSG_EXCESSIVE, "New control interface message from %d",
745 len = recv(sock, buf, sizeof(buf), 0);
747 wpa_printf(MSG_INFO, "recv(ctrl): %s", strerror(errno));
748 ctrl_disconnect(wt, sock);
752 ctrl_disconnect(wt, sock);
757 wpa_printf(MSG_INFO, "Too short control interface command "
759 ctrl_disconnect(wt, sock);
762 cmd = WPA_GET_BE32(buf);
763 wpa_printf(MSG_EXCESSIVE, "Control interface command %d from %d",
767 case WLANTEST_CTRL_PING:
768 ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
770 case WLANTEST_CTRL_TERMINATE:
771 ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
774 case WLANTEST_CTRL_LIST_BSS:
775 ctrl_list_bss(wt, sock);
777 case WLANTEST_CTRL_LIST_STA:
778 ctrl_list_sta(wt, sock, buf + 4, len - 4);
780 case WLANTEST_CTRL_FLUSH:
781 ctrl_flush(wt, sock);
783 case WLANTEST_CTRL_CLEAR_STA_COUNTERS:
784 ctrl_clear_sta_counters(wt, sock, buf + 4, len - 4);
786 case WLANTEST_CTRL_CLEAR_BSS_COUNTERS:
787 ctrl_clear_bss_counters(wt, sock, buf + 4, len - 4);
789 case WLANTEST_CTRL_GET_STA_COUNTER:
790 ctrl_get_sta_counter(wt, sock, buf + 4, len - 4);
792 case WLANTEST_CTRL_GET_BSS_COUNTER:
793 ctrl_get_bss_counter(wt, sock, buf + 4, len - 4);
795 case WLANTEST_CTRL_INJECT:
796 ctrl_inject(wt, sock, buf + 4, len - 4);
798 case WLANTEST_CTRL_VERSION:
799 ctrl_version(wt, sock);
801 case WLANTEST_CTRL_ADD_PASSPHRASE:
802 ctrl_add_passphrase(wt, sock, buf + 4, len - 4);
805 ctrl_send_simple(wt, sock, WLANTEST_CTRL_UNKNOWN_CMD);
811 static void ctrl_connect(int sock, void *eloop_ctx, void *sock_ctx)
813 struct wlantest *wt = eloop_ctx;
816 conn = accept(sock, NULL, NULL);
818 wpa_printf(MSG_INFO, "accept(ctrl): %s", strerror(errno));
821 wpa_printf(MSG_MSGDUMP, "New control interface connection %d", conn);
823 for (i = 0; i < MAX_CTRL_CONNECTIONS; i++) {
824 if (wt->ctrl_socks[i] < 0)
828 if (i == MAX_CTRL_CONNECTIONS) {
829 wpa_printf(MSG_INFO, "No room for new control connection");
834 wt->ctrl_socks[i] = conn;
835 eloop_register_read_sock(conn, ctrl_read, wt, NULL);
839 int ctrl_init(struct wlantest *wt)
841 struct sockaddr_un addr;
843 wt->ctrl_sock = socket(AF_UNIX, SOCK_SEQPACKET, 0);
844 if (wt->ctrl_sock < 0) {
845 wpa_printf(MSG_ERROR, "socket: %s", strerror(errno));
849 os_memset(&addr, 0, sizeof(addr));
850 addr.sun_family = AF_UNIX;
851 os_strlcpy(addr.sun_path + 1, WLANTEST_SOCK_NAME,
852 sizeof(addr.sun_path) - 1);
853 if (bind(wt->ctrl_sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
854 wpa_printf(MSG_ERROR, "bind: %s", strerror(errno));
855 close(wt->ctrl_sock);
860 if (listen(wt->ctrl_sock, 5) < 0) {
861 wpa_printf(MSG_ERROR, "listen: %s", strerror(errno));
862 close(wt->ctrl_sock);
867 if (eloop_register_read_sock(wt->ctrl_sock, ctrl_connect, wt, NULL)) {
868 close(wt->ctrl_sock);
877 void ctrl_deinit(struct wlantest *wt)
881 if (wt->ctrl_sock < 0)
884 for (i = 0; i < MAX_CTRL_CONNECTIONS; i++) {
885 if (wt->ctrl_socks[i] >= 0) {
886 close(wt->ctrl_socks[i]);
887 eloop_unregister_read_sock(wt->ctrl_socks[i]);
888 wt->ctrl_socks[i] = -1;
892 eloop_unregister_read_sock(wt->ctrl_sock);
893 close(wt->ctrl_sock);