2 * wlantest control interface
3 * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
9 #include "utils/includes.h"
12 #include "utils/common.h"
13 #include "utils/eloop.h"
14 #include "common/defs.h"
15 #include "common/version.h"
16 #include "common/ieee802_11_defs.h"
18 #include "wlantest_ctrl.h"
21 static u8
* attr_get(u8
*buf
, size_t buflen
, enum wlantest_ctrl_attr attr
,
26 while (pos
+ 8 <= buf
+ buflen
) {
27 enum wlantest_ctrl_attr a
;
29 a
= WPA_GET_BE32(pos
);
31 alen
= WPA_GET_BE32(pos
);
33 if (pos
+ alen
> buf
+ buflen
) {
34 wpa_printf(MSG_DEBUG
, "Invalid control message "
49 static u8
* attr_get_macaddr(u8
*buf
, size_t buflen
,
50 enum wlantest_ctrl_attr attr
)
54 addr
= attr_get(buf
, buflen
, attr
, &addr_len
);
55 if (addr
&& addr_len
!= ETH_ALEN
)
61 static int attr_get_int(u8
*buf
, size_t buflen
, enum wlantest_ctrl_attr attr
)
65 pos
= attr_get(buf
, buflen
, attr
, &len
);
66 if (pos
== NULL
|| len
!= 4)
68 return WPA_GET_BE32(pos
);
72 static u8
* attr_add_str(u8
*pos
, u8
*end
, enum wlantest_ctrl_attr attr
,
75 size_t len
= os_strlen(str
);
77 if (pos
== NULL
|| end
- pos
< 8 + len
)
79 WPA_PUT_BE32(pos
, attr
);
81 WPA_PUT_BE32(pos
, len
);
83 os_memcpy(pos
, str
, len
);
89 static u8
* attr_add_be32(u8
*pos
, u8
*end
, enum wlantest_ctrl_attr attr
,
92 if (pos
== NULL
|| end
- pos
< 12)
94 WPA_PUT_BE32(pos
, attr
);
98 WPA_PUT_BE32(pos
, val
);
104 static void ctrl_disconnect(struct wlantest
*wt
, int sock
)
107 wpa_printf(MSG_DEBUG
, "Disconnect control interface connection %d",
109 for (i
= 0; i
< MAX_CTRL_CONNECTIONS
; i
++) {
110 if (wt
->ctrl_socks
[i
] == sock
) {
111 close(wt
->ctrl_socks
[i
]);
112 eloop_unregister_read_sock(wt
->ctrl_socks
[i
]);
113 wt
->ctrl_socks
[i
] = -1;
120 static void ctrl_send(struct wlantest
*wt
, int sock
, const u8
*buf
,
123 if (send(sock
, buf
, len
, 0) < 0) {
124 wpa_printf(MSG_INFO
, "send(ctrl): %s", strerror(errno
));
125 ctrl_disconnect(wt
, sock
);
130 static void ctrl_send_simple(struct wlantest
*wt
, int sock
,
131 enum wlantest_ctrl_cmd cmd
)
134 WPA_PUT_BE32(buf
, cmd
);
135 ctrl_send(wt
, sock
, buf
, sizeof(buf
));
139 static struct wlantest_bss
* ctrl_get_bss(struct wlantest
*wt
, int sock
,
140 u8
*cmd
, size_t clen
)
142 struct wlantest_bss
*bss
;
146 pos
= attr_get(cmd
, clen
, WLANTEST_ATTR_BSSID
, &len
);
147 if (pos
== NULL
|| len
!= ETH_ALEN
) {
148 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_INVALID_CMD
);
152 bss
= bss_find(wt
, pos
);
154 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_FAILURE
);
162 static struct wlantest_sta
* ctrl_get_sta(struct wlantest
*wt
, int sock
,
163 u8
*cmd
, size_t clen
,
164 struct wlantest_bss
*bss
)
166 struct wlantest_sta
*sta
;
173 pos
= attr_get(cmd
, clen
, WLANTEST_ATTR_STA_ADDR
, &len
);
174 if (pos
== NULL
|| len
!= ETH_ALEN
) {
175 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_INVALID_CMD
);
179 sta
= sta_find(bss
, pos
);
181 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_FAILURE
);
189 static struct wlantest_sta
* ctrl_get_sta2(struct wlantest
*wt
, int sock
,
190 u8
*cmd
, size_t clen
,
191 struct wlantest_bss
*bss
)
193 struct wlantest_sta
*sta
;
200 pos
= attr_get(cmd
, clen
, WLANTEST_ATTR_STA2_ADDR
, &len
);
201 if (pos
== NULL
|| len
!= ETH_ALEN
) {
202 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_INVALID_CMD
);
206 sta
= sta_find(bss
, pos
);
208 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_FAILURE
);
216 static void ctrl_list_bss(struct wlantest
*wt
, int sock
)
218 u8 buf
[WLANTEST_CTRL_MAX_RESP_LEN
], *pos
, *len
;
219 struct wlantest_bss
*bss
;
222 WPA_PUT_BE32(pos
, WLANTEST_CTRL_SUCCESS
);
224 WPA_PUT_BE32(pos
, WLANTEST_ATTR_BSSID
);
226 len
= pos
; /* to be filled */
229 dl_list_for_each(bss
, &wt
->bss
, struct wlantest_bss
, list
) {
230 if (pos
+ ETH_ALEN
> buf
+ WLANTEST_CTRL_MAX_RESP_LEN
)
232 os_memcpy(pos
, bss
->bssid
, ETH_ALEN
);
236 WPA_PUT_BE32(len
, pos
- len
- 4);
237 ctrl_send(wt
, sock
, buf
, pos
- buf
);
241 static void ctrl_list_sta(struct wlantest
*wt
, int sock
, u8
*cmd
, size_t clen
)
243 u8 buf
[WLANTEST_CTRL_MAX_RESP_LEN
], *pos
, *len
;
244 struct wlantest_bss
*bss
;
245 struct wlantest_sta
*sta
;
247 bss
= ctrl_get_bss(wt
, sock
, cmd
, clen
);
252 WPA_PUT_BE32(pos
, WLANTEST_CTRL_SUCCESS
);
254 WPA_PUT_BE32(pos
, WLANTEST_ATTR_STA_ADDR
);
256 len
= pos
; /* to be filled */
259 dl_list_for_each(sta
, &bss
->sta
, struct wlantest_sta
, list
) {
260 if (pos
+ ETH_ALEN
> buf
+ WLANTEST_CTRL_MAX_RESP_LEN
)
262 os_memcpy(pos
, sta
->addr
, ETH_ALEN
);
266 WPA_PUT_BE32(len
, pos
- len
- 4);
267 ctrl_send(wt
, sock
, buf
, pos
- buf
);
271 static void ctrl_flush(struct wlantest
*wt
, int sock
)
273 wpa_printf(MSG_DEBUG
, "Drop all collected BSS data");
275 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_SUCCESS
);
279 static void ctrl_clear_sta_counters(struct wlantest
*wt
, int sock
, u8
*cmd
,
282 struct wlantest_bss
*bss
;
283 struct wlantest_sta
*sta
;
285 bss
= ctrl_get_bss(wt
, sock
, cmd
, clen
);
286 sta
= ctrl_get_sta(wt
, sock
, cmd
, clen
, bss
);
288 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_FAILURE
);
292 os_memset(sta
->counters
, 0, sizeof(sta
->counters
));
293 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_SUCCESS
);
297 static void ctrl_clear_bss_counters(struct wlantest
*wt
, int sock
, u8
*cmd
,
300 struct wlantest_bss
*bss
;
302 bss
= ctrl_get_bss(wt
, sock
, cmd
, clen
);
304 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_FAILURE
);
308 os_memset(bss
->counters
, 0, sizeof(bss
->counters
));
309 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_SUCCESS
);
313 static void ctrl_clear_tdls_counters(struct wlantest
*wt
, int sock
, u8
*cmd
,
316 struct wlantest_bss
*bss
;
317 struct wlantest_sta
*sta
;
318 struct wlantest_sta
*sta2
;
319 struct wlantest_tdls
*tdls
;
321 bss
= ctrl_get_bss(wt
, sock
, cmd
, clen
);
322 sta
= ctrl_get_sta(wt
, sock
, cmd
, clen
, bss
);
323 sta2
= ctrl_get_sta2(wt
, sock
, cmd
, clen
, bss
);
324 if (sta
== NULL
|| sta2
== NULL
) {
325 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_FAILURE
);
329 dl_list_for_each(tdls
, &bss
->tdls
, struct wlantest_tdls
, list
) {
330 if ((tdls
->init
== sta
&& tdls
->resp
== sta2
) ||
331 (tdls
->init
== sta2
&& tdls
->resp
== sta
))
332 os_memset(tdls
->counters
, 0, sizeof(tdls
->counters
));
334 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_SUCCESS
);
338 static void ctrl_get_sta_counter(struct wlantest
*wt
, int sock
, u8
*cmd
,
343 struct wlantest_bss
*bss
;
344 struct wlantest_sta
*sta
;
346 u8 buf
[4 + 12], *end
, *pos
;
348 bss
= ctrl_get_bss(wt
, sock
, cmd
, clen
);
349 sta
= ctrl_get_sta(wt
, sock
, cmd
, clen
, bss
);
353 addr
= attr_get(cmd
, clen
, WLANTEST_ATTR_STA_COUNTER
, &addr_len
);
354 if (addr
== NULL
|| addr_len
!= 4) {
355 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_INVALID_CMD
);
358 counter
= WPA_GET_BE32(addr
);
359 if (counter
>= NUM_WLANTEST_STA_COUNTER
) {
360 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_INVALID_CMD
);
365 end
= buf
+ sizeof(buf
);
366 WPA_PUT_BE32(pos
, WLANTEST_CTRL_SUCCESS
);
368 pos
= attr_add_be32(pos
, end
, WLANTEST_ATTR_COUNTER
,
369 sta
->counters
[counter
]);
370 ctrl_send(wt
, sock
, buf
, pos
- buf
);
374 static void ctrl_get_bss_counter(struct wlantest
*wt
, int sock
, u8
*cmd
,
379 struct wlantest_bss
*bss
;
381 u8 buf
[4 + 12], *end
, *pos
;
383 bss
= ctrl_get_bss(wt
, sock
, cmd
, clen
);
387 addr
= attr_get(cmd
, clen
, WLANTEST_ATTR_BSS_COUNTER
, &addr_len
);
388 if (addr
== NULL
|| addr_len
!= 4) {
389 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_INVALID_CMD
);
392 counter
= WPA_GET_BE32(addr
);
393 if (counter
>= NUM_WLANTEST_BSS_COUNTER
) {
394 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_INVALID_CMD
);
399 end
= buf
+ sizeof(buf
);
400 WPA_PUT_BE32(pos
, WLANTEST_CTRL_SUCCESS
);
402 pos
= attr_add_be32(pos
, end
, WLANTEST_ATTR_COUNTER
,
403 bss
->counters
[counter
]);
404 ctrl_send(wt
, sock
, buf
, pos
- buf
);
408 static void ctrl_get_tdls_counter(struct wlantest
*wt
, int sock
, u8
*cmd
,
413 struct wlantest_bss
*bss
;
414 struct wlantest_sta
*sta
;
415 struct wlantest_sta
*sta2
;
416 struct wlantest_tdls
*tdls
;
418 u8 buf
[4 + 12], *end
, *pos
;
421 bss
= ctrl_get_bss(wt
, sock
, cmd
, clen
);
422 sta
= ctrl_get_sta(wt
, sock
, cmd
, clen
, bss
);
423 sta2
= ctrl_get_sta2(wt
, sock
, cmd
, clen
, bss
);
424 if (sta
== NULL
|| sta2
== NULL
) {
425 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_FAILURE
);
429 addr
= attr_get(cmd
, clen
, WLANTEST_ATTR_TDLS_COUNTER
, &addr_len
);
430 if (addr
== NULL
|| addr_len
!= 4) {
431 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_INVALID_CMD
);
434 counter
= WPA_GET_BE32(addr
);
435 if (counter
>= NUM_WLANTEST_TDLS_COUNTER
) {
436 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_INVALID_CMD
);
440 dl_list_for_each(tdls
, &bss
->tdls
, struct wlantest_tdls
, list
) {
441 if (tdls
->init
== sta
&& tdls
->resp
== sta2
) {
448 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_FAILURE
);
453 end
= buf
+ sizeof(buf
);
454 WPA_PUT_BE32(pos
, WLANTEST_CTRL_SUCCESS
);
456 pos
= attr_add_be32(pos
, end
, WLANTEST_ATTR_COUNTER
,
457 tdls
->counters
[counter
]);
458 ctrl_send(wt
, sock
, buf
, pos
- buf
);
462 static void build_mgmt_hdr(struct ieee80211_mgmt
*mgmt
,
463 struct wlantest_bss
*bss
, struct wlantest_sta
*sta
,
464 int sender_ap
, int stype
)
466 os_memset(mgmt
, 0, 24);
467 mgmt
->frame_control
= IEEE80211_FC(WLAN_FC_TYPE_MGMT
, stype
);
470 os_memcpy(mgmt
->da
, sta
->addr
, ETH_ALEN
);
472 os_memset(mgmt
->da
, 0xff, ETH_ALEN
);
473 os_memcpy(mgmt
->sa
, bss
->bssid
, ETH_ALEN
);
475 os_memcpy(mgmt
->da
, bss
->bssid
, ETH_ALEN
);
476 os_memcpy(mgmt
->sa
, sta
->addr
, ETH_ALEN
);
478 os_memcpy(mgmt
->bssid
, bss
->bssid
, ETH_ALEN
);
482 static int ctrl_inject_auth(struct wlantest
*wt
, struct wlantest_bss
*bss
,
483 struct wlantest_sta
*sta
, int sender_ap
,
484 enum wlantest_inject_protection prot
)
486 struct ieee80211_mgmt mgmt
;
488 if (prot
!= WLANTEST_INJECT_NORMAL
&&
489 prot
!= WLANTEST_INJECT_UNPROTECTED
)
490 return -1; /* Authentication frame is never protected */
492 return -1; /* No broadcast Authentication frames */
495 wpa_printf(MSG_INFO
, "INJECT: Auth " MACSTR
" -> " MACSTR
,
496 MAC2STR(bss
->bssid
), MAC2STR(sta
->addr
));
498 wpa_printf(MSG_INFO
, "INJECT: Auth " MACSTR
" -> " MACSTR
,
499 MAC2STR(sta
->addr
), MAC2STR(bss
->bssid
));
500 build_mgmt_hdr(&mgmt
, bss
, sta
, sender_ap
, WLAN_FC_STYPE_AUTH
);
502 mgmt
.u
.auth
.auth_alg
= host_to_le16(WLAN_AUTH_OPEN
);
503 mgmt
.u
.auth
.auth_transaction
= host_to_le16(1);
504 mgmt
.u
.auth
.status_code
= host_to_le16(WLAN_STATUS_SUCCESS
);
506 return wlantest_inject(wt
, bss
, sta
, (u8
*) &mgmt
, 24 + 6,
507 WLANTEST_INJECT_UNPROTECTED
);
511 static int ctrl_inject_assocreq(struct wlantest
*wt
, struct wlantest_bss
*bss
,
512 struct wlantest_sta
*sta
, int sender_ap
,
513 enum wlantest_inject_protection prot
)
516 struct ieee80211_mgmt
*mgmt
;
519 if (prot
!= WLANTEST_INJECT_NORMAL
&&
520 prot
!= WLANTEST_INJECT_UNPROTECTED
)
521 return -1; /* Association Request frame is never protected */
523 return -1; /* No broadcast Association Request frames */
525 return -1; /* No Association Request frame sent by AP */
526 if (sta
->assocreq_ies
== NULL
) {
527 wpa_printf(MSG_INFO
, "INJECT: No previous (Re)Association "
528 "Request available for " MACSTR
,
533 wpa_printf(MSG_INFO
, "INJECT: AssocReq " MACSTR
" -> " MACSTR
,
534 MAC2STR(sta
->addr
), MAC2STR(bss
->bssid
));
535 buf
= os_malloc(sizeof(*mgmt
) + sta
->assocreq_ies_len
);
538 mgmt
= (struct ieee80211_mgmt
*) buf
;
540 build_mgmt_hdr(mgmt
, bss
, sta
, sender_ap
, WLAN_FC_STYPE_ASSOC_REQ
);
542 mgmt
->u
.assoc_req
.capab_info
= host_to_le16(sta
->assocreq_capab_info
);
543 mgmt
->u
.assoc_req
.listen_interval
=
544 host_to_le16(sta
->assocreq_listen_int
);
545 os_memcpy(mgmt
->u
.assoc_req
.variable
, sta
->assocreq_ies
,
546 sta
->assocreq_ies_len
);
548 ret
= wlantest_inject(wt
, bss
, sta
, buf
,
549 24 + 4 + sta
->assocreq_ies_len
,
550 WLANTEST_INJECT_UNPROTECTED
);
556 static int ctrl_inject_reassocreq(struct wlantest
*wt
,
557 struct wlantest_bss
*bss
,
558 struct wlantest_sta
*sta
, int sender_ap
,
559 enum wlantest_inject_protection prot
)
562 struct ieee80211_mgmt
*mgmt
;
565 if (prot
!= WLANTEST_INJECT_NORMAL
&&
566 prot
!= WLANTEST_INJECT_UNPROTECTED
)
567 return -1; /* Reassociation Request frame is never protected */
569 return -1; /* No broadcast Reassociation Request frames */
571 return -1; /* No Reassociation Request frame sent by AP */
572 if (sta
->assocreq_ies
== NULL
) {
573 wpa_printf(MSG_INFO
, "INJECT: No previous (Re)Association "
574 "Request available for " MACSTR
,
579 wpa_printf(MSG_INFO
, "INJECT: ReassocReq " MACSTR
" -> " MACSTR
,
580 MAC2STR(sta
->addr
), MAC2STR(bss
->bssid
));
581 buf
= os_malloc(sizeof(*mgmt
) + sta
->assocreq_ies_len
);
584 mgmt
= (struct ieee80211_mgmt
*) buf
;
586 build_mgmt_hdr(mgmt
, bss
, sta
, sender_ap
, WLAN_FC_STYPE_REASSOC_REQ
);
588 mgmt
->u
.reassoc_req
.capab_info
=
589 host_to_le16(sta
->assocreq_capab_info
);
590 mgmt
->u
.reassoc_req
.listen_interval
=
591 host_to_le16(sta
->assocreq_listen_int
);
592 os_memcpy(mgmt
->u
.reassoc_req
.current_ap
, bss
->bssid
, ETH_ALEN
);
593 os_memcpy(mgmt
->u
.reassoc_req
.variable
, sta
->assocreq_ies
,
594 sta
->assocreq_ies_len
);
596 ret
= wlantest_inject(wt
, bss
, sta
, buf
,
597 24 + 10 + sta
->assocreq_ies_len
,
598 WLANTEST_INJECT_UNPROTECTED
);
604 static int ctrl_inject_deauth(struct wlantest
*wt
, struct wlantest_bss
*bss
,
605 struct wlantest_sta
*sta
, int sender_ap
,
606 enum wlantest_inject_protection prot
)
608 struct ieee80211_mgmt mgmt
;
612 wpa_printf(MSG_INFO
, "INJECT: Deauth " MACSTR
" -> "
614 MAC2STR(bss
->bssid
), MAC2STR(sta
->addr
));
616 wpa_printf(MSG_INFO
, "INJECT: Deauth " MACSTR
617 " -> broadcast", MAC2STR(bss
->bssid
));
619 wpa_printf(MSG_INFO
, "INJECT: Deauth " MACSTR
" -> " MACSTR
,
620 MAC2STR(sta
->addr
), MAC2STR(bss
->bssid
));
621 build_mgmt_hdr(&mgmt
, bss
, sta
, sender_ap
, WLAN_FC_STYPE_DEAUTH
);
623 mgmt
.u
.deauth
.reason_code
= host_to_le16(WLAN_REASON_UNSPECIFIED
);
625 return wlantest_inject(wt
, bss
, sta
, (u8
*) &mgmt
, 24 + 2, prot
);
629 static int ctrl_inject_disassoc(struct wlantest
*wt
, struct wlantest_bss
*bss
,
630 struct wlantest_sta
*sta
, int sender_ap
,
631 enum wlantest_inject_protection prot
)
633 struct ieee80211_mgmt mgmt
;
637 wpa_printf(MSG_INFO
, "INJECT: Disassoc " MACSTR
" -> "
639 MAC2STR(bss
->bssid
), MAC2STR(sta
->addr
));
641 wpa_printf(MSG_INFO
, "INJECT: Disassoc " MACSTR
642 " -> broadcast", MAC2STR(bss
->bssid
));
644 wpa_printf(MSG_INFO
, "INJECT: Disassoc " MACSTR
" -> " MACSTR
,
645 MAC2STR(sta
->addr
), MAC2STR(bss
->bssid
));
646 build_mgmt_hdr(&mgmt
, bss
, sta
, sender_ap
, WLAN_FC_STYPE_DISASSOC
);
648 mgmt
.u
.disassoc
.reason_code
= host_to_le16(WLAN_REASON_UNSPECIFIED
);
650 return wlantest_inject(wt
, bss
, sta
, (u8
*) &mgmt
, 24 + 2, prot
);
654 static int ctrl_inject_saqueryreq(struct wlantest
*wt
,
655 struct wlantest_bss
*bss
,
656 struct wlantest_sta
*sta
, int sender_ap
,
657 enum wlantest_inject_protection prot
)
659 struct ieee80211_mgmt mgmt
;
662 return -1; /* No broadcast SA Query frames */
665 wpa_printf(MSG_INFO
, "INJECT: SA Query Request " MACSTR
" -> "
666 MACSTR
, MAC2STR(bss
->bssid
), MAC2STR(sta
->addr
));
668 wpa_printf(MSG_INFO
, "INJECT: SA Query Request " MACSTR
" -> "
669 MACSTR
, MAC2STR(sta
->addr
), MAC2STR(bss
->bssid
));
670 build_mgmt_hdr(&mgmt
, bss
, sta
, sender_ap
, WLAN_FC_STYPE_ACTION
);
672 mgmt
.u
.action
.category
= WLAN_ACTION_SA_QUERY
;
673 mgmt
.u
.action
.u
.sa_query_req
.action
= WLAN_SA_QUERY_REQUEST
;
674 mgmt
.u
.action
.u
.sa_query_req
.trans_id
[0] = 0x12;
675 mgmt
.u
.action
.u
.sa_query_req
.trans_id
[1] = 0x34;
676 os_memcpy(sender_ap
? sta
->ap_sa_query_tr
: sta
->sta_sa_query_tr
,
677 mgmt
.u
.action
.u
.sa_query_req
.trans_id
,
678 WLAN_SA_QUERY_TR_ID_LEN
);
679 return wlantest_inject(wt
, bss
, sta
, (u8
*) &mgmt
, 24 + 4, prot
);
683 static void ctrl_inject(struct wlantest
*wt
, int sock
, u8
*cmd
, size_t clen
)
685 u8
*bssid
, *sta_addr
;
686 struct wlantest_bss
*bss
;
687 struct wlantest_sta
*sta
;
688 int frame
, sender_ap
, prot
;
691 bssid
= attr_get_macaddr(cmd
, clen
, WLANTEST_ATTR_BSSID
);
692 sta_addr
= attr_get_macaddr(cmd
, clen
, WLANTEST_ATTR_STA_ADDR
);
693 frame
= attr_get_int(cmd
, clen
, WLANTEST_ATTR_INJECT_FRAME
);
694 sender_ap
= attr_get_int(cmd
, clen
, WLANTEST_ATTR_INJECT_SENDER_AP
);
697 prot
= attr_get_int(cmd
, clen
, WLANTEST_ATTR_INJECT_PROTECTION
);
698 if (bssid
== NULL
|| sta_addr
== NULL
|| frame
< 0 || prot
< 0) {
699 wpa_printf(MSG_INFO
, "Invalid inject command parameters");
700 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_INVALID_CMD
);
704 bss
= bss_find(wt
, bssid
);
706 wpa_printf(MSG_INFO
, "BSS not found for inject command");
707 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_FAILURE
);
711 if (is_broadcast_ether_addr(sta_addr
)) {
713 wpa_printf(MSG_INFO
, "Invalid broadcast inject "
714 "command without sender_ap set");
715 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_INVALID_CMD
);
719 sta
= sta_find(bss
, sta_addr
);
721 wpa_printf(MSG_INFO
, "Station not found for inject "
723 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_FAILURE
);
729 case WLANTEST_FRAME_AUTH
:
730 ret
= ctrl_inject_auth(wt
, bss
, sta
, sender_ap
, prot
);
732 case WLANTEST_FRAME_ASSOCREQ
:
733 ret
= ctrl_inject_assocreq(wt
, bss
, sta
, sender_ap
, prot
);
735 case WLANTEST_FRAME_REASSOCREQ
:
736 ret
= ctrl_inject_reassocreq(wt
, bss
, sta
, sender_ap
, prot
);
738 case WLANTEST_FRAME_DEAUTH
:
739 ret
= ctrl_inject_deauth(wt
, bss
, sta
, sender_ap
, prot
);
741 case WLANTEST_FRAME_DISASSOC
:
742 ret
= ctrl_inject_disassoc(wt
, bss
, sta
, sender_ap
, prot
);
744 case WLANTEST_FRAME_SAQUERYREQ
:
745 ret
= ctrl_inject_saqueryreq(wt
, bss
, sta
, sender_ap
, prot
);
748 wpa_printf(MSG_INFO
, "Unsupported inject command frame %d",
750 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_INVALID_CMD
);
755 wpa_printf(MSG_INFO
, "Failed to inject frame");
757 wpa_printf(MSG_INFO
, "Frame injected successfully");
758 ctrl_send_simple(wt
, sock
, ret
== 0 ? WLANTEST_CTRL_SUCCESS
:
759 WLANTEST_CTRL_FAILURE
);
763 static void ctrl_version(struct wlantest
*wt
, int sock
)
765 u8 buf
[WLANTEST_CTRL_MAX_RESP_LEN
], *pos
;
768 WPA_PUT_BE32(pos
, WLANTEST_CTRL_SUCCESS
);
770 pos
= attr_add_str(pos
, buf
+ sizeof(buf
), WLANTEST_ATTR_VERSION
,
772 ctrl_send(wt
, sock
, buf
, pos
- buf
);
776 static void ctrl_add_passphrase(struct wlantest
*wt
, int sock
, u8
*cmd
,
781 struct wlantest_passphrase
*p
, *pa
;
784 passphrase
= attr_get(cmd
, clen
, WLANTEST_ATTR_PASSPHRASE
, &len
);
785 if (passphrase
== NULL
) {
788 enum wlantest_ctrl_cmd res
;
790 wepkey
= attr_get(cmd
, clen
, WLANTEST_ATTR_WEPKEY
, &len
);
791 if (wepkey
== NULL
) {
792 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_INVALID_CMD
);
795 key
= os_zalloc(len
+ 1);
797 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_FAILURE
);
800 os_memcpy(key
, wepkey
, len
);
801 if (add_wep(wt
, key
) < 0)
802 res
= WLANTEST_CTRL_FAILURE
;
804 res
= WLANTEST_CTRL_SUCCESS
;
806 ctrl_send_simple(wt
, sock
, res
);
810 if (len
< 8 || len
> 63) {
811 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_INVALID_CMD
);
815 p
= os_zalloc(sizeof(*p
));
817 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_FAILURE
);
820 os_memcpy(p
->passphrase
, passphrase
, len
);
821 wpa_printf(MSG_INFO
, "Add passphrase '%s'", p
->passphrase
);
823 bssid
= attr_get_macaddr(cmd
, clen
, WLANTEST_ATTR_BSSID
);
825 os_memcpy(p
->bssid
, bssid
, ETH_ALEN
);
826 wpa_printf(MSG_INFO
, "Limit passphrase for BSSID " MACSTR
,
830 dl_list_for_each(pa
, &wt
->passphrase
, struct wlantest_passphrase
, list
)
832 if (os_strcmp(p
->passphrase
, pa
->passphrase
) == 0 &&
833 os_memcmp(p
->bssid
, pa
->bssid
, ETH_ALEN
) == 0) {
834 wpa_printf(MSG_INFO
, "Passphrase was already known");
842 struct wlantest_bss
*bss
;
843 dl_list_add(&wt
->passphrase
, &p
->list
);
844 dl_list_for_each(bss
, &wt
->bss
, struct wlantest_bss
, list
) {
846 os_memcmp(p
->bssid
, bss
->bssid
, ETH_ALEN
) != 0)
848 bss_add_pmk_from_passphrase(bss
, p
->passphrase
);
852 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_SUCCESS
);
856 static void info_print_proto(char *buf
, size_t len
, int proto
)
861 os_snprintf(buf
, len
, "OPEN");
868 if (proto
& WPA_PROTO_WPA
)
869 pos
+= os_snprintf(pos
, end
- pos
, "%sWPA",
870 pos
== buf
? "" : " ");
871 if (proto
& WPA_PROTO_RSN
)
872 pos
+= os_snprintf(pos
, end
- pos
, "%sWPA2",
873 pos
== buf
? "" : " ");
877 static void info_print_cipher(char *buf
, size_t len
, int cipher
)
882 os_snprintf(buf
, len
, "N/A");
889 if (cipher
& WPA_CIPHER_NONE
)
890 pos
+= os_snprintf(pos
, end
- pos
, "%sNONE",
891 pos
== buf
? "" : " ");
892 if (cipher
& WPA_CIPHER_WEP40
)
893 pos
+= os_snprintf(pos
, end
- pos
, "%sWEP40",
894 pos
== buf
? "" : " ");
895 if (cipher
& WPA_CIPHER_WEP104
)
896 pos
+= os_snprintf(pos
, end
- pos
, "%sWEP104",
897 pos
== buf
? "" : " ");
898 if (cipher
& WPA_CIPHER_TKIP
)
899 pos
+= os_snprintf(pos
, end
- pos
, "%sTKIP",
900 pos
== buf
? "" : " ");
901 if (cipher
& WPA_CIPHER_CCMP
)
902 pos
+= os_snprintf(pos
, end
- pos
, "%sCCMP",
903 pos
== buf
? "" : " ");
904 if (cipher
& WPA_CIPHER_AES_128_CMAC
)
905 pos
+= os_snprintf(pos
, end
- pos
, "%sBIP",
906 pos
== buf
? "" : " ");
910 static void info_print_key_mgmt(char *buf
, size_t len
, int key_mgmt
)
915 os_snprintf(buf
, len
, "N/A");
922 if (key_mgmt
& WPA_KEY_MGMT_IEEE8021X
)
923 pos
+= os_snprintf(pos
, end
- pos
, "%sEAP",
924 pos
== buf
? "" : " ");
925 if (key_mgmt
& WPA_KEY_MGMT_PSK
)
926 pos
+= os_snprintf(pos
, end
- pos
, "%sPSK",
927 pos
== buf
? "" : " ");
928 if (key_mgmt
& WPA_KEY_MGMT_WPA_NONE
)
929 pos
+= os_snprintf(pos
, end
- pos
, "%sWPA-NONE",
930 pos
== buf
? "" : " ");
931 if (key_mgmt
& WPA_KEY_MGMT_FT_IEEE8021X
)
932 pos
+= os_snprintf(pos
, end
- pos
, "%sFT-EAP",
933 pos
== buf
? "" : " ");
934 if (key_mgmt
& WPA_KEY_MGMT_FT_PSK
)
935 pos
+= os_snprintf(pos
, end
- pos
, "%sFT-PSK",
936 pos
== buf
? "" : " ");
937 if (key_mgmt
& WPA_KEY_MGMT_IEEE8021X_SHA256
)
938 pos
+= os_snprintf(pos
, end
- pos
, "%sEAP-SHA256",
939 pos
== buf
? "" : " ");
940 if (key_mgmt
& WPA_KEY_MGMT_PSK_SHA256
)
941 pos
+= os_snprintf(pos
, end
- pos
, "%sPSK-SHA256",
942 pos
== buf
? "" : " ");
946 static void info_print_rsn_capab(char *buf
, size_t len
, int capab
)
953 if (capab
& WPA_CAPABILITY_PREAUTH
)
954 pos
+= os_snprintf(pos
, end
- pos
, "%sPREAUTH",
955 pos
== buf
? "" : " ");
956 if (capab
& WPA_CAPABILITY_NO_PAIRWISE
)
957 pos
+= os_snprintf(pos
, end
- pos
, "%sNO_PAIRWISE",
958 pos
== buf
? "" : " ");
959 if (capab
& WPA_CAPABILITY_MFPR
)
960 pos
+= os_snprintf(pos
, end
- pos
, "%sMFPR",
961 pos
== buf
? "" : " ");
962 if (capab
& WPA_CAPABILITY_MFPC
)
963 pos
+= os_snprintf(pos
, end
- pos
, "%sMFPC",
964 pos
== buf
? "" : " ");
965 if (capab
& WPA_CAPABILITY_PEERKEY_ENABLED
)
966 pos
+= os_snprintf(pos
, end
- pos
, "%sPEERKEY",
967 pos
== buf
? "" : " ");
971 static void info_print_state(char *buf
, size_t len
, int state
)
975 os_strlcpy(buf
, "NOT-AUTH", len
);
978 os_strlcpy(buf
, "AUTH", len
);
981 os_strlcpy(buf
, "AUTH+ASSOC", len
);
987 static void info_print_gtk(char *buf
, size_t len
, struct wlantest_sta
*sta
)
991 pos
= os_snprintf(buf
, len
, "IDX=%d,GTK=", sta
->gtk_idx
);
992 wpa_snprintf_hex(buf
+ pos
, len
- pos
, sta
->gtk
, sta
->gtk_len
);
996 static void ctrl_info_sta(struct wlantest
*wt
, int sock
, u8
*cmd
, size_t clen
)
1000 struct wlantest_bss
*bss
;
1001 struct wlantest_sta
*sta
;
1002 enum wlantest_sta_info info
;
1003 u8 buf
[4 + 108], *end
, *pos
;
1006 bss
= ctrl_get_bss(wt
, sock
, cmd
, clen
);
1007 sta
= ctrl_get_sta(wt
, sock
, cmd
, clen
, bss
);
1011 addr
= attr_get(cmd
, clen
, WLANTEST_ATTR_STA_INFO
, &addr_len
);
1012 if (addr
== NULL
|| addr_len
!= 4) {
1013 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_INVALID_CMD
);
1016 info
= WPA_GET_BE32(addr
);
1020 case WLANTEST_STA_INFO_PROTO
:
1021 info_print_proto(resp
, sizeof(resp
), sta
->proto
);
1023 case WLANTEST_STA_INFO_PAIRWISE
:
1024 info_print_cipher(resp
, sizeof(resp
), sta
->pairwise_cipher
);
1026 case WLANTEST_STA_INFO_KEY_MGMT
:
1027 info_print_key_mgmt(resp
, sizeof(resp
), sta
->key_mgmt
);
1029 case WLANTEST_STA_INFO_RSN_CAPAB
:
1030 info_print_rsn_capab(resp
, sizeof(resp
), sta
->rsn_capab
);
1032 case WLANTEST_STA_INFO_STATE
:
1033 info_print_state(resp
, sizeof(resp
), sta
->state
);
1035 case WLANTEST_STA_INFO_GTK
:
1036 info_print_gtk(resp
, sizeof(resp
), sta
);
1039 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_INVALID_CMD
);
1044 end
= buf
+ sizeof(buf
);
1045 WPA_PUT_BE32(pos
, WLANTEST_CTRL_SUCCESS
);
1047 pos
= attr_add_str(pos
, end
, WLANTEST_ATTR_INFO
, resp
);
1048 ctrl_send(wt
, sock
, buf
, pos
- buf
);
1052 static void ctrl_info_bss(struct wlantest
*wt
, int sock
, u8
*cmd
, size_t clen
)
1056 struct wlantest_bss
*bss
;
1057 enum wlantest_bss_info info
;
1058 u8 buf
[4 + 108], *end
, *pos
;
1061 bss
= ctrl_get_bss(wt
, sock
, cmd
, clen
);
1065 addr
= attr_get(cmd
, clen
, WLANTEST_ATTR_BSS_INFO
, &addr_len
);
1066 if (addr
== NULL
|| addr_len
!= 4) {
1067 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_INVALID_CMD
);
1070 info
= WPA_GET_BE32(addr
);
1074 case WLANTEST_BSS_INFO_PROTO
:
1075 info_print_proto(resp
, sizeof(resp
), bss
->proto
);
1077 case WLANTEST_BSS_INFO_PAIRWISE
:
1078 info_print_cipher(resp
, sizeof(resp
), bss
->pairwise_cipher
);
1080 case WLANTEST_BSS_INFO_GROUP
:
1081 info_print_cipher(resp
, sizeof(resp
), bss
->group_cipher
);
1083 case WLANTEST_BSS_INFO_GROUP_MGMT
:
1084 info_print_cipher(resp
, sizeof(resp
), bss
->mgmt_group_cipher
);
1086 case WLANTEST_BSS_INFO_KEY_MGMT
:
1087 info_print_key_mgmt(resp
, sizeof(resp
), bss
->key_mgmt
);
1089 case WLANTEST_BSS_INFO_RSN_CAPAB
:
1090 info_print_rsn_capab(resp
, sizeof(resp
), bss
->rsn_capab
);
1093 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_INVALID_CMD
);
1098 end
= buf
+ sizeof(buf
);
1099 WPA_PUT_BE32(pos
, WLANTEST_CTRL_SUCCESS
);
1101 pos
= attr_add_str(pos
, end
, WLANTEST_ATTR_INFO
, resp
);
1102 ctrl_send(wt
, sock
, buf
, pos
- buf
);
1106 static void ctrl_send_(struct wlantest
*wt
, int sock
, u8
*cmd
, size_t clen
)
1108 struct wlantest_bss
*bss
;
1109 struct wlantest_sta
*sta
;
1110 u8
*bssid
, *sta_addr
;
1115 struct ieee80211_hdr
*hdr
;
1118 frame
= attr_get(cmd
, clen
, WLANTEST_ATTR_FRAME
, &frame_len
);
1119 prot
= attr_get_int(cmd
, clen
, WLANTEST_ATTR_INJECT_PROTECTION
);
1120 if (frame
== NULL
|| frame_len
< 24 || prot
< 0) {
1121 wpa_printf(MSG_INFO
, "Invalid send command parameters");
1122 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_INVALID_CMD
);
1126 hdr
= (struct ieee80211_hdr
*) frame
;
1127 fc
= le_to_host16(hdr
->frame_control
);
1128 switch (WLAN_FC_GET_TYPE(fc
)) {
1129 case WLAN_FC_TYPE_MGMT
:
1131 if (os_memcmp(hdr
->addr2
, hdr
->addr3
, ETH_ALEN
) == 0)
1132 sta_addr
= hdr
->addr1
;
1134 sta_addr
= hdr
->addr2
;
1136 case WLAN_FC_TYPE_DATA
:
1137 switch (fc
& (WLAN_FC_TODS
| WLAN_FC_FROMDS
)) {
1140 sta_addr
= hdr
->addr2
;
1144 sta_addr
= hdr
->addr2
;
1146 case WLAN_FC_FROMDS
:
1148 sta_addr
= hdr
->addr1
;
1151 wpa_printf(MSG_INFO
, "Unsupported inject frame");
1152 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_FAILURE
);
1157 wpa_printf(MSG_INFO
, "Unsupported inject frame");
1158 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_FAILURE
);
1162 bss
= bss_find(wt
, bssid
);
1163 if (bss
== NULL
&& prot
!= WLANTEST_INJECT_UNPROTECTED
) {
1164 wpa_printf(MSG_INFO
, "Unknown BSSID");
1165 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_FAILURE
);
1170 sta
= sta_find(bss
, sta_addr
);
1173 if (sta
== NULL
&& prot
!= WLANTEST_INJECT_UNPROTECTED
) {
1174 wpa_printf(MSG_INFO
, "Unknown STA address");
1175 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_FAILURE
);
1179 ret
= wlantest_inject(wt
, bss
, sta
, frame
, frame_len
, prot
);
1182 wpa_printf(MSG_INFO
, "Failed to inject frame");
1184 wpa_printf(MSG_INFO
, "Frame injected successfully");
1185 ctrl_send_simple(wt
, sock
, ret
== 0 ? WLANTEST_CTRL_SUCCESS
:
1186 WLANTEST_CTRL_FAILURE
);
1190 static void ctrl_read(int sock
, void *eloop_ctx
, void *sock_ctx
)
1192 struct wlantest
*wt
= eloop_ctx
;
1193 u8 buf
[WLANTEST_CTRL_MAX_CMD_LEN
];
1195 enum wlantest_ctrl_cmd cmd
;
1197 wpa_printf(MSG_EXCESSIVE
, "New control interface message from %d",
1199 len
= recv(sock
, buf
, sizeof(buf
), 0);
1201 wpa_printf(MSG_INFO
, "recv(ctrl): %s", strerror(errno
));
1202 ctrl_disconnect(wt
, sock
);
1206 ctrl_disconnect(wt
, sock
);
1211 wpa_printf(MSG_INFO
, "Too short control interface command "
1213 ctrl_disconnect(wt
, sock
);
1216 cmd
= WPA_GET_BE32(buf
);
1217 wpa_printf(MSG_EXCESSIVE
, "Control interface command %d from %d",
1221 case WLANTEST_CTRL_PING
:
1222 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_SUCCESS
);
1224 case WLANTEST_CTRL_TERMINATE
:
1225 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_SUCCESS
);
1228 case WLANTEST_CTRL_LIST_BSS
:
1229 ctrl_list_bss(wt
, sock
);
1231 case WLANTEST_CTRL_LIST_STA
:
1232 ctrl_list_sta(wt
, sock
, buf
+ 4, len
- 4);
1234 case WLANTEST_CTRL_FLUSH
:
1235 ctrl_flush(wt
, sock
);
1237 case WLANTEST_CTRL_CLEAR_STA_COUNTERS
:
1238 ctrl_clear_sta_counters(wt
, sock
, buf
+ 4, len
- 4);
1240 case WLANTEST_CTRL_CLEAR_BSS_COUNTERS
:
1241 ctrl_clear_bss_counters(wt
, sock
, buf
+ 4, len
- 4);
1243 case WLANTEST_CTRL_CLEAR_TDLS_COUNTERS
:
1244 ctrl_clear_tdls_counters(wt
, sock
, buf
+ 4, len
- 4);
1246 case WLANTEST_CTRL_GET_STA_COUNTER
:
1247 ctrl_get_sta_counter(wt
, sock
, buf
+ 4, len
- 4);
1249 case WLANTEST_CTRL_GET_BSS_COUNTER
:
1250 ctrl_get_bss_counter(wt
, sock
, buf
+ 4, len
- 4);
1252 case WLANTEST_CTRL_GET_TDLS_COUNTER
:
1253 ctrl_get_tdls_counter(wt
, sock
, buf
+ 4, len
- 4);
1255 case WLANTEST_CTRL_INJECT
:
1256 ctrl_inject(wt
, sock
, buf
+ 4, len
- 4);
1258 case WLANTEST_CTRL_VERSION
:
1259 ctrl_version(wt
, sock
);
1261 case WLANTEST_CTRL_ADD_PASSPHRASE
:
1262 ctrl_add_passphrase(wt
, sock
, buf
+ 4, len
- 4);
1264 case WLANTEST_CTRL_INFO_STA
:
1265 ctrl_info_sta(wt
, sock
, buf
+ 4, len
- 4);
1267 case WLANTEST_CTRL_INFO_BSS
:
1268 ctrl_info_bss(wt
, sock
, buf
+ 4, len
- 4);
1270 case WLANTEST_CTRL_SEND
:
1271 ctrl_send_(wt
, sock
, buf
+ 4, len
- 4);
1274 ctrl_send_simple(wt
, sock
, WLANTEST_CTRL_UNKNOWN_CMD
);
1280 static void ctrl_connect(int sock
, void *eloop_ctx
, void *sock_ctx
)
1282 struct wlantest
*wt
= eloop_ctx
;
1285 conn
= accept(sock
, NULL
, NULL
);
1287 wpa_printf(MSG_INFO
, "accept(ctrl): %s", strerror(errno
));
1290 wpa_printf(MSG_MSGDUMP
, "New control interface connection %d", conn
);
1292 for (i
= 0; i
< MAX_CTRL_CONNECTIONS
; i
++) {
1293 if (wt
->ctrl_socks
[i
] < 0)
1297 if (i
== MAX_CTRL_CONNECTIONS
) {
1298 wpa_printf(MSG_INFO
, "No room for new control connection");
1303 wt
->ctrl_socks
[i
] = conn
;
1304 eloop_register_read_sock(conn
, ctrl_read
, wt
, NULL
);
1308 int ctrl_init(struct wlantest
*wt
)
1310 struct sockaddr_un addr
;
1312 wt
->ctrl_sock
= socket(AF_UNIX
, SOCK_SEQPACKET
, 0);
1313 if (wt
->ctrl_sock
< 0) {
1314 wpa_printf(MSG_ERROR
, "socket: %s", strerror(errno
));
1318 os_memset(&addr
, 0, sizeof(addr
));
1319 addr
.sun_family
= AF_UNIX
;
1320 os_strlcpy(addr
.sun_path
+ 1, WLANTEST_SOCK_NAME
,
1321 sizeof(addr
.sun_path
) - 1);
1322 if (bind(wt
->ctrl_sock
, (struct sockaddr
*) &addr
, sizeof(addr
)) < 0) {
1323 wpa_printf(MSG_ERROR
, "bind: %s", strerror(errno
));
1324 close(wt
->ctrl_sock
);
1329 if (listen(wt
->ctrl_sock
, 5) < 0) {
1330 wpa_printf(MSG_ERROR
, "listen: %s", strerror(errno
));
1331 close(wt
->ctrl_sock
);
1336 if (eloop_register_read_sock(wt
->ctrl_sock
, ctrl_connect
, wt
, NULL
)) {
1337 close(wt
->ctrl_sock
);
1346 void ctrl_deinit(struct wlantest
*wt
)
1350 if (wt
->ctrl_sock
< 0)
1353 for (i
= 0; i
< MAX_CTRL_CONNECTIONS
; i
++) {
1354 if (wt
->ctrl_socks
[i
] >= 0) {
1355 close(wt
->ctrl_socks
[i
]);
1356 eloop_unregister_read_sock(wt
->ctrl_socks
[i
]);
1357 wt
->ctrl_socks
[i
] = -1;
1361 eloop_unregister_read_sock(wt
->ctrl_sock
);
1362 close(wt
->ctrl_sock
);