/*
 * wlantest control interface
 * Copyright (c) 2010-2015, Jouni Malinen <j@w1.fi>
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 */

#include "utils/includes.h"
#include <sys/un.h>

#include "utils/common.h"
#include "utils/eloop.h"
#include "common/defs.h"
#include "common/version.h"
#include "common/ieee802_11_defs.h"
#include "wlantest.h"
#include "wlantest_ctrl.h"


static u8 * attr_get(u8 *buf, size_t buflen, enum wlantest_ctrl_attr attr,
		     size_t *len)
{
	u8 *pos = buf;

	while (pos + 8 <= buf + buflen) {
		enum wlantest_ctrl_attr a;
		size_t alen;
		a = WPA_GET_BE32(pos);
		pos += 4;
		alen = WPA_GET_BE32(pos);
		pos += 4;
		if (pos + alen > buf + buflen) {
			wpa_printf(MSG_DEBUG, "Invalid control message "
				   "attribute");
			return NULL;
		}
		if (a == attr) {
			*len = alen;
			return pos;
		}
		pos += alen;
	}

	return NULL;
}


static u8 * attr_get_macaddr(u8 *buf, size_t buflen,
			     enum wlantest_ctrl_attr attr)
{
	u8 *addr;
	size_t addr_len;
	addr = attr_get(buf, buflen, attr, &addr_len);
	if (addr && addr_len != ETH_ALEN)
		addr = NULL;
	return addr;
}


static int attr_get_int(u8 *buf, size_t buflen, enum wlantest_ctrl_attr attr)
{
	u8 *pos;
	size_t len;
	pos = attr_get(buf, buflen, attr, &len);
	if (pos == NULL || len != 4)
		return -1;
	return WPA_GET_BE32(pos);
}


static u8 * attr_add_str(u8 *pos, u8 *end, enum wlantest_ctrl_attr attr,
			 const char *str)
{
	size_t len = os_strlen(str);

	if (pos == NULL || end - pos < 8 + len)
		return NULL;
	WPA_PUT_BE32(pos, attr);
	pos += 4;
	WPA_PUT_BE32(pos, len);
	pos += 4;
	os_memcpy(pos, str, len);
	pos += len;
	return pos;
}


static u8 * attr_add_be32(u8 *pos, u8 *end, enum wlantest_ctrl_attr attr,
			  u32 val)
{
	if (pos == NULL || end - pos < 12)
		return NULL;
	WPA_PUT_BE32(pos, attr);
	pos += 4;
	WPA_PUT_BE32(pos, 4);
	pos += 4;
	WPA_PUT_BE32(pos, val);
	pos += 4;
	return pos;
}


static void ctrl_disconnect(struct wlantest *wt, int sock)
{
	int i;
	wpa_printf(MSG_DEBUG, "Disconnect control interface connection %d",
		   sock);
	for (i = 0; i < MAX_CTRL_CONNECTIONS; i++) {
		if (wt->ctrl_socks[i] == sock) {
			close(wt->ctrl_socks[i]);
			eloop_unregister_read_sock(wt->ctrl_socks[i]);
			wt->ctrl_socks[i] = -1;
			break;
		}
	}
}


static void ctrl_send(struct wlantest *wt, int sock, const u8 *buf,
		      size_t len)
{
	if (send(sock, buf, len, 0) < 0) {
		wpa_printf(MSG_INFO, "send(ctrl): %s", strerror(errno));
		ctrl_disconnect(wt, sock);
	}
}


static void ctrl_send_simple(struct wlantest *wt, int sock,
			     enum wlantest_ctrl_cmd cmd)
{
	u8 buf[4];
	WPA_PUT_BE32(buf, cmd);
	ctrl_send(wt, sock, buf, sizeof(buf));
}


static struct wlantest_bss * ctrl_get_bss(struct wlantest *wt, int sock,
					  u8 *cmd, size_t clen)
{
	struct wlantest_bss *bss;
	u8 *pos;
	size_t len;

	pos = attr_get(cmd, clen, WLANTEST_ATTR_BSSID, &len);
	if (pos == NULL || len != ETH_ALEN) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
		return NULL;
	}

	bss = bss_find(wt, pos);
	if (bss == NULL) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
		return NULL;
	}

	return bss;
}


static struct wlantest_sta * ctrl_get_sta(struct wlantest *wt, int sock,
					  u8 *cmd, size_t clen,
					  struct wlantest_bss *bss)
{
	struct wlantest_sta *sta;
	u8 *pos;
	size_t len;

	if (bss == NULL)
		return NULL;

	pos = attr_get(cmd, clen, WLANTEST_ATTR_STA_ADDR, &len);
	if (pos == NULL || len != ETH_ALEN) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
		return NULL;
	}

	sta = sta_find(bss, pos);
	if (sta == NULL) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
		return NULL;
	}

	return sta;
}


static struct wlantest_sta * ctrl_get_sta2(struct wlantest *wt, int sock,
					   u8 *cmd, size_t clen,
					   struct wlantest_bss *bss)
{
	struct wlantest_sta *sta;
	u8 *pos;
	size_t len;

	if (bss == NULL)
		return NULL;

	pos = attr_get(cmd, clen, WLANTEST_ATTR_STA2_ADDR, &len);
	if (pos == NULL || len != ETH_ALEN) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
		return NULL;
	}

	sta = sta_find(bss, pos);
	if (sta == NULL) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
		return NULL;
	}

	return sta;
}


static void ctrl_list_bss(struct wlantest *wt, int sock)
{
	u8 buf[WLANTEST_CTRL_MAX_RESP_LEN], *pos, *len;
	struct wlantest_bss *bss;

	pos = buf;
	WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
	pos += 4;
	WPA_PUT_BE32(pos, WLANTEST_ATTR_BSSID);
	pos += 4;
	len = pos; /* to be filled */
	pos += 4;

	dl_list_for_each(bss, &wt->bss, struct wlantest_bss, list) {
		if (pos + ETH_ALEN > buf + WLANTEST_CTRL_MAX_RESP_LEN)
			break;
		os_memcpy(pos, bss->bssid, ETH_ALEN);
		pos += ETH_ALEN;
	}

	WPA_PUT_BE32(len, pos - len - 4);
	ctrl_send(wt, sock, buf, pos - buf);
}


