[Click] [RFC] Update radiotap parser

Roberto Riggio roberto.riggio at create-net.org
Thu Jul 14 03:42:35 EDT 2011


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().

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


-- 
--------------------------------------------------------
Roberto Riggio, Ph.D.
CREATE-NET
Network & Security Solutions for Pervasive Computing Systems (iNSPIRE)
Senior Researcher
Via alla Cascata 56/D - 38123 Povo Trento (Italy)
e-mail: roberto.riggio at create-net.org
Tel: (+39) 0461 408400 - interno/extension 708
Fax: (+39) 0461 421157
www.create-net.org/~rriggio
--------------------------------------------------------

The information transmitted is intended only for the person or entity to
which it is addressed and may contain confidential and/or privileged
material. Any review, retransmission, dissemination or other use of, or
taking of any action in reliance upon, this information by persons or
entities other than the intended recipient is prohibited according to
the Italian Law 196/2003 of the Legislature. If you received this in
error, please contact the sender and delete the material from any
computer.

Le informazioni contenute in questo messaggio di posta elettronica e nei
file allegati sono da considerarsi strettamente riservate. Il loro
utilizzo e' consentito esclusivamente al destinatario del messaggio, per
le finalita' indicate nel messaggio stesso. Qualora riceveste questo
messaggio senza esserne il destinatario, Vi preghiamo cortesemente di
darcene notizia via e-mail e di procedere alla cancellazione del
messaggio stesso dal Vostro sistema. Trattenere il messaggio stesso,
divulgarlo anche in parte, distribuirlo ad altri soggetti, copiarlo,
od utilizzarlo per finalita' diverse, costituisce comportamento
contrario ai principi dettati dal D. Lgs. 196/2003.


More information about the click mailing list