/*
 * Received Management frame processing
 * 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 "utils/common.h"
#include "common/defs.h"
#include "common/ieee802_11_defs.h"
#include "common/ieee802_11_common.h"
#include "crypto/aes_wrap.h"
#include "wlantest.h"


static const char * mgmt_stype(u16 stype)
{
	switch (stype) {
	case WLAN_FC_STYPE_ASSOC_REQ:
		return "ASSOC-REQ";
	case WLAN_FC_STYPE_ASSOC_RESP:
		return "ASSOC-RESP";
	case WLAN_FC_STYPE_REASSOC_REQ:
		return "REASSOC-REQ";
	case WLAN_FC_STYPE_REASSOC_RESP:
		return "REASSOC-RESP";
	case WLAN_FC_STYPE_PROBE_REQ:
		return "PROBE-REQ";
	case WLAN_FC_STYPE_PROBE_RESP:
		return "PROBE-RESP";
	case WLAN_FC_STYPE_BEACON:
		return "BEACON";
	case WLAN_FC_STYPE_ATIM:
		return "ATIM";
	case WLAN_FC_STYPE_DISASSOC:
		return "DISASSOC";
	case WLAN_FC_STYPE_AUTH:
		return "AUTH";
	case WLAN_FC_STYPE_DEAUTH:
		return "DEAUTH";
	case WLAN_FC_STYPE_ACTION:
		return "ACTION";
	}
	return "??";
}


static void rx_mgmt_beacon(struct wlantest *wt, const u8 *data, size_t len)
{
	const struct ieee80211_mgmt *mgmt;
	struct wlantest_bss *bss;
	struct ieee802_11_elems elems;
	size_t offset;

	mgmt = (const struct ieee80211_mgmt *) data;
	offset = mgmt->u.beacon.variable - data;
	if (len < offset)
		return;
	bss = bss_get(wt, mgmt->bssid);
	if (bss == NULL)
		return;
	if (bss->proberesp_seen)
		return; /* do not override with Beacon data */
	bss->capab_info = le_to_host16(mgmt->u.beacon.capab_info);
	if (ieee802_11_parse_elems(mgmt->u.beacon.variable, len - offset,
				   &elems, 0) == ParseFailed) {
		if (bss->parse_error_reported)
			return;
		add_note(wt, MSG_INFO, "Invalid IEs in a Beacon frame from "
			 MACSTR, MAC2STR(mgmt->sa));
		bss->parse_error_reported = 1;
		return;
	}

	bss_update(wt, bss, &elems);
}


static void rx_mgmt_probe_resp(struct wlantest *wt, const u8 *data, size_t len)
{
	const struct ieee80211_mgmt *mgmt;
	struct wlantest_bss *bss;
	struct ieee802_11_elems elems;
	size_t offset;

	mgmt = (const struct ieee80211_mgmt *) data;
	offset = mgmt->u.probe_resp.variable - data;
	if (len < offset)
		return;
	bss = bss_get(wt, mgmt->bssid);
	if (bss == NULL)
		return;

	bss->counters[WLANTEST_BSS_COUNTER_PROBE_RESPONSE]++;
	bss->capab_info = le_to_host16(mgmt->u.probe_resp.capab_info);
	if (ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - offset,
				   &elems, 0) == ParseFailed) {
		if (bss->parse_error_reported)
			return;
		add_note(wt, MSG_INFO, "Invalid IEs in a Probe Response frame "
			 "from " MACSTR, MAC2STR(mgmt->sa));
		bss->parse_error_reported = 1;
		return;
	}

	bss_update(wt, bss, &elems);
}


static void rx_mgmt_auth(struct wlantest *wt, const u8 *data, size_t len)
{
	const struct ieee80211_mgmt *mgmt;
	struct wlantest_bss *bss;
	struct wlantest_sta *sta;
	u16 alg, trans, status;

	mgmt = (const struct ieee80211_mgmt *) data;
	bss = bss_get(wt, mgmt->bssid);
	if (bss == NULL)
		return;
	if (os_memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN) == 0)
		sta = sta_get(bss, mgmt->da);
	else
		sta = sta_get(bss, mgmt->sa);
	if (sta == NULL)
		return;

	if (len < 24 + 6) {
		add_note(wt, MSG_INFO, "Too short Authentication frame from "
			 MACSTR, MAC2STR(mgmt->sa));
		return;
	}

	alg = le_to_host16(mgmt->u.auth.auth_alg);
	trans = le_to_host16(mgmt->u.auth.auth_transaction);
	status = le_to_host16(mgmt->u.auth.status_code);

	wpa_printf(MSG_DEBUG, "AUTH " MACSTR " -> " MACSTR
		   " (alg=%u trans=%u status=%u)",
		   MAC2STR(mgmt->sa), MAC2STR(mgmt->da), alg, trans, status);

	if (alg == 0 && trans == 2 && status == 0) {
		if (sta->state == STATE1) {
			add_note(wt, MSG_DEBUG, "STA " MACSTR
				 " moved to State 2 with " MACSTR,
				 MAC2STR(sta->addr), MAC2STR(bss->bssid));
			sta->state = STATE2;
		}
	}

	if (os_memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN) == 0)
		sta->counters[WLANTEST_STA_COUNTER_AUTH_RX]++;
	else
		sta->counters[WLANTEST_STA_COUNTER_AUTH_TX]++;
}


static void deauth_all_stas(struct wlantest *wt, struct wlantest_bss *bss)
{
	struct wlantest_sta *sta;
	dl_list_for_each(sta, &bss->sta, struct wlantest_sta, list) {
		if (sta->state == STATE1)
			continue;
		add_note(wt, MSG_DEBUG, "STA " MACSTR
			 " moved to State 1 with " MACSTR,
			 MAC2STR(sta->addr), MAC2STR(bss->bssid));
		sta->state = STATE1;
	}
}