static void ctrl_list_sta(struct wlantest *wt, int sock, u8 *cmd, size_t clen)
{
	u8 buf[WLANTEST_CTRL_MAX_RESP_LEN], *pos, *len;
	struct wlantest_bss *bss;
	struct wlantest_sta *sta;

	bss = ctrl_get_bss(wt, sock, cmd, clen);
	if (bss == NULL)
		return;

	pos = buf;
	WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
	pos += 4;
	WPA_PUT_BE32(pos, WLANTEST_ATTR_STA_ADDR);
	pos += 4;
	len = pos; /* to be filled */
	pos += 4;

	dl_list_for_each(sta, &bss->sta, struct wlantest_sta, list) {
		if (pos + ETH_ALEN > buf + WLANTEST_CTRL_MAX_RESP_LEN)
			break;
		os_memcpy(pos, sta->addr, ETH_ALEN);
		pos += ETH_ALEN;
	}

	WPA_PUT_BE32(len, pos - len - 4);
	ctrl_send(wt, sock, buf, pos - buf);
}


static void ctrl_flush(struct wlantest *wt, int sock)
{
	wpa_printf(MSG_DEBUG, "Drop all collected BSS data");
	bss_flush(wt);
	ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
}


static void ctrl_clear_sta_counters(struct wlantest *wt, int sock, u8 *cmd,
				    size_t clen)
{
	struct wlantest_bss *bss;
	struct wlantest_sta *sta;

	bss = ctrl_get_bss(wt, sock, cmd, clen);
	sta = ctrl_get_sta(wt, sock, cmd, clen, bss);
	if (sta == NULL) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
		return;
	}

	os_memset(sta->counters, 0, sizeof(sta->counters));
	os_memset(sta->tx_tid, 0, sizeof(sta->tx_tid));
	os_memset(sta->rx_tid, 0, sizeof(sta->rx_tid));
	ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
}


static void ctrl_clear_bss_counters(struct wlantest *wt, int sock, u8 *cmd,
				    size_t clen)
{
	struct wlantest_bss *bss;

	bss = ctrl_get_bss(wt, sock, cmd, clen);
	if (bss == NULL) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
		return;
	}

	os_memset(bss->counters, 0, sizeof(bss->counters));
	ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
}


static void ctrl_clear_tdls_counters(struct wlantest *wt, int sock, u8 *cmd,
				     size_t clen)
{
	struct wlantest_bss *bss;
	struct wlantest_sta *sta;
	struct wlantest_sta *sta2;
	struct wlantest_tdls *tdls;

	bss = ctrl_get_bss(wt, sock, cmd, clen);
	sta = ctrl_get_sta(wt, sock, cmd, clen, bss);
	sta2 = ctrl_get_sta2(wt, sock, cmd, clen, bss);
	if (sta == NULL || sta2 == NULL) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
		return;
	}

	dl_list_for_each(tdls, &bss->tdls, struct wlantest_tdls, list) {
		if ((tdls->init == sta && tdls->resp == sta2) ||
		    (tdls->init == sta2 && tdls->resp == sta))
			os_memset(tdls->counters, 0, sizeof(tdls->counters));
	}
	ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
}


static void ctrl_get_sta_counter(struct wlantest *wt, int sock, u8 *cmd,
				 size_t clen)
{
	u8 *addr;
	size_t addr_len;
	struct wlantest_bss *bss;
	struct wlantest_sta *sta;
	u32 counter;
	u8 buf[4 + 12], *end, *pos;

	bss = ctrl_get_bss(wt, sock, cmd, clen);
	sta = ctrl_get_sta(wt, sock, cmd, clen, bss);
	if (sta == NULL)
		return;

	addr = attr_get(cmd, clen, WLANTEST_ATTR_STA_COUNTER, &addr_len);
	if (addr == NULL || addr_len != 4) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
		return;
	}
	counter = WPA_GET_BE32(addr);
	if (counter >= NUM_WLANTEST_STA_COUNTER) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
		return;
	}

	pos = buf;
	end = buf + sizeof(buf);
	WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
	pos += 4;
	pos = attr_add_be32(pos, end, WLANTEST_ATTR_COUNTER,
			    sta->counters[counter]);
	ctrl_send(wt, sock, buf, pos - buf);
}


static void ctrl_get_bss_counter(struct wlantest *wt, int sock, u8 *cmd,
				 size_t clen)
{
	u8 *addr;
	size_t addr_len;
	struct wlantest_bss *bss;
	u32 counter;
	u8 buf[4 + 12], *end, *pos;

	bss = ctrl_get_bss(wt, sock, cmd, clen);
	if (bss == NULL)
		return;

	addr = attr_get(cmd, clen, WLANTEST_ATTR_BSS_COUNTER, &addr_len);
	if (addr == NULL || addr_len != 4) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
		return;
	}
	counter = WPA_GET_BE32(addr);
	if (counter >= NUM_WLANTEST_BSS_COUNTER) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
		return;
	}

	pos = buf;
	end = buf + sizeof(buf);
	WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
	pos += 4;
	pos = attr_add_be32(pos, end, WLANTEST_ATTR_COUNTER,
			    bss->counters[counter]);
	ctrl_send(wt, sock, buf, pos - buf);
}


static void ctrl_get_tdls_counter(struct wlantest *wt, int sock, u8 *cmd,
				  size_t clen)
{
	u8 *addr;
	size_t addr_len;
	struct wlantest_bss *bss;
	struct wlantest_sta *sta;
	struct wlantest_sta *sta2;
	struct wlantest_tdls *tdls;
	u32 counter;
	u8 buf[4 + 12], *end, *pos;
	int found = 0;

	bss = ctrl_get_bss(wt, sock, cmd, clen);
	sta = ctrl_get_sta(wt, sock, cmd, clen, bss);
	sta2 = ctrl_get_sta2(wt, sock, cmd, clen, bss);
	if (sta == NULL || sta2 == NULL) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
		return;
	}

	addr = attr_get(cmd, clen, WLANTEST_ATTR_TDLS_COUNTER, &addr_len);
	if (addr == NULL || addr_len != 4) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
		return;
	}
	counter = WPA_GET_BE32(addr);
	if (counter >= NUM_WLANTEST_TDLS_COUNTER) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
		return;
	}

	dl_list_for_each(tdls, &bss->tdls, struct wlantest_tdls, list) {
		if (tdls->init == sta && tdls->resp == sta2) {
			found = 1;
			break;
		}
	}

	if (!found) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
		return;
	}

	pos = buf;
	end = buf + sizeof(buf);
	WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
	pos += 4;
	pos = attr_add_be32(pos, end, WLANTEST_ATTR_COUNTER,
			    tdls->counters[counter]);
	ctrl_send(wt, sock, buf, pos - buf);
}


