summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorDamien Bergamini <damien@cvs.openbsd.org>2007-08-23 16:59:33 +0000
committerDamien Bergamini <damien@cvs.openbsd.org>2007-08-23 16:59:33 +0000
commitec2abfcab406c3cde7bb626c18e18f38838d533e (patch)
treec9dd32a5797513bdf924ae2c3b323902f507d8fc /sys
parentc84959746f5ee4d419f7271daada4eeb9febca49 (diff)
add ieee80211_get_hdrlen() to compute the size of the 802.11 header
of a management or data frame (check if the i_qos, i_ht or i_addr4 are present).
Diffstat (limited to 'sys')
-rw-r--r--sys/net80211/ieee80211_input.c27
-rw-r--r--sys/net80211/ieee80211_proto.h3
2 files changed, 28 insertions, 2 deletions
diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c
index 89e9dd5ce5e..69d97a98df8 100644
--- a/sys/net80211/ieee80211_input.c
+++ b/sys/net80211/ieee80211_input.c
@@ -1,5 +1,5 @@
/* $NetBSD: ieee80211_input.c,v 1.24 2004/05/31 11:12:24 dyoung Exp $ */
-/* $OpenBSD: ieee80211_input.c,v 1.65 2007/08/23 16:53:51 damien Exp $ */
+/* $OpenBSD: ieee80211_input.c,v 1.66 2007/08/23 16:59:32 damien Exp $ */
/*-
* Copyright (c) 2001 Atsushi Onoe
* Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting
@@ -116,6 +116,31 @@ void ieee80211_recv_eapol_key_req(struct ieee80211com *,
const struct ieee80211_eapol_key *, struct ieee80211_node *);
/*
+ * Retrieve the length in bytes of a 802.11 header.
+ */
+u_int
+ieee80211_get_hdrlen(const void *data)
+{
+ 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 */
+ return size;
+}
+
+/*
* Process a received frame. The node associated with the sender
* should be supplied. If nothing was found in the node table then
* the caller is assumed to supply a reference to ic_bss instead.
diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h
index a778c85a553..fd43c0c49a3 100644
--- a/sys/net80211/ieee80211_proto.h
+++ b/sys/net80211/ieee80211_proto.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee80211_proto.h,v 1.26 2007/08/03 16:51:06 damien Exp $ */
+/* $OpenBSD: ieee80211_proto.h,v 1.27 2007/08/23 16:59:32 damien Exp $ */
/* $NetBSD: ieee80211_proto.h,v 1.3 2003/10/13 04:23:56 dyoung Exp $ */
/*-
@@ -57,6 +57,7 @@ extern void ieee80211_proto_attach(struct ifnet *);
extern void ieee80211_proto_detach(struct ifnet *);
struct ieee80211_node;
+extern u_int ieee80211_get_hdrlen(const void *);
extern void ieee80211_input(struct ifnet *, struct mbuf *,
struct ieee80211_node *, int, u_int32_t);
extern int ieee80211_output(struct ifnet *, struct mbuf *, struct sockaddr *,