summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/net80211/ieee80211_input.h
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/sys/net80211/ieee80211_input.h')
-rw-r--r--freebsd/sys/net80211/ieee80211_input.h72
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_ */