static void build_mgmt_hdr(struct ieee80211_mgmt *mgmt,
			   struct wlantest_bss *bss, struct wlantest_sta *sta,
			   int sender_ap, int stype)
{
	os_memset(mgmt, 0, 24);
	mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, stype);
	if (sender_ap) {
		if (sta)
			os_memcpy(mgmt->da, sta->addr, ETH_ALEN);
		else
			os_memset(mgmt->da, 0xff, ETH_ALEN);
		os_memcpy(mgmt->sa, bss->bssid, ETH_ALEN);
	} else {
		os_memcpy(mgmt->da, bss->bssid, ETH_ALEN);
		os_memcpy(mgmt->sa, sta->addr, ETH_ALEN);
	}
	os_memcpy(mgmt->bssid, bss->bssid, ETH_ALEN);
}


static int ctrl_inject_auth(struct wlantest *wt, struct wlantest_bss *bss,
			    struct wlantest_sta *sta, int sender_ap,
			    enum wlantest_inject_protection prot)
{
	struct ieee80211_mgmt mgmt;

	if (prot != WLANTEST_INJECT_NORMAL &&
	    prot != WLANTEST_INJECT_UNPROTECTED)
		return -1; /* Authentication frame is never protected */
	if (sta == NULL)
		return -1; /* No broadcast Authentication frames */

	if (sender_ap)
		wpa_printf(MSG_INFO, "INJECT: Auth " MACSTR " -> " MACSTR,
			   MAC2STR(bss->bssid), MAC2STR(sta->addr));
	else
		wpa_printf(MSG_INFO, "INJECT: Auth " MACSTR " -> " MACSTR,
			   MAC2STR(sta->addr), MAC2STR(bss->bssid));
	build_mgmt_hdr(&mgmt, bss, sta, sender_ap, WLAN_FC_STYPE_AUTH);

	mgmt.u.auth.auth_alg = host_to_le16(WLAN_AUTH_OPEN);
	mgmt.u.auth.auth_transaction = host_to_le16(1);
	mgmt.u.auth.status_code = host_to_le16(WLAN_STATUS_SUCCESS);

	return wlantest_inject(wt, bss, sta, (u8 *) &mgmt, 24 + 6,
			       WLANTEST_INJECT_UNPROTECTED);
}


static int ctrl_inject_assocreq(struct wlantest *wt, struct wlantest_bss *bss,
				struct wlantest_sta *sta, int sender_ap,
				enum wlantest_inject_protection prot)
{
	u8 *buf;
	struct ieee80211_mgmt *mgmt;
	int ret;

	if (prot != WLANTEST_INJECT_NORMAL &&
	    prot != WLANTEST_INJECT_UNPROTECTED)
		return -1; /* Association Request frame is never protected */
	if (sta == NULL)
		return -1; /* No broadcast Association Request frames */
	if (sender_ap)
		return -1; /* No Association Request frame sent by AP */
	if (sta->assocreq_ies == NULL) {
		wpa_printf(MSG_INFO, "INJECT: No previous (Re)Association "
			   "Request available for " MACSTR,
			   MAC2STR(sta->addr));
		return -1;
	}

	wpa_printf(MSG_INFO, "INJECT: AssocReq " MACSTR " -> " MACSTR,
		   MAC2STR(sta->addr), MAC2STR(bss->bssid));
	buf = os_malloc(sizeof(*mgmt) + sta->assocreq_ies_len);
	if (buf == NULL)
		return -1;
	mgmt = (struct ieee80211_mgmt *) buf;

	build_mgmt_hdr(mgmt, bss, sta, sender_ap, WLAN_FC_STYPE_ASSOC_REQ);

	mgmt->u.assoc_req.capab_info = host_to_le16(sta->assocreq_capab_info);
	mgmt->u.assoc_req.listen_interval =
		host_to_le16(sta->assocreq_listen_int);
	os_memcpy(mgmt->u.assoc_req.variable, sta->assocreq_ies,
		  sta->assocreq_ies_len);

	ret = wlantest_inject(wt, bss, sta, buf,
			      24 + 4 + sta->assocreq_ies_len,
			      WLANTEST_INJECT_UNPROTECTED);
	os_free(buf);
	return ret;
}


static int ctrl_inject_reassocreq(struct wlantest *wt,
				  struct wlantest_bss *bss,
				  struct wlantest_sta *sta, int sender_ap,
				  enum wlantest_inject_protection prot)
{
	u8 *buf;
	struct ieee80211_mgmt *mgmt;
	int ret;

	if (prot != WLANTEST_INJECT_NORMAL &&
	    prot != WLANTEST_INJECT_UNPROTECTED)
		return -1; /* Reassociation Request frame is never protected */
	if (sta == NULL)
		return -1; /* No broadcast Reassociation Request frames */
	if (sender_ap)
		return -1; /* No Reassociation Request frame sent by AP */
	if (sta->assocreq_ies == NULL) {
		wpa_printf(MSG_INFO, "INJECT: No previous (Re)Association "
			   "Request available for " MACSTR,
			   MAC2STR(sta->addr));
		return -1;
	}

	wpa_printf(MSG_INFO, "INJECT: ReassocReq " MACSTR " -> " MACSTR,
		   MAC2STR(sta->addr), MAC2STR(bss->bssid));
	buf = os_malloc(sizeof(*mgmt) + sta->assocreq_ies_len);
	if (buf == NULL)
		return -1;
	mgmt = (struct ieee80211_mgmt *) buf;

	build_mgmt_hdr(mgmt, bss, sta, sender_ap, WLAN_FC_STYPE_REASSOC_REQ);

	mgmt->u.reassoc_req.capab_info =
		host_to_le16(sta->assocreq_capab_info);
	mgmt->u.reassoc_req.listen_interval =
		host_to_le16(sta->assocreq_listen_int);
	os_memcpy(mgmt->u.reassoc_req.current_ap, bss->bssid, ETH_ALEN);
	os_memcpy(mgmt->u.reassoc_req.variable, sta->assocreq_ies,
		  sta->assocreq_ies_len);