static void tdls_link_down(struct wlantest *wt, struct wlantest_bss *bss,
			   struct wlantest_sta *sta)
{
	struct wlantest_tdls *tdls;
	dl_list_for_each(tdls, &bss->tdls, struct wlantest_tdls, list) {
		if ((tdls->init == sta || tdls->resp == sta) && tdls->link_up)
		{
			add_note(wt, MSG_DEBUG, "TDLS: Set link down based on "
				 "STA deauth/disassoc");
			tdls->link_up = 0;
		}
	}
}


static void rx_mgmt_deauth(struct wlantest *wt, const u8 *data, size_t len,
			   int valid)
{
	const struct ieee80211_mgmt *mgmt;
	struct wlantest_bss *bss;
	struct wlantest_sta *sta;
	u16 fc, reason;

	mgmt = (const struct ieee80211_mgmt *) data;
	bss = bss_get(wt, mgmt->bssid);
	if (bss == NULL)
		return;
	if (os_memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN) == 0)
		sta = sta_get(bss, mgmt->da);
	else
		sta = sta_get(bss, mgmt->sa);

	if (len < 24 + 2) {
		add_note(wt, MSG_INFO, "Too short Deauthentication frame from "
			 MACSTR, MAC2STR(mgmt->sa));
		return;
	}

	reason = le_to_host16(mgmt->u.deauth.reason_code);
	wpa_printf(MSG_DEBUG, "DEAUTH " MACSTR " -> " MACSTR
		   " (reason=%u) (valid=%d)",
		   MAC2STR(mgmt->sa), MAC2STR(mgmt->da),
		   reason, valid);
	wpa_hexdump(MSG_MSGDUMP, "DEAUTH payload", data + 24, len - 24);

	if (sta == NULL) {
		if (valid && mgmt->da[0] == 0xff)
			deauth_all_stas(wt, bss);
		return;
	}

	if (os_memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN) == 0) {
		sta->counters[valid ? WLANTEST_STA_COUNTER_VALID_DEAUTH_RX :
			      WLANTEST_STA_COUNTER_INVALID_DEAUTH_RX]++;
		if (sta->pwrmgt && !sta->pspoll)
			sta->counters[WLANTEST_STA_COUNTER_DEAUTH_RX_ASLEEP]++;
		else
			sta->counters[WLANTEST_STA_COUNTER_DEAUTH_RX_AWAKE]++;

		fc = le_to_host16(mgmt->frame_control);
		if (!(fc & WLAN_FC_ISWEP) && reason == 6)
			sta->counters[WLANTEST_STA_COUNTER_DEAUTH_RX_RC6]++;
		else if (!(fc & WLAN_FC_ISWEP) && reason == 7)
			sta->counters[WLANTEST_STA_COUNTER_DEAUTH_RX_RC7]++;
	} else
		sta->counters[valid ? WLANTEST_STA_COUNTER_VALID_DEAUTH_TX :
			      WLANTEST_STA_COUNTER_INVALID_DEAUTH_TX]++;

	if (!valid) {
		add_note(wt, MSG_INFO, "Do not change STA " MACSTR " State "
			 "since Disassociation frame was not protected "
			 "correctly", MAC2STR(sta->addr));
		return;
	}

	if (sta->state != STATE1) {
		add_note(wt, MSG_DEBUG, "STA " MACSTR
			 " moved to State 1 with " MACSTR,
			 MAC2STR(sta->addr), MAC2STR(bss->bssid));
		sta->state = STATE1;
	}
	tdls_link_down(wt, bss, sta);
}


static void rx_mgmt_assoc_req(struct wlantest *wt, const u8 *data, size_t len)
{
	const struct ieee80211_mgmt *mgmt;
	struct wlantest_bss *bss;
	struct wlantest_sta *sta;
	struct ieee802_11_elems elems;

	mgmt = (const struct ieee80211_mgmt *) data;
	bss = bss_get(wt, mgmt->bssid);
	if (bss == NULL)
		return;
	sta = sta_get(bss, mgmt->sa);
	if (sta == NULL)
		return;

	if (len < 24 + 4) {
		add_note(wt, MSG_INFO, "Too short Association Request frame "
			 "from " MACSTR, MAC2STR(mgmt->sa));
		return;
	}

	wpa_printf(MSG_DEBUG, "ASSOCREQ " MACSTR " -> " MACSTR
		   " (capab=0x%x listen_int=%u)",
		   MAC2STR(mgmt->sa), MAC2STR(mgmt->da),
		   le_to_host16(mgmt->u.assoc_req.capab_info),
		   le_to_host16(mgmt->u.assoc_req.listen_interval));

	sta->counters[WLANTEST_STA_COUNTER_ASSOCREQ_TX]++;

	if (ieee802_11_parse_elems(mgmt->u.assoc_req.variable,
				   len - (mgmt->u.assoc_req.variable - data),
				   &elems, 0) == ParseFailed) {
		add_note(wt, MSG_INFO, "Invalid IEs in Association Request "
			 "frame from " MACSTR, MAC2STR(mgmt->sa));
		return;
	}

	sta->assocreq_capab_info = le_to_host16(mgmt->u.assoc_req.capab_info);
	sta->assocreq_listen_int =
		le_to_host16(mgmt->u.assoc_req.listen_interval);
	os_free(sta->assocreq_ies);
	sta->assocreq_ies_len = len - (mgmt->u.assoc_req.variable - data);
	sta->assocreq_ies = os_malloc(sta->assocreq_ies_len);
	if (sta->assocreq_ies)
		os_memcpy(sta->assocreq_ies, mgmt->u.assoc_req.variable,
			  sta->assocreq_ies_len);

	sta_update_assoc(sta, &elems);
}


