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-2.diff

File enhanced-iwspy-2.diff, 5.8 kB (added by masala@web.de, 13 years ago)

Enhanced iwspy-support. Same as first patch, but macros in ieee80211_input.c are replaced by functions. Signed-off-by: Christian Buennig <masala@web.de>

  • 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" 
     
    123126static unsigned short ath_eth_type_trans(struct sk_buff *, struct net_device *); 
    124127#endif 
    125128 
     129/* Enhanced iwspy support */ 
     130#ifdef CONFIG_NET_WIRELESS 
     131#if WIRELESS_EXT >= 16 
     132 
     133/** 
     134 * This function is a clone of set_quality(..) in ieee80211_wireless.c 
     135 */ 
     136static void 
     137set_quality(struct iw_quality *iq, u_int rssi) 
     138{ 
     139        iq->qual = rssi; 
     140        /* NB: max is 94 because noise is hardcoded to 161 */ 
     141        if (iq->qual > 94) 
     142                iq->qual = 94; 
     143 
     144        iq->noise = 161;                /* -95dBm */ 
     145        iq->level = iq->noise + iq->qual; 
     146        iq->updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | 
     147                IW_QUAL_NOISE_UPDATED; 
     148} 
     149 
     150/** 
     151 * Given a node and the rssi value of a just received frame from the node, this 
     152 * function checks if to raise an iwspy event because we iwspy the node and rssi 
     153 * exceeds threshold (if active). 
     154 *  
     155 * @param vap: vap 
     156 * @param ni: sender node 
     157 * @param rssi: rssi value of received frame 
     158 */ 
     159static void 
     160iwspy_event(struct ieee80211vap *vap, struct ieee80211_node *ni, u_int rssi) 
     161{ 
     162        if (vap->iv_spy.thr_low && vap->iv_spy.num && ni && (rssi < 
     163                vap->iv_spy.thr_low || rssi > vap->iv_spy.thr_high)) { 
     164                int i; 
     165                for (i = 0; i < vap->iv_spy.num; i++) { 
     166                        if (IEEE80211_ADDR_EQ(ni->ni_macaddr, 
     167                                &(vap->iv_spy.mac[i * IEEE80211_ADDR_LEN]))) { 
     168                                         
     169                                union iwreq_data wrq; 
     170                                struct iw_thrspy thr; 
     171                                IEEE80211_DPRINTF(vap, IEEE80211_MSG_DEBUG, 
     172                                        "%s: we spy %s, threshold is active " 
     173                                        "and rssi exceeds it -> raise an iwspy" 
     174                                        " event\n", __func__, ether_sprintf( 
     175                                         ni->ni_macaddr)); 
     176                                memset(&wrq, 0, sizeof(wrq)); 
     177                                wrq.data.length = 1; 
     178                                memset(&thr, 0, sizeof(struct iw_thrspy)); 
     179                                memcpy(thr.addr.sa_data, ni->ni_macaddr, 
     180                                        IEEE80211_ADDR_LEN); 
     181                                thr.addr.sa_family = ARPHRD_ETHER; 
     182                                set_quality(&thr.qual, rssi); 
     183                                set_quality(&thr.low, vap->iv_spy.thr_low); 
     184                                set_quality(&thr.high, vap->iv_spy.thr_high); 
     185                                wireless_send_event(vap->iv_dev, 
     186                                        SIOCGIWTHRSPY, &wrq, (char*) &thr); 
     187                                break; 
     188                        } 
     189                } 
     190        } 
     191} 
     192 
     193#else 
     194#define iwspy_event(_vap, _ni, _rssi) 
     195#endif /* WIRELESS_EXT >= 16 */ 
     196#else 
     197#define iwspy_event(_vap, _ni, _rssi) 
     198#endif /* CONFIG_NET_WIRELESS */ 
     199 
    126200/* 
    127201 * Process a received frame.  The node associated with the sender 
    128202 * should be supplied.  If nothing was found in the node table then 
     
    209283                                vap->iv_stats.is_rx_wrongbss++; 
    210284                                goto out; 
    211285                        } 
     286                        iwspy_event(vap, ni, rssi); 
    212287                        break; 
    213288                case IEEE80211_M_IBSS: 
    214289                case IEEE80211_M_AHDEMO: 
     
    247322                                        } 
    248323                                } 
    249324                        } 
     325                        iwspy_event(vap, ni, rssi); 
    250326                        break; 
    251327                case IEEE80211_M_HOSTAP: 
    252328                        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