	ret = wlantest_inject(wt, bss, sta, buf,
			      24 + 10 + sta->assocreq_ies_len,
			      WLANTEST_INJECT_UNPROTECTED);
	os_free(buf);
	return ret;
}


static int ctrl_inject_deauth(struct wlantest *wt, struct wlantest_bss *bss,
			      struct wlantest_sta *sta, int sender_ap,
			      enum wlantest_inject_protection prot)
{
	struct ieee80211_mgmt mgmt;

	if (sender_ap) {
		if (sta)
			wpa_printf(MSG_INFO, "INJECT: Deauth " MACSTR " -> "
				   MACSTR,
				   MAC2STR(bss->bssid), MAC2STR(sta->addr));
		else
			wpa_printf(MSG_INFO, "INJECT: Deauth " MACSTR
				   " -> broadcast", MAC2STR(bss->bssid));
	} else
		wpa_printf(MSG_INFO, "INJECT: Deauth " MACSTR " -> " MACSTR,
			   MAC2STR(sta->addr), MAC2STR(bss->bssid));
	build_mgmt_hdr(&mgmt, bss, sta, sender_ap, WLAN_FC_STYPE_DEAUTH);

	mgmt.u.deauth.reason_code = host_to_le16(WLAN_REASON_UNSPECIFIED);

	return wlantest_inject(wt, bss, sta, (u8 *) &mgmt, 24 + 2, prot);
}


static int ctrl_inject_disassoc(struct wlantest *wt, struct wlantest_bss *bss,
				struct wlantest_sta *sta, int sender_ap,
				enum wlantest_inject_protection prot)
{
	struct ieee80211_mgmt mgmt;

	if (sender_ap) {
		if (sta)
			wpa_printf(MSG_INFO, "INJECT: Disassoc " MACSTR " -> "
				   MACSTR,
				   MAC2STR(bss->bssid), MAC2STR(sta->addr));
		else
			wpa_printf(MSG_INFO, "INJECT: Disassoc " MACSTR
				   " -> broadcast", MAC2STR(bss->bssid));
	} else
		wpa_printf(MSG_INFO, "INJECT: Disassoc " MACSTR " -> " MACSTR,
			   MAC2STR(sta->addr), MAC2STR(bss->bssid));
	build_mgmt_hdr(&mgmt, bss, sta, sender_ap, WLAN_FC_STYPE_DISASSOC);

	mgmt.u.disassoc.reason_code = host_to_le16(WLAN_REASON_UNSPECIFIED);

	return wlantest_inject(wt, bss, sta, (u8 *) &mgmt, 24 + 2, prot);
}


static int ctrl_inject_saqueryreq(struct wlantest *wt,
				  struct wlantest_bss *bss,
				  struct wlantest_sta *sta, int sender_ap,
				  enum wlantest_inject_protection prot)
{
	struct ieee80211_mgmt mgmt;

	if (sta == NULL)
		return -1; /* No broadcast SA Query frames */

	if (sender_ap)
		wpa_printf(MSG_INFO, "INJECT: SA Query Request " MACSTR " -> "
			   MACSTR, MAC2STR(bss->bssid), MAC2STR(sta->addr));
	else
		wpa_printf(MSG_INFO, "INJECT: SA Query Request " MACSTR " -> "
			   MACSTR, MAC2STR(sta->addr), MAC2STR(bss->bssid));
	build_mgmt_hdr(&mgmt, bss, sta, sender_ap, WLAN_FC_STYPE_ACTION);

	mgmt.u.action.category = WLAN_ACTION_SA_QUERY;
	mgmt.u.action.u.sa_query_req.action = WLAN_SA_QUERY_REQUEST;
	mgmt.u.action.u.sa_query_req.trans_id[0] = 0x12;
	mgmt.u.action.u.sa_query_req.trans_id[1] = 0x34;
	os_memcpy(sender_ap ? sta->ap_sa_query_tr : sta->sta_sa_query_tr,
		  mgmt.u.action.u.sa_query_req.trans_id,
		  WLAN_SA_QUERY_TR_ID_LEN);
	return wlantest_inject(wt, bss, sta, (u8 *) &mgmt, 24 + 4, prot);
}


static void ctrl_inject(struct wlantest *wt, int sock, u8 *cmd, size_t clen)
{
	u8 *bssid, *sta_addr;
	struct wlantest_bss *bss;
	struct wlantest_sta *sta;
	int frame, sender_ap, prot;
	int ret = 0;

	bssid = attr_get_macaddr(cmd, clen, WLANTEST_ATTR_BSSID);
	sta_addr = attr_get_macaddr(cmd, clen, WLANTEST_ATTR_STA_ADDR);
	frame = attr_get_int(cmd, clen, WLANTEST_ATTR_INJECT_FRAME);
	sender_ap = attr_get_int(cmd, clen, WLANTEST_ATTR_INJECT_SENDER_AP);
	if (sender_ap < 0)
		sender_ap = 0;
	prot = attr_get_int(cmd, clen, WLANTEST_ATTR_INJECT_PROTECTION);
	if (bssid == NULL || sta_addr == NULL || frame < 0 || prot < 0) {
		wpa_printf(MSG_INFO, "Invalid inject command parameters");
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
		return;
	}

	bss = bss_find(wt, bssid);
	if (bss == NULL) {
		wpa_printf(MSG_INFO, "BSS not found for inject command");
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
		return;
	}

	if (is_broadcast_ether_addr(sta_addr)) {
		if (!sender_ap) {
			wpa_printf(MSG_INFO, "Invalid broadcast inject "
				   "command without sender_ap set");
			ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
			return;
		} sta = NULL;
	} else {
		sta = sta_find(bss, sta_addr);
		if (sta == NULL) {
			wpa_printf(MSG_INFO, "Station not found for inject "
				   "command");
			ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
			return;
		}
	}

	switch (frame) {
	case WLANTEST_FRAME_AUTH:
		ret = ctrl_inject_auth(wt, bss, sta, sender_ap, prot);
		break;
	case WLANTEST_FRAME_ASSOCREQ:
		ret = ctrl_inject_assocreq(wt, bss, sta, sender_ap, prot);
		break;
	case WLANTEST_FRAME_REASSOCREQ:
		ret = ctrl_inject_reassocreq(wt, bss, sta, sender_ap, prot);
		break;
	case WLANTEST_FRAME_DEAUTH:
		ret = ctrl_inject_deauth(wt, bss, sta, sender_ap, prot);
		break;
	case WLANTEST_FRAME_DISASSOC:
		ret = ctrl_inject_disassoc(wt, bss, sta, sender_ap, prot);
		break;
	case WLANTEST_FRAME_SAQUERYREQ:
		ret = ctrl_inject_saqueryreq(wt, bss, sta, sender_ap, prot);
		break;
	default:
		wpa_printf(MSG_INFO, "Unsupported inject command frame %d",
			   frame);
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
		return;
	}

	if (ret)
		wpa_printf(MSG_INFO, "Failed to inject frame");
	else
		wpa_printf(MSG_INFO, "Frame injected successfully");
	ctrl_send_simple(wt, sock, ret == 0 ? WLANTEST_CTRL_SUCCESS :
			 WLANTEST_CTRL_FAILURE);
}


