[Click] [RFC] Update radiotap parser

Eddie Kohler kohler at cs.ucla.edu
Thu Jul 14 10:47:27 EDT 2011


On 07/14/2011 12:42 AM, Roberto Riggio wrote:
> Hi,
>
> well since there are other general purpose functions like md5.o etc I thought
> that the right place for radiotap.o was in the userlevel makefile. I could
> move the code in the wifi elements package and make it an ELEMENT_PROVIDES().

That sounds like the right idea.

Eddie



>
> Yes, there could be bugs, although I'm using it on our mesh network for the
> last year an everything works fine, frame are delivered to the drivers and the
> re-trasnmission count is send back for tx feedback frame and for incoming
> frames. Tested with madwifi, ath9k (patched).
>
> R.
>
> Il 14/07/2011 01:28, Eddie Kohler ha scritto:
>> Hi Roberto,
>>
>> I'd like to merge something like this, but including radiotap.o in EVERY
>> click build is a no go. Why not make it an ELEMENT_PROVIDES() type
>> library? I also worry that this change might be disruptive to other users.
>>
>> Eddie
>>
>>
>> On 4/11/11 6:16 AM, Roberto Riggio wrote:
>>> Hi,
>>>
>>> this patch updates the click radiotap parser. The code is taken directly
>>> from the upstream
>>> project and allows to parse radiotap header with extended bitmap
>>> presence field and with
>>> vendor extension.
>>>
>>> The main advantage is that now the multi rate retry chain is supported
>>> by both radiotap{encap, decap}
>>> elements (whose updates are included in this patch), so setting the
>>> rate{1,2,3} fields in
>>> the click_wifi_extra struct results in a properly formed radiotap header.
>>>
>>> I've also included a few warnings for wifi-related elements.
>>>
>>> R.
>>>
>>> --
>>> diff -urN --exclude .git --exclude conf --exclude diffserv --exclude
>>> ethernet --exclude secaggr --exclude wing --exclude availablechannels
>>> --exclude availablerates
>>> click.upstream/elements/wifi/ap/associationresponder.cc
>>> click/elements/wifi/ap/associationresponder.cc
>>> --- click.upstream/elements/wifi/ap/associationresponder.cc
>>> 2011-04-11 11:52:49.785608001 +0200
>>> +++ click/elements/wifi/ap/associationresponder.cc 2011-03-24
>>> 20:50:55.691217001 +0100
>>> @@ -270,9 +270,10 @@
>>> memcpy(w->i_addr2, bssid.data(), 6);
>>> memcpy(w->i_addr3, bssid.data(), 6);
>>>
>>> -
>>> - *(uint16_t *) w->i_dur = 0;
>>> - *(uint16_t *) w->i_seq = 0;
>>> + uint16_t * d16 = (uint16_t *) w->i_dur;
>>> + uint16_t * s16 = (uint16_t *) w->i_seq;
>>> + *d16 = 0;
>>> + *s16 = 0;
>>>
>>> uint8_t *ptr = (uint8_t *) p->data() + sizeof(struct click_wifi);
>>> int actual_length = sizeof(struct click_wifi);
>>> @@ -354,8 +355,10 @@
>>> memcpy(w->i_addr3, bssid.data(), 6);
>>>
>>>
>>> - *(uint16_t *) w->i_dur = 0;
>>> - *(uint16_t *) w->i_seq = 0;
>>> + uint16_t * d16 = (uint16_t *) w->i_dur;
>>> + uint16_t * s16 = (uint16_t *) w->i_seq;
>>> + *d16 = 0;
>>> + *s16 = 0;
>>>
>>>
>>> uint8_t *ptr;
>>> diff -urN --exclude .git --exclude conf --exclude diffserv --exclude
>>> ethernet --exclude secaggr --exclude wing --exclude availablechannels
>>> --exclude availablerates click.upstream/elements/wifi/ap/beaconsource.cc
>>> click/elements/wifi/ap/beaconsource.cc
>>> --- click.upstream/elements/wifi/ap/beaconsource.cc 2011-04-11
>>> 11:52:49.785608001 +0200
>>> +++ click/elements/wifi/ap/beaconsource.cc 2011-03-24
>>> 20:50:55.691217001 +0100
>>> @@ -129,8 +129,10 @@
>>> memcpy(w->i_addr2, bssid.data(), 6);
>>> memcpy(w->i_addr3, bssid.data(), 6);
>>>
>>> - *(uint16_t *) w->i_dur = 0;
>>> - *(uint16_t *) w->i_seq = 0;
>>> + uint16_t * d16 = (uint16_t *) w->i_dur;
>>> + uint16_t * s16 = (uint16_t *) w->i_seq;
>>> + *d16 = 0;
>>> + *s16 = 0;
>>>
>>> uint8_t *ptr;
>>>
>>> diff -urN --exclude .git --exclude conf --exclude diffserv --exclude
>>> ethernet --exclude secaggr --exclude wing --exclude availablechannels
>>> --exclude availablerates
>>> click.upstream/elements/wifi/ap/openauthresponder.cc
>>> click/elements/wifi/ap/openauthresponder.cc
>>> --- click.upstream/elements/wifi/ap/openauthresponder.cc 2011-04-11
>>> 11:52:49.785608001 +0200
>>> +++ click/elements/wifi/ap/openauthresponder.cc 2011-03-24
>>> 20:50:55.691217001 +0100
>>> @@ -169,8 +169,10 @@
>>> memcpy(w->i_addr3, _winfo->_bssid.data(), 6);
>>>
>>>
>>> - *(uint16_t *) w->i_dur = 0;
>>> - *(uint16_t *) w->i_seq = 0;
>>> + uint16_t * d16 = (uint16_t *) w->i_dur;
>>> + uint16_t * s16 = (uint16_t *) w->i_seq;
>>> + *d16 = 0;
>>> + *s16 = 0;
>>>
>>> uint8_t *ptr;
>>>
>>> diff -urN --exclude .git --exclude conf --exclude diffserv --exclude
>>> ethernet --exclude secaggr --exclude wing --exclude availablechannels
>>> --exclude availablerates
>>> click.upstream/elements/wifi/ap/proberesponder.cc
>>> click/elements/wifi/ap/proberesponder.cc
>>> --- click.upstream/elements/wifi/ap/proberesponder.cc 2011-04-11
>>> 11:52:49.785608001 +0200
>>> +++ click/elements/wifi/ap/proberesponder.cc 2011-03-24
>>> 20:50:55.691217001 +0100
>>> @@ -214,8 +214,10 @@
>>> memcpy(w->i_addr3, _bssid.data(), 6);
>>>
>>>
>>> - *(uint16_t *) w->i_dur = 0;
>>> - *(uint16_t *) w->i_seq = 0;
>>> + uint16_t * d16 = (uint16_t *) w->i_dur;
>>> + uint16_t * s16 = (uint16_t *) w->i_seq;
>>> + *d16 = 0;
>>> + *s16 = 0;
>>>
>>> uint8_t *ptr;
>>>
>>> diff -urN --exclude .git --exclude conf --exclude diffserv --exclude
>>> ethernet --exclude secaggr --exclude wing --exclude availablechannels
>>> --exclude availablerates click.upstream/elements/wifi/printwifi.cc
>>> click/elements/wifi/printwifi.cc
>>> --- click.upstream/elements/wifi/printwifi.cc 2011-04-11
>>> 11:52:49.789608001 +0200
>>> +++ click/elements/wifi/printwifi.cc 2011-04-05 16:08:37.056939649 +0200
>>> @@ -308,7 +308,8 @@
>>> struct click_wifi_extra *ceh = WIFI_EXTRA_ANNO(p);
>>> int type = wh->i_fc[0]& WIFI_FC0_TYPE_MASK;
>>> int subtype = wh->i_fc[0]& WIFI_FC0_SUBTYPE_MASK;
>>> - int duration = cpu_to_le16(*(uint16_t *) wh->i_dur);
>>> + uint16_t *d16 = (uint16_t *) wh->i_dur;
>>> + int duration = cpu_to_le16(*d16);
>>> EtherAddress src;
>>> EtherAddress dst;
>>> EtherAddress bssid;
>>> @@ -506,8 +507,9 @@
>>> sa<< " ";
>>>
>>> if (p->length()>= sizeof(click_wifi)) {
>>> - uint16_t seq = le16_to_cpu(*(u_int16_t *)wh->i_seq)>>
>>> WIFI_SEQ_SEQ_SHIFT;
>>> - uint8_t frag = le16_to_cpu(*(u_int16_t *)wh->i_seq)&
>>> WIFI_SEQ_FRAG_MASK;
>>> + uint16_t *s16 = (uint16_t *) wh->i_seq;
>>> + uint16_t seq = le16_to_cpu(*s16)>> WIFI_SEQ_SEQ_SHIFT;
>>> + uint8_t frag = le16_to_cpu(*s16)& WIFI_SEQ_FRAG_MASK;
>>> sa<< "seq "<< (int) seq;
>>> if (frag || wh->i_fc[1]& WIFI_FC1_MORE_FRAG) {
>>> sa<< " frag "<< (int) frag;
>>> diff -urN --exclude .git --exclude conf --exclude diffserv --exclude
>>> ethernet --exclude secaggr --exclude wing --exclude availablechannels
>>> --exclude availablerates click.upstream/elements/wifi/radiotapdecap.cc
>>> click/elements/wifi/radiotapdecap.cc
>>> --- click.upstream/elements/wifi/radiotapdecap.cc 2011-04-11
>>> 11:52:49.789608001 +0200
>>> +++ click/elements/wifi/radiotapdecap.cc 2011-04-05
>>> 16:08:29.380939649 +0200
>>> @@ -21,80 +21,14 @@
>>> #include<click/confparse.hh>
>>> #include<click/error.hh>
>>> #include<click/glue.hh>
>>> +#include<click/packet_anno.hh>
>>> #include<clicknet/wifi.h>
>>> #include<clicknet/radiotap.h>
>>> -#include<click/packet_anno.hh>
>>> #include<clicknet/llc.h>
>>> -CLICK_DECLS
>>> -
>>> -#define NUM_RADIOTAP_ELEMENTS 18
>>> -
>>> -static const int radiotap_elem_to_bytes[NUM_RADIOTAP_ELEMENTS] =
>>> - {8, /* IEEE80211_RADIOTAP_TSFT */
>>> - 1, /* IEEE80211_RADIOTAP_FLAGS */
>>> - 1, /* IEEE80211_RADIOTAP_RATE */
>>> - 4, /* IEEE80211_RADIOTAP_CHANNEL */
>>> - 2, /* IEEE80211_RADIOTAP_FHSS */
>>> - 1, /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */
>>> - 1, /* IEEE80211_RADIOTAP_DBM_ANTNOISE */
>>> - 2, /* IEEE80211_RADIOTAP_LOCK_QUALITY */
>>> - 2, /* IEEE80211_RADIOTAP_TX_ATTENUATION */
>>> - 2, /* IEEE80211_RADIOTAP_DB_TX_ATTENUATION */
>>> - 1, /* IEEE80211_RADIOTAP_DBM_TX_POWER */
>>> - 1, /* IEEE80211_RADIOTAP_ANTENNA */
>>> - 1, /* IEEE80211_RADIOTAP_DB_ANTSIGNAL */
>>> - 1, /* IEEE80211_RADIOTAP_DB_ANTNOISE */
>>> - 2, /* IEEE80211_RADIOTAP_RX_FLAGS */
>>> - 2, /* IEEE80211_RADIOTAP_TX_FLAGS */
>>> - 1, /* IEEE80211_RADIOTAP_RTS_RETRIES */
>>> - 1, /* IEEE80211_RADIOTAP_DATA_RETRIES */
>>> - };
>>> -
>>> -static int rt_el_present(struct ieee80211_radiotap_header *th,
>>> u_int32_t element)
>>> -{
>>> - if (element> NUM_RADIOTAP_ELEMENTS)
>>> - return 0;
>>> - return le32_to_cpu(th->it_present)& (1<< element);
>>> -}
>>> -
>>> -static int rt_check_header(struct ieee80211_radiotap_header *th, int
>>> len)
>>> -{
>>> - int bytes = 0;
>>> - int x = 0;
>>> - if (th->it_version != 0) {
>>> - return 0;
>>> - }
>>> -
>>> - if (le16_to_cpu(th->it_len)< sizeof(struct
>>> ieee80211_radiotap_header)) {
>>> - return 0;
>>> - }
>>> -
>>> - for (x = 0; x< NUM_RADIOTAP_ELEMENTS; x++) {
>>> - if (rt_el_present(th, x))
>>> - bytes += radiotap_elem_to_bytes[x];
>>> - }
>>> -
>>> - if (le16_to_cpu(th->it_len)< sizeof(struct
>>> ieee80211_radiotap_header) + bytes) {
>>> - return 0;
>>> - }
>>> -
>>> - if (le16_to_cpu(th->it_len)> len) {
>>> - return 0;
>>> - }
>>> -
>>> - return 1;
>>> -}
>>> -
>>> -static u_int8_t *rt_el_offset(struct ieee80211_radiotap_header *th,
>>> u_int32_t element) {
>>> - unsigned int x = 0;
>>> - u_int8_t *offset = ((u_int8_t *) th) +
>>> sizeof(ieee80211_radiotap_header);
>>> - for (x = 0; x< NUM_RADIOTAP_ELEMENTS&& x< element; x++) {
>>> - if (rt_el_present(th, x))
>>> - offset += radiotap_elem_to_bytes[x];
>>> - }
>>> -
>>> - return offset;
>>> +extern "C" {
>>> + #include<click/radiotap_iter.h>
>>> }
>>> +CLICK_DECLS
>>>
>>> RadiotapDecap::RadiotapDecap()
>>> {
>>> @@ -104,114 +38,86 @@
>>> {
>>> }
>>>
>>> -int
>>> -RadiotapDecap::configure(Vector<String> &conf, ErrorHandler *errh)
>>> -{
>>> -
>>> - _debug = false;
>>> - if (cp_va_kparse(conf, this, errh,
>>> - "DEBUG", 0, cpBool,&_debug,
>>> - cpEnd)< 0)
>>> - return -1;
>>> - return 0;
>>> -}
>>> -
>>> Packet *
>>> -RadiotapDecap::simple_action(Packet *p)
>>> -{
>>> +RadiotapDecap::simple_action(Packet *p) {
>>> +
>>> struct ieee80211_radiotap_header *th = (struct
>>> ieee80211_radiotap_header *) p->data();
>>> + struct ieee80211_radiotap_iterator iter;
>>> struct click_wifi_extra *ceh = WIFI_EXTRA_ANNO(p);
>>> - if (rt_check_header(th, p->length())) {
>>> - memset((void*)ceh, 0, sizeof(struct click_wifi_extra));
>>> - ceh->magic = WIFI_EXTRA_MAGIC;
>>>
>>> - if (rt_el_present(th, IEEE80211_RADIOTAP_FLAGS)) {
>>> - u_int8_t flags = *((u_int8_t *) rt_el_offset(th,
>>> IEEE80211_RADIOTAP_FLAGS));
>>> + int err = ieee80211_radiotap_iterator_init(&iter, th, p->length(), 0);
>>> +
>>> + if (err) {
>>> + click_chatter("%{element} :: %s :: malformed radiotap header
>>> (init returns %d)", this, __func__, err);
>>> + goto drop;
>>> + }
>>> +
>>> + memset((void*)ceh, 0, sizeof(struct click_wifi_extra));
>>> + ceh->magic = WIFI_EXTRA_MAGIC;
>>> +
>>> + while (!(err = ieee80211_radiotap_iterator_next(&iter))) {
>>> + u_int16_t flags;
>>> + switch (iter.this_arg_index) {
>>> + case IEEE80211_RADIOTAP_FLAGS:
>>> + flags = le16_to_cpu(*(uint16_t *)iter.this_arg);
>>> if (flags& IEEE80211_RADIOTAP_F_DATAPAD) {
>>> ceh->pad = 1;
>>> }
>>> if (flags& IEEE80211_RADIOTAP_F_FCS) {
>>> p->take(4);
>>> }
>>> - }
>>> -
>>> - if (rt_el_present(th, IEEE80211_RADIOTAP_RATE)) {
>>> - ceh->rate = *((u_int8_t *) rt_el_offset(th,
>>> IEEE80211_RADIOTAP_RATE));
>>> - }
>>> -
>>> - if (rt_el_present(th, IEEE80211_RADIOTAP_DBM_ANTSIGNAL))
>>> - ceh->rssi = *((u_int8_t *) rt_el_offset(th,
>>> IEEE80211_RADIOTAP_DBM_ANTSIGNAL));
>>> -
>>> - if (rt_el_present(th, IEEE80211_RADIOTAP_DBM_ANTNOISE))
>>> - ceh->silence = *((u_int8_t *) rt_el_offset(th,
>>> IEEE80211_RADIOTAP_DBM_ANTNOISE));
>>> -
>>> - if (rt_el_present(th, IEEE80211_RADIOTAP_DB_ANTSIGNAL))
>>> - ceh->rssi = *((u_int8_t *) rt_el_offset(th,
>>> IEEE80211_RADIOTAP_DB_ANTSIGNAL));
>>> -
>>> - if (rt_el_present(th, IEEE80211_RADIOTAP_DB_ANTNOISE))
>>> - ceh->silence = *((u_int8_t *) rt_el_offset(th,
>>> IEEE80211_RADIOTAP_DB_ANTNOISE));
>>> -
>>> - if (rt_el_present(th, IEEE80211_RADIOTAP_RX_FLAGS)) {
>>> - u_int16_t flags = le16_to_cpu(*((u_int16_t *)
>>> rt_el_offset(th, IEEE80211_RADIOTAP_RX_FLAGS)));
>>> - if (flags& IEEE80211_RADIOTAP_F_RX_BADFCS)
>>> + break;
>>> + case IEEE80211_RADIOTAP_RATE:
>>> + ceh->rate = *iter.this_arg;
>>> + break;
>>> + case IEEE80211_RADIOTAP_DATA_RETRIES:
>>> + ceh->retries = *iter.this_arg;
>>> + break;
>>> + case IEEE80211_RADIOTAP_CHANNEL:
>>> + ceh->channel = le16_to_cpu(*(uint16_t *)iter.this_arg);
>>> + break;
>>> + case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
>>> + ceh->rssi = *iter.this_arg;
>>> + break;
>>> + case IEEE80211_RADIOTAP_DBM_ANTNOISE:
>>> + ceh->silence = *iter.this_arg;
>>> + break;
>>> + case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
>>> + ceh->rssi = *iter.this_arg;
>>> + break;
>>> + case IEEE80211_RADIOTAP_DB_ANTNOISE:
>>> + ceh->silence = *iter.this_arg;
>>> + break;
>>> + case IEEE80211_RADIOTAP_RX_FLAGS:
>>> + flags = le16_to_cpu(*(uint16_t *)iter.this_arg);
>>> + if (flags& IEEE80211_RADIOTAP_F_BADFCS)
>>> ceh->flags |= WIFI_EXTRA_RX_ERR;
>>> - }
>>> -
>>> - if (rt_el_present(th, IEEE80211_RADIOTAP_TX_FLAGS)) {
>>> - u_int16_t flags = le16_to_cpu(*((u_int16_t *)
>>> rt_el_offset(th, IEEE80211_RADIOTAP_TX_FLAGS)));
>>> + break;
>>> + case IEEE80211_RADIOTAP_TX_FLAGS:
>>> + flags = le16_to_cpu(*(uint16_t *)iter.this_arg);
>>> ceh->flags |= WIFI_EXTRA_TX;
>>> if (flags& IEEE80211_RADIOTAP_F_TX_FAIL)
>>> ceh->flags |= WIFI_EXTRA_TX_FAIL;
>>> + break;
>>> }
>>> + }
>>>
>>> - if (rt_el_present(th, IEEE80211_RADIOTAP_DATA_RETRIES))
>>> - ceh->retries = *((u_int8_t *) rt_el_offset(th,
>>> IEEE80211_RADIOTAP_DATA_RETRIES));
>>> -
>>> - p->pull(le16_to_cpu(th->it_len));
>>> - p->set_mac_header(p->data()); // reset mac-header pointer
>>> + if (err != -ENOENT) {
>>> + click_chatter("%{element} :: %s :: malformed radiotap data",
>>> this, __func__);
>>> + goto drop;
>>> }
>>>
>>> - return p;
>>> -}
>>> + p->pull(le16_to_cpu(th->it_len));
>>> + p->set_mac_header(p->data()); // reset mac-header pointer
>>>
>>> + return p;
>>>
>>> -enum {H_DEBUG};
>>> + drop:
>>>
>>> -static String
>>> -RadiotapDecap_read_param(Element *e, void *thunk)
>>> -{
>>> - RadiotapDecap *td = (RadiotapDecap *)e;
>>> - switch ((uintptr_t) thunk) {
>>> - case H_DEBUG:
>>> - return String(td->_debug) + "\n";
>>> - default:
>>> - return String();
>>> - }
>>> -}
>>> -static int
>>> -RadiotapDecap_write_param(const String&in_s, Element *e, void *vparam,
>>> - ErrorHandler *errh)
>>> -{
>>> - RadiotapDecap *f = (RadiotapDecap *)e;
>>> - String s = cp_uncomment(in_s);
>>> - switch((intptr_t)vparam) {
>>> - case H_DEBUG: { //debug
>>> - bool debug;
>>> - if (!cp_bool(s,&debug))
>>> - return errh->error("debug parameter must be boolean");
>>> - f->_debug = debug;
>>> - break;
>>> - }
>>> - }
>>> - return 0;
>>> -}
>>> + p->kill();
>>> + return 0;
>>>
>>> -void
>>> -RadiotapDecap::add_handlers()
>>> -{
>>> - add_read_handler("debug", RadiotapDecap_read_param, (void *) H_DEBUG);
>>> -
>>> - add_write_handler("debug", RadiotapDecap_write_param, (void *)
>>> H_DEBUG);
>>> }
>>> +
>>> CLICK_ENDDECLS
>>> EXPORT_ELEMENT(RadiotapDecap)
>>> diff -urN --exclude .git --exclude conf --exclude diffserv --exclude
>>> ethernet --exclude secaggr --exclude wing --exclude availablechannels
>>> --exclude availablerates click.upstream/elements/wifi/radiotapdecap.hh
>>> click/elements/wifi/radiotapdecap.hh
>>> --- click.upstream/elements/wifi/radiotapdecap.hh 2011-04-11
>>> 11:52:49.789608001 +0200
>>> +++ click/elements/wifi/radiotapdecap.hh 2011-03-31
>>> 16:53:52.929465001 +0200
>>> @@ -28,18 +28,10 @@
>>> const char *port_count() const { return PORTS_1_1; }
>>> const char *processing() const { return AGNOSTIC; }
>>>
>>> - int configure(Vector<String> &, ErrorHandler *);
>>> bool can_live_reconfigure() const { return true; }
>>>
>>> Packet *simple_action(Packet *);
>>>
>>> -
>>> - void add_handlers();
>>> -
>>> -
>>> - bool _debug;
>>> - private:
>>> -
>>> };
>>>
>>> CLICK_ENDDECLS
>>> diff -urN --exclude .git --exclude conf --exclude diffserv --exclude
>>> ethernet --exclude secaggr --exclude wing --exclude availablechannels
>>> --exclude availablerates click.upstream/elements/wifi/radiotapencap.cc
>>> click/elements/wifi/radiotapencap.cc
>>> --- click.upstream/elements/wifi/radiotapencap.cc 2011-04-11
>>> 11:52:49.789608001 +0200
>>> +++ click/elements/wifi/radiotapencap.cc 2011-04-05
>>> 16:09:58.240939648 +0200
>>> @@ -27,121 +27,115 @@
>>> #include<clicknet/radiotap.h>
>>> CLICK_DECLS
>>>
>>> -
>>> -
>>> -#define CLICK_RADIOTAP_PRESENT ( \
>>> - (1<< IEEE80211_RADIOTAP_RATE) | \
>>> - (1<< IEEE80211_RADIOTAP_DBM_TX_POWER) | \
>>> - (1<< IEEE80211_RADIOTAP_RTS_RETRIES) | \
>>> - (1<< IEEE80211_RADIOTAP_DATA_RETRIES) | \
>>> +#define CLICK_RADIOTAP_PRESENT ( \
>>> + (1<< IEEE80211_RADIOTAP_RATE) | \
>>> + (1<< IEEE80211_RADIOTAP_DBM_TX_POWER) | \
>>> + (1<< IEEE80211_RADIOTAP_RTS_RETRIES) | \
>>> + (1<< IEEE80211_RADIOTAP_DATA_RETRIES) | \
>>> + (1<< IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE) | \
>>> + (1<< IEEE80211_RADIOTAP_EXT) | \
>>> 0)
>>>
>>> struct click_radiotap_header {
>>> struct ieee80211_radiotap_header wt_ihdr;
>>> + u_int32_t it_present1;
>>> + u_int32_t it_present2;
>>> + u_int32_t it_present3;
>>> u_int8_t wt_rate;
>>> u_int8_t wt_txpower;
>>> - u_int8_t wt_rts_retries;
>>> - u_int8_t wt_data_retries;
>>> -};
>>> -
>>> -
>>> -
>>> -
>>> -
>>> + u_int8_t wt_rts_retries;
>>> + u_int8_t wt_data_retries;
>>> + u_int8_t wt_rate1;
>>> + u_int8_t wt_data_retries1;
>>> + u_int8_t wt_rate2;
>>> + u_int8_t wt_data_retries2;
>>> + u_int8_t wt_rate3;
>>> + u_int8_t wt_data_retries3;
>>> +} __attribute__((__packed__));
>>>
>>> -RadiotapEncap::RadiotapEncap()
>>> -{
>>> +RadiotapEncap::RadiotapEncap() {
>>> }
>>>
>>> -RadiotapEncap::~RadiotapEncap()
>>> -{
>>> -}
>>> -
>>> -int
>>> -RadiotapEncap::configure(Vector<String> &conf, ErrorHandler *errh)
>>> -{
>>> -
>>> - _debug = false;
>>> - if (cp_va_kparse(conf, this, errh,
>>> - "DEBUG", 0, cpBool,&_debug,
>>> - cpEnd)< 0)
>>> - return -1;
>>> - return 0;
>>> +RadiotapEncap::~RadiotapEncap() {
>>> }
>>>
>>> Packet *
>>> -RadiotapEncap::simple_action(Packet *p)
>>> -{
>>> +RadiotapEncap::simple_action(Packet *p) {
>>>
>>> - WritablePacket *p_out = p->uniqueify();
>>> - if (!p_out) {
>>> - p->kill();
>>> - return 0;
>>> - }
>>> -
>>> - p_out = p_out->push(sizeof(struct click_radiotap_header));
>>> -
>>> - if (p_out) {
>>> - struct click_radiotap_header *crh = (struct
>>> click_radiotap_header *) p_out->data();
>>> - click_wifi_extra *ceh = WIFI_EXTRA_ANNO(p);
>>> -
>>> - memset(crh, 0, sizeof(struct click_radiotap_header));
>>> -
>>> - crh->wt_ihdr.it_version = 0;
>>> - crh->wt_ihdr.it_len = cpu_to_le16(sizeof(struct
>>> click_radiotap_header));
>>> - crh->wt_ihdr.it_present = cpu_to_le32(CLICK_RADIOTAP_PRESENT);
>>> -
>>> - crh->wt_rate = ceh->rate;
>>> - crh->wt_txpower = ceh->power;
>>> - crh->wt_rts_retries = 0;
>>> - if (ceh->max_tries> 0) {
>>> - crh->wt_data_retries = ceh->max_tries - 1;
>>> - } else {
>>> - crh->wt_data_retries = WIFI_MAX_RETRIES + 1;
>>> - }
>>> - }
>>> -
>>> - return p_out;
>>> -}
>>> + WritablePacket *p_out = p->uniqueify();
>>> + click_wifi_extra *ceh = WIFI_EXTRA_ANNO(p);
>>>
>>> + if (!p_out) {
>>> + p->kill();
>>> + return 0;
>>> + }
>>> +
>>> + p_out = p_out->push(sizeof(struct click_radiotap_header));
>>> +
>>> + if (!p_out) {
>>> + p->kill();
>>> + return 0;
>>> + }
>>> +
>>> + struct click_radiotap_header *crh = (struct click_radiotap_header
>>> *) p_out->data();
>>> +
>>> + memset(crh, 0, sizeof(struct click_radiotap_header));
>>> +
>>> + crh->wt_ihdr.it_version = 0;
>>> + crh->wt_ihdr.it_len = cpu_to_le16(sizeof(struct
>>> click_radiotap_header));
>>> +
>>> + crh->wt_ihdr.it_present = cpu_to_le32(CLICK_RADIOTAP_PRESENT);
>>> +
>>> + crh->wt_rate = ceh->rate;
>>> + crh->wt_txpower = ceh->power;
>>> + crh->wt_rts_retries = 0;
>>> +
>>> + if (ceh->max_tries> 0) {
>>> + crh->wt_data_retries = ceh->max_tries;
>>> + } else {
>>> + crh->wt_data_retries = WIFI_MAX_RETRIES + 1;
>>> + }
>>> +
>>> + crh->it_present1 |= cpu_to_le32(1<<
>>> IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE);
>>> + crh->it_present1 |= cpu_to_le32(1<< IEEE80211_RADIOTAP_EXT);
>>> +
>>> + crh->it_present2 |= cpu_to_le32(1<<
>>> IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE);
>>> + crh->it_present2 |= cpu_to_le32(1<< IEEE80211_RADIOTAP_EXT);
>>> +
>>> + if (ceh->rate1 != 0) {
>>> + crh->it_present1 |= cpu_to_le32(1<< IEEE80211_RADIOTAP_RATE);
>>> + crh->it_present1 |= cpu_to_le32(1<<
>>> IEEE80211_RADIOTAP_DATA_RETRIES);
>>> + crh->wt_rate1 = ceh->rate1;
>>> + if (ceh->max_tries1> 0) {
>>> + crh->wt_data_retries1 = ceh->max_tries1;
>>> + } else {
>>> + crh->wt_data_retries1 = WIFI_MAX_RETRIES + 1;
>>> + }
>>> + if (ceh->rate2 != 0) {
>>> + crh->it_present2 |= cpu_to_le32(1<< IEEE80211_RADIOTAP_RATE);
>>> + crh->it_present2 |= cpu_to_le32(1<<
>>> IEEE80211_RADIOTAP_DATA_RETRIES);
>>> + crh->wt_rate2 = ceh->rate2;
>>> + if (ceh->max_tries2> 0) {
>>> + crh->wt_data_retries2 = ceh->max_tries2;
>>> + } else {
>>> + crh->wt_data_retries2 = WIFI_MAX_RETRIES + 1;
>>> + }
>>> + if (ceh->rate3 != 0) {
>>> + crh->it_present3 |= cpu_to_le32(1<<
>>> IEEE80211_RADIOTAP_RATE);
>>> + crh->it_present3 |= cpu_to_le32(1<<
>>> IEEE80211_RADIOTAP_DATA_RETRIES);
>>> + crh->wt_rate3 = ceh->rate3;
>>> + if (ceh->max_tries3> 0) {
>>> + crh->wt_data_retries3 = ceh->max_tries3;
>>> + } else {
>>> + crh->wt_data_retries3 = WIFI_MAX_RETRIES + 1;
>>> + }
>>> + }
>>> + }
>>> + }
>>>
>>> -enum {H_DEBUG};
>>> + return p_out;
>>>
>>> -static String
>>> -RadiotapEncap_read_param(Element *e, void *thunk)
>>> -{
>>> - RadiotapEncap *td = (RadiotapEncap *)e;
>>> - switch ((uintptr_t) thunk) {
>>> - case H_DEBUG:
>>> - return String(td->_debug) + "\n";
>>> - default:
>>> - return String();
>>> - }
>>> }
>>> -static int
>>> -RadiotapEncap_write_param(const String&in_s, Element *e, void *vparam,
>>> - ErrorHandler *errh)
>>> -{
>>> - RadiotapEncap *f = (RadiotapEncap *)e;
>>> - String s = cp_uncomment(in_s);
>>> - switch((intptr_t)vparam) {
>>> - case H_DEBUG: { //debug
>>> - bool debug;
>>> - if (!cp_bool(s,&debug))
>>> - return errh->error("debug parameter must be boolean");
>>> - f->_debug = debug;
>>> - break;
>>> - }
>>> - }
>>> - return 0;
>>> -}
>>> -
>>> -void
>>> -RadiotapEncap::add_handlers()
>>> -{
>>> - add_read_handler("debug", RadiotapEncap_read_param, (void *) H_DEBUG);
>>>
>>> - add_write_handler("debug", RadiotapEncap_write_param, (void *)
>>> H_DEBUG);
>>> -}
>>> CLICK_ENDDECLS
>>> EXPORT_ELEMENT(RadiotapEncap)
>>> diff -urN --exclude .git --exclude conf --exclude diffserv --exclude
>>> ethernet --exclude secaggr --exclude wing --exclude availablechannels
>>> --exclude availablerates click.upstream/elements/wifi/radiotapencap.hh
>>> click/elements/wifi/radiotapencap.hh
>>> --- click.upstream/elements/wifi/radiotapencap.hh 2011-04-11
>>> 11:52:49.789608001 +0200
>>> +++ click/elements/wifi/radiotapencap.hh 2011-03-31
>>> 16:43:26.000000000 +0200
>>> @@ -29,18 +29,10 @@
>>> const char *port_count() const { return PORTS_1_1; }
>>> const char *processing() const { return AGNOSTIC; }
>>>
>>> - int configure(Vector<String> &, ErrorHandler *);
>>> bool can_live_reconfigure() const { return true; }
>>>
>>> Packet *simple_action(Packet *);
>>>
>>> -
>>> - void add_handlers();
>>> -
>>> -
>>> - bool _debug;
>>> - private:
>>> -
>>> };
>>>
>>> CLICK_ENDDECLS
>>> diff -urN --exclude .git --exclude conf --exclude diffserv --exclude
>>> ethernet --exclude secaggr --exclude wing --exclude availablechannels
>>> --exclude availablerates
>>> click.upstream/elements/wifi/station/beacontracker.cc
>>> click/elements/wifi/station/beacontracker.cc
>>> --- click.upstream/elements/wifi/station/beacontracker.cc 2011-04-11
>>> 11:52:49.793608001 +0200
>>> +++ click/elements/wifi/station/beacontracker.cc 2011-03-24
>>> 20:50:55.699217001 +0100
>>> @@ -117,7 +117,8 @@
>>>
>>>
>>> struct beacon_t b;
>>> - uint16_t seq = le16_to_cpu(*(uint16_t *) w->i_seq)>>
>>> WIFI_SEQ_SEQ_SHIFT;
>>> + uint16_t * s16 = (uint16_t *) w->i_seq;
>>> + uint16_t seq = le16_to_cpu(*s16)>> WIFI_SEQ_SEQ_SHIFT;
>>>
>>>
>>> b.rx = p->timestamp_anno();
>>> diff -urN --exclude .git --exclude conf --exclude diffserv --exclude
>>> ethernet --exclude secaggr --exclude wing --exclude availablechannels
>>> --exclude availablerates
>>> click.upstream/elements/wifi/station/openauthrequester.cc
>>> click/elements/wifi/station/openauthrequester.cc
>>> --- click.upstream/elements/wifi/station/openauthrequester.cc
>>> 2011-04-11 11:52:49.793608001 +0200
>>> +++ click/elements/wifi/station/openauthrequester.cc 2011-03-24
>>> 20:50:55.699217001 +0100
>>> @@ -157,9 +157,10 @@
>>> memcpy(w->i_addr2, _eth.data(), 6);
>>> memcpy(w->i_addr3, bssid.data(), 6);
>>>
>>> -
>>> - *(uint16_t *) w->i_dur = 0;
>>> - *(uint16_t *) w->i_seq = 0;
>>> + uint16_t * d16 = (uint16_t *) w->i_dur;
>>> + uint16_t * s16 = (uint16_t *) w->i_seq;
>>> + *d16 = 0;
>>> + *s16 = 0;
>>>
>>> uint8_t *ptr;
>>>
>>> diff -urN --exclude .git --exclude conf --exclude diffserv --exclude
>>> ethernet --exclude secaggr --exclude wing --exclude availablechannels
>>> --exclude availablerates
>>> click.upstream/elements/wifi/station/proberequester.cc
>>> click/elements/wifi/station/proberequester.cc
>>> --- click.upstream/elements/wifi/station/proberequester.cc 2011-04-11
>>> 11:52:49.793608001 +0200
>>> +++ click/elements/wifi/station/proberequester.cc 2011-03-24
>>> 20:50:55.699217001 +0100
>>> @@ -86,8 +86,10 @@
>>> memset(w->i_addr3, 0xff, 6);
>>>
>>>
>>> - *(uint16_t *) w->i_dur = 0;
>>> - *(uint16_t *) w->i_seq = 0;
>>> + uint16_t * d16 = (uint16_t *) w->i_dur;
>>> + uint16_t * s16 = (uint16_t *) w->i_seq;
>>> + *d16 = 0;
>>> + *s16 = 0;
>>>
>>> uint8_t *ptr = (uint8_t *) p->data() + sizeof(struct click_wifi);
>>> int actual_length = sizeof (struct click_wifi);
>>> diff -urN --exclude .git --exclude conf --exclude diffserv --exclude
>>> ethernet --exclude secaggr --exclude wing --exclude availablechannels
>>> --exclude availablerates click.upstream/elements/wifi/wepdecap.cc
>>> click/elements/wifi/wepdecap.cc
>>> --- click.upstream/elements/wifi/wepdecap.cc 2011-04-11
>>> 11:52:49.793608001 +0200
>>> +++ click/elements/wifi/wepdecap.cc 2011-03-31 11:00:25.000000000 +0200
>>> @@ -128,13 +128,14 @@
>>> icv = payload + payload_len;
>>> rc4_crypt_skip(&_rc4, icv, crcbuf, WIFI_WEP_CRCLEN, 0);
>>>
>>> - if (crc != ~le32_to_cpu(*(u_int32_t *)crcbuf)) {
>>> + u_int32_t * crc32 = (u_int32_t *) crcbuf;
>>> + if (crc != ~le32_to_cpu(*crc32)) {
>>> click_chatter("crc failed keyid %d iv %d %x wanted %x %x\n",
>>> keyid,
>>> iv,
>>> crc,
>>> - ~le32_to_cpu(*(u_int32_t *)crcbuf),
>>> - *(u_int32_t *)crcbuf);
>>> + ~le32_to_cpu(*crc32),
>>> + *crc32);
>>> /* packet failed decrypt */
>>> return p;
>>> }
>>> diff -urN --exclude .git --exclude conf --exclude diffserv --exclude
>>> ethernet --exclude secaggr --exclude wing --exclude availablechannels
>>> --exclude availablerates click.upstream/elements/wifi/wepencap.cc
>>> click/elements/wifi/wepencap.cc
>>> --- click.upstream/elements/wifi/wepencap.cc 2011-04-11
>>> 11:52:49.793608001 +0200
>>> +++ click/elements/wifi/wepencap.cc 2011-03-31 11:00:25.000000000 +0200
>>> @@ -139,7 +139,8 @@
>>> p->length() - (sizeof(click_wifi) + WIFI_WEP_HEADERSIZE),
>>> 0);
>>> /* tack on ICV */
>>> - *(u_int32_t *)crcbuf = cpu_to_le32(~crc);
>>> + u_int32_t * crc32 = (u_int32_t *) crcbuf;
>>> + *crc32 = cpu_to_le32(~crc);
>>> p = p->put(WIFI_WEP_CRCLEN);
>>> icv = p->end_data() - WIFI_WEP_CRCLEN;
>>> rc4_crypt_skip(&_rc4, crcbuf, icv, WIFI_WEP_CRCLEN, 0);
>>> diff -urN --exclude .git --exclude conf --exclude diffserv --exclude
>>> ethernet --exclude secaggr --exclude wing --exclude availablechannels
>>> --exclude availablerates click.upstream/elements/wifi/wifidefrag.cc
>>> click/elements/wifi/wifidefrag.cc
>>> --- click.upstream/elements/wifi/wifidefrag.cc 2011-04-11
>>> 11:52:49.793608001 +0200
>>> +++ click/elements/wifi/wifidefrag.cc 2011-03-31 11:00:25.000000000 +0200
>>> @@ -53,8 +53,9 @@
>>>
>>> click_wifi *w = (click_wifi *) p->data();
>>> EtherAddress src = EtherAddress(w->i_addr2);
>>> - uint16_t seq = le16_to_cpu(*(uint16_t *) w->i_seq)>>
>>> WIFI_SEQ_SEQ_SHIFT;
>>> - uint8_t frag = le16_to_cpu(*(u_int16_t *)w->i_seq)& WIFI_SEQ_FRAG_MASK;
>>> + uint16_t * s16 = (uint16_t *) w->i_seq;
>>> + uint16_t seq = le16_to_cpu(*s16)>> WIFI_SEQ_SEQ_SHIFT;
>>> + uint8_t frag = le16_to_cpu(*s16)& WIFI_SEQ_FRAG_MASK;
>>> u_int8_t more_frag = w->i_fc[1]& WIFI_FC1_MORE_FRAG;
>>> PacketInfo *nfo = _packets.findp(src);
>>>
>>> @@ -139,7 +140,8 @@
>>> }
>>> p = nfo->p;
>>> w = (click_wifi *) p->data();
>>> - *((uint16_t *) w->i_seq) = cpu_to_le16(((u_int16_t) nfo->seq)<<
>>> WIFI_SEQ_SEQ_SHIFT);
>>> + s16 = (uint16_t *) w->i_seq;
>>> + *s16 = cpu_to_le16(((u_int16_t) nfo->seq)<< WIFI_SEQ_SEQ_SHIFT);
>>> w->i_fc[1] ^= WIFI_FC1_MORE_FRAG;
>>>
>>> nfo->p = 0;
>>> diff -urN --exclude .git --exclude conf --exclude diffserv --exclude
>>> ethernet --exclude secaggr --exclude wing --exclude availablechannels
>>> --exclude availablerates click.upstream/elements/wifi/wifidupefilter.cc
>>> click/elements/wifi/wifidupefilter.cc
>>> --- click.upstream/elements/wifi/wifidupefilter.cc 2011-04-11
>>> 11:52:49.793608001 +0200
>>> +++ click/elements/wifi/wifidupefilter.cc 2011-03-31
>>> 11:00:25.000000000 +0200
>>> @@ -60,8 +60,9 @@
>>>
>>> EtherAddress src = EtherAddress(w->i_addr2);
>>> EtherAddress dst = EtherAddress(w->i_addr1);
>>> - uint16_t seq = le16_to_cpu(*(uint16_t *) w->i_seq)>>
>>> WIFI_SEQ_SEQ_SHIFT;
>>> - uint8_t frag = le16_to_cpu(*(u_int16_t *)w->i_seq)& WIFI_SEQ_FRAG_MASK;
>>> + uint16_t * s16 = (uint16_t *) w->i_seq;
>>> + uint16_t seq = le16_to_cpu(*s16)>> WIFI_SEQ_SEQ_SHIFT;
>>> + uint8_t frag = le16_to_cpu(*s16)& WIFI_SEQ_FRAG_MASK;
>>> u_int8_t more_frag = w->i_fc[1]& WIFI_FC1_MORE_FRAG;
>>>
>>> bool is_frag = frag || more_frag;
>>> diff -urN --exclude .git --exclude conf --exclude diffserv --exclude
>>> ethernet --exclude secaggr --exclude wing --exclude availablechannels
>>> --exclude availablerates click.upstream/elements/wifi/wififragment.cc
>>> click/elements/wifi/wififragment.cc
>>> --- click.upstream/elements/wifi/wififragment.cc 2011-04-11
>>> 11:52:49.793608001 +0200
>>> +++ click/elements/wifi/wififragment.cc 2011-03-31 11:00:25.000000000
>>> +0200
>>> @@ -55,7 +55,8 @@
>>> {
>>>
>>> click_wifi *w = (click_wifi *) p->data();
>>> - uint16_t seq = le16_to_cpu(*(u_int16_t *)w->i_seq)>>
>>> WIFI_SEQ_SEQ_SHIFT;
>>> + uint16_t * s16 = (uint16_t *) w->i_seq;
>>> + uint16_t seq = le16_to_cpu(*s16)>> WIFI_SEQ_SEQ_SHIFT;
>>> if (!_max_length ||
>>> p->length()<= sizeof(click_wifi) + _max_length) {
>>> if (_debug) {
>>> @@ -95,7 +96,8 @@
>>> frag_len);
>>> click_wifi *w_o = (click_wifi *) p_out->data();
>>> uint16_t seq_o = (seq<< WIFI_SEQ_SEQ_SHIFT) | (((u_int8_t) frag)
>>> & WIFI_SEQ_FRAG_MASK);
>>> - *((uint16_t *)w_o->i_seq) = cpu_to_le16(seq_o);
>>> + uint16_t * s16 = (uint16_t *)w_o->i_seq;
>>> + *s16 = cpu_to_le16(seq_o);
>>> if (frag != num_frags - 1) {
>>> w_o->i_fc[1] |= WIFI_FC1_MORE_FRAG;
>>> }
>>> diff -urN --exclude .git --exclude conf --exclude diffserv --exclude
>>> ethernet --exclude secaggr --exclude wing --exclude availablechannels
>>> --exclude availablerates click.upstream/include/click/platform.h
>>> click/include/click/platform.h
>>> --- click.upstream/include/click/platform.h 1970-01-01
>>> 01:00:00.000000000 +0100
>>> +++ click/include/click/platform.h 2011-04-07 16:54:32.000000000 +0200
>>> @@ -0,0 +1,19 @@
>>> +#include<stddef.h>
>>> +#include<errno.h>
>>> +#ifndef _BSD_SOURCE
>>> +#define _BSD_SOURCE
>>> +#endif
>>> +#include<endian.h>
>>> +
>>> +#define le16_to_cpu le16toh
>>> +#define le32_to_cpu le32toh
>>> +#define get_unaligned(p) \
>>> +({ \
>>> + struct packed_dummy_struct { \
>>> + typeof(*(p)) __val; \
>>> + } __attribute__((packed)) *__ptr = (void *) (p); \
>>> + \
>>> + __ptr->__val; \
>>> +})
>>> +#define get_unaligned_le16(p) le16_to_cpu(get_unaligned((uint16_t
>>> *)(p)))
>>> +#define get_unaligned_le32(p) le32_to_cpu(get_unaligned((uint32_t
>>> *)(p)))
>>> diff -urN --exclude .git --exclude conf --exclude diffserv --exclude
>>> ethernet --exclude secaggr --exclude wing --exclude availablechannels
>>> --exclude availablerates click.upstream/include/click/radiotap_iter.h
>>> click/include/click/radiotap_iter.h
>>> --- click.upstream/include/click/radiotap_iter.h 1970-01-01
>>> 01:00:00.000000000 +0100
>>> +++ click/include/click/radiotap_iter.h 2011-03-24 20:50:55.739217001
>>> +0100
>>> @@ -0,0 +1,96 @@
>>> +#ifndef CLICK_RADIOTAP_ITER_H
>>> +#define CLICK_RADIOTAP_ITER_H
>>> +
>>> +#include<stdint.h>
>>> +#include<clicknet/radiotap.h>
>>> +
>>> +/* Radiotap header iteration
>>> + * implemented in radiotap.c
>>> + */
>>> +
>>> +struct radiotap_override {
>>> + uint8_t field;
>>> + uint8_t align:4, size:4;
>>> +};
>>> +
>>> +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
>>> + * @this_arg_index: index of current arg, valid after each successful
>>> call
>>> + * to ieee80211_radiotap_iterator_next()
>>> + * @this_arg: pointer to current radiotap arg; it is valid after each
>>> + * call to ieee80211_radiotap_iterator_next() but also after
>>> + * ieee80211_radiotap_iterator_init() where it will point to
>>> + * the beginning of the actual data portion
>>> + * @this_arg_size: length of the current arg, for convenience
>>> + * @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_header *_rtheader;
>>> + 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;
>>> +#ifdef RADIOTAP_SUPPORT_OVERRIDES
>>> + const struct radiotap_override *overrides;
>>> + int n_overrides;
>>> +#endif
>>> + int this_arg_index;
>>> + int this_arg_size;
>>> +
>>> + int is_radiotap_ns;
>>> +
>>> + int _max_length;
>>> + int _arg_index;
>>> + uint32_t _bitmap_shifter;
>>> + int _reset_on_ext;
>>> +};
>>> +
>>> +extern int ieee80211_radiotap_iterator_init(
>>> + struct ieee80211_radiotap_iterator *iterator,
>>> + struct ieee80211_radiotap_header *radiotap_header,
>>> + int max_length, const struct ieee80211_radiotap_vendor_namespaces
>>> *vns);
>>> +
>>> +extern int ieee80211_radiotap_iterator_next(
>>> + struct ieee80211_radiotap_iterator *iterator);
>>> +
>>> +#endif /* CLICK_RADIOTAP_ITER_H */
>>> diff -urN --exclude .git --exclude conf --exclude diffserv --exclude
>>> ethernet --exclude secaggr --exclude wing --exclude availablechannels
>>> --exclude availablerates click.upstream/include/clicknet/platform.h
>>> click/include/clicknet/platform.h
>>> --- click.upstream/include/clicknet/platform.h 1970-01-01
>>> 01:00:00.000000000 +0100
>>> +++ click/include/clicknet/platform.h 2011-03-24 20:50:55.739217001 +0100
>>> @@ -0,0 +1,19 @@
>>> +#include<stddef.h>
>>> +#include<errno.h>
>>> +#ifndef _BSD_SOURCE
>>> +#define _BSD_SOURCE
>>> +#endif
>>> +#include<endian.h>
>>> +
>>> +#define le16_to_cpu le16toh
>>> +#define le32_to_cpu le32toh
>>> +#define get_unaligned(p) \
>>> +({ \
>>> + struct packed_dummy_struct { \
>>> + typeof(*(p)) __val; \
>>> + } __attribute__((packed)) *__ptr = (void *) (p); \
>>> + \
>>> + __ptr->__val; \
>>> +})
>>> +#define get_unaligned_le16(p) le16_to_cpu(get_unaligned((uint16_t
>>> *)(p)))
>>> +#define get_unaligned_le32(p) le32_to_cpu(get_unaligned((uint32_t
>>> *)(p)))
>>> diff -urN --exclude .git --exclude conf --exclude diffserv --exclude
>>> ethernet --exclude secaggr --exclude wing --exclude availablechannels
>>> --exclude availablerates click.upstream/include/clicknet/radiotap.h
>>> click/include/clicknet/radiotap.h
>>> --- click.upstream/include/clicknet/radiotap.h 2011-04-11
>>> 11:52:49.841608001 +0200
>>> +++ click/include/clicknet/radiotap.h 2011-03-31 10:46:19.000000000 +0200
>>> @@ -1,6 +1,3 @@
>>> -/* $FreeBSD: src/sys/net80211/ieee80211_radiotap.h,v 1.5 2005/01/22
>>> 20:12:05 sam Exp $ */
>>> -/* $NetBSD: ieee80211_radiotap.h,v 1.10 2005/01/04 00:34:58 dyoung
>>> Exp $ */
>>> -
>>> /*-
>>> * Copyright (c) 2003, 2004 David Young. All rights reserved.
>>> *
>>> @@ -29,8 +26,19 @@
>>> * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
>>> * OF SUCH DAMAGE.
>>> */
>>> -#ifndef _NET_IF_IEEE80211RADIOTAP_H_
>>> -#define _NET_IF_IEEE80211RADIOTAP_H_
>>> +
>>> +/*
>>> + * Modifications to fit into the linux IEEE 802.11 stack,
>>> + * Mike Kershaw (dragorn at kismetwireless.net)
>>> + */
>>> +
>>> +#ifndef IEEE80211RADIOTAP_H
>>> +#define IEEE80211RADIOTAP_H
>>> +
>>> +#include<stdint.h>
>>> +
>>> +/* Base version of the radiotap packet header data */
>>> +#define PKTHDR_RADIOTAP_VERSION 0
>>>
>>> /* A generic radio capture format is desirable. There is one for
>>> * Linux, but it is neither rigidly defined (there were not even
>>> @@ -46,135 +54,132 @@
>>> * function of...") that I cannot set false expectations for lawyerly
>>> * readers.
>>> */
>>> -#if defined(__KERNEL__) || defined(_KERNEL)
>>> -#ifndef DLT_IEEE802_11_RADIO
>>> -#define DLT_IEEE802_11_RADIO 127 /* 802.11 plus WLAN header */
>>> -#endif
>>> -#endif /* defined(__KERNEL__) || defined(_KERNEL) */
>>>
>>> -/* XXX tcpdump/libpcap do not tolerate variable-length headers,
>>> - * yet, so we pad every radiotap header to 64 bytes. Ugh.
>>> +/* The radio capture header precedes the 802.11 header.
>>> + * All data in the header is little endian on all platforms.
>>> */
>>> -#define IEEE80211_RADIOTAP_HDRLEN 64
>>> -
>>> -/* The radio capture header precedes the 802.11 header. */
>>> struct ieee80211_radiotap_header {
>>> - u_int8_t it_version; /* Version 0. Only increases
>>> - * for drastic changes,
>>> - * introduction of compatible
>>> - * new fields does not count.
>>> - */
>>> - u_int8_t it_pad;
>>> - u_int16_t it_len; /* length of the whole
>>> - * header in bytes, including
>>> - * it_version, it_pad,
>>> - * it_len, and data fields.
>>> - */
>>> - u_int32_t it_present; /* A bitmap telling which
>>> - * fields are present. Set bit 31
>>> - * (0x80000000) to extend the
>>> - * bitmap by another 32 bits.
>>> - * Additional extensions are made
>>> - * by setting bit 31.
>>> - */
>>> + uint8_t it_version; /* Version 0. Only increases
>>> + * for drastic changes,
>>> + * introduction of compatible
>>> + * new fields does not count.
>>> + */
>>> + uint8_t it_pad;
>>> + uint16_t it_len; /* length of the whole
>>> + * header in bytes, including
>>> + * it_version, it_pad,
>>> + * it_len, and data fields.
>>> + */
>>> + uint32_t it_present; /* A bitmap telling which
>>> + * fields are present. Set bit 31
>>> + * (0x80000000) to extend the
>>> + * bitmap by another 32 bits.
>>> + * Additional extensions are made
>>> + * by setting bit 31.
>>> + */
>>> } __attribute__((__packed__));
>>>
>>> -/* Name Data type Units
>>> - * ---- --------- -----
>>> +/* Name Data type Units
>>> + * ---- --------- -----
>>> *
>>> - * IEEE80211_RADIOTAP_TSFT u_int64_t microseconds
>>> + * IEEE80211_RADIOTAP_TSFT __le64 microseconds
>>> *
>>> * Value in microseconds of the MAC's 64-bit 802.11 Time
>>> * Synchronization Function timer when the first bit of the
>>> * MPDU arrived at the MAC. For received frames, only.
>>> *
>>> - * IEEE80211_RADIOTAP_CHANNEL 2 x u_int16_t MHz, bitmap
>>> + * IEEE80211_RADIOTAP_CHANNEL 2 x uint16_t MHz, bitmap
>>> *
>>> * Tx/Rx frequency in MHz, followed by flags (see below).
>>> *
>>> - * IEEE80211_RADIOTAP_FHSS u_int16_t see below
>>> + * IEEE80211_RADIOTAP_FHSS uint16_t see below
>>> *
>>> * For frequency-hopping radios, the hop set (first byte)
>>> * and pattern (second byte).
>>> *
>>> - * IEEE80211_RADIOTAP_RATE u_int8_t 500kb/s
>>> + * IEEE80211_RADIOTAP_RATE u8 500kb/s
>>> *
>>> * Tx/Rx data rate
>>> *
>>> - * IEEE80211_RADIOTAP_DBM_ANTSIGNAL int8_t decibels from
>>> - * one milliwatt (dBm)
>>> + * IEEE80211_RADIOTAP_DBM_ANTSIGNAL s8 decibels from
>>> + * one milliwatt (dBm)
>>> *
>>> * RF signal power at the antenna, decibel difference from
>>> * one milliwatt.
>>> *
>>> - * IEEE80211_RADIOTAP_DBM_ANTNOISE int8_t decibels from
>>> - * one milliwatt (dBm)
>>> + * IEEE80211_RADIOTAP_DBM_ANTNOISE s8 decibels from
>>> + * one milliwatt (dBm)
>>> *
>>> * RF noise power at the antenna, decibel difference from one
>>> * milliwatt.
>>> *
>>> - * IEEE80211_RADIOTAP_DB_ANTSIGNAL u_int8_t decibel (dB)
>>> + * IEEE80211_RADIOTAP_DB_ANTSIGNAL u8 decibel (dB)
>>> *
>>> * RF signal power at the antenna, decibel difference from an
>>> * arbitrary, fixed reference.
>>> *
>>> - * IEEE80211_RADIOTAP_DB_ANTNOISE u_int8_t decibel (dB)
>>> + * IEEE80211_RADIOTAP_DB_ANTNOISE u8 decibel (dB)
>>> *
>>> * RF noise power at the antenna, decibel difference from an
>>> * arbitrary, fixed reference point.
>>> *
>>> - * IEEE80211_RADIOTAP_LOCK_QUALITY u_int16_t unitless
>>> + * IEEE80211_RADIOTAP_LOCK_QUALITY uint16_t unitless
>>> *
>>> * Quality of Barker code lock. Unitless. Monotonically
>>> * nondecreasing with "better" lock strength. Called "Signal
>>> * Quality" in datasheets. (Is there a standard way to measure
>>> * this?)
>>> *
>>> - * IEEE80211_RADIOTAP_TX_ATTENUATION u_int16_t unitless
>>> + * IEEE80211_RADIOTAP_TX_ATTENUATION uint16_t unitless
>>> *
>>> * Transmit power expressed as unitless distance from max
>>> * power set at factory calibration. 0 is max power.
>>> * Monotonically nondecreasing with lower power levels.
>>> *
>>> - * IEEE80211_RADIOTAP_DB_TX_ATTENUATION u_int16_t decibels (dB)
>>> + * IEEE80211_RADIOTAP_DB_TX_ATTENUATION uint16_t decibels (dB)
>>> *
>>> * Transmit power expressed as decibel distance from max power
>>> * set at factory calibration. 0 is max power. Monotonically
>>> * nondecreasing with lower power levels.
>>> *
>>> - * IEEE80211_RADIOTAP_DBM_TX_POWER int8_t decibels from
>>> - * one milliwatt (dBm)
>>> + * IEEE80211_RADIOTAP_DBM_TX_POWER s8 decibels from
>>> + * one milliwatt (dBm)
>>> *
>>> * Transmit power expressed as dBm (decibels from a 1 milliwatt
>>> * reference). This is the absolute power level measured at
>>> * the antenna port.
>>> *
>>> - * IEEE80211_RADIOTAP_FLAGS u_int8_t bitmap
>>> + * IEEE80211_RADIOTAP_FLAGS u8 bitmap
>>> *
>>> * Properties of transmitted and received frames. See flags
>>> * defined below.
>>> *
>>> - * IEEE80211_RADIOTAP_ANTENNA u_int8_t antenna index
>>> + * IEEE80211_RADIOTAP_ANTENNA u8 antenna index
>>> *
>>> * Unitless indication of the Rx/Tx antenna for this packet.
>>> * The first antenna is antenna 0.
>>> *
>>> - * IEEE80211_RADIOTAP_RX_FLAGS u_int16_t bitmap
>>> + * IEEE80211_RADIOTAP_RX_FLAGS uint16_t bitmap
>>> *
>>> - * Properties of received frames. See flags defined below.
>>> + * Properties of received frames. See flags defined below.
>>> *
>>> - * IEEE80211_RADIOTAP_TX_FLAGS u_int16_t bitmap
>>> + * IEEE80211_RADIOTAP_TX_FLAGS uint16_t bitmap
>>> *
>>> - * Properties of transmitted frames. See flags defined below.
>>> + * Properties of transmitted frames. See flags defined below.
>>> *
>>> - * IEEE80211_RADIOTAP_RTS_RETRIES u_int8_t data
>>> + * IEEE80211_RADIOTAP_RTS_RETRIES u8 data
>>> *
>>> - * Number of rts retries a transmitted frame used.
>>> - *
>>> - * IEEE80211_RADIOTAP_DATA_RETRIES u_int8_t data
>>> + * Number of rts retries a transmitted frame used.
>>> + *
>>> + * IEEE80211_RADIOTAP_DATA_RETRIES u8 data
>>> + *
>>> + * Number of unicast retries a transmitted frame used.
>>> + *
>>> + * IEEE80211_RADIOTAP_MCS u8, u8, u8 unitless
>>> + *
>>> + * Contains a bitmap of known fields/flags, the flags, and
>>> + * the MCS index.
>>> *
>>> - * Number of unicast retries a transmitted frame used.
>>> - *
>>> */
>>> enum ieee80211_radiotap_type {
>>> IEEE80211_RADIOTAP_TSFT = 0,
>>> @@ -195,20 +200,24 @@
>>> IEEE80211_RADIOTAP_TX_FLAGS = 15,
>>> IEEE80211_RADIOTAP_RTS_RETRIES = 16,
>>> IEEE80211_RADIOTAP_DATA_RETRIES = 17,
>>> +
>>> + IEEE80211_RADIOTAP_MCS = 19,
>>> +
>>> + /* valid in every it_present bitmap, even vendor namespaces */
>>> + IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE = 29,
>>> + IEEE80211_RADIOTAP_VENDOR_NAMESPACE = 30,
>>> IEEE80211_RADIOTAP_EXT = 31
>>> };
>>>
>>> -#if !defined(__KERNEL__)&& !defined(_KERNEL)
>>> /* Channel flags. */
>>> -#define IEEE80211_CHAN_TURBO 0x0010 /* Turbo channel */
>>> -#define IEEE80211_CHAN_CCK 0x0020 /* CCK channel */
>>> -#define IEEE80211_CHAN_OFDM 0x0040 /* OFDM channel */
>>> -#define IEEE80211_CHAN_2GHZ 0x0080 /* 2 GHz spectrum channel. */
>>> -#define IEEE80211_CHAN_5GHZ 0x0100 /* 5 GHz spectrum channel */
>>> -#define IEEE80211_CHAN_PASSIVE 0x0200 /* Only passive scan allowed */
>>> +#define IEEE80211_CHAN_TURBO 0x0010 /* Turbo channel */
>>> +#define IEEE80211_CHAN_CCK 0x0020 /* CCK channel */
>>> +#define IEEE80211_CHAN_OFDM 0x0040 /* OFDM channel */
>>> +#define IEEE80211_CHAN_2GHZ 0x0080 /* 2 GHz spectrum channel. */
>>> +#define IEEE80211_CHAN_5GHZ 0x0100 /* 5 GHz spectrum channel */
>>> +#define IEEE80211_CHAN_PASSIVE 0x0200 /* Only passive scan
>>> allowed */
>>> #define IEEE80211_CHAN_DYN 0x0400 /* Dynamic CCK-OFDM channel */
>>> #define IEEE80211_CHAN_GFSK 0x0800 /* GFSK channel (FHSS PHY) */
>>> -#endif /* !defined(__KERNEL__)&& !defined(_KERNEL) */
>>>
>>> /* For IEEE80211_RADIOTAP_FLAGS */
>>> #define IEEE80211_RADIOTAP_F_CFP 0x01 /* sent/received
>>> @@ -229,15 +238,32 @@
>>> * 802.11 header and payload
>>> * (to 32-bit boundary)
>>> */
>>> +#define IEEE80211_RADIOTAP_F_BADFCS 0x40 /* frame failed FCS check */
>>> +
>>> /* For IEEE80211_RADIOTAP_RX_FLAGS */
>>> -#define IEEE80211_RADIOTAP_F_RX_BADFCS 0x0001 /* frame failed
>>> crc check */
>>> +#define IEEE80211_RADIOTAP_F_RX_BADPLCP 0x0002 /* bad PLCP */
>>>
>>> /* For IEEE80211_RADIOTAP_TX_FLAGS */
>>> -#define IEEE80211_RADIOTAP_F_TX_FAIL 0x0001 /* failed due to
>>> excessive
>>> +#define IEEE80211_RADIOTAP_F_TX_FAIL 0x0001 /* failed due to
>>> excessive
>>> * retries */
>>> -#define IEEE80211_RADIOTAP_F_TX_CTS 0x0002 /* used cts
>>> 'protection' */
>>> -#define IEEE80211_RADIOTAP_F_TX_RTS 0x0004 /* used rts/cts
>>> handshake */
>>> +#define IEEE80211_RADIOTAP_F_TX_CTS 0x0002 /* used cts
>>> 'protection' */
>>> +#define IEEE80211_RADIOTAP_F_TX_RTS 0x0004 /* used rts/cts
>>> handshake */
>>>
>>>
>>> +/* For IEEE80211_RADIOTAP_MCS */
>>> +#define IEEE80211_RADIOTAP_MCS_HAVE_BW 0x01
>>> +#define IEEE80211_RADIOTAP_MCS_HAVE_MCS 0x02
>>> +#define IEEE80211_RADIOTAP_MCS_HAVE_GI 0x04
>>> +#define IEEE80211_RADIOTAP_MCS_HAVE_FMT 0x08
>>> +#define IEEE80211_RADIOTAP_MCS_HAVE_FEC 0x10
>>> +
>>> +#define IEEE80211_RADIOTAP_MCS_BW_MASK 0x03
>>> +#define IEEE80211_RADIOTAP_MCS_BW_20 0
>>> +#define IEEE80211_RADIOTAP_MCS_BW_40 1
>>> +#define IEEE80211_RADIOTAP_MCS_BW_20L 2
>>> +#define IEEE80211_RADIOTAP_MCS_BW_20U 3
>>> +#define IEEE80211_RADIOTAP_MCS_SGI 0x04
>>> +#define IEEE80211_RADIOTAP_MCS_FMT_GF 0x08
>>> +#define IEEE80211_RADIOTAP_MCS_FEC_LDPC 0x10
>>>
>>> -#endif /* _NET_IF_IEEE80211RADIOTAP_H_ */
>>> +#endif /* IEEE80211_RADIOTAP_H */
>>> diff -urN --exclude .git --exclude conf --exclude diffserv --exclude
>>> ethernet --exclude secaggr --exclude wing --exclude availablechannels
>>> --exclude availablerates click.upstream/include/clicknet/wifi.h
>>> click/include/clicknet/wifi.h
>>> --- click.upstream/include/clicknet/wifi.h 2011-04-11
>>> 11:52:49.841608001 +0200
>>> +++ click/include/clicknet/wifi.h 2011-04-05 16:08:51.724939649 +0200
>>> @@ -29,7 +29,9 @@
>>>
>>> struct click_wifi_extra {
>>> uint32_t magic;
>>> - uint32_t flags;
>>> +
>>> + uint16_t flags;
>>> + uint16_t channel;
>>>
>>> uint8_t rssi;
>>> uint8_t silence;
>>> diff -urN --exclude .git --exclude conf --exclude diffserv --exclude
>>> ethernet --exclude secaggr --exclude wing --exclude availablechannels
>>> --exclude availablerates click.upstream/lib/radiotap.c
>>> click/lib/radiotap.c
>>> --- click.upstream/lib/radiotap.c 1970-01-01 01:00:00.000000000 +0100
>>> +++ click/lib/radiotap.c 2011-03-24 20:50:55.747217001 +0100
>>> @@ -0,0 +1,383 @@
>>> +/*
>>> + * Radiotap parser
>>> + *
>>> + * Copyright 2007 Andy Green<andy at warmcat.com>
>>> + * Copyright 2009 Johannes Berg<johannes at sipsolutions.net>
>>> + *
>>> + * This program is free software; you can redistribute it and/or modify
>>> + * it under the terms of the GNU General Public License version 2 as
>>> + * published by the Free Software Foundation.
>>> + *
>>> + * Alternatively, this software may be distributed under the terms of
>>> BSD
>>> + * license.
>>> + *
>>> + * See COPYING for more details.
>>> + */
>>> +#include<click/radiotap_iter.h>
>>> +#include<click/platform.h>
>>> +
>>> +/* function prototypes and related defs are in radiotap_iter.h */
>>> +
>>> +static const struct radiotap_align_size rtap_namespace_sizes[] = {
>>> + [IEEE80211_RADIOTAP_TSFT] = { .align = 8, .size = 8, },
>>> + [IEEE80211_RADIOTAP_FLAGS] = { .align = 1, .size = 1, },
>>> + [IEEE80211_RADIOTAP_RATE] = { .align = 1, .size = 1, },
>>> + [IEEE80211_RADIOTAP_CHANNEL] = { .align = 2, .size = 4, },
>>> + [IEEE80211_RADIOTAP_FHSS] = { .align = 2, .size = 2, },
>>> + [IEEE80211_RADIOTAP_DBM_ANTSIGNAL] = { .align = 1, .size = 1, },
>>> + [IEEE80211_RADIOTAP_DBM_ANTNOISE] = { .align = 1, .size = 1, },
>>> + [IEEE80211_RADIOTAP_LOCK_QUALITY] = { .align = 2, .size = 2, },
>>> + [IEEE80211_RADIOTAP_TX_ATTENUATION] = { .align = 2, .size = 2, },
>>> + [IEEE80211_RADIOTAP_DB_TX_ATTENUATION] = { .align = 2, .size = 2, },
>>> + [IEEE80211_RADIOTAP_DBM_TX_POWER] = { .align = 1, .size = 1, },
>>> + [IEEE80211_RADIOTAP_ANTENNA] = { .align = 1, .size = 1, },
>>> + [IEEE80211_RADIOTAP_DB_ANTSIGNAL] = { .align = 1, .size = 1, },
>>> + [IEEE80211_RADIOTAP_DB_ANTNOISE] = { .align = 1, .size = 1, },
>>> + [IEEE80211_RADIOTAP_RX_FLAGS] = { .align = 2, .size = 2, },
>>> + [IEEE80211_RADIOTAP_TX_FLAGS] = { .align = 2, .size = 2, },
>>> + [IEEE80211_RADIOTAP_RTS_RETRIES] = { .align = 1, .size = 1, },
>>> + [IEEE80211_RADIOTAP_DATA_RETRIES] = { .align = 1, .size = 1, },
>>> + [IEEE80211_RADIOTAP_MCS] = { .align = 1, .size = 3, },
>>> + /*
>>> + * add more here as they are defined in radiotap.h
>>> + */
>>> +};
>>> +
>>> +static const struct ieee80211_radiotap_namespace radiotap_ns = {
>>> + .n_bits = sizeof(rtap_namespace_sizes) /
>>> sizeof(rtap_namespace_sizes[0]),
>>> + .align_size = rtap_namespace_sizes,
>>> +};
>>> +
>>> +/**
>>> + * ieee80211_radiotap_iterator_init - radiotap parser iterator
>>> initialization
>>> + * @iterator: radiotap_iterator to initialize
>>> + * @radiotap_header: radiotap header to parse
>>> + * @max_length: total length we can parse into (eg, whole packet length)
>>> + *
>>> + * Returns: 0 or a negative error code if there is a problem.
>>> + *
>>> + * This function initializes an opaque iterator struct which can then
>>> + * be passed to ieee80211_radiotap_iterator_next() to visit every
>>> radiotap
>>> + * argument which is present in the header. It knows about extended
>>> + * present headers and handles them.
>>> + *
>>> + * How to use:
>>> + * call __ieee80211_radiotap_iterator_init() to init a semi-opaque
>>> iterator
>>> + * struct ieee80211_radiotap_iterator (no need to init the struct
>>> beforehand)
>>> + * checking for a good 0 return code. Then loop calling
>>> + * __ieee80211_radiotap_iterator_next()... it returns either 0,
>>> + * -ENOENT if there are no more args to parse, or -EINVAL if there is a
>>> problem.
>>> + * The iterator's @this_arg member points to the start of the argument
>>> + * associated with the current argument index that is present, which
>>> can be
>>> + * found in the iterator's @this_arg_index member. This arg index
>>> corresponds
>>> + * to the IEEE80211_RADIOTAP_... defines.
>>> + *
>>> + * Radiotap header length:
>>> + * You can find the CPU-endian total radiotap header length in
>>> + * iterator->max_length after executing
>>> ieee80211_radiotap_iterator_init()
>>> + * successfully.
>>> + *
>>> + * Alignment Gotcha:
>>> + * You must take care when dereferencing iterator.this_arg
>>> + * for multibyte types... the pointer is not aligned. Use
>>> + * get_unaligned((type *)iterator.this_arg) to dereference
>>> + * iterator.this_arg for type "type" safely on all arches.
>>> + *
>>> + * Example code: parse.c
>>> + */
>>> +
>>> +int ieee80211_radiotap_iterator_init(
>>> + struct ieee80211_radiotap_iterator *iterator,
>>> + struct ieee80211_radiotap_header *radiotap_header,
>>> + int max_length, const struct ieee80211_radiotap_vendor_namespaces *vns)
>>> +{
>>> + /* Linux only supports version 0 radiotap format */
>>> + if (radiotap_header->it_version)
>>> + return -EINVAL;
>>> +
>>> + /* sanity check for allowed length and radiotap length field */
>>> + if (max_length< get_unaligned_le16(&radiotap_header->it_len))
>>> + return -EINVAL;
>>> +
>>> + iterator->_rtheader = radiotap_header;
>>> + iterator->_max_length = get_unaligned_le16(&radiotap_header->it_len);
>>> + iterator->_arg_index = 0;
>>> + iterator->_bitmap_shifter =
>>> get_unaligned_le32(&radiotap_header->it_present);
>>> + iterator->_arg = (uint8_t *)radiotap_header + sizeof(*radiotap_header);
>>> + iterator->_reset_on_ext = 0;
>>> + iterator->_next_bitmap =&radiotap_header->it_present;
>>> + iterator->_next_bitmap++;
>>> + iterator->_vns = vns;
>>> + iterator->current_namespace =&radiotap_ns;
>>> + iterator->is_radiotap_ns = 1;
>>> +#ifdef RADIOTAP_SUPPORT_OVERRIDES
>>> + iterator->n_overrides = 0;
>>> + iterator->overrides = NULL;
>>> +#endif
>>> +
>>> + /* find payload start allowing for extended bitmap(s) */
>>> +
>>> + if (iterator->_bitmap_shifter& (1<<IEEE80211_RADIOTAP_EXT)) {
>>> + while (get_unaligned_le32(iterator->_arg)&
>>> + (1<< IEEE80211_RADIOTAP_EXT)) {
>>> + iterator->_arg += sizeof(uint32_t);
>>> +
>>> + /*
>>> + * check for insanity where the present bitmaps
>>> + * keep claiming to extend up to or even beyond the
>>> + * stated radiotap header length
>>> + */
>>> +
>>> + if ((unsigned long)iterator->_arg -
>>> + (unsigned long)iterator->_rtheader>
>>> + (unsigned long)iterator->_max_length)
>>> + return -EINVAL;
>>> + }
>>> +
>>> + iterator->_arg += sizeof(uint32_t);
>>> +
>>> + /*
>>> + * no need to check again for blowing past stated radiotap
>>> + * header length, because ieee80211_radiotap_iterator_next
>>> + * checks it before it is dereferenced
>>> + */
>>> + }
>>> +
>>> + iterator->this_arg = iterator->_arg;
>>> +
>>> + /* we are all initialized happily */
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +static void find_ns(struct ieee80211_radiotap_iterator *iterator,
>>> + uint32_t oui, uint8_t subns)
>>> +{
>>> + int i;
>>> +
>>> + iterator->current_namespace = NULL;
>>> +
>>> + if (!iterator->_vns)
>>> + return;
>>> +
>>> + for (i = 0; i< iterator->_vns->n_ns; i++) {
>>> + if (iterator->_vns->ns[i].oui != oui)
>>> + continue;
>>> + if (iterator->_vns->ns[i].subns != subns)
>>> + continue;
>>> +
>>> + iterator->current_namespace =&iterator->_vns->ns[i];
>>> + break;
>>> + }
>>> +}
>>> +
>>> +#ifdef RADIOTAP_SUPPORT_OVERRIDES
>>> +static int find_override(struct ieee80211_radiotap_iterator *iterator,
>>> + int *align, int *size)
>>> +{
>>> + int i;
>>> +
>>> + if (!iterator->overrides)
>>> + return 0;
>>> +
>>> + for (i = 0; i< iterator->n_overrides; i++) {
>>> + if (iterator->_arg_index == iterator->overrides[i].field) {
>>> + *align = iterator->overrides[i].align;
>>> + *size = iterator->overrides[i].size;
>>> + if (!*align) /* erroneous override */
>>> + return 0;
>>> + return 1;
>>> + }
>>> + }
>>> +
>>> + return 0;
>>> +}
>>> +#endif
>>> +
>>> +
>>> +/**
>>> + * ieee80211_radiotap_iterator_next - return next radiotap parser
>>> iterator arg
>>> + * @iterator: radiotap_iterator to move to next arg (if any)
>>> + *
>>> + * Returns: 0 if there is an argument to handle,
>>> + * -ENOENT if there are no more args or -EINVAL
>>> + * if there is something else wrong.
>>> + *
>>> + * This function provides the next radiotap arg index
>>> (IEEE80211_RADIOTAP_*)
>>> + * in @this_arg_index and sets @this_arg to point to the
>>> + * payload for the field. It takes care of alignment handling and
>>> extended
>>> + * present fields. @this_arg can be changed by the caller (eg,
>>> + * incremented to move inside a compound argument like
>>> + * IEEE80211_RADIOTAP_CHANNEL). The args pointed to are in
>>> + * little-endian format whatever the endianess of your CPU.
>>> + *
>>> + * Alignment Gotcha:
>>> + * You must take care when dereferencing iterator.this_arg
>>> + * for multibyte types... the pointer is not aligned. Use
>>> + * get_unaligned((type *)iterator.this_arg) to dereference
>>> + * iterator.this_arg for type "type" safely on all arches.
>>> + */
>>> +
>>> +int ieee80211_radiotap_iterator_next(
>>> + struct ieee80211_radiotap_iterator *iterator)
>>> +{
>>> + while (1) {
>>> + int hit = 0;
>>> + int pad, align, size, subns;
>>> + uint32_t oui;
>>> +
>>> + /* if no more EXT bits, that's it */
>>> + if ((iterator->_arg_index % 32) == IEEE80211_RADIOTAP_EXT&&
>>> + !(iterator->_bitmap_shifter& 1))
>>> + return -ENOENT;
>>> +
>>> + if (!(iterator->_bitmap_shifter& 1))
>>> + goto next_entry; /* arg not present */
>>> +
>>> + /* get alignment/size of data */
>>> + switch (iterator->_arg_index % 32) {
>>> + case IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE:
>>> + case IEEE80211_RADIOTAP_EXT:
>>> + align = 1;
>>> + size = 0;
>>> + break;
>>> + case IEEE80211_RADIOTAP_VENDOR_NAMESPACE:
>>> + align = 2;
>>> + size = 6;
>>> + break;
>>> + default:
>>> +#ifdef RADIOTAP_SUPPORT_OVERRIDES
>>> + if (find_override(iterator,&align,&size)) {
>>> + /* all set */
>>> + } else
>>> +#endif
>>> + if (!iterator->current_namespace ||
>>> + iterator->_arg_index>=
>>> iterator->current_namespace->n_bits) {
>>> + if (iterator->current_namespace ==&radiotap_ns)
>>> + return -ENOENT;
>>> + align = 0;
>>> + } else {
>>> + align =
>>> iterator->current_namespace->align_size[iterator->_arg_index].align;
>>> + size =
>>> iterator->current_namespace->align_size[iterator->_arg_index].size;
>>> + }
>>> + if (!align) {
>>> + /* skip all subsequent data */
>>> + iterator->_arg = iterator->_next_ns_data;
>>> + /* give up on this namespace */
>>> + iterator->current_namespace = NULL;
>>> + goto next_entry;
>>> + }
>>> + break;
>>> + }
>>> +
>>> + /*
>>> + * arg is present, account for alignment padding
>>> + *
>>> + * Note that these alignments are relative to the start
>>> + * of the radiotap header. There is no guarantee
>>> + * that the radiotap header itself is aligned on any
>>> + * kind of boundary.
>>> + *
>>> + * The above is why get_unaligned() is used to dereference
>>> + * multibyte elements from the radiotap area.
>>> + */
>>> +
>>> + pad = ((unsigned long)iterator->_arg -
>>> + (unsigned long)iterator->_rtheader)& (align - 1);
>>> +
>>> + if (pad)
>>> + iterator->_arg += align - pad;
>>> +
>>> + if (iterator->_arg_index % 32 ==
>>> IEEE80211_RADIOTAP_VENDOR_NAMESPACE) {
>>> + int vnslen;
>>> +
>>> + if ((unsigned long)iterator->_arg + size -
>>> + (unsigned long)iterator->_rtheader>
>>> + (unsigned long)iterator->_max_length)
>>> + return -EINVAL;
>>> +
>>> + oui = (*iterator->_arg<< 16) |
>>> + (*(iterator->_arg + 1)<< 8) |
>>> + *(iterator->_arg + 2);
>>> + subns = *(iterator->_arg + 3);
>>> +
>>> + find_ns(iterator, oui, subns);
>>> +
>>> + vnslen = get_unaligned_le16(iterator->_arg + 4);
>>> + iterator->_next_ns_data = iterator->_arg + size + vnslen;
>>> + if (!iterator->current_namespace)
>>> + size += vnslen;
>>> + }
>>> +
>>> + /*
>>> + * this is what we will return to user, but we need to
>>> + * move on first so next call has something fresh to test
>>> + */
>>> + iterator->this_arg_index = iterator->_arg_index;
>>> + iterator->this_arg = iterator->_arg;
>>> + iterator->this_arg_size = size;
>>> +
>>> + /* internally move on the size of this arg */
>>> + iterator->_arg += size;
>>> +
>>> + /*
>>> + * check for insanity where we are given a bitmap that
>>> + * claims to have more arg content than the length of the
>>> + * radiotap section. We will normally end up equalling this
>>> + * max_length on the last arg, never exceeding it.
>>> + */
>>> +
>>> + if ((unsigned long)iterator->_arg -
>>> + (unsigned long)iterator->_rtheader>
>>> + (unsigned long)iterator->_max_length)
>>> + return -EINVAL;
>>> +
>>> + /* these special ones are valid in each bitmap word */
>>> + switch (iterator->_arg_index % 32) {
>>> + case IEEE80211_RADIOTAP_VENDOR_NAMESPACE:
>>> + iterator->_reset_on_ext = 1;
>>> +
>>> + iterator->is_radiotap_ns = 0;
>>> + /*
>>> + * If parser didn't register this vendor
>>> + * namespace with us, allow it to show it
>>> + * as 'raw. Do do that, set argument index
>>> + * to vendor namespace.
>>> + */
>>> + iterator->this_arg_index =
>>> + IEEE80211_RADIOTAP_VENDOR_NAMESPACE;
>>> + if (!iterator->current_namespace)
>>> + hit = 1;
>>> + goto next_entry;
>>> + case IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE:
>>> + iterator->_reset_on_ext = 1;
>>> + iterator->current_namespace =&radiotap_ns;
>>> + iterator->is_radiotap_ns = 1;
>>> + goto next_entry;
>>> + case IEEE80211_RADIOTAP_EXT:
>>> + /*
>>> + * bit 31 was set, there is more
>>> + * -- move to next u32 bitmap
>>> + */
>>> + iterator->_bitmap_shifter =
>>> + get_unaligned_le32(iterator->_next_bitmap);
>>> + iterator->_next_bitmap++;
>>> + if (iterator->_reset_on_ext)
>>> + iterator->_arg_index = 0;
>>> + else
>>> + iterator->_arg_index++;
>>> + iterator->_reset_on_ext = 0;
>>> + break;
>>> + default:
>>> + /* we've got a hit! */
>>> + hit = 1;
>>> + next_entry:
>>> + iterator->_bitmap_shifter>>= 1;
>>> + iterator->_arg_index++;
>>> + }
>>> +
>>> + /* if we found a valid arg earlier, return it now */
>>> + if (hit)
>>> + return 0;
>>> + }
>>> +}
>>> diff -urN --exclude .git --exclude conf --exclude diffserv --exclude
>>> ethernet --exclude secaggr --exclude wing --exclude availablechannels
>>> --exclude availablerates click.upstream/userlevel/Makefile.in
>>> click/userlevel/Makefile.in
>>> --- click.upstream/userlevel/Makefile.in 2011-04-11
>>> 11:52:49.881608001 +0200
>>> +++ click/userlevel/Makefile.in 2011-03-31 16:56:55.457465001 +0200
>>> @@ -61,7 +61,7 @@
>>> element.o \
>>> confparse.o variableenv.o lexer.o elemfilter.o routervisitor.o \
>>> routerthread.o router.o master.o handlercall.o notifier.o \
>>> - integers.o md5.o crc32.o in_cksum.o iptable.o \
>>> + integers.o md5.o radiotap.o crc32.o in_cksum.o iptable.o \
>>> archive.o userutils.o driver.o \
>>> $(EXTRA_DRIVER_OBJS)
>>>
>>>
>>>
>>> _______________________________________________
>>> click mailing list
>>> click at amsterdam.lcs.mit.edu
>>> https://amsterdam.lcs.mit.edu/mailman/listinfo/click
>
>


More information about the click mailing list