Ticket #699: enhanced-iwspy-2.diff
| File enhanced-iwspy-2.diff, 5.8 kB (added by masala@web.de, 6 years ago) |
|---|
-
net80211/ieee80211_wireless.c
old new 1101 1101 return 0; 1102 1102 } 1103 1103 1104 /* Enhanced iwspy support */ 1104 1105 static int 1106 ieee80211_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 1140 static int 1141 ieee80211_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 1159 static int 1105 1160 ieee80211_ioctl_siwmode(struct net_device *dev, struct iw_request_info *info, 1106 1161 __u32 *mode, char *extra) 1107 1162 { … … 4707 4762 (iw_handler) NULL /* kernel code */, /* SIOCGIWSTATS */ 4708 4763 (iw_handler) ieee80211_ioctl_setspy, /* SIOCSIWSPY */ 4709 4764 (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 */ 4712 4767 (iw_handler) ieee80211_ioctl_siwap, /* SIOCSIWAP */ 4713 4768 (iw_handler) ieee80211_ioctl_giwap, /* SIOCGIWAP */ 4714 4769 #ifdef SIOCSIWMLME -
net80211/ieee80211_input.c
old new 46 46 #include <linux/etherdevice.h> 47 47 #include <linux/random.h> 48 48 #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 */ 49 52 50 53 #include "if_llc.h" 51 54 #include "if_ethersubr.h" … … 123 126 static unsigned short ath_eth_type_trans(struct sk_buff *, struct net_device *); 124 127 #endif 125 128 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 */ 136 static void 137 set_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 */ 159 static void 160 iwspy_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 126 200 /* 127 201 * Process a received frame. The node associated with the sender 128 202 * should be supplied. If nothing was found in the node table then … … 209 283 vap->iv_stats.is_rx_wrongbss++; 210 284 goto out; 211 285 } 286 iwspy_event(vap, ni, rssi); 212 287 break; 213 288 case IEEE80211_M_IBSS: 214 289 case IEEE80211_M_AHDEMO: … … 247 322 } 248 323 } 249 324 } 325 iwspy_event(vap, ni, rssi); 250 326 break; 251 327 case IEEE80211_M_HOSTAP: 252 328 if (dir != IEEE80211_FC1_DIR_NODS) -
net80211/ieee80211_var.h
old new 262 262 #define IW_MAX_SPY 8 263 263 struct ieee80211_spy { 264 264 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 */ 265 267 u_int8_t num; 266 268 }; 267 269