static void ctrl_version(struct wlantest *wt, int sock)
{
	u8 buf[WLANTEST_CTRL_MAX_RESP_LEN], *pos;

	pos = buf;
	WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
	pos += 4;
	pos = attr_add_str(pos, buf + sizeof(buf), WLANTEST_ATTR_VERSION,
			   VERSION_STR);
	ctrl_send(wt, sock, buf, pos - buf);
}


static void ctrl_add_passphrase(struct wlantest *wt, int sock, u8 *cmd,
				size_t clen)
{
	u8 *passphrase;
	size_t len;
	struct wlantest_passphrase *p, *pa;
	u8 *bssid;

	passphrase = attr_get(cmd, clen, WLANTEST_ATTR_PASSPHRASE, &len);
	if (passphrase == NULL) {
		u8 *wepkey;
		char *key;
		enum wlantest_ctrl_cmd res;

		wepkey = attr_get(cmd, clen, WLANTEST_ATTR_WEPKEY, &len);
		if (wepkey == NULL) {
			ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
			return;
		}
		key = os_zalloc(len + 1);
		if (key == NULL) {
			ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
			return;
		}
		os_memcpy(key, wepkey, len);
		if (add_wep(wt, key) < 0)
			res = WLANTEST_CTRL_FAILURE;
		else
			res = WLANTEST_CTRL_SUCCESS;
		os_free(key);
		ctrl_send_simple(wt, sock, res);
		return;
	}

	if (len < 8 || len > 63) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
		return;
	}

	p = os_zalloc(sizeof(*p));
	if (p == NULL) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
		return;
	}
	os_memcpy(p->passphrase, passphrase, len);
	wpa_printf(MSG_INFO, "Add passphrase '%s'", p->passphrase);

	bssid = attr_get_macaddr(cmd, clen, WLANTEST_ATTR_BSSID);
	if (bssid) {
		os_memcpy(p->bssid, bssid, ETH_ALEN);
		wpa_printf(MSG_INFO, "Limit passphrase for BSSID " MACSTR,
			   MAC2STR(p->bssid));
	}

	dl_list_for_each(pa, &wt->passphrase, struct wlantest_passphrase, list)
	{
		if (os_strcmp(p->passphrase, pa->passphrase) == 0 &&
		    os_memcmp(p->bssid, pa->bssid, ETH_ALEN) == 0) {
			wpa_printf(MSG_INFO, "Passphrase was already known");
			os_free(p);
			p = NULL;
			break;
		}
	}

	if (p) {
		struct wlantest_bss *bss;
		dl_list_add(&wt->passphrase, &p->list);
		dl_list_for_each(bss, &wt->bss, struct wlantest_bss, list) {
			if (bssid &&
			    os_memcmp(p->bssid, bss->bssid, ETH_ALEN) != 0)
				continue;
			bss_add_pmk_from_passphrase(bss, p->passphrase);
		}
	}

	ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
}


static void info_print_proto(char *buf, size_t len, int proto)
{
	char *pos, *end;

	if (proto == 0) {
		os_snprintf(buf, len, "OPEN");
		return;
	}

	pos = buf;
	end = buf + len;

	if (proto & WPA_PROTO_WPA)
		pos += os_snprintf(pos, end - pos, "%sWPA",
				   pos == buf ? "" : " ");
	if (proto & WPA_PROTO_RSN)
		pos += os_snprintf(pos, end - pos, "%sWPA2",
				   pos == buf ? "" : " ");
}


static void info_print_cipher(char *buf, size_t len, int cipher)
{
	char *pos, *end;

	if (cipher == 0) {
		os_snprintf(buf, len, "N/A");
		return;
	}

	pos = buf;
	end = buf + len;

	if (cipher & WPA_CIPHER_NONE)
		pos += os_snprintf(pos, end - pos, "%sNONE",
				   pos == buf ? "" : " ");
	if (cipher & WPA_CIPHER_WEP40)
		pos += os_snprintf(pos, end - pos, "%sWEP40",
				   pos == buf ? "" : " ");
	if (cipher & WPA_CIPHER_WEP104)
		pos += os_snprintf(pos, end - pos, "%sWEP104",
				   pos == buf ? "" : " ");
	if (cipher & WPA_CIPHER_TKIP)
		pos += os_snprintf(pos, end - pos, "%sTKIP",
				   pos == buf ? "" : " ");
	if (cipher & WPA_CIPHER_CCMP)
		pos += os_snprintf(pos, end - pos, "%sCCMP",
				   pos == buf ? "" : " ");
	if (cipher & WPA_CIPHER_AES_128_CMAC)
		pos += os_snprintf(pos, end - pos, "%sBIP",
				   pos == buf ? "" : " ");
	if (cipher & WPA_CIPHER_BIP_GMAC_128)
		pos += os_snprintf(pos, end - pos, "%sBIP-GMAC-128",
				   pos == buf ? "" : " ");
	if (cipher & WPA_CIPHER_BIP_GMAC_256)
		pos += os_snprintf(pos, end - pos, "%sBIP-GMAC-256",
				   pos == buf ? "" : " ");
	if (cipher & WPA_CIPHER_BIP_CMAC_256)
		pos += os_snprintf(pos, end - pos, "%sBIP-CMAC-256",
				   pos == buf ? "" : " ");
}