static void rx_mgmt_assoc_resp(struct wlantest *wt, const u8 *data, size_t len)
{
	const struct ieee80211_mgmt *mgmt;
	struct wlantest_bss *bss;
	struct wlantest_sta *sta;
	u16 capab, status, aid;

	mgmt = (const struct ieee80211_mgmt *) data;
	bss = bss_get(wt, mgmt->bssid);
	if (bss == NULL)
		return;
	sta = sta_get(bss, mgmt->da);
	if (sta == NULL)
		return;

	if (len < 24 + 6) {
		add_note(wt, MSG_INFO, "Too short Association Response frame "
			 "from " MACSTR, MAC2STR(mgmt->sa));
		return;
	}

	capab = le_to_host16(mgmt->u.assoc_resp.capab_info);
	status = le_to_host16(mgmt->u.assoc_resp.status_code);
	aid = le_to_host16(mgmt->u.assoc_resp.aid);

	wpa_printf(MSG_DEBUG, "ASSOCRESP " MACSTR " -> " MACSTR
		   " (capab=0x%x status=%u aid=%u)",
		   MAC2STR(mgmt->sa), MAC2STR(mgmt->da), capab, status,
		   aid & 0x3fff);

	if (status == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY) {
		struct ieee802_11_elems elems;
		const u8 *ies = mgmt->u.assoc_resp.variable;
		size_t ies_len = len - (mgmt->u.assoc_resp.variable - data);
		if (ieee802_11_parse_elems(ies, ies_len, &elems, 0) ==
		    ParseFailed) {
			add_note(wt, MSG_INFO, "Failed to parse IEs in "
				 "AssocResp from " MACSTR,
				 MAC2STR(mgmt->sa));
		} else if (elems.timeout_int == NULL ||
			   elems.timeout_int[0] !=
			   WLAN_TIMEOUT_ASSOC_COMEBACK) {
			add_note(wt, MSG_INFO, "No valid Timeout Interval IE "
				 "with Assoc Comeback time in AssocResp "
				 "(status=30) from " MACSTR,
				 MAC2STR(mgmt->sa));
		} else {
			sta->counters[
				WLANTEST_STA_COUNTER_ASSOCRESP_COMEBACK]++;
		}
	}

	if (status)
		return;

	if ((aid & 0xc000) != 0xc000) {
		add_note(wt, MSG_DEBUG, "Two MSBs of the AID were not set to 1 "
			 "in Association Response from " MACSTR,
			 MAC2STR(mgmt->sa));
	}
	sta->aid = aid & 0xc000;

	if (sta->state < STATE2) {
		add_note(wt, MSG_DEBUG,
			 "STA " MACSTR " was not in State 2 when "
			 "getting associated", MAC2STR(sta->addr));
	}

	if (sta->state < STATE3) {
		add_note(wt, MSG_DEBUG, "STA " MACSTR
			 " moved to State 3 with " MACSTR,
			 MAC2STR(sta->addr), MAC2STR(bss->bssid));
		sta->state = STATE3;
	}
}


static void rx_mgmt_reassoc_req(struct wlantest *wt, const u8 *data,
				size_t len)
{
	const struct ieee80211_mgmt *mgmt;
	struct wlantest_bss *bss;
	struct wlantest_sta *sta;
	struct ieee802_11_elems elems;

	mgmt = (const struct ieee80211_mgmt *) data;
	bss = bss_get(wt, mgmt->bssid);
	if (bss == NULL)
		return;
	sta = sta_get(bss, mgmt->sa);
	if (sta == NULL)
		return;

	if (len < 24 + 4 + ETH_ALEN) {
		add_note(wt, MSG_INFO, "Too short Reassociation Request frame "
			 "from " MACSTR, MAC2STR(mgmt->sa));
		return;
	}

	wpa_printf(MSG_DEBUG, "REASSOCREQ " MACSTR " -> " MACSTR
		   " (capab=0x%x listen_int=%u current_ap=" MACSTR ")",
		   MAC2STR(mgmt->sa), MAC2STR(mgmt->da),
		   le_to_host16(mgmt->u.reassoc_req.capab_info),
		   le_to_host16(mgmt->u.reassoc_req.listen_interval),
		   MAC2STR(mgmt->u.reassoc_req.current_ap));

	sta->counters[WLANTEST_STA_COUNTER_REASSOCREQ_TX]++;

	if (ieee802_11_parse_elems(mgmt->u.reassoc_req.variable,
				   len - (mgmt->u.reassoc_req.variable - data),
				   &elems, 0) == ParseFailed) {
		add_note(wt, MSG_INFO, "Invalid IEs in Reassociation Request "
			 "frame from " MACSTR, MAC2STR(mgmt->sa));
		return;
	}

	sta->assocreq_capab_info =
		le_to_host16(mgmt->u.reassoc_req.capab_info);
	sta->assocreq_listen_int =
		le_to_host16(mgmt->u.reassoc_req.listen_interval);
	os_free(sta->assocreq_ies);
	sta->assocreq_ies_len = len - (mgmt->u.reassoc_req.variable - data);
	sta->assocreq_ies = os_malloc(sta->assocreq_ies_len);
	if (sta->assocreq_ies)
		os_memcpy(sta->assocreq_ies, mgmt->u.reassoc_req.variable,
			  sta->assocreq_ies_len);

	sta_update_assoc(sta, &elems);
}


static void rx_mgmt_reassoc_resp(struct wlantest *wt, const u8 *data,
				 size_t len)
{
	const struct ieee80211_mgmt *mgmt;
	struct wlantest_bss *bss;
	struct wlantest_sta *sta;
	u16 capab, status, aid;

	mgmt = (const struct ieee80211_mgmt *) data;
	bss = bss_get(wt, mgmt->bssid);
	if (bss == NULL)
		return;
	sta = sta_get(bss, mgmt->da);
	if (sta == NULL)
		return;

	if (len < 24 + 6) {
		add_note(wt, MSG_INFO, "Too short Reassociation Response frame "
			 "from " MACSTR, MAC2STR(mgmt->sa));
		return;
	}

	capab = le_to_host16(mgmt->u.reassoc_resp.capab_info);
	status = le_to_host16(mgmt->u.reassoc_resp.status_code);
	aid = le_to_host16(mgmt->u.reassoc_resp.aid);

	wpa_printf(MSG_DEBUG, "REASSOCRESP " MACSTR " -> " MACSTR
		   " (capab=0x%x status=%u aid=%u)",
		   MAC2STR(mgmt->sa), MAC2STR(mgmt->da), capab, status,
		   aid & 0x3fff);

	if (status == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY) {
		struct ieee802_11_elems elems;
		const u8 *ies = mgmt->u.reassoc_resp.variable;
		size_t ies_len = len - (mgmt->u.reassoc_resp.variable - data);
		if (ieee802_11_parse_elems(ies, ies_len, &elems, 0) ==
		    ParseFailed) {
			add_note(wt, MSG_INFO, "Failed to parse IEs in "
				 "ReassocResp from " MACSTR,
				 MAC2STR(mgmt->sa));
		} else if (elems.timeout_int == NULL ||
			   elems.timeout_int[0] !=
			   WLAN_TIMEOUT_ASSOC_COMEBACK) {
			add_note(wt, MSG_INFO, "No valid Timeout Interval IE "
				 "with Assoc Comeback time in ReassocResp "
				 "(status=30) from " MACSTR,
				 MAC2STR(mgmt->sa));
		} else {
			sta->counters[
				WLANTEST_STA_COUNTER_REASSOCRESP_COMEBACK]++;
		}
	}

	if (status)
		return;

	if ((aid & 0xc000) != 0xc000) {
		add_note(wt, MSG_DEBUG, "Two MSBs of the AID were not set to 1 "
			 "in Reassociation Response from " MACSTR,
			 MAC2STR(mgmt->sa));
	}
	sta->aid = aid & 0xc000;

	if (sta->state < STATE2) {
		add_note(wt, MSG_DEBUG,
			 "STA " MACSTR " was not in State 2 when "
			 "getting associated", MAC2STR(sta->addr));
	}

	if (sta->state < STATE3) {
		add_note(wt, MSG_DEBUG, "STA " MACSTR
			 " moved to State 3 with " MACSTR,
			 MAC2STR(sta->addr), MAC2STR(bss->bssid));
		sta->state = STATE3;
	}
}


static void disassoc_all_stas(struct wlantest *wt, struct wlantest_bss *bss)
{
	struct wlantest_sta *sta;
	dl_list_for_each(sta, &bss->sta, struct wlantest_sta, list) {
		if (sta->state <= STATE2)
			continue;
		add_note(wt, MSG_DEBUG, "STA " MACSTR
			 " moved to State 2 with " MACSTR,
			 MAC2STR(sta->addr), MAC2STR(bss->bssid));
		sta->state = STATE2;
	}
}


static void rx_mgmt_disassoc(struct wlantest *wt, const u8 *data, size_t len,
			     int valid)
{
	const struct ieee80211_mgmt *mgmt;
	struct wlantest_bss *bss;
	struct wlantest_sta *sta;
	u16 fc, reason;

	mgmt = (const struct ieee80211_mgmt *) data;
	bss = bss_get(wt, mgmt->bssid);
	if (bss == NULL)
		return;
	if (os_memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN) == 0)
		sta = sta_get(bss, mgmt->da);
	else
		sta = sta_get(bss, mgmt->sa);

	if (len < 24 + 2) {
		add_note(wt, MSG_INFO, "Too short Disassociation frame from "
			 MACSTR, MAC2STR(mgmt->sa));
		return;
	}

	reason = le_to_host16(mgmt->u.disassoc.reason_code);
	wpa_printf(MSG_DEBUG, "DISASSOC " MACSTR " -> " MACSTR
		   " (reason=%u) (valid=%d)",
		   MAC2STR(mgmt->sa), MAC2STR(mgmt->da),
		   reason, valid);
	wpa_hexdump(MSG_MSGDUMP, "DISASSOC payload", data + 24, len - 24);

	if (sta == NULL) {
		if (valid && mgmt->da[0] == 0xff)
			disassoc_all_stas(wt, bss);
		return;
	}

	if (os_memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN) == 0) {
		sta->counters[valid ? WLANTEST_STA_COUNTER_VALID_DISASSOC_RX :
			      WLANTEST_STA_COUNTER_INVALID_DISASSOC_RX]++;
		if (sta->pwrmgt && !sta->pspoll)
			sta->counters[
				WLANTEST_STA_COUNTER_DISASSOC_RX_ASLEEP]++;
		else
			sta->counters[
				WLANTEST_STA_COUNTER_DISASSOC_RX_AWAKE]++;

		fc = le_to_host16(mgmt->frame_control);
		if (!(fc & WLAN_FC_ISWEP) && reason == 6)
			sta->counters[WLANTEST_STA_COUNTER_DISASSOC_RX_RC6]++;
		else if (!(fc & WLAN_FC_ISWEP) && reason == 7)
			sta->counters[WLANTEST_STA_COUNTER_DISASSOC_RX_RC7]++;
	} else
		sta->counters[valid ? WLANTEST_STA_COUNTER_VALID_DISASSOC_TX :
			      WLANTEST_STA_COUNTER_INVALID_DISASSOC_TX]++;

	if (!valid) {
		add_note(wt, MSG_INFO, "Do not change STA " MACSTR " State "
			 "since Disassociation frame was not protected "
			 "correctly", MAC2STR(sta->addr));
		return;
	}

	if (sta->state < STATE2) {
		add_note(wt, MSG_DEBUG,
			 "STA " MACSTR " was not in State 2 or 3 "
			 "when getting disassociated", MAC2STR(sta->addr));
	}

	if (sta->state > STATE2) {
		add_note(wt, MSG_DEBUG, "STA " MACSTR
			 " moved to State 2 with " MACSTR,
			 MAC2STR(sta->addr), MAC2STR(bss->bssid));
		sta->state = STATE2;
	}
	tdls_link_down(wt, bss, sta);
}


static void rx_mgmt_action_sa_query_req(struct wlantest *wt,
					struct wlantest_sta *sta,
					const struct ieee80211_mgmt *mgmt,
					size_t len, int valid)
{
	const u8 *rx_id;
	u8 *id;

	rx_id = (const u8 *) mgmt->u.action.u.sa_query_req.trans_id;
	if (os_memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN) == 0)
		id = sta->ap_sa_query_tr;
	else
		id = sta->sta_sa_query_tr;
	add_note(wt, MSG_INFO, "SA Query Request " MACSTR " -> " MACSTR
		 " (trans_id=%02x%02x)%s",
		 MAC2STR(mgmt->sa), MAC2STR(mgmt->da), rx_id[0], rx_id[1],
		 valid ? "" : " (invalid protection)");
	os_memcpy(id, mgmt->u.action.u.sa_query_req.trans_id, 2);
	if (os_memcmp(mgmt->sa, sta->addr, ETH_ALEN) == 0)
		sta->counters[valid ?
			      WLANTEST_STA_COUNTER_VALID_SAQUERYREQ_TX :
			      WLANTEST_STA_COUNTER_INVALID_SAQUERYREQ_TX]++;
	else
		sta->counters[valid ?
			      WLANTEST_STA_COUNTER_VALID_SAQUERYREQ_RX :
			      WLANTEST_STA_COUNTER_INVALID_SAQUERYREQ_RX]++;
}


