Commit 33e5a2f7 authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville

wireless: update radiotap parser

Upstream radiotap has adopted the namespace
proposal David Young made and I then took care
of, for which I had adapted the radiotap parser
as a library outside the kernel. This brings
the in-kernel parser up to speed.
Signed-off-by: default avatarJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 69068036
...@@ -1561,37 +1561,82 @@ ieee80211_get_response_rate(struct ieee80211_supported_band *sband, ...@@ -1561,37 +1561,82 @@ ieee80211_get_response_rate(struct ieee80211_supported_band *sband,
* Documentation in Documentation/networking/radiotap-headers.txt * Documentation in Documentation/networking/radiotap-headers.txt
*/ */
struct radiotap_align_size {
uint8_t align:4, size:4;
};
struct ieee80211_radiotap_namespace {
const struct radiotap_align_size *align_size;
int n_bits;
uint32_t oui;
uint8_t subns;
};
struct ieee80211_radiotap_vendor_namespaces {
const struct ieee80211_radiotap_namespace *ns;
int n_ns;
};
/** /**
* struct ieee80211_radiotap_iterator - tracks walk thru present radiotap args * struct ieee80211_radiotap_iterator - tracks walk thru present radiotap args
* @rtheader: pointer to the radiotap header we are walking through * @this_arg_index: index of current arg, valid after each successful call
* @max_length: length of radiotap header in cpu byte ordering * to ieee80211_radiotap_iterator_next()
* @this_arg_index: IEEE80211_RADIOTAP_... index of current arg * @this_arg: pointer to current radiotap arg; it is valid after each
* @this_arg: pointer to current radiotap arg * call to ieee80211_radiotap_iterator_next() but also after
* @arg_index: internal next argument index * ieee80211_radiotap_iterator_init() where it will point to
* @arg: internal next argument pointer * the beginning of the actual data portion
* @next_bitmap: internal pointer to next present u32 * @this_arg_size: length of the current arg, for convenience
* @bitmap_shifter: internal shifter for curr u32 bitmap, b0 set == arg present * @current_namespace: pointer to the current namespace definition
* (or internally %NULL if the current namespace is unknown)
* @is_radiotap_ns: indicates whether the current namespace is the default
* radiotap namespace or not
*
* @overrides: override standard radiotap fields
* @n_overrides: number of overrides
*
* @_rtheader: pointer to the radiotap header we are walking through
* @_max_length: length of radiotap header in cpu byte ordering
* @_arg_index: next argument index
* @_arg: next argument pointer
* @_next_bitmap: internal pointer to next present u32
* @_bitmap_shifter: internal shifter for curr u32 bitmap, b0 set == arg present
* @_vns: vendor namespace definitions
* @_next_ns_data: beginning of the next namespace's data
* @_reset_on_ext: internal; reset the arg index to 0 when going to the
* next bitmap word
*
* Describes the radiotap parser state. Fields prefixed with an underscore
* must not be used by users of the parser, only by the parser internally.
*/ */
struct ieee80211_radiotap_iterator { struct ieee80211_radiotap_iterator {
struct ieee80211_radiotap_header *rtheader; struct ieee80211_radiotap_header *_rtheader;
int max_length; const struct ieee80211_radiotap_vendor_namespaces *_vns;
const struct ieee80211_radiotap_namespace *current_namespace;
unsigned char *_arg, *_next_ns_data;
uint32_t *_next_bitmap;
unsigned char *this_arg;
int this_arg_index; int this_arg_index;
u8 *this_arg; int this_arg_size;
int arg_index; int is_radiotap_ns;
u8 *arg;
__le32 *next_bitmap; int _max_length;
u32 bitmap_shifter; int _arg_index;
uint32_t _bitmap_shifter;
int _reset_on_ext;
}; };
extern int ieee80211_radiotap_iterator_init( extern int ieee80211_radiotap_iterator_init(
struct ieee80211_radiotap_iterator *iterator, struct ieee80211_radiotap_iterator *iterator,
struct ieee80211_radiotap_header *radiotap_header, struct ieee80211_radiotap_header *radiotap_header,
int max_length); int max_length, const struct ieee80211_radiotap_vendor_namespaces *vns);
extern int ieee80211_radiotap_iterator_next( extern int ieee80211_radiotap_iterator_next(
struct ieee80211_radiotap_iterator *iterator); struct ieee80211_radiotap_iterator *iterator);
extern const unsigned char rfc1042_header[6]; extern const unsigned char rfc1042_header[6];
extern const unsigned char bridge_tunnel_header[6]; extern const unsigned char bridge_tunnel_header[6];
......
...@@ -198,6 +198,10 @@ enum ieee80211_radiotap_type { ...@@ -198,6 +198,10 @@ enum ieee80211_radiotap_type {
IEEE80211_RADIOTAP_TX_FLAGS = 15, IEEE80211_RADIOTAP_TX_FLAGS = 15,
IEEE80211_RADIOTAP_RTS_RETRIES = 16, IEEE80211_RADIOTAP_RTS_RETRIES = 16,
IEEE80211_RADIOTAP_DATA_RETRIES = 17, IEEE80211_RADIOTAP_DATA_RETRIES = 17,
/* valid in every it_present bitmap, even vendor namespaces */
IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE = 29,
IEEE80211_RADIOTAP_VENDOR_NAMESPACE = 30,
IEEE80211_RADIOTAP_EXT = 31 IEEE80211_RADIOTAP_EXT = 31
}; };
......
...@@ -1010,7 +1010,8 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, ...@@ -1010,7 +1010,8 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
(struct ieee80211_radiotap_header *) skb->data; (struct ieee80211_radiotap_header *) skb->data;
struct ieee80211_supported_band *sband; struct ieee80211_supported_band *sband;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len); int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len,
NULL);
sband = tx->local->hw.wiphy->bands[tx->channel->band]; sband = tx->local->hw.wiphy->bands[tx->channel->band];
...@@ -1046,7 +1047,7 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, ...@@ -1046,7 +1047,7 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
* because it will be recomputed and added * because it will be recomputed and added
* on transmission * on transmission
*/ */
if (skb->len < (iterator.max_length + FCS_LEN)) if (skb->len < (iterator._max_length + FCS_LEN))
return false; return false;
skb_trim(skb, skb->len - FCS_LEN); skb_trim(skb, skb->len - FCS_LEN);
...@@ -1073,10 +1074,10 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, ...@@ -1073,10 +1074,10 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
/* /*
* remove the radiotap header * remove the radiotap header
* iterator->max_length was sanity-checked against * iterator->_max_length was sanity-checked against
* skb->len by iterator init * skb->len by iterator init
*/ */
skb_pull(skb, iterator.max_length); skb_pull(skb, iterator._max_length);
return true; return true;
} }
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment