From d72d72d38110a7f7dae1703fdffdbdf5e9b32fb3 Mon Sep 17 00:00:00 2001 From: Andriy Voskoboinyk Date: Wed, 20 Apr 2016 20:30:18 +0000 Subject: [PATCH] net80211: provide descriptions for reason codes Add text description for deauth/disassoc/etc reason codes in addition to 'reason: ' string. Reviewed by: adrian Obtained from: IEEE Std 802.11-2012, 8.4.1.7 "Reason Code field" Differential Revision: https://reviews.freebsd.org/D5367 --- sys/net80211/ieee80211_hostap.c | 6 +- sys/net80211/ieee80211_ht.c | 14 ++-- sys/net80211/ieee80211_ioctl.c | 10 ++- sys/net80211/ieee80211_mesh.c | 4 +- sys/net80211/ieee80211_output.c | 6 +- sys/net80211/ieee80211_proto.c | 133 ++++++++++++++++++++++++++++++++ sys/net80211/ieee80211_proto.h | 2 + sys/net80211/ieee80211_sta.c | 6 +- 8 files changed, 163 insertions(+), 18 deletions(-) diff --git a/sys/net80211/ieee80211_hostap.c b/sys/net80211/ieee80211_hostap.c index e55c6c1da29b..5965a5ed2e66 100644 --- a/sys/net80211/ieee80211_hostap.c +++ b/sys/net80211/ieee80211_hostap.c @@ -2183,8 +2183,10 @@ hostap_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, IEEE80211_NODE_STAT(ni, rx_disassoc); } IEEE80211_NOTE(vap, IEEE80211_MSG_AUTH, ni, - "recv %s (reason %d)", ieee80211_mgt_subtype_name[subtype >> - IEEE80211_FC0_SUBTYPE_SHIFT], reason); + "recv %s (reason: %d (%s))", + ieee80211_mgt_subtype_name[subtype >> + IEEE80211_FC0_SUBTYPE_SHIFT], + reason, ieee80211_reason_to_string(reason)); if (ni != vap->iv_bss) ieee80211_node_leave(ni); break; diff --git a/sys/net80211/ieee80211_ht.c b/sys/net80211/ieee80211_ht.c index 315d20226bee..c4f61fe0ffc9 100644 --- a/sys/net80211/ieee80211_ht.c +++ b/sys/net80211/ieee80211_ht.c @@ -2243,8 +2243,9 @@ ieee80211_ampdu_stop(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, tap->txa_flags &= ~IEEE80211_AGGR_BARPEND; if (IEEE80211_AMPDU_RUNNING(tap)) { IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, - ni, "%s: stop BA stream for TID %d (reason %d)", - __func__, tap->txa_tid, reason); + ni, "%s: stop BA stream for TID %d (reason: %d (%s))", + __func__, tap->txa_tid, reason, + ieee80211_reason_to_string(reason)); vap->iv_stats.is_ampdu_stop++; ic->ic_addba_stop(ni, tap); @@ -2255,8 +2256,9 @@ ieee80211_ampdu_stop(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, IEEE80211_ACTION_BA_DELBA, args); } else { IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, - ni, "%s: BA stream for TID %d not running (reason %d)", - __func__, tap->txa_tid, reason); + ni, "%s: BA stream for TID %d not running " + "(reason: %d (%s))", __func__, tap->txa_tid, reason, + ieee80211_reason_to_string(reason)); vap->iv_stats.is_ampdu_stop_failed++; } } @@ -2584,8 +2586,8 @@ ht_send_action_ba_delba(struct ieee80211_node *ni, | args[1] ; IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni, - "send DELBA action: tid %d, initiator %d reason %d", - args[0], args[1], args[2]); + "send DELBA action: tid %d, initiator %d reason %d (%s)", + args[0], args[1], args[2], ieee80211_reason_to_string(args[2])); IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", __func__, __LINE__, diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c index 3a362df39388..919471a1e813 100644 --- a/sys/net80211/ieee80211_ioctl.c +++ b/sys/net80211/ieee80211_ioctl.c @@ -1281,18 +1281,20 @@ mlmedebug(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN], if (op == IEEE80211_MLME_AUTH) { IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_IOCTL | IEEE80211_MSG_STATE | IEEE80211_MSG_AUTH, mac, - "station authenticate %s via MLME (reason %d)", + "station authenticate %s via MLME (reason: %d (%s))", reason == IEEE80211_STATUS_SUCCESS ? "ACCEPT" : "REJECT", - reason); + reason, ieee80211_reason_to_string(reason)); } else if (!(IEEE80211_MLME_ASSOC <= op && op <= IEEE80211_MLME_AUTH)) { IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ANY, mac, - "unknown MLME request %d (reason %d)", op, reason); + "unknown MLME request %d (reason: %d (%s))", op, reason, + ieee80211_reason_to_string(reason)); } else if (reason == IEEE80211_STATUS_SUCCESS) { IEEE80211_NOTE_MAC(vap, ops[op].mask, mac, "station %s via MLME", ops[op].opstr); } else { IEEE80211_NOTE_MAC(vap, ops[op].mask, mac, - "station %s via MLME (reason %d)", ops[op].opstr, reason); + "station %s via MLME (reason: %d (%s))", ops[op].opstr, + reason, ieee80211_reason_to_string(reason)); } #endif /* IEEE80211_DEBUG */ } diff --git a/sys/net80211/ieee80211_mesh.c b/sys/net80211/ieee80211_mesh.c index 1ee3f0b505ea..c48c2f3a0940 100644 --- a/sys/net80211/ieee80211_mesh.c +++ b/sys/net80211/ieee80211_mesh.c @@ -2856,8 +2856,8 @@ mesh_send_action_meshpeering_close(struct ieee80211_node *ni, uint8_t *frm; IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, ni, - "send PEER CLOSE action: localid 0x%x, peerid 0x%x reason %d", - args[0], args[1], args[2]); + "send PEER CLOSE action: localid 0x%x, peerid 0x%x reason %d (%s)", + args[0], args[1], args[2], ieee80211_reason_to_string(args[2])); IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", __func__, __LINE__, diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c index a7e913efd93f..532317964a37 100644 --- a/sys/net80211/ieee80211_output.c +++ b/sys/net80211/ieee80211_output.c @@ -2317,7 +2317,8 @@ ieee80211_send_mgmt(struct ieee80211_node *ni, int type, int arg) case IEEE80211_FC0_SUBTYPE_DEAUTH: IEEE80211_NOTE(vap, IEEE80211_MSG_AUTH, ni, - "send station deauthenticate (reason %d)", arg); + "send station deauthenticate (reason: %d (%s))", arg, + ieee80211_reason_to_string(arg)); m = ieee80211_getmgtframe(&frm, ic->ic_headroom + sizeof(struct ieee80211_frame), sizeof(uint16_t)); @@ -2537,7 +2538,8 @@ ieee80211_send_mgmt(struct ieee80211_node *ni, int type, int arg) case IEEE80211_FC0_SUBTYPE_DISASSOC: IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni, - "send station disassociate (reason %d)", arg); + "send station disassociate (reason: %d (%s))", arg, + ieee80211_reason_to_string(arg)); m = ieee80211_getmgtframe(&frm, ic->ic_headroom + sizeof(struct ieee80211_frame), sizeof(uint16_t)); diff --git a/sys/net80211/ieee80211_proto.c b/sys/net80211/ieee80211_proto.c index 2feb59a94f71..5301f975ef87 100644 --- a/sys/net80211/ieee80211_proto.c +++ b/sys/net80211/ieee80211_proto.c @@ -1,6 +1,7 @@ /*- * Copyright (c) 2001 Atsushi Onoe * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting + * Copyright (c) 2012 IEEE * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -101,6 +102,138 @@ const char *ieee80211_wme_acnames[] = { "WME_UPSD", }; + +/* + * Reason code descriptions were (mostly) obtained from + * IEEE Std 802.11-2012, pp. 442-445 Table 8-36. + */ +const char * +ieee80211_reason_to_string(uint16_t reason) +{ + switch (reason) { + case IEEE80211_REASON_UNSPECIFIED: + return ("unspecified"); + case IEEE80211_REASON_AUTH_EXPIRE: + return ("previous authentication is expired"); + case IEEE80211_REASON_AUTH_LEAVE: + return ("sending STA is leaving/has left IBSS or ESS"); + case IEEE80211_REASON_ASSOC_EXPIRE: + return ("disassociated due to inactivity"); + case IEEE80211_REASON_ASSOC_TOOMANY: + return ("too many associated STAs"); + case IEEE80211_REASON_NOT_AUTHED: + return ("class 2 frame received from nonauthenticated STA"); + case IEEE80211_REASON_NOT_ASSOCED: + return ("class 3 frame received from nonassociated STA"); + case IEEE80211_REASON_ASSOC_LEAVE: + return ("sending STA is leaving/has left BSS"); + case IEEE80211_REASON_ASSOC_NOT_AUTHED: + return ("STA requesting (re)association is not authenticated"); + case IEEE80211_REASON_DISASSOC_PWRCAP_BAD: + return ("information in the Power Capability element is " + "unacceptable"); + case IEEE80211_REASON_DISASSOC_SUPCHAN_BAD: + return ("information in the Supported Channels element is " + "unacceptable"); + case IEEE80211_REASON_IE_INVALID: + return ("invalid element"); + case IEEE80211_REASON_MIC_FAILURE: + return ("MIC failure"); + case IEEE80211_REASON_4WAY_HANDSHAKE_TIMEOUT: + return ("4-Way handshake timeout"); + case IEEE80211_REASON_GROUP_KEY_UPDATE_TIMEOUT: + return ("group key update timeout"); + case IEEE80211_REASON_IE_IN_4WAY_DIFFERS: + return ("element in 4-Way handshake different from " + "(re)association request/probe response/beacon frame"); + case IEEE80211_REASON_GROUP_CIPHER_INVALID: + return ("invalid group cipher"); + case IEEE80211_REASON_PAIRWISE_CIPHER_INVALID: + return ("invalid pairwise cipher"); + case IEEE80211_REASON_AKMP_INVALID: + return ("invalid AKMP"); + case IEEE80211_REASON_UNSUPP_RSN_IE_VERSION: + return ("unsupported version in RSN IE"); + case IEEE80211_REASON_INVALID_RSN_IE_CAP: + return ("invalid capabilities in RSN IE"); + case IEEE80211_REASON_802_1X_AUTH_FAILED: + return ("IEEE 802.1X authentication failed"); + case IEEE80211_REASON_CIPHER_SUITE_REJECTED: + return ("cipher suite rejected because of the security " + "policy"); + case IEEE80211_REASON_UNSPECIFIED_QOS: + return ("unspecified (QoS-related)"); + case IEEE80211_REASON_INSUFFICIENT_BW: + return ("QoS AP lacks sufficient bandwidth for this QoS STA"); + case IEEE80211_REASON_TOOMANY_FRAMES: + return ("too many frames need to be acknowledged"); + case IEEE80211_REASON_OUTSIDE_TXOP: + return ("STA is transmitting outside the limits of its TXOPs"); + case IEEE80211_REASON_LEAVING_QBSS: + return ("requested from peer STA (the STA is " + "resetting/leaving the BSS)"); + case IEEE80211_REASON_BAD_MECHANISM: + return ("requested from peer STA (it does not want to use " + "the mechanism)"); + case IEEE80211_REASON_SETUP_NEEDED: + return ("requested from peer STA (setup is required for the " + "used mechanism)"); + case IEEE80211_REASON_TIMEOUT: + return ("requested from peer STA (timeout)"); + case IEEE80211_REASON_PEER_LINK_CANCELED: + return ("SME cancels the mesh peering instance (not related " + "to the maximum number of peer mesh STAs)"); + case IEEE80211_REASON_MESH_MAX_PEERS: + return ("maximum number of peer mesh STAs was reached"); + case IEEE80211_REASON_MESH_CPVIOLATION: + return ("the received information violates the Mesh " + "Configuration policy configured in the mesh STA " + "profile"); + case IEEE80211_REASON_MESH_CLOSE_RCVD: + return ("the mesh STA has received a Mesh Peering Close " + "message requesting to close the mesh peering"); + case IEEE80211_REASON_MESH_MAX_RETRIES: + return ("the mesh STA has resent dot11MeshMaxRetries Mesh " + "Peering Open messages, without receiving a Mesh " + "Peering Confirm message"); + case IEEE80211_REASON_MESH_CONFIRM_TIMEOUT: + return ("the confirmTimer for the mesh peering instance times " + "out"); + case IEEE80211_REASON_MESH_INVALID_GTK: + return ("the mesh STA fails to unwrap the GTK or the values " + "in the wrapped contents do not match"); + case IEEE80211_REASON_MESH_INCONS_PARAMS: + return ("the mesh STA receives inconsistent information about " + "the mesh parameters between Mesh Peering Management " + "frames"); + case IEEE80211_REASON_MESH_INVALID_SECURITY: + return ("the mesh STA fails the authenticated mesh peering " + "exchange because due to failure in selecting " + "pairwise/group ciphersuite"); + case IEEE80211_REASON_MESH_PERR_NO_PROXY: + return ("the mesh STA does not have proxy information for " + "this external destination"); + case IEEE80211_REASON_MESH_PERR_NO_FI: + return ("the mesh STA does not have forwarding information " + "for this destination"); + case IEEE80211_REASON_MESH_PERR_DEST_UNREACH: + return ("the mesh STA determines that the link to the next " + "hop of an active path in its forwarding information " + "is no longer usable"); + case IEEE80211_REASON_MESH_MAC_ALRDY_EXISTS_MBSS: + return ("the MAC address of the STA already exists in the " + "mesh BSS"); + case IEEE80211_REASON_MESH_CHAN_SWITCH_REG: + return ("the mesh STA performs channel switch to meet " + "regulatory requirements"); + case IEEE80211_REASON_MESH_CHAN_SWITCH_UNSPEC: + return ("the mesh STA performs channel switch with " + "unspecified reason"); + default: + return ("reserved/unknown"); + } +} + static void beacon_miss(void *, int); static void beacon_swmiss(void *, int); static void parent_updown(void *, int); diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h index 88633e7f2767..607e4b67a190 100644 --- a/sys/net80211/ieee80211_proto.h +++ b/sys/net80211/ieee80211_proto.h @@ -51,6 +51,8 @@ extern const char *ieee80211_mgt_subtype_name[]; extern const char *ieee80211_phymode_name[IEEE80211_MODE_MAX]; extern const int ieee80211_opcap[IEEE80211_OPMODE_MAX]; +const char *ieee80211_reason_to_string(uint16_t); + void ieee80211_proto_attach(struct ieee80211com *); void ieee80211_proto_detach(struct ieee80211com *); void ieee80211_proto_vattach(struct ieee80211vap *); diff --git a/sys/net80211/ieee80211_sta.c b/sys/net80211/ieee80211_sta.c index fa3cc68874e2..0c0eb13cd596 100644 --- a/sys/net80211/ieee80211_sta.c +++ b/sys/net80211/ieee80211_sta.c @@ -1788,7 +1788,8 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, int subtype, IEEE80211_NODE_STAT(ni, rx_deauth); IEEE80211_NOTE(vap, IEEE80211_MSG_AUTH, ni, - "recv deauthenticate (reason %d)", reason); + "recv deauthenticate (reason: %d (%s))", reason, + ieee80211_reason_to_string(reason)); ieee80211_new_state(vap, IEEE80211_S_AUTH, (reason << 8) | IEEE80211_FC0_SUBTYPE_DEAUTH); break; @@ -1821,7 +1822,8 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, int subtype, IEEE80211_NODE_STAT(ni, rx_disassoc); IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni, - "recv disassociate (reason %d)", reason); + "recv disassociate (reason: %d (%s))", reason, + ieee80211_reason_to_string(reason)); ieee80211_new_state(vap, IEEE80211_S_ASSOC, 0); break; }