static void rx_mgmt_action_sa_query_resp(struct wlantest *wt,
					 struct wlantest_sta *sta,
					 const struct ieee80211_mgmt *mgmt,
					 size_t len, int valid)
{
	const u8 *rx_id;
	u8 *id;
	int match;

	rx_id = (const u8 *) mgmt->u.action.u.sa_query_resp.trans_id;
	if (os_memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN) == 0)
		id = sta->sta_sa_query_tr;
	else
		id = sta->ap_sa_query_tr;
	match = os_memcmp(rx_id, id, 2) == 0;
	add_note(wt, MSG_INFO, "SA Query Response " MACSTR " -> " MACSTR
		 " (trans_id=%02x%02x; %s)%s",
		 MAC2STR(mgmt->sa), MAC2STR(mgmt->da), rx_id[0], rx_id[1],
		 match ? "match" : "mismatch",
		 valid ? "" : " (invalid protection)");
	if (os_memcmp(mgmt->sa, sta->addr, ETH_ALEN) == 0)
		sta->counters[(valid && match) ?
			      WLANTEST_STA_COUNTER_VALID_SAQUERYRESP_TX :
			      WLANTEST_STA_COUNTER_INVALID_SAQUERYRESP_TX]++;
	else
		sta->counters[(valid && match) ?
			      WLANTEST_STA_COUNTER_VALID_SAQUERYRESP_RX :
			      WLANTEST_STA_COUNTER_INVALID_SAQUERYRESP_RX]++;
}


static void rx_mgmt_action_sa_query(struct wlantest *wt,
				    struct wlantest_sta *sta,
				    const struct ieee80211_mgmt *mgmt,
				    size_t len, int valid)
{
	if (len < 24 + 2 + WLAN_SA_QUERY_TR_ID_LEN) {
		add_note(wt, MSG_INFO, "Too short SA Query frame from " MACSTR,
			 MAC2STR(mgmt->sa));
		return;
	}

	if (len > 24 + 2 + WLAN_SA_QUERY_TR_ID_LEN) {
		size_t elen = len - (24 + 2 + WLAN_SA_QUERY_TR_ID_LEN);
		add_note(wt, MSG_INFO, "Unexpected %u octets of extra data at "
			 "the end of SA Query frame from " MACSTR,
			 (unsigned) elen, MAC2STR(mgmt->sa));
		wpa_hexdump(MSG_INFO, "SA Query extra data",
			    ((const u8 *) mgmt) + len - elen, elen);
	}

	switch (mgmt->u.action.u.sa_query_req.action) {
	case WLAN_SA_QUERY_REQUEST:
		rx_mgmt_action_sa_query_req(wt, sta, mgmt, len, valid);
		break;
	case WLAN_SA_QUERY_RESPONSE:
		rx_mgmt_action_sa_query_resp(wt, sta, mgmt, len, valid);
		break;
	default:
		add_note(wt, MSG_INFO, "Unexpected SA Query action value %u "
			 "from " MACSTR,
			 mgmt->u.action.u.sa_query_req.action,
			 MAC2STR(mgmt->sa));
	}
}


static void rx_mgmt_action(struct wlantest *wt, const u8 *data, size_t len,
			   int valid)
{
	const struct ieee80211_mgmt *mgmt;
	struct wlantest_bss *bss;
	struct wlantest_sta *sta;

	mgmt = (const struct ieee80211_mgmt *) data;
	if (mgmt->da[0] & 0x01) {
		add_note(wt, MSG_DEBUG, "Group addressed Action frame: DA="
			 MACSTR " SA=" MACSTR " BSSID=" MACSTR
			 " category=%u",
			 MAC2STR(mgmt->da), MAC2STR(mgmt->sa),
			 MAC2STR(mgmt->bssid), mgmt->u.action.category);
		return; /* Ignore group addressed Action frames for now */
	}
	bss = bss_get(wt, mgmt->bssid);
	if (bss == NULL)
		return;
	if (os_memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN) == 0)
		sta = sta_get(bss, mgmt->da);
	else
		sta = sta_get(bss, mgmt->sa);
	if (sta == NULL)
		return;

	if (len < 24 + 1) {
		add_note(wt, MSG_INFO, "Too short Action frame from " MACSTR,
			 MAC2STR(mgmt->sa));
		return;
	}

	wpa_printf(MSG_DEBUG, "ACTION " MACSTR " -> " MACSTR
		   " (category=%u) (valid=%d)",
		   MAC2STR(mgmt->sa), MAC2STR(mgmt->da),
		   mgmt->u.action.category, valid);
	wpa_hexdump(MSG_MSGDUMP, "ACTION payload", data + 24, len - 24);

	if (mgmt->u.action.category != WLAN_ACTION_PUBLIC &&
	    sta->state < STATE3) {
		add_note(wt, MSG_INFO, "Action frame sent when STA is not in "
			 "State 3 (SA=" MACSTR " DATA=" MACSTR ")",
			 MAC2STR(mgmt->sa), MAC2STR(mgmt->da));
	}

	switch (mgmt->u.action.category) {
	case WLAN_ACTION_SA_QUERY:
		rx_mgmt_action_sa_query(wt, sta, mgmt, len, valid);
		break;
	}
}


