summaryrefslogtreecommitdiff
path: root/sys/net80211/ieee80211_input.c
diff options
context:
space:
mode:
authorDamien Bergamini <damien@cvs.openbsd.org>2008-09-27 15:00:09 +0000
committerDamien Bergamini <damien@cvs.openbsd.org>2008-09-27 15:00:09 +0000
commit5f302c06db0af70022a22dff119bab0838242f86 (patch)
treeaf7866c1af4bf7a55e6309742db185452b8fb9f0 /sys/net80211/ieee80211_input.c
parent9a51adf9e1f95367147c0432825cb7dbf90d57f2 (diff)
Add some inline functions to test the presence of optional 802.11
header fields (Sequence Control, Address 4, QoS Control, +HTC) and use them where appropriate. Add ieee80211_get_qos() inline function to extract the QoS control field of an 802.11 header instead of duplicating the same scary code everywhere (the location of this field depends on the presence of an Address 4 field). Export ieee80211_up_to_ac() so that drivers can select the access category to use based on the TID subfield of the QoS Control field. Define more QoS-related bits for the RSN Capabilities field of RSN IE (will be used later).
Diffstat (limited to 'sys/net80211/ieee80211_input.c')
-rw-r--r--sys/net80211/ieee80211_input.c49
1 files changed, 17 insertions, 32 deletions
diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c
index a98174527c0..38428f009a0 100644
--- a/sys/net80211/ieee80211_input.c
+++ b/sys/net80211/ieee80211_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee80211_input.c,v 1.104 2008/09/01 19:41:10 damien Exp $ */
+/* $OpenBSD: ieee80211_input.c,v 1.105 2008/09/27 15:00:08 damien Exp $ */
/*-
* Copyright (c) 2001 Atsushi Onoe
@@ -102,24 +102,19 @@ void ieee80211_recv_action(struct ieee80211com *, struct mbuf *,
* Retrieve the length in bytes of a 802.11 header.
*/
u_int
-ieee80211_get_hdrlen(const void *data)
+ieee80211_get_hdrlen(const struct ieee80211_frame *wh)
{
- const u_int8_t *fc = data;
- u_int size = sizeof(struct ieee80211_frame);
-
- /* NB: doesn't work with control frames */
- KASSERT((fc[0] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_CTL);
-
- if ((fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS)
- size += IEEE80211_ADDR_LEN; /* i_addr4 */
- if ((fc[0] & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_QOS)) ==
- (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS)) {
- size += sizeof(u_int16_t); /* i_qos */
- if (fc[1] & IEEE80211_FC1_ORDER)
- size += sizeof(u_int32_t); /* i_ht */
- } else if ((fc[0] & IEEE80211_FC0_TYPE_MASK) ==
- IEEE80211_FC0_TYPE_MGT && (fc[1] & IEEE80211_FC1_ORDER))
- size += sizeof(u_int32_t); /* i_ht */
+ u_int size = sizeof(*wh);
+
+ /* NB: does not work with control frames */
+ KASSERT(ieee80211_has_seq(wh));
+
+ if (ieee80211_has_addr4(wh))
+ size += IEEE80211_ADDR_LEN; /* i_addr4 */
+ if (ieee80211_has_qos(wh))
+ size += sizeof(u_int16_t); /* i_qos */
+ if (ieee80211_has_htc(wh))
+ size += sizeof(u_int32_t); /* i_ht */
return size;
}
@@ -181,22 +176,12 @@ ieee80211_input(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni,
}
}
/* check and save sequence control field, if present */
- if (ic->ic_state != IEEE80211_S_SCAN &&
- type != IEEE80211_FC0_TYPE_CTL) {
+ if (ieee80211_has_seq(wh) &&
+ ic->ic_state != IEEE80211_S_SCAN) {
nrxseq = letoh16(*(u_int16_t *)wh->i_seq) >>
IEEE80211_SEQ_SEQ_SHIFT;
- if ((wh->i_fc[0] &
- (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_QOS)) ==
- (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS)) {
- if (dir == IEEE80211_FC1_DIR_DSTODS) {
- struct ieee80211_qosframe_addr4 *qwh4 =
- (struct ieee80211_qosframe_addr4 *)wh;
- tid = qwh4->i_qos[0] & 0x0f;
- } else {
- struct ieee80211_qosframe *qwh =
- (struct ieee80211_qosframe *)wh;
- tid = qwh->i_qos[0] & 0x0f;
- }
+ if (ieee80211_has_qos(wh)) {
+ tid = ieee80211_get_qos(wh) & IEEE80211_QOS_TID;
orxseq = &ni->ni_qos_rxseqs[tid];
} else
orxseq = &ni->ni_rxseq;