diff options
Diffstat (limited to 'freebsd/sys/net80211/ieee80211_input.h')
-rw-r--r-- | freebsd/sys/net80211/ieee80211_input.h | 72 |
1 files changed, 39 insertions, 33 deletions
diff --git a/freebsd/sys/net80211/ieee80211_input.h b/freebsd/sys/net80211/ieee80211_input.h index b90f46a1..6fb0d707 100644 --- a/freebsd/sys/net80211/ieee80211_input.h +++ b/freebsd/sys/net80211/ieee80211_input.h @@ -62,8 +62,7 @@ void ieee80211_ssid_mismatch(struct ieee80211vap *, const char *tag, memcmp((_ssid) + 2, (_ni)->ni_essid, (_ssid)[1]) != 0)) { \ if (ieee80211_msg_input(vap)) \ ieee80211_ssid_mismatch(vap, \ - ieee80211_mgt_subtype_name[subtype >> \ - IEEE80211_FC0_SUBTYPE_SHIFT], \ + ieee80211_mgt_subtype_name(subtype), \ wh->i_addr2, _ssid); \ vap->iv_stats.is_rx_ssidmismatch++; \ _action; \ @@ -80,70 +79,58 @@ void ieee80211_ssid_mismatch(struct ieee80211vap *, const char *tag, } while (0) #endif /* !IEEE80211_DEBUG */ -/* unalligned little endian access */ -#define LE_READ_2(p) \ - ((uint16_t) \ - ((((const uint8_t *)(p))[0] ) | \ - (((const uint8_t *)(p))[1] << 8))) -#define LE_READ_4(p) \ - ((uint32_t) \ - ((((const uint8_t *)(p))[0] ) | \ - (((const uint8_t *)(p))[1] << 8) | \ - (((const uint8_t *)(p))[2] << 16) | \ - (((const uint8_t *)(p))[3] << 24))) +#include <sys/endian.h> /* For le16toh() / le32dec() */ static __inline int iswpaoui(const uint8_t *frm) { - return frm[1] > 3 && LE_READ_4(frm+2) == ((WPA_OUI_TYPE<<24)|WPA_OUI); + return frm[1] > 3 && le32dec(frm+2) == ((WPA_OUI_TYPE<<24)|WPA_OUI); } static __inline int iswmeoui(const uint8_t *frm) { - return frm[1] > 3 && LE_READ_4(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI); + return frm[1] > 3 && le32dec(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI); } static __inline int iswmeparam(const uint8_t *frm) { - return frm[1] > 5 && LE_READ_4(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI) && + return frm[1] > 5 && le32dec(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI) && frm[6] == WME_PARAM_OUI_SUBTYPE; } static __inline int iswmeinfo(const uint8_t *frm) { - return frm[1] > 5 && LE_READ_4(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI) && + return frm[1] > 5 && le32dec(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI) && frm[6] == WME_INFO_OUI_SUBTYPE; } static __inline int isatherosoui(const uint8_t *frm) { - return frm[1] > 3 && LE_READ_4(frm+2) == ((ATH_OUI_TYPE<<24)|ATH_OUI); + return frm[1] > 3 && le32dec(frm+2) == ((ATH_OUI_TYPE<<24)|ATH_OUI); } static __inline int istdmaoui(const uint8_t *frm) { - return frm[1] > 3 && LE_READ_4(frm+2) == ((TDMA_OUI_TYPE<<24)|TDMA_OUI); + return frm[1] > 3 && le32dec(frm+2) == ((TDMA_OUI_TYPE<<24)|TDMA_OUI); } static __inline int ishtcapoui(const uint8_t *frm) { - return frm[1] > 3 && LE_READ_4(frm+2) == ((BCM_OUI_HTCAP<<24)|BCM_OUI); + return frm[1] > 3 && le32dec(frm+2) == ((BCM_OUI_HTCAP<<24)|BCM_OUI); } static __inline int ishtinfooui(const uint8_t *frm) { - return frm[1] > 3 && LE_READ_4(frm+2) == ((BCM_OUI_HTINFO<<24)|BCM_OUI); + return frm[1] > 3 && le32dec(frm+2) == ((BCM_OUI_HTINFO<<24)|BCM_OUI); } -#include <sys/endian.h> /* For le16toh() */ - /* * Check the current frame sequence number against the current TID * state and return whether it's in sequence or should be dropped. @@ -164,23 +151,28 @@ ishtinfooui(const uint8_t *frm) * but a retransmit since the initial packet didn't make it. */ static __inline int -ieee80211_check_rxseq(struct ieee80211_node *ni, struct ieee80211_frame *wh) +ieee80211_check_rxseq(struct ieee80211_node *ni, struct ieee80211_frame *wh, + uint8_t *bssid) { #define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0) #define SEQ_EQ(a,b) ((int)((a)-(b)) == 0) -#define HAS_SEQ(type) ((type & 0x4) == 0) #define SEQNO(a) ((a) >> IEEE80211_SEQ_SEQ_SHIFT) #define FRAGNO(a) ((a) & IEEE80211_SEQ_FRAG_MASK) + struct ieee80211vap *vap = ni->ni_vap; uint16_t rxseq; - uint8_t type; + uint8_t type, subtype; uint8_t tid; struct ieee80211_rx_ampdu *rap; rxseq = le16toh(*(uint16_t *)wh->i_seq); type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; + subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; - /* Types with no sequence number are always treated valid */ - if (! HAS_SEQ(type)) + /* + * Types with no sequence number (or QoS (+)Null frames) + * are always treated valid. + */ + if (! IEEE80211_HAS_SEQ(type, subtype)) return 1; tid = ieee80211_gettid(wh); @@ -195,7 +187,7 @@ ieee80211_check_rxseq(struct ieee80211_node *ni, struct ieee80211_frame *wh) /* HT nodes currently doing RX AMPDU are always valid */ if ((ni->ni_flags & IEEE80211_NODE_HT) && (rap->rxa_flags & IEEE80211_AGGR_RUNNING)) - return 1; + goto ok; } /* @@ -213,7 +205,7 @@ ieee80211_check_rxseq(struct ieee80211_node *ni, struct ieee80211_frame *wh) */ if (SEQ_EQ(rxseq, ni->ni_rxseqs[tid]) && (wh->i_fc[1] & IEEE80211_FC1_RETRY)) - return 0; + goto fail; /* * Treat any subsequent frame as fine if the last seen frame * is 4095 and it's not a retransmit for the same sequence @@ -221,7 +213,7 @@ ieee80211_check_rxseq(struct ieee80211_node *ni, struct ieee80211_frame *wh) * fragments w/ sequence number 4095. It shouldn't be seen * in practice, but see the comment above for further info. */ - return 1; + goto ok; } /* @@ -230,12 +222,25 @@ ieee80211_check_rxseq(struct ieee80211_node *ni, struct ieee80211_frame *wh) */ if ((wh->i_fc[1] & IEEE80211_FC1_RETRY) && SEQ_LEQ(rxseq, ni->ni_rxseqs[tid])) - return 0; + goto fail; + +ok: + ni->ni_rxseqs[tid] = rxseq; return 1; + +fail: + /* duplicate, discard */ + IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, bssid, "duplicate", + "seqno <%u,%u> fragno <%u,%u> tid %u", + SEQNO(rxseq), SEQNO(ni->ni_rxseqs[tid]), + FRAGNO(rxseq), FRAGNO(ni->ni_rxseqs[tid]), tid); + vap->iv_stats.is_rx_dup++; + IEEE80211_NODE_STAT(ni, rx_dup); + + return 0; #undef SEQ_LEQ #undef SEQ_EQ -#undef HAS_SEQ #undef SEQNO #undef FRAGNO } @@ -253,6 +258,7 @@ void ieee80211_send_error(struct ieee80211_node *, const uint8_t mac[IEEE80211_ADDR_LEN], int subtype, int arg); int ieee80211_alloc_challenge(struct ieee80211_node *); int ieee80211_parse_beacon(struct ieee80211_node *, struct mbuf *, + struct ieee80211_channel *, struct ieee80211_scanparams *); int ieee80211_parse_action(struct ieee80211_node *, struct mbuf *); #endif /* _NET80211_IEEE80211_INPUT_H_ */ |