static int check_mmie_mic(unsigned int mgmt_group_cipher,
			  const u8 *igtk, size_t igtk_len,
			  const u8 *data, size_t len)
{
	u8 *buf;
	u8 mic[16];
	u16 fc;
	const struct ieee80211_hdr *hdr;
	int ret, mic_len;

	if (!mgmt_group_cipher || igtk_len < 16)
		return -1;
	mic_len = mgmt_group_cipher == WPA_CIPHER_AES_128_CMAC ? 8 : 16;

	if (len < 24 || len - 24 < mic_len)
		return -1;

	buf = os_malloc(len + 20 - 24);
	if (buf == NULL)
		return -1;

	/* BIP AAD: FC(masked) A1 A2 A3 */
	hdr = (const struct ieee80211_hdr *) data;
	fc = le_to_host16(hdr->frame_control);
	fc &= ~(WLAN_FC_RETRY | WLAN_FC_PWRMGT | WLAN_FC_MOREDATA);
	WPA_PUT_LE16(buf, fc);
	os_memcpy(buf + 2, hdr->addr1, 3 * ETH_ALEN);

	/* Frame body with MMIE MIC masked to zero */
	os_memcpy(buf + 20, data + 24, len - 24 - mic_len);
	os_memset(buf + 20 + len - 24 - mic_len, 0, mic_len);

	wpa_hexdump(MSG_MSGDUMP, "BIP: AAD|Body(masked)", buf, len + 20 - 24);
	/* MIC = L(AES-128-CMAC(AAD || Frame Body(masked)), 0, 64) */
	if (mgmt_group_cipher == WPA_CIPHER_AES_128_CMAC) {
		ret = omac1_aes_128(igtk, buf, len + 20 - 24, mic);
	} else if (mgmt_group_cipher == WPA_CIPHER_BIP_CMAC_256) {
		ret = omac1_aes_256(igtk, buf, len + 20 - 24, mic);
	} else if (mgmt_group_cipher == WPA_CIPHER_BIP_GMAC_128 ||
		 mgmt_group_cipher == WPA_CIPHER_BIP_GMAC_256) {
		u8 nonce[12], *npos;
		const u8 *ipn;

		ipn = data + len - mic_len - 6;

		/* Nonce: A2 | IPN */
		os_memcpy(nonce, hdr->addr2, ETH_ALEN);
		npos = nonce + ETH_ALEN;
		*npos++ = ipn[5];
		*npos++ = ipn[4];
		*npos++ = ipn[3];
		*npos++ = ipn[2];
		*npos++ = ipn[1];
		*npos++ = ipn[0];

		ret = aes_gmac(igtk, igtk_len, nonce, sizeof(nonce),
			       buf, len + 20 - 24, mic);
	} else {
		ret = -1;
	}
	if (ret < 0) {
		os_free(buf);
		return -1;
	}

	os_free(buf);

	if (os_memcmp(data + len - mic_len, mic, mic_len) != 0)
		return -1;

	return 0;
}


static int check_bip(struct wlantest *wt, const u8 *data, size_t len)
{
	const struct ieee80211_mgmt *mgmt;
	u16 fc, stype;
	const u8 *mmie;
	u16 keyid;
	struct wlantest_bss *bss;
	size_t mic_len;

	mgmt = (const struct ieee80211_mgmt *) data;
	fc = le_to_host16(mgmt->frame_control);
	stype = WLAN_FC_GET_STYPE(fc);

	if (stype == WLAN_FC_STYPE_ACTION) {
		if (len < 24 + 1)
			return 0;
		if (mgmt->u.action.category == WLAN_ACTION_PUBLIC)
			return 0; /* Not a robust management frame */
	}

	bss = bss_get(wt, mgmt->bssid);
	if (bss == NULL)
		return 0; /* No key known yet */

	mic_len = bss->mgmt_group_cipher == WPA_CIPHER_AES_128_CMAC ? 8 : 16;

	if (len < 24 + 10 + mic_len ||
	    data[len - (10 + mic_len)] != WLAN_EID_MMIE ||
	    data[len - (10 + mic_len - 1)] != 8 + mic_len) {
		/* No MMIE */
		if (bss->rsn_capab & WPA_CAPABILITY_MFPC) {
			add_note(wt, MSG_INFO, "Robust group-addressed "
				 "management frame sent without BIP by "
				 MACSTR, MAC2STR(mgmt->sa));
			bss->counters[WLANTEST_BSS_COUNTER_MISSING_BIP_MMIE]++;
			return -1;
		}
		return 0;
	}

	mmie = data + len - (8 + mic_len);
	keyid = WPA_GET_LE16(mmie);
	if (keyid & 0xf000) {
		add_note(wt, MSG_INFO, "MMIE KeyID reserved bits not zero "
			 "(%04x) from " MACSTR, keyid, MAC2STR(mgmt->sa));
		keyid &= 0x0fff;
	}
	if (keyid < 4 || keyid > 5) {
		add_note(wt, MSG_INFO, "Unexpected MMIE KeyID %u from " MACSTR,
			 keyid, MAC2STR(mgmt->sa));
		bss->counters[WLANTEST_BSS_COUNTER_INVALID_BIP_MMIE]++;
		return 0;
	}
	wpa_printf(MSG_DEBUG, "MMIE KeyID %u", keyid);
	wpa_hexdump(MSG_MSGDUMP, "MMIE IPN", mmie + 2, 6);
	wpa_hexdump(MSG_MSGDUMP, "MMIE MIC", mmie + 8, mic_len);

	if (!bss->igtk_len[keyid]) {
		add_note(wt, MSG_DEBUG, "No IGTK known to validate BIP frame");
		return 0;
	}

	if (os_memcmp(mmie + 2, bss->ipn[keyid], 6) <= 0) {
		add_note(wt, MSG_INFO, "BIP replay detected: SA=" MACSTR,
			 MAC2STR(mgmt->sa));
		wpa_hexdump(MSG_INFO, "RX IPN", mmie + 2, 6);
		wpa_hexdump(MSG_INFO, "Last RX IPN", bss->ipn[keyid], 6);
	}

	if (check_mmie_mic(bss->mgmt_group_cipher, bss->igtk[keyid],
			   bss->igtk_len[keyid], data, len) < 0) {
		add_note(wt, MSG_INFO, "Invalid MMIE MIC in a frame from "
			 MACSTR, MAC2STR(mgmt->sa));
		bss->counters[WLANTEST_BSS_COUNTER_INVALID_BIP_MMIE]++;
		return -1;
	}

	add_note(wt, MSG_DEBUG, "Valid MMIE MIC");
	os_memcpy(bss->ipn[keyid], mmie + 2, 6);
	bss->counters[WLANTEST_BSS_COUNTER_VALID_BIP_MMIE]++;

	if (stype == WLAN_FC_STYPE_DEAUTH)
		bss->counters[WLANTEST_BSS_COUNTER_BIP_DEAUTH]++;
	else if (stype == WLAN_FC_STYPE_DISASSOC)
		bss->counters[WLANTEST_BSS_COUNTER_BIP_DISASSOC]++;

	return 0;
}