static void info_print_key_mgmt(char *buf, size_t len, int key_mgmt)
{
	char *pos, *end;

	if (key_mgmt == 0) {
		os_snprintf(buf, len, "N/A");
		return;
	}

	pos = buf;
	end = buf + len;

	if (key_mgmt & WPA_KEY_MGMT_IEEE8021X)
		pos += os_snprintf(pos, end - pos, "%sEAP",
				   pos == buf ? "" : " ");
	if (key_mgmt & WPA_KEY_MGMT_PSK)
		pos += os_snprintf(pos, end - pos, "%sPSK",
				   pos == buf ? "" : " ");
	if (key_mgmt & WPA_KEY_MGMT_WPA_NONE)
		pos += os_snprintf(pos, end - pos, "%sWPA-NONE",
				   pos == buf ? "" : " ");
	if (key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X)
		pos += os_snprintf(pos, end - pos, "%sFT-EAP",
				   pos == buf ? "" : " ");
	if (key_mgmt & WPA_KEY_MGMT_FT_PSK)
		pos += os_snprintf(pos, end - pos, "%sFT-PSK",
				   pos == buf ? "" : " ");
	if (key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256)
		pos += os_snprintf(pos, end - pos, "%sEAP-SHA256",
				   pos == buf ? "" : " ");
	if (key_mgmt & WPA_KEY_MGMT_PSK_SHA256)
		pos += os_snprintf(pos, end - pos, "%sPSK-SHA256",
				   pos == buf ? "" : " ");
	if (key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B)
		pos += os_snprintf(pos, end - pos, "%sEAP-SUITE-B",
				   pos == buf ? "" : " ");
	if (key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
		pos += os_snprintf(pos, end - pos, "%sEAP-SUITE-B-192",
				   pos == buf ? "" : " ");
}


static void info_print_rsn_capab(char *buf, size_t len, int capab)
{
	char *pos, *end;

	pos = buf;
	end = buf + len;

	if (capab & WPA_CAPABILITY_PREAUTH)
		pos += os_snprintf(pos, end - pos, "%sPREAUTH",
				   pos == buf ? "" : " ");
	if (capab & WPA_CAPABILITY_NO_PAIRWISE)
		pos += os_snprintf(pos, end - pos, "%sNO_PAIRWISE",
				   pos == buf ? "" : " ");
	if (capab & WPA_CAPABILITY_MFPR)
		pos += os_snprintf(pos, end - pos, "%sMFPR",
				   pos == buf ? "" : " ");
	if (capab & WPA_CAPABILITY_MFPC)
		pos += os_snprintf(pos, end - pos, "%sMFPC",
				   pos == buf ? "" : " ");
	if (capab & WPA_CAPABILITY_PEERKEY_ENABLED)
		pos += os_snprintf(pos, end - pos, "%sPEERKEY",
				   pos == buf ? "" : " ");
}


static void info_print_state(char *buf, size_t len, int state)
{
	switch (state) {
	case STATE1:
		os_strlcpy(buf, "NOT-AUTH", len);
		break;
	case STATE2:
		os_strlcpy(buf, "AUTH", len);
		break;
	case STATE3:
		os_strlcpy(buf, "AUTH+ASSOC", len);
		break;
	}
}


static void info_print_gtk(char *buf, size_t len, struct wlantest_sta *sta)
{
	size_t pos;

	pos = os_snprintf(buf, len, "IDX=%d,GTK=", sta->gtk_idx);
	wpa_snprintf_hex(buf + pos, len - pos, sta->gtk, sta->gtk_len);
}


static void ctrl_info_sta(struct wlantest *wt, int sock, u8 *cmd, size_t clen)
{
	u8 *addr;
	size_t addr_len;
	struct wlantest_bss *bss;
	struct wlantest_sta *sta;
	enum wlantest_sta_info info;
	u8 buf[4 + 108], *end, *pos;
	char resp[100];

	bss = ctrl_get_bss(wt, sock, cmd, clen);
	sta = ctrl_get_sta(wt, sock, cmd, clen, bss);
	if (sta == NULL)
		return;

	addr = attr_get(cmd, clen, WLANTEST_ATTR_STA_INFO, &addr_len);
	if (addr == NULL || addr_len != 4) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
		return;
	}
	info = WPA_GET_BE32(addr);

	resp[0] = '\0';
	switch (info) {
	case WLANTEST_STA_INFO_PROTO:
		info_print_proto(resp, sizeof(resp), sta->proto);
		break;
	case WLANTEST_STA_INFO_PAIRWISE:
		info_print_cipher(resp, sizeof(resp), sta->pairwise_cipher);
		break;
	case WLANTEST_STA_INFO_KEY_MGMT:
		info_print_key_mgmt(resp, sizeof(resp), sta->key_mgmt);
		break;
	case WLANTEST_STA_INFO_RSN_CAPAB:
		info_print_rsn_capab(resp, sizeof(resp), sta->rsn_capab);
		break;
	case WLANTEST_STA_INFO_STATE:
		info_print_state(resp, sizeof(resp), sta->state);
		break;
	case WLANTEST_STA_INFO_GTK:
		info_print_gtk(resp, sizeof(resp), sta);
		break;
	default:
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
		return;
	}

	pos = buf;
	end = buf + sizeof(buf);
	WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
	pos += 4;
	pos = attr_add_str(pos, end, WLANTEST_ATTR_INFO, resp);
	ctrl_send(wt, sock, buf, pos - buf);
}


static void ctrl_info_bss(struct wlantest *wt, int sock, u8 *cmd, size_t clen)
{
	u8 *addr;
	size_t addr_len;
	struct wlantest_bss *bss;
	enum wlantest_bss_info info;
	u8 buf[4 + 108], *end, *pos;
	char resp[100];

	bss = ctrl_get_bss(wt, sock, cmd, clen);
	if (bss == NULL)
		return;

	addr = attr_get(cmd, clen, WLANTEST_ATTR_BSS_INFO, &addr_len);
	if (addr == NULL || addr_len != 4) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
		return;
	}
	info = WPA_GET_BE32(addr);

	resp[0] = '\0';
	switch (info) {
	case WLANTEST_BSS_INFO_PROTO:
		info_print_proto(resp, sizeof(resp), bss->proto);
		break;
	case WLANTEST_BSS_INFO_PAIRWISE:
		info_print_cipher(resp, sizeof(resp), bss->pairwise_cipher);
		break;
	case WLANTEST_BSS_INFO_GROUP:
		info_print_cipher(resp, sizeof(resp), bss->group_cipher);
		break;
	case WLANTEST_BSS_INFO_GROUP_MGMT:
		info_print_cipher(resp, sizeof(resp), bss->mgmt_group_cipher);
		break;
	case WLANTEST_BSS_INFO_KEY_MGMT:
		info_print_key_mgmt(resp, sizeof(resp), bss->key_mgmt);
		break;
	case WLANTEST_BSS_INFO_RSN_CAPAB:
		info_print_rsn_capab(resp, sizeof(resp), bss->rsn_capab);
		break;
	default:
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
		return;
	}

	pos = buf;
	end = buf + sizeof(buf);
	WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
	pos += 4;
	pos = attr_add_str(pos, end, WLANTEST_ATTR_INFO, resp);
	ctrl_send(wt, sock, buf, pos - buf);
}


