Please note: This project is no longer active. The website is kept online for historic purposes only.
If you´re looking for a Linux driver for your Atheros WLAN device, you should continue here .

Ticket #699: enhanced-iwspy.diff

File enhanced-iwspy.diff, 6.1 kB (added by Christian Buennig <masala@web.de>, 13 years ago)
  • net80211/ieee80211_wireless.c

    old new  
    11011101        return 0; 
    11021102} 
    11031103 
     1104/* Enhanced iwspy support */ 
    11041105static int 
     1106ieee80211_ioctl_setthrspy(struct net_device *dev, struct iw_request_info *info, 
     1107        struct iw_point *data, char *extra) 
     1108{ 
     1109        struct ieee80211vap *vap = dev->priv; 
     1110        struct iw_thrspy threshold; 
     1111 
     1112        if (data->length != 1) 
     1113                return -EINVAL; 
     1114         
     1115        /* get the threshold values into the driver */ 
     1116        if (data->pointer) { 
     1117                if (copy_from_user(&threshold, data->pointer, 
     1118                    sizeof(struct iw_thrspy))) 
     1119                        return -EFAULT; 
     1120        } else 
     1121                return -EINVAL; 
     1122                 
     1123        if (threshold.low.level == 0) { 
     1124                /* disable threshold */ 
     1125                vap->iv_spy.thr_low = 0; 
     1126                vap->iv_spy.thr_high = 0; 
     1127                IEEE80211_DPRINTF(vap, IEEE80211_MSG_DEBUG, 
     1128                        "%s: disabled iw_spy threshold\n", __func__); 
     1129        } else { 
     1130                /* calculate corresponding rssi values */ 
     1131                vap->iv_spy.thr_low = threshold.low.level - 161; 
     1132                vap->iv_spy.thr_high = threshold.high.level - 161; 
     1133                IEEE80211_DPRINTF(vap, IEEE80211_MSG_DEBUG, 
     1134                        "%s: enabled iw_spy threshold\n", __func__); 
     1135        } 
     1136 
     1137        return 0; 
     1138} 
     1139 
     1140static int 
     1141ieee80211_ioctl_getthrspy(struct net_device *dev, struct iw_request_info *info, 
     1142        struct iw_point *data, char *extra) 
     1143{ 
     1144        struct ieee80211vap *vap = dev->priv; 
     1145        struct iw_thrspy *threshold;     
     1146         
     1147        threshold = (struct iw_thrspy *) extra; 
     1148 
     1149        /* set threshold values */ 
     1150        set_quality(&(threshold->low), vap->iv_spy.thr_low); 
     1151        set_quality(&(threshold->high), vap->iv_spy.thr_high); 
     1152 
     1153        /* copy results to userspace */ 
     1154        data->length = 1; 
     1155         
     1156        return 0; 
     1157} 
     1158 
     1159static int 
    11051160ieee80211_ioctl_siwmode(struct net_device *dev, struct iw_request_info *info, 
    11061161        __u32 *mode, char *extra) 
    11071162{ 
     
    47074762        (iw_handler) NULL /* kernel code */,            /* SIOCGIWSTATS */ 
    47084763        (iw_handler) ieee80211_ioctl_setspy,            /* SIOCSIWSPY */ 
    47094764        (iw_handler) ieee80211_ioctl_getspy,            /* SIOCGIWSPY */ 
    4710         (iw_handler) NULL,                             /* -- hole -- */ 
    4711         (iw_handler) NULL,                             /* -- hole -- */ 
     4765        (iw_handler) ieee80211_ioctl_setthrspy,                /* SIOCSIWTHRSPY */ 
     4766        (iw_handler) ieee80211_ioctl_getthrspy,                /* SIOCGIWTHRSPY */ 
    47124767        (iw_handler) ieee80211_ioctl_siwap,             /* SIOCSIWAP */ 
    47134768        (iw_handler) ieee80211_ioctl_giwap,             /* SIOCGIWAP */ 
    47144769#ifdef SIOCSIWMLME 
  • net80211/ieee80211_input.c

    old new  
    4646#include <linux/etherdevice.h> 
    4747#include <linux/random.h> 
    4848#include <linux/if_vlan.h> 
     49#include <net/iw_handler.h> /* wireless_send_event(..) */ 
     50#include <linux/wireless.h> /* SIOCGIWTHRSPY */ 
     51#include <linux/if_arp.h> /* ARPHRD_ETHER */ 
    4952 
    5053#include "if_llc.h" 
    5154#include "if_ethersubr.h" 
     
    107110#define IEEE80211_DISCARD_MAC(_vap, _m, _mac, _type, _fmt, ...) 
    108111#endif /* IEEE80211_DEBUG */ 
    109112 
     113/* Enhanced iwspy support */ 
     114#ifdef CONFIG_NET_WIRELESS 
     115#if WIRELESS_EXT >= 16 
     116/* 
     117 * Macro that does the same as set_quality(..) in ieee80211_wireless.c 
     118 *  
     119 * @param _iwq (struct iw_quality): iw_quality to set 
     120 * @param _rssi (u_int_8): rssi value to sue for setting quality 
     121 */ 
     122#define SET_QUALITY(_iwq, _rssi) do {                                   \ 
     123        _iwq.qual = _rssi;                                              \ 
     124        if (_iwq.qual > 94) _iwq.qual = 94;                             \ 
     125        _iwq.noise = 161;                                               \ 
     126        _iwq.level = _iwq.noise + _iwq.qual;                            \ 
     127        _iwq.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED |   \ 
     128                IW_QUAL_NOISE_UPDATED;                                  \ 
     129} while (0); 
     130 
     131/* 
     132 * Given a node and the rssi value of a just received frame from the node, this 
     133 * macro checks if to raise an iwspy event because we iwspy the node and rssi 
     134 * exceeds threshold (if active). 
     135 *  
     136 * @param _vap (struct ieee80211vap *): ref to vap 
     137 * @param _ni (struct ieee80211_node *): ref to sender node 
     138 * @param _rssi (u_int_8): rssi value of received frame 
     139 */ 
     140#define IWSPY_EVENT(_vap, _ni, _rssi) do {                                      \ 
     141        if (_vap->iv_spy.thr_low && _vap->iv_spy.num && _ni && (_rssi <         \ 
     142                _vap->iv_spy.thr_low || _rssi > _vap->iv_spy.thr_high)) {       \ 
     143                int i;                                                          \ 
     144                for (i = 0; i < _vap->iv_spy.num; i++) {                        \ 
     145                        if (IEEE80211_ADDR_EQ(_ni->ni_macaddr,                  \ 
     146                                &(_vap->iv_spy.mac[i * IEEE80211_ADDR_LEN]))) { \ 
     147                                union iwreq_data wrq;                           \ 
     148                                struct iw_thrspy thr;                           \ 
     149                                IEEE80211_DPRINTF(_vap, IEEE80211_MSG_DEBUG,    \ 
     150                                        "%s: we spy %s, threshold is active "   \ 
     151                                        "and rssi exceeds it -> raise an iwspy" \ 
     152                                        " event\n", __func__, ether_sprintf(    \ 
     153                                         _ni->ni_macaddr));                     \ 
     154                                memset(&wrq, 0, sizeof(wrq));                   \ 
     155                                wrq.data.length = 1;                            \ 
     156                                memset(&thr, 0, sizeof(struct iw_thrspy));      \ 
     157                                memcpy(thr.addr.sa_data, _ni->ni_macaddr,       \ 
     158                                        IEEE80211_ADDR_LEN);                    \ 
     159                                thr.addr.sa_family = ARPHRD_ETHER;              \ 
     160                                SET_QUALITY(thr.qual, _rssi);                   \ 
     161                                SET_QUALITY(thr.low, _vap->iv_spy.thr_low);     \ 
     162                                SET_QUALITY(thr.high, _vap->iv_spy.thr_high);   \ 
     163                                wireless_send_event(_vap->iv_dev,               \ 
     164                                        SIOCGIWTHRSPY, &wrq, (char*) &thr);     \ 
     165                                break;                                          \ 
     166                        }                                                       \ 
     167                }                                                               \ 
     168        }                                                                       \ 
     169} while (0); 
     170#else 
     171#define IWSPY_EVENT(_vap, _ni, _rssi) 
     172#endif /* WIRELESS_EXT >= 16 */ 
     173#else 
     174#define IWSPY_EVENT(_vap, _ni, _rssi) 
     175#endif /* CONFIG_NET_WIRELESS */ 
     176 
    110177static struct sk_buff *ieee80211_defrag(struct ieee80211_node *, 
    111178        struct sk_buff *, int); 
    112179static void ieee80211_deliver_data(struct ieee80211_node *, struct sk_buff *); 
     
    209276                                vap->iv_stats.is_rx_wrongbss++; 
    210277                                goto out; 
    211278                        } 
     279                        IWSPY_EVENT(vap, ni, rssi); 
    212280                        break; 
    213281                case IEEE80211_M_IBSS: 
    214282                case IEEE80211_M_AHDEMO: 
     
    247315                                        } 
    248316                                } 
    249317                        } 
     318                        IWSPY_EVENT(vap, ni, rssi); 
    250319                        break; 
    251320                case IEEE80211_M_HOSTAP: 
    252321                        if (dir != IEEE80211_FC1_DIR_NODS) 
  • net80211/ieee80211_var.h

    old new  
    262262#define IW_MAX_SPY 8 
    263263struct ieee80211_spy { 
    264264        u_int8_t mac[IW_MAX_SPY * IEEE80211_ADDR_LEN]; 
     265        u_int8_t thr_low;       /* 1 byte rssi value, 0 = threshold is off */ 
     266        u_int8_t thr_high;      /* 1 byte rssi value */    
    265267        u_int8_t num; 
    266268}; 
    267269