static u8 * mgmt_ccmp_decrypt(struct wlantest *wt, const u8 *data, size_t len,
			      size_t *dlen)
{
	struct wlantest_bss *bss;
	struct wlantest_sta *sta;
	const struct ieee80211_hdr *hdr;
	int keyid;
	u8 *decrypted, *frame = NULL;
	u8 pn[6], *rsc;

	hdr = (const struct ieee80211_hdr *) data;
	bss = bss_get(wt, hdr->addr3);
	if (bss == NULL)
		return NULL;
	if (os_memcmp(hdr->addr1, hdr->addr3, ETH_ALEN) == 0)
		sta = sta_get(bss, hdr->addr2);
	else
		sta = sta_get(bss, hdr->addr1);
	if (sta == NULL || !sta->ptk_set) {
		add_note(wt, MSG_MSGDUMP, "No PTK known to decrypt the frame");
		return NULL;
	}

	if (len < 24 + 4)
		return NULL;

	if (!(data[24 + 3] & 0x20)) {
		add_note(wt, MSG_INFO, "Expected CCMP frame from " MACSTR
			 " did not have ExtIV bit set to 1",
			 MAC2STR(hdr->addr2));
		return NULL;
	}

	if (data[24 + 2] != 0 || (data[24 + 3] & 0x1f) != 0) {
		add_note(wt, MSG_INFO, "CCMP mgmt frame from " MACSTR " used "
			 "non-zero reserved bit", MAC2STR(hdr->addr2));
	}

	keyid = data[24 + 3] >> 6;
	if (keyid != 0) {
		add_note(wt, MSG_INFO, "Unexpected non-zero KeyID %d in "
			 "individually addressed Management frame from "
			 MACSTR, keyid, MAC2STR(hdr->addr2));
	}

	if (os_memcmp(hdr->addr1, hdr->addr3, ETH_ALEN) == 0)
		rsc = sta->rsc_tods[16];
	else
		rsc = sta->rsc_fromds[16];

	ccmp_get_pn(pn, data + 24);
	if (os_memcmp(pn, rsc, 6) <= 0) {
		u16 seq_ctrl = le_to_host16(hdr->seq_ctrl);
		add_note(wt, MSG_INFO, "CCMP/TKIP replay detected: A1=" MACSTR
			 " A2=" MACSTR " A3=" MACSTR " seq=%u frag=%u%s",
			 MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
			 MAC2STR(hdr->addr3),
			 WLAN_GET_SEQ_SEQ(seq_ctrl),
			 WLAN_GET_SEQ_FRAG(seq_ctrl),
			 (le_to_host16(hdr->frame_control) & WLAN_FC_RETRY) ?
			 " Retry" : "");
		wpa_hexdump(MSG_INFO, "RX PN", pn, 6);
		wpa_hexdump(MSG_INFO, "RSC", rsc, 6);
	}

	decrypted = ccmp_decrypt(sta->ptk.tk, hdr, data + 24, len - 24, dlen);
	if (decrypted) {
		os_memcpy(rsc, pn, 6);
		frame = os_malloc(24 + *dlen);
		if (frame) {
			os_memcpy(frame, data, 24);
			os_memcpy(frame + 24, decrypted, *dlen);
			*dlen += 24;
		}
	}

	os_free(decrypted);

	return frame;
}


static int check_mgmt_ccmp(struct wlantest *wt, const u8 *data, size_t len)
{
	const struct ieee80211_mgmt *mgmt;
	u16 fc;
	struct wlantest_bss *bss;
	struct wlantest_sta *sta;

	mgmt = (const struct ieee80211_mgmt *) data;
	fc = le_to_host16(mgmt->frame_control);

	if (WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACTION) {
		if (len > 24 &&
		    mgmt->u.action.category == WLAN_ACTION_PUBLIC)
			return 0; /* Not a robust management frame */
	}

	bss = bss_get(wt, mgmt->bssid);
	if (bss == NULL)
		return 0;
	if (os_memcmp(mgmt->da, mgmt->bssid, ETH_ALEN) == 0)
		sta = sta_get(bss, mgmt->sa);
	else
		sta = sta_get(bss, mgmt->da);
	if (sta == NULL)
		return 0;

	if ((sta->rsn_capab & WPA_CAPABILITY_MFPC) &&
	    (sta->state == STATE3 ||
	     WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACTION)) {
		add_note(wt, MSG_INFO, "Robust individually-addressed "
			 "management frame sent without CCMP by "
			 MACSTR, MAC2STR(mgmt->sa));
		return -1;
	}

	return 0;
}