static void ctrl_send_(struct wlantest *wt, int sock, u8 *cmd, size_t clen)
{
	struct wlantest_bss *bss;
	struct wlantest_sta *sta;
	u8 *bssid, *sta_addr;
	int prot;
	u8 *frame;
	size_t frame_len;
	int ret = 0;
	struct ieee80211_hdr *hdr;
	u16 fc;

	frame = attr_get(cmd, clen, WLANTEST_ATTR_FRAME, &frame_len);
	prot = attr_get_int(cmd, clen, WLANTEST_ATTR_INJECT_PROTECTION);
	if (frame == NULL || frame_len < 24 || prot < 0) {
		wpa_printf(MSG_INFO, "Invalid send command parameters");
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
		return;
	}

	hdr = (struct ieee80211_hdr *) frame;
	fc = le_to_host16(hdr->frame_control);
	switch (WLAN_FC_GET_TYPE(fc)) {
	case WLAN_FC_TYPE_MGMT:
		bssid = hdr->addr3;
		if (os_memcmp(hdr->addr2, hdr->addr3, ETH_ALEN) == 0)
			sta_addr = hdr->addr1;
		else
			sta_addr = hdr->addr2;
		break;
	case WLAN_FC_TYPE_DATA:
		switch (fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) {
		case 0:
			bssid = hdr->addr3;
			sta_addr = hdr->addr2;
			break;
		case WLAN_FC_TODS:
			bssid = hdr->addr1;
			sta_addr = hdr->addr2;
			break;
		case WLAN_FC_FROMDS:
			bssid = hdr->addr2;
			sta_addr = hdr->addr1;
			break;
		default:
			wpa_printf(MSG_INFO, "Unsupported inject frame");
			ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
			return;
		}
		break;
	default:
		wpa_printf(MSG_INFO, "Unsupported inject frame");
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
		return;
	}

	bss = bss_find(wt, bssid);
	if (bss == NULL && prot != WLANTEST_INJECT_UNPROTECTED) {
		wpa_printf(MSG_INFO, "Unknown BSSID");
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
		return;
	}

	if (bss)
		sta = sta_find(bss, sta_addr);
	else
		sta = NULL;
	if (sta == NULL && prot != WLANTEST_INJECT_UNPROTECTED) {
		wpa_printf(MSG_INFO, "Unknown STA address");
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
		return;
	}

	ret = wlantest_inject(wt, bss, sta, frame, frame_len, prot);

	if (ret)
		wpa_printf(MSG_INFO, "Failed to inject frame");
	else
		wpa_printf(MSG_INFO, "Frame injected successfully");
	ctrl_send_simple(wt, sock, ret == 0 ? WLANTEST_CTRL_SUCCESS :
			 WLANTEST_CTRL_FAILURE);
}


static void ctrl_relog(struct wlantest *wt, int sock)
{
	int res = wlantest_relog(wt);
	ctrl_send_simple(wt, sock, res ? WLANTEST_CTRL_FAILURE :
			 WLANTEST_CTRL_SUCCESS);
}


static void ctrl_get_tx_tid(struct wlantest *wt, int sock, u8 *cmd, size_t clen)
{
	u8 *addr;
	size_t addr_len;
	struct wlantest_bss *bss;
	struct wlantest_sta *sta;
	u32 counter;
	u8 buf[4 + 12], *end, *pos;

	bss = ctrl_get_bss(wt, sock, cmd, clen);
	sta = ctrl_get_sta(wt, sock, cmd, clen, bss);
	if (sta == NULL)
		return;

	addr = attr_get(cmd, clen, WLANTEST_ATTR_TID, &addr_len);
	if (addr == NULL || addr_len != 4) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
		return;
	}
	counter = WPA_GET_BE32(addr);
	if (counter >= 16 + 1) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
		return;
	}

	pos = buf;
	end = buf + sizeof(buf);
	WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
	pos += 4;
	pos = attr_add_be32(pos, end, WLANTEST_ATTR_COUNTER,
			    sta->tx_tid[counter]);
	ctrl_send(wt, sock, buf, pos - buf);
}


static void ctrl_get_rx_tid(struct wlantest *wt, int sock, u8 *cmd, size_t clen)
{
	u8 *addr;
	size_t addr_len;
	struct wlantest_bss *bss;
	struct wlantest_sta *sta;
	u32 counter;
	u8 buf[4 + 12], *end, *pos;

	bss = ctrl_get_bss(wt, sock, cmd, clen);
	sta = ctrl_get_sta(wt, sock, cmd, clen, bss);
	if (sta == NULL)
		return;

	addr = attr_get(cmd, clen, WLANTEST_ATTR_TID, &addr_len);
	if (addr == NULL || addr_len != 4) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
		return;
	}
	counter = WPA_GET_BE32(addr);
	if (counter >= 16 + 1) {
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
		return;
	}

	pos = buf;
	end = buf + sizeof(buf);
	WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
	pos += 4;
	pos = attr_add_be32(pos, end, WLANTEST_ATTR_COUNTER,
			    sta->rx_tid[counter]);
	ctrl_send(wt, sock, buf, pos - buf);
}


