[Click] [RFC] Update radiotap parser
Eddie Kohler
kohler at cs.ucla.edu
Wed Jul 13 19:28:46 EDT 2011
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