void rx_mgmt(struct wlantest *wt, const u8 *data, size_t len)
{
	const struct ieee80211_hdr *hdr;
	u16 fc, stype;
	int valid = 1;
	u8 *decrypted = NULL;
	size_t dlen;

	if (len < 24)
		return;

	hdr = (const struct ieee80211_hdr *) data;
	fc = le_to_host16(hdr->frame_control);
	wt->rx_mgmt++;
	stype = WLAN_FC_GET_STYPE(fc);

	if ((hdr->addr1[0] & 0x01) &&
	    (stype == WLAN_FC_STYPE_DEAUTH ||
	     stype == WLAN_FC_STYPE_DISASSOC ||
	     stype == WLAN_FC_STYPE_ACTION)) {
		if (check_bip(wt, data, len) < 0)
			valid = 0;
	}

	wpa_printf((stype == WLAN_FC_STYPE_BEACON ||
		    stype == WLAN_FC_STYPE_PROBE_RESP ||
		    stype == WLAN_FC_STYPE_PROBE_REQ) ?
		   MSG_EXCESSIVE : MSG_MSGDUMP,
		   "MGMT %s%s%s DA=" MACSTR " SA=" MACSTR " BSSID=" MACSTR,
		   mgmt_stype(stype),
		   fc & WLAN_FC_PWRMGT ? " PwrMgt" : "",
		   fc & WLAN_FC_ISWEP ? " Prot" : "",
		   MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
		   MAC2STR(hdr->addr3));

	if ((fc & WLAN_FC_ISWEP) &&
	    !(hdr->addr1[0] & 0x01) &&
	    (stype == WLAN_FC_STYPE_DEAUTH ||
	     stype == WLAN_FC_STYPE_DISASSOC ||
	     stype == WLAN_FC_STYPE_ACTION)) {
		decrypted = mgmt_ccmp_decrypt(wt, data, len, &dlen);
		if (decrypted) {
			write_pcap_decrypted(wt, decrypted, dlen, NULL, 0);
			data = decrypted;
			len = dlen;
		} else
			valid = 0;
	}

	if (!(fc & WLAN_FC_ISWEP) &&
	    !(hdr->addr1[0] & 0x01) &&
	    (stype == WLAN_FC_STYPE_DEAUTH ||
	     stype == WLAN_FC_STYPE_DISASSOC ||
	     stype == WLAN_FC_STYPE_ACTION)) {
		if (check_mgmt_ccmp(wt, data, len) < 0)
			valid = 0;
	}

	switch (stype) {
	case WLAN_FC_STYPE_BEACON:
		rx_mgmt_beacon(wt, data, len);
		break;
	case WLAN_FC_STYPE_PROBE_RESP:
		rx_mgmt_probe_resp(wt, data, len);
		break;
	case WLAN_FC_STYPE_AUTH:
		rx_mgmt_auth(wt, data, len);
		break;
	case WLAN_FC_STYPE_DEAUTH:
		rx_mgmt_deauth(wt, data, len, valid);
		break;
	case WLAN_FC_STYPE_ASSOC_REQ:
		rx_mgmt_assoc_req(wt, data, len);
		break;
	case WLAN_FC_STYPE_ASSOC_RESP:
		rx_mgmt_assoc_resp(wt, data, len);
		break;
	case WLAN_FC_STYPE_REASSOC_REQ:
		rx_mgmt_reassoc_req(wt, data, len);
		break;
	case WLAN_FC_STYPE_REASSOC_RESP:
		rx_mgmt_reassoc_resp(wt, data, len);
		break;
	case WLAN_FC_STYPE_DISASSOC:
		rx_mgmt_disassoc(wt, data, len, valid);
		break;
	case WLAN_FC_STYPE_ACTION:
		rx_mgmt_action(wt, data, len, valid);
		break;
	}

	os_free(decrypted);

	wt->last_mgmt_valid = valid;
}


static void rx_mgmt_deauth_ack(struct wlantest *wt,
			       const struct ieee80211_hdr *hdr)
{
	const struct ieee80211_mgmt *mgmt;
	struct wlantest_bss *bss;
	struct wlantest_sta *sta;

	mgmt = (const struct ieee80211_mgmt *) hdr;
	bss = bss_get(wt, mgmt->bssid);
	if (bss == NULL)
		return;
	if (os_memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN) == 0)
		sta = sta_get(bss, mgmt->da);
	else
		sta = sta_get(bss, mgmt->sa);
	if (sta == NULL)
		return;

	add_note(wt, MSG_DEBUG, "DEAUTH from " MACSTR " acknowledged by "
		 MACSTR, MAC2STR(mgmt->sa), MAC2STR(mgmt->da));
	if (os_memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN) == 0) {
		int c;
		c = wt->last_mgmt_valid ?
			WLANTEST_STA_COUNTER_VALID_DEAUTH_RX_ACK :
			WLANTEST_STA_COUNTER_INVALID_DEAUTH_RX_ACK;
		sta->counters[c]++;
	}
}


static void rx_mgmt_disassoc_ack(struct wlantest *wt,
				 const struct ieee80211_hdr *hdr)
{
	const struct ieee80211_mgmt *mgmt;
	struct wlantest_bss *bss;
	struct wlantest_sta *sta;

	mgmt = (const struct ieee80211_mgmt *) hdr;
	bss = bss_get(wt, mgmt->bssid);
	if (bss == NULL)
		return;
	if (os_memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN) == 0)
		sta = sta_get(bss, mgmt->da);
	else
		sta = sta_get(bss, mgmt->sa);
	if (sta == NULL)
		return;

	add_note(wt, MSG_DEBUG, "DISASSOC from " MACSTR " acknowledged by "
		 MACSTR, MAC2STR(mgmt->sa), MAC2STR(mgmt->da));
	if (os_memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN) == 0) {
		int c;
		c = wt->last_mgmt_valid ?
			WLANTEST_STA_COUNTER_VALID_DISASSOC_RX_ACK :
			WLANTEST_STA_COUNTER_INVALID_DISASSOC_RX_ACK;
		sta->counters[c]++;
	}
}


void rx_mgmt_ack(struct wlantest *wt, const struct ieee80211_hdr *hdr)
{
	u16 fc, stype;
	fc = le_to_host16(hdr->frame_control);
	stype = WLAN_FC_GET_STYPE(fc);

	wpa_printf(MSG_MSGDUMP, "MGMT ACK: stype=%u a1=" MACSTR " a2=" MACSTR
		   " a3=" MACSTR,
		   stype, MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
		   MAC2STR(hdr->addr3));

	switch (stype) {
	case WLAN_FC_STYPE_DEAUTH:
		rx_mgmt_deauth_ack(wt, hdr);
		break;
	case WLAN_FC_STYPE_DISASSOC:
		rx_mgmt_disassoc_ack(wt, hdr);
		break;
	}
}