static void ctrl_read(int sock, void *eloop_ctx, void *sock_ctx)
{
	struct wlantest *wt = eloop_ctx;
	u8 buf[WLANTEST_CTRL_MAX_CMD_LEN];
	int len;
	enum wlantest_ctrl_cmd cmd;

	wpa_printf(MSG_EXCESSIVE, "New control interface message from %d",
		   sock);
	len = recv(sock, buf, sizeof(buf), 0);
	if (len < 0) {
		wpa_printf(MSG_INFO, "recv(ctrl): %s", strerror(errno));
		ctrl_disconnect(wt, sock);
		return;
	}
	if (len == 0) {
		ctrl_disconnect(wt, sock);
		return;
	}

	if (len < 4) {
		wpa_printf(MSG_INFO, "Too short control interface command "
			   "from %d", sock);
		ctrl_disconnect(wt, sock);
		return;
	}
	cmd = WPA_GET_BE32(buf);
	wpa_printf(MSG_EXCESSIVE, "Control interface command %d from %d",
		   cmd, sock);

	switch (cmd) {
	case WLANTEST_CTRL_PING:
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
		break;
	case WLANTEST_CTRL_TERMINATE:
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
		eloop_terminate();
		break;
	case WLANTEST_CTRL_LIST_BSS:
		ctrl_list_bss(wt, sock);
		break;
	case WLANTEST_CTRL_LIST_STA:
		ctrl_list_sta(wt, sock, buf + 4, len - 4);
		break;
	case WLANTEST_CTRL_FLUSH:
		ctrl_flush(wt, sock);
		break;
	case WLANTEST_CTRL_CLEAR_STA_COUNTERS:
		ctrl_clear_sta_counters(wt, sock, buf + 4, len - 4);
		break;
	case WLANTEST_CTRL_CLEAR_BSS_COUNTERS:
		ctrl_clear_bss_counters(wt, sock, buf + 4, len - 4);
		break;
	case WLANTEST_CTRL_CLEAR_TDLS_COUNTERS:
		ctrl_clear_tdls_counters(wt, sock, buf + 4, len - 4);
		break;
	case WLANTEST_CTRL_GET_STA_COUNTER:
		ctrl_get_sta_counter(wt, sock, buf + 4, len - 4);
		break;
	case WLANTEST_CTRL_GET_BSS_COUNTER:
		ctrl_get_bss_counter(wt, sock, buf + 4, len - 4);
		break;
	case WLANTEST_CTRL_GET_TDLS_COUNTER:
		ctrl_get_tdls_counter(wt, sock, buf + 4, len - 4);
		break;
	case WLANTEST_CTRL_INJECT:
		ctrl_inject(wt, sock, buf + 4, len - 4);
		break;
	case WLANTEST_CTRL_VERSION:
		ctrl_version(wt, sock);
		break;
	case WLANTEST_CTRL_ADD_PASSPHRASE:
		ctrl_add_passphrase(wt, sock, buf + 4, len - 4);
		break;
	case WLANTEST_CTRL_INFO_STA:
		ctrl_info_sta(wt, sock, buf + 4, len - 4);
		break;
	case WLANTEST_CTRL_INFO_BSS:
		ctrl_info_bss(wt, sock, buf + 4, len - 4);
		break;
	case WLANTEST_CTRL_SEND:
		ctrl_send_(wt, sock, buf + 4, len - 4);
		break;
	case WLANTEST_CTRL_RELOG:
		ctrl_relog(wt, sock);
		break;
	case WLANTEST_CTRL_GET_TX_TID:
		ctrl_get_tx_tid(wt, sock, buf + 4, len - 4);
		break;
	case WLANTEST_CTRL_GET_RX_TID:
		ctrl_get_rx_tid(wt, sock, buf + 4, len - 4);
		break;
	default:
		ctrl_send_simple(wt, sock, WLANTEST_CTRL_UNKNOWN_CMD);
		break;
	}
}


static void ctrl_connect(int sock, void *eloop_ctx, void *sock_ctx)
{
	struct wlantest *wt = eloop_ctx;
	int conn, i;

	conn = accept(sock, NULL, NULL);
	if (conn < 0) {
		wpa_printf(MSG_INFO, "accept(ctrl): %s", strerror(errno));
		return;
	}
	wpa_printf(MSG_MSGDUMP, "New control interface connection %d", conn);

	for (i = 0; i < MAX_CTRL_CONNECTIONS; i++) {
		if (wt->ctrl_socks[i] < 0)
			break;
	}

	if (i == MAX_CTRL_CONNECTIONS) {
		wpa_printf(MSG_INFO, "No room for new control connection");
		close(conn);
		return;
	}

	wt->ctrl_socks[i] = conn;
	eloop_register_read_sock(conn, ctrl_read, wt, NULL);
}


int ctrl_init(struct wlantest *wt)
{
	struct sockaddr_un addr;

	wt->ctrl_sock = socket(AF_UNIX, SOCK_SEQPACKET, 0);
	if (wt->ctrl_sock < 0) {
		wpa_printf(MSG_ERROR, "socket: %s", strerror(errno));
		return -1;
	}

	os_memset(&addr, 0, sizeof(addr));
	addr.sun_family = AF_UNIX;
	os_strlcpy(addr.sun_path + 1, WLANTEST_SOCK_NAME,
		   sizeof(addr.sun_path) - 1);
	if (bind(wt->ctrl_sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
		wpa_printf(MSG_ERROR, "bind: %s", strerror(errno));
		close(wt->ctrl_sock);
		wt->ctrl_sock = -1;
		return -1;
	}

	if (listen(wt->ctrl_sock, 5) < 0) {
		wpa_printf(MSG_ERROR, "listen: %s", strerror(errno));
		close(wt->ctrl_sock);
		wt->ctrl_sock = -1;
		return -1;
	}

	if (eloop_register_read_sock(wt->ctrl_sock, ctrl_connect, wt, NULL)) {
		close(wt->ctrl_sock);
		wt->ctrl_sock = -1;
		return -1;
	}

	return 0;
}


void ctrl_deinit(struct wlantest *wt)
{
	int i;

	if (wt->ctrl_sock < 0)
		return;

	for (i = 0; i < MAX_CTRL_CONNECTIONS; i++) {
		if (wt->ctrl_socks[i] >= 0) {
			close(wt->ctrl_socks[i]);
			eloop_unregister_read_sock(wt->ctrl_socks[i]);
			wt->ctrl_socks[i] = -1;
		}
	}

	eloop_unregister_read_sock(wt->ctrl_sock);
	close(wt->ctrl_sock);
	wt->ctrl_sock = -1;
}
