mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-04 20:19:47 +08:00
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/wireless-2.6
This commit is contained in:
commit
1839cea91e
@ -571,6 +571,7 @@ static void gelic_wl_parse_ie(u8 *data, size_t len,
|
|||||||
* independent format
|
* independent format
|
||||||
*/
|
*/
|
||||||
static char *gelic_wl_translate_scan(struct net_device *netdev,
|
static char *gelic_wl_translate_scan(struct net_device *netdev,
|
||||||
|
struct iw_request_info *info,
|
||||||
char *ev,
|
char *ev,
|
||||||
char *stop,
|
char *stop,
|
||||||
struct gelic_wl_scan_info *network)
|
struct gelic_wl_scan_info *network)
|
||||||
@ -588,26 +589,26 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
|
|||||||
iwe.cmd = SIOCGIWAP;
|
iwe.cmd = SIOCGIWAP;
|
||||||
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
|
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
|
||||||
memcpy(iwe.u.ap_addr.sa_data, &scan->bssid[2], ETH_ALEN);
|
memcpy(iwe.u.ap_addr.sa_data, &scan->bssid[2], ETH_ALEN);
|
||||||
ev = iwe_stream_add_event(ev, stop, &iwe, IW_EV_ADDR_LEN);
|
ev = iwe_stream_add_event(info, ev, stop, &iwe, IW_EV_ADDR_LEN);
|
||||||
|
|
||||||
/* ESSID */
|
/* ESSID */
|
||||||
iwe.cmd = SIOCGIWESSID;
|
iwe.cmd = SIOCGIWESSID;
|
||||||
iwe.u.data.flags = 1;
|
iwe.u.data.flags = 1;
|
||||||
iwe.u.data.length = strnlen(scan->essid, 32);
|
iwe.u.data.length = strnlen(scan->essid, 32);
|
||||||
ev = iwe_stream_add_point(ev, stop, &iwe, scan->essid);
|
ev = iwe_stream_add_point(info, ev, stop, &iwe, scan->essid);
|
||||||
|
|
||||||
/* FREQUENCY */
|
/* FREQUENCY */
|
||||||
iwe.cmd = SIOCGIWFREQ;
|
iwe.cmd = SIOCGIWFREQ;
|
||||||
iwe.u.freq.m = be16_to_cpu(scan->channel);
|
iwe.u.freq.m = be16_to_cpu(scan->channel);
|
||||||
iwe.u.freq.e = 0; /* table value in MHz */
|
iwe.u.freq.e = 0; /* table value in MHz */
|
||||||
iwe.u.freq.i = 0;
|
iwe.u.freq.i = 0;
|
||||||
ev = iwe_stream_add_event(ev, stop, &iwe, IW_EV_FREQ_LEN);
|
ev = iwe_stream_add_event(info, ev, stop, &iwe, IW_EV_FREQ_LEN);
|
||||||
|
|
||||||
/* RATES */
|
/* RATES */
|
||||||
iwe.cmd = SIOCGIWRATE;
|
iwe.cmd = SIOCGIWRATE;
|
||||||
iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
|
iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
|
||||||
/* to stuff multiple values in one event */
|
/* to stuff multiple values in one event */
|
||||||
tmp = ev + IW_EV_LCP_LEN;
|
tmp = ev + iwe_stream_lcp_len(info);
|
||||||
/* put them in ascendant order (older is first) */
|
/* put them in ascendant order (older is first) */
|
||||||
i = 0;
|
i = 0;
|
||||||
j = 0;
|
j = 0;
|
||||||
@ -620,16 +621,16 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
|
|||||||
else
|
else
|
||||||
rate = scan->rate[i++] & 0x7f;
|
rate = scan->rate[i++] & 0x7f;
|
||||||
iwe.u.bitrate.value = rate * 500000; /* 500kbps unit */
|
iwe.u.bitrate.value = rate * 500000; /* 500kbps unit */
|
||||||
tmp = iwe_stream_add_value(ev, tmp, stop, &iwe,
|
tmp = iwe_stream_add_value(info, ev, tmp, stop, &iwe,
|
||||||
IW_EV_PARAM_LEN);
|
IW_EV_PARAM_LEN);
|
||||||
}
|
}
|
||||||
while (j < network->rate_ext_len) {
|
while (j < network->rate_ext_len) {
|
||||||
iwe.u.bitrate.value = (scan->ext_rate[j++] & 0x7f) * 500000;
|
iwe.u.bitrate.value = (scan->ext_rate[j++] & 0x7f) * 500000;
|
||||||
tmp = iwe_stream_add_value(ev, tmp, stop, &iwe,
|
tmp = iwe_stream_add_value(info, ev, tmp, stop, &iwe,
|
||||||
IW_EV_PARAM_LEN);
|
IW_EV_PARAM_LEN);
|
||||||
}
|
}
|
||||||
/* Check if we added any rate */
|
/* Check if we added any rate */
|
||||||
if (IW_EV_LCP_LEN < (tmp - ev))
|
if (iwe_stream_lcp_len(info) < (tmp - ev))
|
||||||
ev = tmp;
|
ev = tmp;
|
||||||
|
|
||||||
/* ENCODE */
|
/* ENCODE */
|
||||||
@ -639,7 +640,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
|
|||||||
else
|
else
|
||||||
iwe.u.data.flags = IW_ENCODE_DISABLED;
|
iwe.u.data.flags = IW_ENCODE_DISABLED;
|
||||||
iwe.u.data.length = 0;
|
iwe.u.data.length = 0;
|
||||||
ev = iwe_stream_add_point(ev, stop, &iwe, scan->essid);
|
ev = iwe_stream_add_point(info, ev, stop, &iwe, scan->essid);
|
||||||
|
|
||||||
/* MODE */
|
/* MODE */
|
||||||
iwe.cmd = SIOCGIWMODE;
|
iwe.cmd = SIOCGIWMODE;
|
||||||
@ -649,7 +650,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
|
|||||||
iwe.u.mode = IW_MODE_MASTER;
|
iwe.u.mode = IW_MODE_MASTER;
|
||||||
else
|
else
|
||||||
iwe.u.mode = IW_MODE_ADHOC;
|
iwe.u.mode = IW_MODE_ADHOC;
|
||||||
ev = iwe_stream_add_event(ev, stop, &iwe, IW_EV_UINT_LEN);
|
ev = iwe_stream_add_event(info, ev, stop, &iwe, IW_EV_UINT_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* QUAL */
|
/* QUAL */
|
||||||
@ -659,7 +660,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
|
|||||||
iwe.u.qual.level = be16_to_cpu(scan->rssi);
|
iwe.u.qual.level = be16_to_cpu(scan->rssi);
|
||||||
iwe.u.qual.qual = be16_to_cpu(scan->rssi);
|
iwe.u.qual.qual = be16_to_cpu(scan->rssi);
|
||||||
iwe.u.qual.noise = 0;
|
iwe.u.qual.noise = 0;
|
||||||
ev = iwe_stream_add_event(ev, stop, &iwe, IW_EV_QUAL_LEN);
|
ev = iwe_stream_add_event(info, ev, stop, &iwe, IW_EV_QUAL_LEN);
|
||||||
|
|
||||||
/* RSN */
|
/* RSN */
|
||||||
memset(&iwe, 0, sizeof(iwe));
|
memset(&iwe, 0, sizeof(iwe));
|
||||||
@ -669,7 +670,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
|
|||||||
if (len) {
|
if (len) {
|
||||||
iwe.cmd = IWEVGENIE;
|
iwe.cmd = IWEVGENIE;
|
||||||
iwe.u.data.length = len;
|
iwe.u.data.length = len;
|
||||||
ev = iwe_stream_add_point(ev, stop, &iwe, buf);
|
ev = iwe_stream_add_point(info, ev, stop, &iwe, buf);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* this scan info has IE data */
|
/* this scan info has IE data */
|
||||||
@ -684,7 +685,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
|
|||||||
memcpy(buf, ie_info.wpa.data, ie_info.wpa.len);
|
memcpy(buf, ie_info.wpa.data, ie_info.wpa.len);
|
||||||
iwe.cmd = IWEVGENIE;
|
iwe.cmd = IWEVGENIE;
|
||||||
iwe.u.data.length = ie_info.wpa.len;
|
iwe.u.data.length = ie_info.wpa.len;
|
||||||
ev = iwe_stream_add_point(ev, stop, &iwe, buf);
|
ev = iwe_stream_add_point(info, ev, stop, &iwe, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ie_info.rsn.len && (ie_info.rsn.len <= sizeof(buf))) {
|
if (ie_info.rsn.len && (ie_info.rsn.len <= sizeof(buf))) {
|
||||||
@ -692,7 +693,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
|
|||||||
memcpy(buf, ie_info.rsn.data, ie_info.rsn.len);
|
memcpy(buf, ie_info.rsn.data, ie_info.rsn.len);
|
||||||
iwe.cmd = IWEVGENIE;
|
iwe.cmd = IWEVGENIE;
|
||||||
iwe.u.data.length = ie_info.rsn.len;
|
iwe.u.data.length = ie_info.rsn.len;
|
||||||
ev = iwe_stream_add_point(ev, stop, &iwe, buf);
|
ev = iwe_stream_add_point(info, ev, stop, &iwe, buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -737,7 +738,8 @@ static int gelic_wl_get_scan(struct net_device *netdev,
|
|||||||
if (wl->scan_age == 0 ||
|
if (wl->scan_age == 0 ||
|
||||||
time_after(scan_info->last_scanned + wl->scan_age,
|
time_after(scan_info->last_scanned + wl->scan_age,
|
||||||
this_time))
|
this_time))
|
||||||
ev = gelic_wl_translate_scan(netdev, ev, stop,
|
ev = gelic_wl_translate_scan(netdev, info,
|
||||||
|
ev, stop,
|
||||||
scan_info);
|
scan_info);
|
||||||
else
|
else
|
||||||
pr_debug("%s:entry too old\n", __func__);
|
pr_debug("%s:entry too old\n", __func__);
|
||||||
|
@ -7156,6 +7156,7 @@ out:
|
|||||||
* format that the Wireless Tools will understand - Jean II
|
* format that the Wireless Tools will understand - Jean II
|
||||||
*/
|
*/
|
||||||
static inline char *airo_translate_scan(struct net_device *dev,
|
static inline char *airo_translate_scan(struct net_device *dev,
|
||||||
|
struct iw_request_info *info,
|
||||||
char *current_ev,
|
char *current_ev,
|
||||||
char *end_buf,
|
char *end_buf,
|
||||||
BSSListRid *bss)
|
BSSListRid *bss)
|
||||||
@ -7172,7 +7173,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
|
|||||||
iwe.cmd = SIOCGIWAP;
|
iwe.cmd = SIOCGIWAP;
|
||||||
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
|
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
|
||||||
memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
|
memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
|
||||||
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
|
current_ev = iwe_stream_add_event(info, current_ev, end_buf,
|
||||||
|
&iwe, IW_EV_ADDR_LEN);
|
||||||
|
|
||||||
/* Other entries will be displayed in the order we give them */
|
/* Other entries will be displayed in the order we give them */
|
||||||
|
|
||||||
@ -7182,7 +7184,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
|
|||||||
iwe.u.data.length = 32;
|
iwe.u.data.length = 32;
|
||||||
iwe.cmd = SIOCGIWESSID;
|
iwe.cmd = SIOCGIWESSID;
|
||||||
iwe.u.data.flags = 1;
|
iwe.u.data.flags = 1;
|
||||||
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->ssid);
|
current_ev = iwe_stream_add_point(info, current_ev, end_buf,
|
||||||
|
&iwe, bss->ssid);
|
||||||
|
|
||||||
/* Add mode */
|
/* Add mode */
|
||||||
iwe.cmd = SIOCGIWMODE;
|
iwe.cmd = SIOCGIWMODE;
|
||||||
@ -7192,7 +7195,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
|
|||||||
iwe.u.mode = IW_MODE_MASTER;
|
iwe.u.mode = IW_MODE_MASTER;
|
||||||
else
|
else
|
||||||
iwe.u.mode = IW_MODE_ADHOC;
|
iwe.u.mode = IW_MODE_ADHOC;
|
||||||
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
|
current_ev = iwe_stream_add_event(info, current_ev, end_buf,
|
||||||
|
&iwe, IW_EV_UINT_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add frequency */
|
/* Add frequency */
|
||||||
@ -7203,7 +7207,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
|
|||||||
*/
|
*/
|
||||||
iwe.u.freq.m = frequency_list[iwe.u.freq.m - 1] * 100000;
|
iwe.u.freq.m = frequency_list[iwe.u.freq.m - 1] * 100000;
|
||||||
iwe.u.freq.e = 1;
|
iwe.u.freq.e = 1;
|
||||||
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
|
current_ev = iwe_stream_add_event(info, current_ev, end_buf,
|
||||||
|
&iwe, IW_EV_FREQ_LEN);
|
||||||
|
|
||||||
dBm = le16_to_cpu(bss->dBm);
|
dBm = le16_to_cpu(bss->dBm);
|
||||||
|
|
||||||
@ -7223,7 +7228,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
|
|||||||
| IW_QUAL_DBM;
|
| IW_QUAL_DBM;
|
||||||
}
|
}
|
||||||
iwe.u.qual.noise = ai->wstats.qual.noise;
|
iwe.u.qual.noise = ai->wstats.qual.noise;
|
||||||
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
|
current_ev = iwe_stream_add_event(info, current_ev, end_buf,
|
||||||
|
&iwe, IW_EV_QUAL_LEN);
|
||||||
|
|
||||||
/* Add encryption capability */
|
/* Add encryption capability */
|
||||||
iwe.cmd = SIOCGIWENCODE;
|
iwe.cmd = SIOCGIWENCODE;
|
||||||
@ -7232,11 +7238,12 @@ static inline char *airo_translate_scan(struct net_device *dev,
|
|||||||
else
|
else
|
||||||
iwe.u.data.flags = IW_ENCODE_DISABLED;
|
iwe.u.data.flags = IW_ENCODE_DISABLED;
|
||||||
iwe.u.data.length = 0;
|
iwe.u.data.length = 0;
|
||||||
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->ssid);
|
current_ev = iwe_stream_add_point(info, current_ev, end_buf,
|
||||||
|
&iwe, bss->ssid);
|
||||||
|
|
||||||
/* Rate : stuffing multiple values in a single event require a bit
|
/* Rate : stuffing multiple values in a single event require a bit
|
||||||
* more of magic - Jean II */
|
* more of magic - Jean II */
|
||||||
current_val = current_ev + IW_EV_LCP_LEN;
|
current_val = current_ev + iwe_stream_lcp_len(info);
|
||||||
|
|
||||||
iwe.cmd = SIOCGIWRATE;
|
iwe.cmd = SIOCGIWRATE;
|
||||||
/* Those two flags are ignored... */
|
/* Those two flags are ignored... */
|
||||||
@ -7249,10 +7256,12 @@ static inline char *airo_translate_scan(struct net_device *dev,
|
|||||||
/* Bit rate given in 500 kb/s units (+ 0x80) */
|
/* Bit rate given in 500 kb/s units (+ 0x80) */
|
||||||
iwe.u.bitrate.value = ((bss->rates[i] & 0x7f) * 500000);
|
iwe.u.bitrate.value = ((bss->rates[i] & 0x7f) * 500000);
|
||||||
/* Add new value to event */
|
/* Add new value to event */
|
||||||
current_val = iwe_stream_add_value(current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
|
current_val = iwe_stream_add_value(info, current_ev,
|
||||||
|
current_val, end_buf,
|
||||||
|
&iwe, IW_EV_PARAM_LEN);
|
||||||
}
|
}
|
||||||
/* Check if we added any event */
|
/* Check if we added any event */
|
||||||
if((current_val - current_ev) > IW_EV_LCP_LEN)
|
if ((current_val - current_ev) > iwe_stream_lcp_len(info))
|
||||||
current_ev = current_val;
|
current_ev = current_val;
|
||||||
|
|
||||||
/* Beacon interval */
|
/* Beacon interval */
|
||||||
@ -7261,7 +7270,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
|
|||||||
iwe.cmd = IWEVCUSTOM;
|
iwe.cmd = IWEVCUSTOM;
|
||||||
sprintf(buf, "bcn_int=%d", bss->beaconInterval);
|
sprintf(buf, "bcn_int=%d", bss->beaconInterval);
|
||||||
iwe.u.data.length = strlen(buf);
|
iwe.u.data.length = strlen(buf);
|
||||||
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, buf);
|
current_ev = iwe_stream_add_point(info, current_ev, end_buf,
|
||||||
|
&iwe, buf);
|
||||||
kfree(buf);
|
kfree(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7295,8 +7305,10 @@ static inline char *airo_translate_scan(struct net_device *dev,
|
|||||||
iwe.cmd = IWEVGENIE;
|
iwe.cmd = IWEVGENIE;
|
||||||
iwe.u.data.length = min(info_element->len + 2,
|
iwe.u.data.length = min(info_element->len + 2,
|
||||||
MAX_WPA_IE_LEN);
|
MAX_WPA_IE_LEN);
|
||||||
current_ev = iwe_stream_add_point(current_ev, end_buf,
|
current_ev = iwe_stream_add_point(
|
||||||
&iwe, (char *) info_element);
|
info, current_ev,
|
||||||
|
end_buf, &iwe,
|
||||||
|
(char *) info_element);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -7304,7 +7316,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
|
|||||||
iwe.cmd = IWEVGENIE;
|
iwe.cmd = IWEVGENIE;
|
||||||
iwe.u.data.length = min(info_element->len + 2,
|
iwe.u.data.length = min(info_element->len + 2,
|
||||||
MAX_WPA_IE_LEN);
|
MAX_WPA_IE_LEN);
|
||||||
current_ev = iwe_stream_add_point(current_ev, end_buf,
|
current_ev = iwe_stream_add_point(
|
||||||
|
info, current_ev, end_buf,
|
||||||
&iwe, (char *) info_element);
|
&iwe, (char *) info_element);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -7344,7 +7357,7 @@ static int airo_get_scan(struct net_device *dev,
|
|||||||
|
|
||||||
list_for_each_entry (net, &ai->network_list, list) {
|
list_for_each_entry (net, &ai->network_list, list) {
|
||||||
/* Translate to WE format this entry */
|
/* Translate to WE format this entry */
|
||||||
current_ev = airo_translate_scan(dev, current_ev,
|
current_ev = airo_translate_scan(dev, info, current_ev,
|
||||||
extra + dwrq->length,
|
extra + dwrq->length,
|
||||||
&net->bss);
|
&net->bss);
|
||||||
|
|
||||||
|
@ -2310,30 +2310,40 @@ static int atmel_get_scan(struct net_device *dev,
|
|||||||
iwe.cmd = SIOCGIWAP;
|
iwe.cmd = SIOCGIWAP;
|
||||||
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
|
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
|
||||||
memcpy(iwe.u.ap_addr.sa_data, priv->BSSinfo[i].BSSID, 6);
|
memcpy(iwe.u.ap_addr.sa_data, priv->BSSinfo[i].BSSID, 6);
|
||||||
current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_ADDR_LEN);
|
current_ev = iwe_stream_add_event(info, current_ev,
|
||||||
|
extra + IW_SCAN_MAX_DATA,
|
||||||
|
&iwe, IW_EV_ADDR_LEN);
|
||||||
|
|
||||||
iwe.u.data.length = priv->BSSinfo[i].SSIDsize;
|
iwe.u.data.length = priv->BSSinfo[i].SSIDsize;
|
||||||
if (iwe.u.data.length > 32)
|
if (iwe.u.data.length > 32)
|
||||||
iwe.u.data.length = 32;
|
iwe.u.data.length = 32;
|
||||||
iwe.cmd = SIOCGIWESSID;
|
iwe.cmd = SIOCGIWESSID;
|
||||||
iwe.u.data.flags = 1;
|
iwe.u.data.flags = 1;
|
||||||
current_ev = iwe_stream_add_point(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, priv->BSSinfo[i].SSID);
|
current_ev = iwe_stream_add_point(info, current_ev,
|
||||||
|
extra + IW_SCAN_MAX_DATA,
|
||||||
|
&iwe, priv->BSSinfo[i].SSID);
|
||||||
|
|
||||||
iwe.cmd = SIOCGIWMODE;
|
iwe.cmd = SIOCGIWMODE;
|
||||||
iwe.u.mode = priv->BSSinfo[i].BSStype;
|
iwe.u.mode = priv->BSSinfo[i].BSStype;
|
||||||
current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_UINT_LEN);
|
current_ev = iwe_stream_add_event(info, current_ev,
|
||||||
|
extra + IW_SCAN_MAX_DATA,
|
||||||
|
&iwe, IW_EV_UINT_LEN);
|
||||||
|
|
||||||
iwe.cmd = SIOCGIWFREQ;
|
iwe.cmd = SIOCGIWFREQ;
|
||||||
iwe.u.freq.m = priv->BSSinfo[i].channel;
|
iwe.u.freq.m = priv->BSSinfo[i].channel;
|
||||||
iwe.u.freq.e = 0;
|
iwe.u.freq.e = 0;
|
||||||
current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_FREQ_LEN);
|
current_ev = iwe_stream_add_event(info, current_ev,
|
||||||
|
extra + IW_SCAN_MAX_DATA,
|
||||||
|
&iwe, IW_EV_FREQ_LEN);
|
||||||
|
|
||||||
/* Add quality statistics */
|
/* Add quality statistics */
|
||||||
iwe.cmd = IWEVQUAL;
|
iwe.cmd = IWEVQUAL;
|
||||||
iwe.u.qual.level = priv->BSSinfo[i].RSSI;
|
iwe.u.qual.level = priv->BSSinfo[i].RSSI;
|
||||||
iwe.u.qual.qual = iwe.u.qual.level;
|
iwe.u.qual.qual = iwe.u.qual.level;
|
||||||
/* iwe.u.qual.noise = SOMETHING */
|
/* iwe.u.qual.noise = SOMETHING */
|
||||||
current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA , &iwe, IW_EV_QUAL_LEN);
|
current_ev = iwe_stream_add_event(info, current_ev,
|
||||||
|
extra + IW_SCAN_MAX_DATA,
|
||||||
|
&iwe, IW_EV_QUAL_LEN);
|
||||||
|
|
||||||
|
|
||||||
iwe.cmd = SIOCGIWENCODE;
|
iwe.cmd = SIOCGIWENCODE;
|
||||||
@ -2342,7 +2352,9 @@ static int atmel_get_scan(struct net_device *dev,
|
|||||||
else
|
else
|
||||||
iwe.u.data.flags = IW_ENCODE_DISABLED;
|
iwe.u.data.flags = IW_ENCODE_DISABLED;
|
||||||
iwe.u.data.length = 0;
|
iwe.u.data.length = 0;
|
||||||
current_ev = iwe_stream_add_point(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, NULL);
|
current_ev = iwe_stream_add_point(info, current_ev,
|
||||||
|
extra + IW_SCAN_MAX_DATA,
|
||||||
|
&iwe, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Length of data */
|
/* Length of data */
|
||||||
|
@ -67,7 +67,8 @@ void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent,
|
|||||||
int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
|
int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
|
||||||
struct iw_quality qual[], int buf_size,
|
struct iw_quality qual[], int buf_size,
|
||||||
int aplist);
|
int aplist);
|
||||||
int prism2_ap_translate_scan(struct net_device *dev, char *buffer);
|
int prism2_ap_translate_scan(struct net_device *dev,
|
||||||
|
struct iw_request_info *info, char *buffer);
|
||||||
int prism2_hostapd(struct ap_data *ap, struct prism2_hostapd_param *param);
|
int prism2_hostapd(struct ap_data *ap, struct prism2_hostapd_param *param);
|
||||||
|
|
||||||
|
|
||||||
|
@ -2420,7 +2420,8 @@ int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
|
|||||||
|
|
||||||
/* Translate our list of Access Points & Stations to a card independant
|
/* Translate our list of Access Points & Stations to a card independant
|
||||||
* format that the Wireless Tools will understand - Jean II */
|
* format that the Wireless Tools will understand - Jean II */
|
||||||
int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
|
int prism2_ap_translate_scan(struct net_device *dev,
|
||||||
|
struct iw_request_info *info, char *buffer)
|
||||||
{
|
{
|
||||||
struct hostap_interface *iface;
|
struct hostap_interface *iface;
|
||||||
local_info_t *local;
|
local_info_t *local;
|
||||||
@ -2449,8 +2450,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
|
|||||||
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
|
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
|
||||||
memcpy(iwe.u.ap_addr.sa_data, sta->addr, ETH_ALEN);
|
memcpy(iwe.u.ap_addr.sa_data, sta->addr, ETH_ALEN);
|
||||||
iwe.len = IW_EV_ADDR_LEN;
|
iwe.len = IW_EV_ADDR_LEN;
|
||||||
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
|
current_ev = iwe_stream_add_event(info, current_ev, end_buf,
|
||||||
IW_EV_ADDR_LEN);
|
&iwe, IW_EV_ADDR_LEN);
|
||||||
|
|
||||||
/* Use the mode to indicate if it's a station or
|
/* Use the mode to indicate if it's a station or
|
||||||
* an Access Point */
|
* an Access Point */
|
||||||
@ -2461,8 +2462,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
|
|||||||
else
|
else
|
||||||
iwe.u.mode = IW_MODE_INFRA;
|
iwe.u.mode = IW_MODE_INFRA;
|
||||||
iwe.len = IW_EV_UINT_LEN;
|
iwe.len = IW_EV_UINT_LEN;
|
||||||
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
|
current_ev = iwe_stream_add_event(info, current_ev, end_buf,
|
||||||
IW_EV_UINT_LEN);
|
&iwe, IW_EV_UINT_LEN);
|
||||||
|
|
||||||
/* Some quality */
|
/* Some quality */
|
||||||
memset(&iwe, 0, sizeof(iwe));
|
memset(&iwe, 0, sizeof(iwe));
|
||||||
@ -2477,8 +2478,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
|
|||||||
iwe.u.qual.noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence);
|
iwe.u.qual.noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence);
|
||||||
iwe.u.qual.updated = sta->last_rx_updated;
|
iwe.u.qual.updated = sta->last_rx_updated;
|
||||||
iwe.len = IW_EV_QUAL_LEN;
|
iwe.len = IW_EV_QUAL_LEN;
|
||||||
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
|
current_ev = iwe_stream_add_event(info, current_ev, end_buf,
|
||||||
IW_EV_QUAL_LEN);
|
&iwe, IW_EV_QUAL_LEN);
|
||||||
|
|
||||||
#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
|
#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
|
||||||
if (sta->ap) {
|
if (sta->ap) {
|
||||||
@ -2486,8 +2487,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
|
|||||||
iwe.cmd = SIOCGIWESSID;
|
iwe.cmd = SIOCGIWESSID;
|
||||||
iwe.u.data.length = sta->u.ap.ssid_len;
|
iwe.u.data.length = sta->u.ap.ssid_len;
|
||||||
iwe.u.data.flags = 1;
|
iwe.u.data.flags = 1;
|
||||||
current_ev = iwe_stream_add_point(current_ev, end_buf,
|
current_ev = iwe_stream_add_point(info, current_ev,
|
||||||
&iwe,
|
end_buf, &iwe,
|
||||||
sta->u.ap.ssid);
|
sta->u.ap.ssid);
|
||||||
|
|
||||||
memset(&iwe, 0, sizeof(iwe));
|
memset(&iwe, 0, sizeof(iwe));
|
||||||
@ -2497,10 +2498,9 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
|
|||||||
IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
|
IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
|
||||||
else
|
else
|
||||||
iwe.u.data.flags = IW_ENCODE_DISABLED;
|
iwe.u.data.flags = IW_ENCODE_DISABLED;
|
||||||
current_ev = iwe_stream_add_point(current_ev, end_buf,
|
current_ev = iwe_stream_add_point(info, current_ev,
|
||||||
&iwe,
|
end_buf, &iwe,
|
||||||
sta->u.ap.ssid
|
sta->u.ap.ssid);
|
||||||
/* 0 byte memcpy */);
|
|
||||||
|
|
||||||
if (sta->u.ap.channel > 0 &&
|
if (sta->u.ap.channel > 0 &&
|
||||||
sta->u.ap.channel <= FREQ_COUNT) {
|
sta->u.ap.channel <= FREQ_COUNT) {
|
||||||
@ -2510,7 +2510,7 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
|
|||||||
* 100000;
|
* 100000;
|
||||||
iwe.u.freq.e = 1;
|
iwe.u.freq.e = 1;
|
||||||
current_ev = iwe_stream_add_event(
|
current_ev = iwe_stream_add_event(
|
||||||
current_ev, end_buf, &iwe,
|
info, current_ev, end_buf, &iwe,
|
||||||
IW_EV_FREQ_LEN);
|
IW_EV_FREQ_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2519,8 +2519,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
|
|||||||
sprintf(buf, "beacon_interval=%d",
|
sprintf(buf, "beacon_interval=%d",
|
||||||
sta->listen_interval);
|
sta->listen_interval);
|
||||||
iwe.u.data.length = strlen(buf);
|
iwe.u.data.length = strlen(buf);
|
||||||
current_ev = iwe_stream_add_point(current_ev, end_buf,
|
current_ev = iwe_stream_add_point(info, current_ev,
|
||||||
&iwe, buf);
|
end_buf, &iwe, buf);
|
||||||
}
|
}
|
||||||
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
|
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
|
||||||
|
|
||||||
|
@ -1793,6 +1793,7 @@ static int prism2_ioctl_siwscan(struct net_device *dev,
|
|||||||
|
|
||||||
#ifndef PRISM2_NO_STATION_MODES
|
#ifndef PRISM2_NO_STATION_MODES
|
||||||
static char * __prism2_translate_scan(local_info_t *local,
|
static char * __prism2_translate_scan(local_info_t *local,
|
||||||
|
struct iw_request_info *info,
|
||||||
struct hfa384x_hostscan_result *scan,
|
struct hfa384x_hostscan_result *scan,
|
||||||
struct hostap_bss_info *bss,
|
struct hostap_bss_info *bss,
|
||||||
char *current_ev, char *end_buf)
|
char *current_ev, char *end_buf)
|
||||||
@ -1823,7 +1824,7 @@ static char * __prism2_translate_scan(local_info_t *local,
|
|||||||
iwe.cmd = SIOCGIWAP;
|
iwe.cmd = SIOCGIWAP;
|
||||||
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
|
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
|
||||||
memcpy(iwe.u.ap_addr.sa_data, bssid, ETH_ALEN);
|
memcpy(iwe.u.ap_addr.sa_data, bssid, ETH_ALEN);
|
||||||
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
|
current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
|
||||||
IW_EV_ADDR_LEN);
|
IW_EV_ADDR_LEN);
|
||||||
|
|
||||||
/* Other entries will be displayed in the order we give them */
|
/* Other entries will be displayed in the order we give them */
|
||||||
@ -1832,7 +1833,8 @@ static char * __prism2_translate_scan(local_info_t *local,
|
|||||||
iwe.cmd = SIOCGIWESSID;
|
iwe.cmd = SIOCGIWESSID;
|
||||||
iwe.u.data.length = ssid_len;
|
iwe.u.data.length = ssid_len;
|
||||||
iwe.u.data.flags = 1;
|
iwe.u.data.flags = 1;
|
||||||
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, ssid);
|
current_ev = iwe_stream_add_point(info, current_ev, end_buf,
|
||||||
|
&iwe, ssid);
|
||||||
|
|
||||||
memset(&iwe, 0, sizeof(iwe));
|
memset(&iwe, 0, sizeof(iwe));
|
||||||
iwe.cmd = SIOCGIWMODE;
|
iwe.cmd = SIOCGIWMODE;
|
||||||
@ -1847,8 +1849,8 @@ static char * __prism2_translate_scan(local_info_t *local,
|
|||||||
iwe.u.mode = IW_MODE_MASTER;
|
iwe.u.mode = IW_MODE_MASTER;
|
||||||
else
|
else
|
||||||
iwe.u.mode = IW_MODE_ADHOC;
|
iwe.u.mode = IW_MODE_ADHOC;
|
||||||
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
|
current_ev = iwe_stream_add_event(info, current_ev, end_buf,
|
||||||
IW_EV_UINT_LEN);
|
&iwe, IW_EV_UINT_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&iwe, 0, sizeof(iwe));
|
memset(&iwe, 0, sizeof(iwe));
|
||||||
@ -1864,8 +1866,8 @@ static char * __prism2_translate_scan(local_info_t *local,
|
|||||||
if (chan > 0) {
|
if (chan > 0) {
|
||||||
iwe.u.freq.m = freq_list[chan - 1] * 100000;
|
iwe.u.freq.m = freq_list[chan - 1] * 100000;
|
||||||
iwe.u.freq.e = 1;
|
iwe.u.freq.e = 1;
|
||||||
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
|
current_ev = iwe_stream_add_event(info, current_ev, end_buf,
|
||||||
IW_EV_FREQ_LEN);
|
&iwe, IW_EV_FREQ_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scan) {
|
if (scan) {
|
||||||
@ -1884,8 +1886,8 @@ static char * __prism2_translate_scan(local_info_t *local,
|
|||||||
| IW_QUAL_NOISE_UPDATED
|
| IW_QUAL_NOISE_UPDATED
|
||||||
| IW_QUAL_QUAL_INVALID
|
| IW_QUAL_QUAL_INVALID
|
||||||
| IW_QUAL_DBM;
|
| IW_QUAL_DBM;
|
||||||
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
|
current_ev = iwe_stream_add_event(info, current_ev, end_buf,
|
||||||
IW_EV_QUAL_LEN);
|
&iwe, IW_EV_QUAL_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&iwe, 0, sizeof(iwe));
|
memset(&iwe, 0, sizeof(iwe));
|
||||||
@ -1895,13 +1897,13 @@ static char * __prism2_translate_scan(local_info_t *local,
|
|||||||
else
|
else
|
||||||
iwe.u.data.flags = IW_ENCODE_DISABLED;
|
iwe.u.data.flags = IW_ENCODE_DISABLED;
|
||||||
iwe.u.data.length = 0;
|
iwe.u.data.length = 0;
|
||||||
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, "");
|
current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, "");
|
||||||
|
|
||||||
/* TODO: add SuppRates into BSS table */
|
/* TODO: add SuppRates into BSS table */
|
||||||
if (scan) {
|
if (scan) {
|
||||||
memset(&iwe, 0, sizeof(iwe));
|
memset(&iwe, 0, sizeof(iwe));
|
||||||
iwe.cmd = SIOCGIWRATE;
|
iwe.cmd = SIOCGIWRATE;
|
||||||
current_val = current_ev + IW_EV_LCP_LEN;
|
current_val = current_ev + iwe_stream_lcp_len(info);
|
||||||
pos = scan->sup_rates;
|
pos = scan->sup_rates;
|
||||||
for (i = 0; i < sizeof(scan->sup_rates); i++) {
|
for (i = 0; i < sizeof(scan->sup_rates); i++) {
|
||||||
if (pos[i] == 0)
|
if (pos[i] == 0)
|
||||||
@ -1909,11 +1911,11 @@ static char * __prism2_translate_scan(local_info_t *local,
|
|||||||
/* Bit rate given in 500 kb/s units (+ 0x80) */
|
/* Bit rate given in 500 kb/s units (+ 0x80) */
|
||||||
iwe.u.bitrate.value = ((pos[i] & 0x7f) * 500000);
|
iwe.u.bitrate.value = ((pos[i] & 0x7f) * 500000);
|
||||||
current_val = iwe_stream_add_value(
|
current_val = iwe_stream_add_value(
|
||||||
current_ev, current_val, end_buf, &iwe,
|
info, current_ev, current_val, end_buf, &iwe,
|
||||||
IW_EV_PARAM_LEN);
|
IW_EV_PARAM_LEN);
|
||||||
}
|
}
|
||||||
/* Check if we added any event */
|
/* Check if we added any event */
|
||||||
if ((current_val - current_ev) > IW_EV_LCP_LEN)
|
if ((current_val - current_ev) > iwe_stream_lcp_len(info))
|
||||||
current_ev = current_val;
|
current_ev = current_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1924,15 +1926,15 @@ static char * __prism2_translate_scan(local_info_t *local,
|
|||||||
iwe.cmd = IWEVCUSTOM;
|
iwe.cmd = IWEVCUSTOM;
|
||||||
sprintf(buf, "bcn_int=%d", le16_to_cpu(scan->beacon_interval));
|
sprintf(buf, "bcn_int=%d", le16_to_cpu(scan->beacon_interval));
|
||||||
iwe.u.data.length = strlen(buf);
|
iwe.u.data.length = strlen(buf);
|
||||||
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
|
current_ev = iwe_stream_add_point(info, current_ev, end_buf,
|
||||||
buf);
|
&iwe, buf);
|
||||||
|
|
||||||
memset(&iwe, 0, sizeof(iwe));
|
memset(&iwe, 0, sizeof(iwe));
|
||||||
iwe.cmd = IWEVCUSTOM;
|
iwe.cmd = IWEVCUSTOM;
|
||||||
sprintf(buf, "resp_rate=%d", le16_to_cpu(scan->rate));
|
sprintf(buf, "resp_rate=%d", le16_to_cpu(scan->rate));
|
||||||
iwe.u.data.length = strlen(buf);
|
iwe.u.data.length = strlen(buf);
|
||||||
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
|
current_ev = iwe_stream_add_point(info, current_ev, end_buf,
|
||||||
buf);
|
&iwe, buf);
|
||||||
|
|
||||||
if (local->last_scan_type == PRISM2_HOSTSCAN &&
|
if (local->last_scan_type == PRISM2_HOSTSCAN &&
|
||||||
(capabilities & WLAN_CAPABILITY_IBSS)) {
|
(capabilities & WLAN_CAPABILITY_IBSS)) {
|
||||||
@ -1940,8 +1942,8 @@ static char * __prism2_translate_scan(local_info_t *local,
|
|||||||
iwe.cmd = IWEVCUSTOM;
|
iwe.cmd = IWEVCUSTOM;
|
||||||
sprintf(buf, "atim=%d", le16_to_cpu(scan->atim));
|
sprintf(buf, "atim=%d", le16_to_cpu(scan->atim));
|
||||||
iwe.u.data.length = strlen(buf);
|
iwe.u.data.length = strlen(buf);
|
||||||
current_ev = iwe_stream_add_point(current_ev, end_buf,
|
current_ev = iwe_stream_add_point(info, current_ev,
|
||||||
&iwe, buf);
|
end_buf, &iwe, buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
kfree(buf);
|
kfree(buf);
|
||||||
@ -1950,16 +1952,16 @@ static char * __prism2_translate_scan(local_info_t *local,
|
|||||||
memset(&iwe, 0, sizeof(iwe));
|
memset(&iwe, 0, sizeof(iwe));
|
||||||
iwe.cmd = IWEVGENIE;
|
iwe.cmd = IWEVGENIE;
|
||||||
iwe.u.data.length = bss->wpa_ie_len;
|
iwe.u.data.length = bss->wpa_ie_len;
|
||||||
current_ev = iwe_stream_add_point(
|
current_ev = iwe_stream_add_point(info, current_ev, end_buf,
|
||||||
current_ev, end_buf, &iwe, bss->wpa_ie);
|
&iwe, bss->wpa_ie);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bss && bss->rsn_ie_len > 0 && bss->rsn_ie_len <= MAX_WPA_IE_LEN) {
|
if (bss && bss->rsn_ie_len > 0 && bss->rsn_ie_len <= MAX_WPA_IE_LEN) {
|
||||||
memset(&iwe, 0, sizeof(iwe));
|
memset(&iwe, 0, sizeof(iwe));
|
||||||
iwe.cmd = IWEVGENIE;
|
iwe.cmd = IWEVGENIE;
|
||||||
iwe.u.data.length = bss->rsn_ie_len;
|
iwe.u.data.length = bss->rsn_ie_len;
|
||||||
current_ev = iwe_stream_add_point(
|
current_ev = iwe_stream_add_point(info, current_ev, end_buf,
|
||||||
current_ev, end_buf, &iwe, bss->rsn_ie);
|
&iwe, bss->rsn_ie);
|
||||||
}
|
}
|
||||||
|
|
||||||
return current_ev;
|
return current_ev;
|
||||||
@ -1969,6 +1971,7 @@ static char * __prism2_translate_scan(local_info_t *local,
|
|||||||
/* Translate scan data returned from the card to a card independant
|
/* Translate scan data returned from the card to a card independant
|
||||||
* format that the Wireless Tools will understand - Jean II */
|
* format that the Wireless Tools will understand - Jean II */
|
||||||
static inline int prism2_translate_scan(local_info_t *local,
|
static inline int prism2_translate_scan(local_info_t *local,
|
||||||
|
struct iw_request_info *info,
|
||||||
char *buffer, int buflen)
|
char *buffer, int buflen)
|
||||||
{
|
{
|
||||||
struct hfa384x_hostscan_result *scan;
|
struct hfa384x_hostscan_result *scan;
|
||||||
@ -1999,13 +2002,14 @@ static inline int prism2_translate_scan(local_info_t *local,
|
|||||||
if (memcmp(bss->bssid, scan->bssid, ETH_ALEN) == 0) {
|
if (memcmp(bss->bssid, scan->bssid, ETH_ALEN) == 0) {
|
||||||
bss->included = 1;
|
bss->included = 1;
|
||||||
current_ev = __prism2_translate_scan(
|
current_ev = __prism2_translate_scan(
|
||||||
local, scan, bss, current_ev, end_buf);
|
local, info, scan, bss, current_ev,
|
||||||
|
end_buf);
|
||||||
found++;
|
found++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found) {
|
if (!found) {
|
||||||
current_ev = __prism2_translate_scan(
|
current_ev = __prism2_translate_scan(
|
||||||
local, scan, NULL, current_ev, end_buf);
|
local, info, scan, NULL, current_ev, end_buf);
|
||||||
}
|
}
|
||||||
/* Check if there is space for one more entry */
|
/* Check if there is space for one more entry */
|
||||||
if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) {
|
if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) {
|
||||||
@ -2023,7 +2027,7 @@ static inline int prism2_translate_scan(local_info_t *local,
|
|||||||
bss = list_entry(ptr, struct hostap_bss_info, list);
|
bss = list_entry(ptr, struct hostap_bss_info, list);
|
||||||
if (bss->included)
|
if (bss->included)
|
||||||
continue;
|
continue;
|
||||||
current_ev = __prism2_translate_scan(local, NULL, bss,
|
current_ev = __prism2_translate_scan(local, info, NULL, bss,
|
||||||
current_ev, end_buf);
|
current_ev, end_buf);
|
||||||
/* Check if there is space for one more entry */
|
/* Check if there is space for one more entry */
|
||||||
if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) {
|
if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) {
|
||||||
@ -2070,7 +2074,7 @@ static inline int prism2_ioctl_giwscan_sta(struct net_device *dev,
|
|||||||
}
|
}
|
||||||
local->scan_timestamp = 0;
|
local->scan_timestamp = 0;
|
||||||
|
|
||||||
res = prism2_translate_scan(local, extra, data->length);
|
res = prism2_translate_scan(local, info, extra, data->length);
|
||||||
|
|
||||||
if (res >= 0) {
|
if (res >= 0) {
|
||||||
data->length = res;
|
data->length = res;
|
||||||
@ -2103,7 +2107,7 @@ static int prism2_ioctl_giwscan(struct net_device *dev,
|
|||||||
* Jean II */
|
* Jean II */
|
||||||
|
|
||||||
/* Translate to WE format */
|
/* Translate to WE format */
|
||||||
res = prism2_ap_translate_scan(dev, extra);
|
res = prism2_ap_translate_scan(dev, info, extra);
|
||||||
if (res >= 0) {
|
if (res >= 0) {
|
||||||
printk(KERN_DEBUG "Scan result translation succeeded "
|
printk(KERN_DEBUG "Scan result translation succeeded "
|
||||||
"(length=%d)\n", res);
|
"(length=%d)\n", res);
|
||||||
|
@ -776,6 +776,7 @@ out:
|
|||||||
#define MAX_CUSTOM_LEN 64
|
#define MAX_CUSTOM_LEN 64
|
||||||
|
|
||||||
static inline char *lbs_translate_scan(struct lbs_private *priv,
|
static inline char *lbs_translate_scan(struct lbs_private *priv,
|
||||||
|
struct iw_request_info *info,
|
||||||
char *start, char *stop,
|
char *start, char *stop,
|
||||||
struct bss_descriptor *bss)
|
struct bss_descriptor *bss)
|
||||||
{
|
{
|
||||||
@ -801,24 +802,24 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
|
|||||||
iwe.cmd = SIOCGIWAP;
|
iwe.cmd = SIOCGIWAP;
|
||||||
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
|
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
|
||||||
memcpy(iwe.u.ap_addr.sa_data, &bss->bssid, ETH_ALEN);
|
memcpy(iwe.u.ap_addr.sa_data, &bss->bssid, ETH_ALEN);
|
||||||
start = iwe_stream_add_event(start, stop, &iwe, IW_EV_ADDR_LEN);
|
start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
|
||||||
|
|
||||||
/* SSID */
|
/* SSID */
|
||||||
iwe.cmd = SIOCGIWESSID;
|
iwe.cmd = SIOCGIWESSID;
|
||||||
iwe.u.data.flags = 1;
|
iwe.u.data.flags = 1;
|
||||||
iwe.u.data.length = min((uint32_t) bss->ssid_len, (uint32_t) IW_ESSID_MAX_SIZE);
|
iwe.u.data.length = min((uint32_t) bss->ssid_len, (uint32_t) IW_ESSID_MAX_SIZE);
|
||||||
start = iwe_stream_add_point(start, stop, &iwe, bss->ssid);
|
start = iwe_stream_add_point(info, start, stop, &iwe, bss->ssid);
|
||||||
|
|
||||||
/* Mode */
|
/* Mode */
|
||||||
iwe.cmd = SIOCGIWMODE;
|
iwe.cmd = SIOCGIWMODE;
|
||||||
iwe.u.mode = bss->mode;
|
iwe.u.mode = bss->mode;
|
||||||
start = iwe_stream_add_event(start, stop, &iwe, IW_EV_UINT_LEN);
|
start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN);
|
||||||
|
|
||||||
/* Frequency */
|
/* Frequency */
|
||||||
iwe.cmd = SIOCGIWFREQ;
|
iwe.cmd = SIOCGIWFREQ;
|
||||||
iwe.u.freq.m = (long)cfp->freq * 100000;
|
iwe.u.freq.m = (long)cfp->freq * 100000;
|
||||||
iwe.u.freq.e = 1;
|
iwe.u.freq.e = 1;
|
||||||
start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN);
|
start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
|
||||||
|
|
||||||
/* Add quality statistics */
|
/* Add quality statistics */
|
||||||
iwe.cmd = IWEVQUAL;
|
iwe.cmd = IWEVQUAL;
|
||||||
@ -852,7 +853,7 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
|
|||||||
nf = priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
|
nf = priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
|
||||||
iwe.u.qual.level = CAL_RSSI(snr, nf);
|
iwe.u.qual.level = CAL_RSSI(snr, nf);
|
||||||
}
|
}
|
||||||
start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN);
|
start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
|
||||||
|
|
||||||
/* Add encryption capability */
|
/* Add encryption capability */
|
||||||
iwe.cmd = SIOCGIWENCODE;
|
iwe.cmd = SIOCGIWENCODE;
|
||||||
@ -862,9 +863,9 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
|
|||||||
iwe.u.data.flags = IW_ENCODE_DISABLED;
|
iwe.u.data.flags = IW_ENCODE_DISABLED;
|
||||||
}
|
}
|
||||||
iwe.u.data.length = 0;
|
iwe.u.data.length = 0;
|
||||||
start = iwe_stream_add_point(start, stop, &iwe, bss->ssid);
|
start = iwe_stream_add_point(info, start, stop, &iwe, bss->ssid);
|
||||||
|
|
||||||
current_val = start + IW_EV_LCP_LEN;
|
current_val = start + iwe_stream_lcp_len(info);
|
||||||
|
|
||||||
iwe.cmd = SIOCGIWRATE;
|
iwe.cmd = SIOCGIWRATE;
|
||||||
iwe.u.bitrate.fixed = 0;
|
iwe.u.bitrate.fixed = 0;
|
||||||
@ -874,7 +875,7 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
|
|||||||
for (j = 0; bss->rates[j] && (j < sizeof(bss->rates)); j++) {
|
for (j = 0; bss->rates[j] && (j < sizeof(bss->rates)); j++) {
|
||||||
/* Bit rate given in 500 kb/s units */
|
/* Bit rate given in 500 kb/s units */
|
||||||
iwe.u.bitrate.value = bss->rates[j] * 500000;
|
iwe.u.bitrate.value = bss->rates[j] * 500000;
|
||||||
current_val = iwe_stream_add_value(start, current_val,
|
current_val = iwe_stream_add_value(info, start, current_val,
|
||||||
stop, &iwe, IW_EV_PARAM_LEN);
|
stop, &iwe, IW_EV_PARAM_LEN);
|
||||||
}
|
}
|
||||||
if ((bss->mode == IW_MODE_ADHOC) && priv->adhoccreate
|
if ((bss->mode == IW_MODE_ADHOC) && priv->adhoccreate
|
||||||
@ -882,11 +883,11 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
|
|||||||
priv->curbssparams.ssid_len,
|
priv->curbssparams.ssid_len,
|
||||||
bss->ssid, bss->ssid_len)) {
|
bss->ssid, bss->ssid_len)) {
|
||||||
iwe.u.bitrate.value = 22 * 500000;
|
iwe.u.bitrate.value = 22 * 500000;
|
||||||
current_val = iwe_stream_add_value(start, current_val,
|
current_val = iwe_stream_add_value(info, start, current_val,
|
||||||
stop, &iwe, IW_EV_PARAM_LEN);
|
stop, &iwe, IW_EV_PARAM_LEN);
|
||||||
}
|
}
|
||||||
/* Check if we added any event */
|
/* Check if we added any event */
|
||||||
if((current_val - start) > IW_EV_LCP_LEN)
|
if ((current_val - start) > iwe_stream_lcp_len(info))
|
||||||
start = current_val;
|
start = current_val;
|
||||||
|
|
||||||
memset(&iwe, 0, sizeof(iwe));
|
memset(&iwe, 0, sizeof(iwe));
|
||||||
@ -895,7 +896,7 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
|
|||||||
memcpy(buf, bss->wpa_ie, bss->wpa_ie_len);
|
memcpy(buf, bss->wpa_ie, bss->wpa_ie_len);
|
||||||
iwe.cmd = IWEVGENIE;
|
iwe.cmd = IWEVGENIE;
|
||||||
iwe.u.data.length = bss->wpa_ie_len;
|
iwe.u.data.length = bss->wpa_ie_len;
|
||||||
start = iwe_stream_add_point(start, stop, &iwe, buf);
|
start = iwe_stream_add_point(info, start, stop, &iwe, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&iwe, 0, sizeof(iwe));
|
memset(&iwe, 0, sizeof(iwe));
|
||||||
@ -904,7 +905,7 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
|
|||||||
memcpy(buf, bss->rsn_ie, bss->rsn_ie_len);
|
memcpy(buf, bss->rsn_ie, bss->rsn_ie_len);
|
||||||
iwe.cmd = IWEVGENIE;
|
iwe.cmd = IWEVGENIE;
|
||||||
iwe.u.data.length = bss->rsn_ie_len;
|
iwe.u.data.length = bss->rsn_ie_len;
|
||||||
start = iwe_stream_add_point(start, stop, &iwe, buf);
|
start = iwe_stream_add_point(info, start, stop, &iwe, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bss->mesh) {
|
if (bss->mesh) {
|
||||||
@ -915,7 +916,8 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
|
|||||||
p += snprintf(p, MAX_CUSTOM_LEN, "mesh-type: olpc");
|
p += snprintf(p, MAX_CUSTOM_LEN, "mesh-type: olpc");
|
||||||
iwe.u.data.length = p - custom;
|
iwe.u.data.length = p - custom;
|
||||||
if (iwe.u.data.length)
|
if (iwe.u.data.length)
|
||||||
start = iwe_stream_add_point(start, stop, &iwe, custom);
|
start = iwe_stream_add_point(info, start, stop,
|
||||||
|
&iwe, custom);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@ -1036,7 +1038,7 @@ int lbs_get_scan(struct net_device *dev, struct iw_request_info *info,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Translate to WE format this entry */
|
/* Translate to WE format this entry */
|
||||||
next_ev = lbs_translate_scan(priv, ev, stop, iter_bss);
|
next_ev = lbs_translate_scan(priv, info, ev, stop, iter_bss);
|
||||||
if (next_ev == NULL)
|
if (next_ev == NULL)
|
||||||
continue;
|
continue;
|
||||||
ev = next_ev;
|
ev = next_ev;
|
||||||
|
@ -4046,6 +4046,7 @@ static int orinoco_ioctl_setscan(struct net_device *dev,
|
|||||||
* format that the Wireless Tools will understand - Jean II
|
* format that the Wireless Tools will understand - Jean II
|
||||||
* Return message length or -errno for fatal errors */
|
* Return message length or -errno for fatal errors */
|
||||||
static inline char *orinoco_translate_scan(struct net_device *dev,
|
static inline char *orinoco_translate_scan(struct net_device *dev,
|
||||||
|
struct iw_request_info *info,
|
||||||
char *current_ev,
|
char *current_ev,
|
||||||
char *end_buf,
|
char *end_buf,
|
||||||
union hermes_scan_info *bss,
|
union hermes_scan_info *bss,
|
||||||
@ -4062,7 +4063,8 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
|
|||||||
iwe.cmd = SIOCGIWAP;
|
iwe.cmd = SIOCGIWAP;
|
||||||
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
|
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
|
||||||
memcpy(iwe.u.ap_addr.sa_data, bss->a.bssid, ETH_ALEN);
|
memcpy(iwe.u.ap_addr.sa_data, bss->a.bssid, ETH_ALEN);
|
||||||
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
|
current_ev = iwe_stream_add_event(info, current_ev, end_buf,
|
||||||
|
&iwe, IW_EV_ADDR_LEN);
|
||||||
|
|
||||||
/* Other entries will be displayed in the order we give them */
|
/* Other entries will be displayed in the order we give them */
|
||||||
|
|
||||||
@ -4072,7 +4074,8 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
|
|||||||
iwe.u.data.length = 32;
|
iwe.u.data.length = 32;
|
||||||
iwe.cmd = SIOCGIWESSID;
|
iwe.cmd = SIOCGIWESSID;
|
||||||
iwe.u.data.flags = 1;
|
iwe.u.data.flags = 1;
|
||||||
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->a.essid);
|
current_ev = iwe_stream_add_point(info, current_ev, end_buf,
|
||||||
|
&iwe, bss->a.essid);
|
||||||
|
|
||||||
/* Add mode */
|
/* Add mode */
|
||||||
iwe.cmd = SIOCGIWMODE;
|
iwe.cmd = SIOCGIWMODE;
|
||||||
@ -4082,7 +4085,8 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
|
|||||||
iwe.u.mode = IW_MODE_MASTER;
|
iwe.u.mode = IW_MODE_MASTER;
|
||||||
else
|
else
|
||||||
iwe.u.mode = IW_MODE_ADHOC;
|
iwe.u.mode = IW_MODE_ADHOC;
|
||||||
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
|
current_ev = iwe_stream_add_event(info, current_ev, end_buf,
|
||||||
|
&iwe, IW_EV_UINT_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
channel = bss->s.channel;
|
channel = bss->s.channel;
|
||||||
@ -4091,7 +4095,7 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
|
|||||||
iwe.cmd = SIOCGIWFREQ;
|
iwe.cmd = SIOCGIWFREQ;
|
||||||
iwe.u.freq.m = channel_frequency[channel-1] * 100000;
|
iwe.u.freq.m = channel_frequency[channel-1] * 100000;
|
||||||
iwe.u.freq.e = 1;
|
iwe.u.freq.e = 1;
|
||||||
current_ev = iwe_stream_add_event(current_ev, end_buf,
|
current_ev = iwe_stream_add_event(info, current_ev, end_buf,
|
||||||
&iwe, IW_EV_FREQ_LEN);
|
&iwe, IW_EV_FREQ_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4106,7 +4110,8 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
|
|||||||
iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
|
iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
|
||||||
else
|
else
|
||||||
iwe.u.qual.qual = 0;
|
iwe.u.qual.qual = 0;
|
||||||
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
|
current_ev = iwe_stream_add_event(info, current_ev, end_buf,
|
||||||
|
&iwe, IW_EV_QUAL_LEN);
|
||||||
|
|
||||||
/* Add encryption capability */
|
/* Add encryption capability */
|
||||||
iwe.cmd = SIOCGIWENCODE;
|
iwe.cmd = SIOCGIWENCODE;
|
||||||
@ -4115,7 +4120,8 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
|
|||||||
else
|
else
|
||||||
iwe.u.data.flags = IW_ENCODE_DISABLED;
|
iwe.u.data.flags = IW_ENCODE_DISABLED;
|
||||||
iwe.u.data.length = 0;
|
iwe.u.data.length = 0;
|
||||||
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->a.essid);
|
current_ev = iwe_stream_add_point(info, current_ev, end_buf,
|
||||||
|
&iwe, bss->a.essid);
|
||||||
|
|
||||||
/* Add EXTRA: Age to display seconds since last beacon/probe response
|
/* Add EXTRA: Age to display seconds since last beacon/probe response
|
||||||
* for given network. */
|
* for given network. */
|
||||||
@ -4126,11 +4132,12 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
|
|||||||
jiffies_to_msecs(jiffies - last_scanned));
|
jiffies_to_msecs(jiffies - last_scanned));
|
||||||
iwe.u.data.length = p - custom;
|
iwe.u.data.length = p - custom;
|
||||||
if (iwe.u.data.length)
|
if (iwe.u.data.length)
|
||||||
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, custom);
|
current_ev = iwe_stream_add_point(info, current_ev, end_buf,
|
||||||
|
&iwe, custom);
|
||||||
|
|
||||||
/* Bit rate is not available in Lucent/Agere firmwares */
|
/* Bit rate is not available in Lucent/Agere firmwares */
|
||||||
if (priv->firmware_type != FIRMWARE_TYPE_AGERE) {
|
if (priv->firmware_type != FIRMWARE_TYPE_AGERE) {
|
||||||
char *current_val = current_ev + IW_EV_LCP_LEN;
|
char *current_val = current_ev + iwe_stream_lcp_len(info);
|
||||||
int i;
|
int i;
|
||||||
int step;
|
int step;
|
||||||
|
|
||||||
@ -4149,12 +4156,13 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
|
|||||||
break;
|
break;
|
||||||
/* Bit rate given in 500 kb/s units (+ 0x80) */
|
/* Bit rate given in 500 kb/s units (+ 0x80) */
|
||||||
iwe.u.bitrate.value = ((bss->p.rates[i] & 0x7f) * 500000);
|
iwe.u.bitrate.value = ((bss->p.rates[i] & 0x7f) * 500000);
|
||||||
current_val = iwe_stream_add_value(current_ev, current_val,
|
current_val = iwe_stream_add_value(info, current_ev,
|
||||||
|
current_val,
|
||||||
end_buf, &iwe,
|
end_buf, &iwe,
|
||||||
IW_EV_PARAM_LEN);
|
IW_EV_PARAM_LEN);
|
||||||
}
|
}
|
||||||
/* Check if we added any event */
|
/* Check if we added any event */
|
||||||
if ((current_val - current_ev) > IW_EV_LCP_LEN)
|
if ((current_val - current_ev) > iwe_stream_lcp_len(info))
|
||||||
current_ev = current_val;
|
current_ev = current_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4190,7 +4198,7 @@ static int orinoco_ioctl_getscan(struct net_device *dev,
|
|||||||
|
|
||||||
list_for_each_entry(bss, &priv->bss_list, list) {
|
list_for_each_entry(bss, &priv->bss_list, list) {
|
||||||
/* Translate to WE format this entry */
|
/* Translate to WE format this entry */
|
||||||
current_ev = orinoco_translate_scan(dev, current_ev,
|
current_ev = orinoco_translate_scan(dev, info, current_ev,
|
||||||
extra + srq->length,
|
extra + srq->length,
|
||||||
&bss->bss,
|
&bss->bss,
|
||||||
bss->last_scanned);
|
bss->last_scanned);
|
||||||
|
@ -571,8 +571,9 @@ prism54_set_scan(struct net_device *dev, struct iw_request_info *info,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
prism54_translate_bss(struct net_device *ndev, char *current_ev,
|
prism54_translate_bss(struct net_device *ndev, struct iw_request_info *info,
|
||||||
char *end_buf, struct obj_bss *bss, char noise)
|
char *current_ev, char *end_buf, struct obj_bss *bss,
|
||||||
|
char noise)
|
||||||
{
|
{
|
||||||
struct iw_event iwe; /* Temporary buffer */
|
struct iw_event iwe; /* Temporary buffer */
|
||||||
short cap;
|
short cap;
|
||||||
@ -584,8 +585,8 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
|
|||||||
memcpy(iwe.u.ap_addr.sa_data, bss->address, 6);
|
memcpy(iwe.u.ap_addr.sa_data, bss->address, 6);
|
||||||
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
|
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
|
||||||
iwe.cmd = SIOCGIWAP;
|
iwe.cmd = SIOCGIWAP;
|
||||||
current_ev =
|
current_ev = iwe_stream_add_event(info, current_ev, end_buf,
|
||||||
iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
|
&iwe, IW_EV_ADDR_LEN);
|
||||||
|
|
||||||
/* The following entries will be displayed in the same order we give them */
|
/* The following entries will be displayed in the same order we give them */
|
||||||
|
|
||||||
@ -593,7 +594,7 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
|
|||||||
iwe.u.data.length = bss->ssid.length;
|
iwe.u.data.length = bss->ssid.length;
|
||||||
iwe.u.data.flags = 1;
|
iwe.u.data.flags = 1;
|
||||||
iwe.cmd = SIOCGIWESSID;
|
iwe.cmd = SIOCGIWESSID;
|
||||||
current_ev = iwe_stream_add_point(current_ev, end_buf,
|
current_ev = iwe_stream_add_point(info, current_ev, end_buf,
|
||||||
&iwe, bss->ssid.octets);
|
&iwe, bss->ssid.octets);
|
||||||
|
|
||||||
/* Capabilities */
|
/* Capabilities */
|
||||||
@ -610,9 +611,8 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
|
|||||||
iwe.u.mode = IW_MODE_ADHOC;
|
iwe.u.mode = IW_MODE_ADHOC;
|
||||||
iwe.cmd = SIOCGIWMODE;
|
iwe.cmd = SIOCGIWMODE;
|
||||||
if (iwe.u.mode)
|
if (iwe.u.mode)
|
||||||
current_ev =
|
current_ev = iwe_stream_add_event(info, current_ev, end_buf,
|
||||||
iwe_stream_add_event(current_ev, end_buf, &iwe,
|
&iwe, IW_EV_UINT_LEN);
|
||||||
IW_EV_UINT_LEN);
|
|
||||||
|
|
||||||
/* Encryption capability */
|
/* Encryption capability */
|
||||||
if (cap & CAP_CRYPT)
|
if (cap & CAP_CRYPT)
|
||||||
@ -621,14 +621,15 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
|
|||||||
iwe.u.data.flags = IW_ENCODE_DISABLED;
|
iwe.u.data.flags = IW_ENCODE_DISABLED;
|
||||||
iwe.u.data.length = 0;
|
iwe.u.data.length = 0;
|
||||||
iwe.cmd = SIOCGIWENCODE;
|
iwe.cmd = SIOCGIWENCODE;
|
||||||
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, NULL);
|
current_ev = iwe_stream_add_point(info, current_ev, end_buf,
|
||||||
|
&iwe, NULL);
|
||||||
|
|
||||||
/* Add frequency. (short) bss->channel is the frequency in MHz */
|
/* Add frequency. (short) bss->channel is the frequency in MHz */
|
||||||
iwe.u.freq.m = bss->channel;
|
iwe.u.freq.m = bss->channel;
|
||||||
iwe.u.freq.e = 6;
|
iwe.u.freq.e = 6;
|
||||||
iwe.cmd = SIOCGIWFREQ;
|
iwe.cmd = SIOCGIWFREQ;
|
||||||
current_ev =
|
current_ev = iwe_stream_add_event(info, current_ev, end_buf,
|
||||||
iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
|
&iwe, IW_EV_FREQ_LEN);
|
||||||
|
|
||||||
/* Add quality statistics */
|
/* Add quality statistics */
|
||||||
iwe.u.qual.level = bss->rssi;
|
iwe.u.qual.level = bss->rssi;
|
||||||
@ -636,20 +637,20 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
|
|||||||
/* do a simple SNR for quality */
|
/* do a simple SNR for quality */
|
||||||
iwe.u.qual.qual = bss->rssi - noise;
|
iwe.u.qual.qual = bss->rssi - noise;
|
||||||
iwe.cmd = IWEVQUAL;
|
iwe.cmd = IWEVQUAL;
|
||||||
current_ev =
|
current_ev = iwe_stream_add_event(info, current_ev, end_buf,
|
||||||
iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
|
&iwe, IW_EV_QUAL_LEN);
|
||||||
|
|
||||||
/* Add WPA/RSN Information Element, if any */
|
/* Add WPA/RSN Information Element, if any */
|
||||||
wpa_ie_len = prism54_wpa_bss_ie_get(priv, bss->address, wpa_ie);
|
wpa_ie_len = prism54_wpa_bss_ie_get(priv, bss->address, wpa_ie);
|
||||||
if (wpa_ie_len > 0) {
|
if (wpa_ie_len > 0) {
|
||||||
iwe.cmd = IWEVGENIE;
|
iwe.cmd = IWEVGENIE;
|
||||||
iwe.u.data.length = min(wpa_ie_len, (size_t)MAX_WPA_IE_LEN);
|
iwe.u.data.length = min(wpa_ie_len, (size_t)MAX_WPA_IE_LEN);
|
||||||
current_ev = iwe_stream_add_point(current_ev, end_buf,
|
current_ev = iwe_stream_add_point(info, current_ev, end_buf,
|
||||||
&iwe, wpa_ie);
|
&iwe, wpa_ie);
|
||||||
}
|
}
|
||||||
/* Do the bitrates */
|
/* Do the bitrates */
|
||||||
{
|
{
|
||||||
char * current_val = current_ev + IW_EV_LCP_LEN;
|
char *current_val = current_ev + iwe_stream_lcp_len(info);
|
||||||
int i;
|
int i;
|
||||||
int mask;
|
int mask;
|
||||||
|
|
||||||
@ -662,14 +663,14 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
|
|||||||
for(i = 0; i < sizeof(scan_rate_list); i++) {
|
for(i = 0; i < sizeof(scan_rate_list); i++) {
|
||||||
if(bss->rates & mask) {
|
if(bss->rates & mask) {
|
||||||
iwe.u.bitrate.value = (scan_rate_list[i] * 500000);
|
iwe.u.bitrate.value = (scan_rate_list[i] * 500000);
|
||||||
current_val = iwe_stream_add_value(current_ev, current_val,
|
current_val = iwe_stream_add_value(
|
||||||
end_buf, &iwe,
|
info, current_ev, current_val,
|
||||||
IW_EV_PARAM_LEN);
|
end_buf, &iwe, IW_EV_PARAM_LEN);
|
||||||
}
|
}
|
||||||
mask <<= 1;
|
mask <<= 1;
|
||||||
}
|
}
|
||||||
/* Check if we added any event */
|
/* Check if we added any event */
|
||||||
if ((current_val - current_ev) > IW_EV_LCP_LEN)
|
if ((current_val - current_ev) > iwe_stream_lcp_len(info))
|
||||||
current_ev = current_val;
|
current_ev = current_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -710,7 +711,7 @@ prism54_get_scan(struct net_device *ndev, struct iw_request_info *info,
|
|||||||
|
|
||||||
/* ok now, scan the list and translate its info */
|
/* ok now, scan the list and translate its info */
|
||||||
for (i = 0; i < (int) bsslist->nr; i++) {
|
for (i = 0; i < (int) bsslist->nr; i++) {
|
||||||
current_ev = prism54_translate_bss(ndev, current_ev,
|
current_ev = prism54_translate_bss(ndev, info, current_ev,
|
||||||
extra + dwrq->length,
|
extra + dwrq->length,
|
||||||
&(bsslist->bsslist[i]),
|
&(bsslist->bsslist[i]),
|
||||||
noise);
|
noise);
|
||||||
@ -2704,6 +2705,7 @@ prism2_ioctl_scan_req(struct net_device *ndev,
|
|||||||
struct prism2_hostapd_param *param)
|
struct prism2_hostapd_param *param)
|
||||||
{
|
{
|
||||||
islpci_private *priv = netdev_priv(ndev);
|
islpci_private *priv = netdev_priv(ndev);
|
||||||
|
struct iw_request_info info;
|
||||||
int i, rvalue;
|
int i, rvalue;
|
||||||
struct obj_bsslist *bsslist;
|
struct obj_bsslist *bsslist;
|
||||||
u32 noise = 0;
|
u32 noise = 0;
|
||||||
@ -2727,9 +2729,12 @@ prism2_ioctl_scan_req(struct net_device *ndev,
|
|||||||
rvalue |= mgt_get_request(priv, DOT11_OID_BSSLIST, 0, NULL, &r);
|
rvalue |= mgt_get_request(priv, DOT11_OID_BSSLIST, 0, NULL, &r);
|
||||||
bsslist = r.ptr;
|
bsslist = r.ptr;
|
||||||
|
|
||||||
|
info.cmd = PRISM54_HOSTAPD;
|
||||||
|
info.flags = 0;
|
||||||
|
|
||||||
/* ok now, scan the list and translate its info */
|
/* ok now, scan the list and translate its info */
|
||||||
for (i = 0; i < min(IW_MAX_AP, (int) bsslist->nr); i++)
|
for (i = 0; i < min(IW_MAX_AP, (int) bsslist->nr); i++)
|
||||||
current_ev = prism54_translate_bss(ndev, current_ev,
|
current_ev = prism54_translate_bss(ndev, &info, current_ev,
|
||||||
extra + IW_SCAN_MAX_DATA,
|
extra + IW_SCAN_MAX_DATA,
|
||||||
&(bsslist->bsslist[i]),
|
&(bsslist->bsslist[i]),
|
||||||
noise);
|
noise);
|
||||||
|
@ -1648,7 +1648,9 @@ static int rndis_iw_set_scan(struct net_device *dev,
|
|||||||
|
|
||||||
|
|
||||||
static char *rndis_translate_scan(struct net_device *dev,
|
static char *rndis_translate_scan(struct net_device *dev,
|
||||||
char *cev, char *end_buf, struct ndis_80211_bssid_ex *bssid)
|
struct iw_request_info *info, char *cev,
|
||||||
|
char *end_buf,
|
||||||
|
struct ndis_80211_bssid_ex *bssid)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
struct usbnet *usbdev = dev->priv;
|
struct usbnet *usbdev = dev->priv;
|
||||||
@ -1667,14 +1669,14 @@ static char *rndis_translate_scan(struct net_device *dev,
|
|||||||
iwe.cmd = SIOCGIWAP;
|
iwe.cmd = SIOCGIWAP;
|
||||||
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
|
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
|
||||||
memcpy(iwe.u.ap_addr.sa_data, bssid->mac, ETH_ALEN);
|
memcpy(iwe.u.ap_addr.sa_data, bssid->mac, ETH_ALEN);
|
||||||
cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_ADDR_LEN);
|
cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_ADDR_LEN);
|
||||||
|
|
||||||
devdbg(usbdev, "SSID(%d) %s", le32_to_cpu(bssid->ssid.length),
|
devdbg(usbdev, "SSID(%d) %s", le32_to_cpu(bssid->ssid.length),
|
||||||
bssid->ssid.essid);
|
bssid->ssid.essid);
|
||||||
iwe.cmd = SIOCGIWESSID;
|
iwe.cmd = SIOCGIWESSID;
|
||||||
iwe.u.essid.length = le32_to_cpu(bssid->ssid.length);
|
iwe.u.essid.length = le32_to_cpu(bssid->ssid.length);
|
||||||
iwe.u.essid.flags = 1;
|
iwe.u.essid.flags = 1;
|
||||||
cev = iwe_stream_add_point(cev, end_buf, &iwe, bssid->ssid.essid);
|
cev = iwe_stream_add_point(info, cev, end_buf, &iwe, bssid->ssid.essid);
|
||||||
|
|
||||||
devdbg(usbdev, "MODE %d", le32_to_cpu(bssid->net_infra));
|
devdbg(usbdev, "MODE %d", le32_to_cpu(bssid->net_infra));
|
||||||
iwe.cmd = SIOCGIWMODE;
|
iwe.cmd = SIOCGIWMODE;
|
||||||
@ -1690,12 +1692,12 @@ static char *rndis_translate_scan(struct net_device *dev,
|
|||||||
iwe.u.mode = IW_MODE_AUTO;
|
iwe.u.mode = IW_MODE_AUTO;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_UINT_LEN);
|
cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_UINT_LEN);
|
||||||
|
|
||||||
devdbg(usbdev, "FREQ %d kHz", le32_to_cpu(bssid->config.ds_config));
|
devdbg(usbdev, "FREQ %d kHz", le32_to_cpu(bssid->config.ds_config));
|
||||||
iwe.cmd = SIOCGIWFREQ;
|
iwe.cmd = SIOCGIWFREQ;
|
||||||
dsconfig_to_freq(le32_to_cpu(bssid->config.ds_config), &iwe.u.freq);
|
dsconfig_to_freq(le32_to_cpu(bssid->config.ds_config), &iwe.u.freq);
|
||||||
cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_FREQ_LEN);
|
cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_FREQ_LEN);
|
||||||
|
|
||||||
devdbg(usbdev, "QUAL %d", le32_to_cpu(bssid->rssi));
|
devdbg(usbdev, "QUAL %d", le32_to_cpu(bssid->rssi));
|
||||||
iwe.cmd = IWEVQUAL;
|
iwe.cmd = IWEVQUAL;
|
||||||
@ -1704,7 +1706,7 @@ static char *rndis_translate_scan(struct net_device *dev,
|
|||||||
iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED
|
iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED
|
||||||
| IW_QUAL_LEVEL_UPDATED
|
| IW_QUAL_LEVEL_UPDATED
|
||||||
| IW_QUAL_NOISE_INVALID;
|
| IW_QUAL_NOISE_INVALID;
|
||||||
cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_QUAL_LEN);
|
cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_QUAL_LEN);
|
||||||
|
|
||||||
devdbg(usbdev, "ENCODE %d", le32_to_cpu(bssid->privacy));
|
devdbg(usbdev, "ENCODE %d", le32_to_cpu(bssid->privacy));
|
||||||
iwe.cmd = SIOCGIWENCODE;
|
iwe.cmd = SIOCGIWENCODE;
|
||||||
@ -1714,10 +1716,10 @@ static char *rndis_translate_scan(struct net_device *dev,
|
|||||||
else
|
else
|
||||||
iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
|
iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
|
||||||
|
|
||||||
cev = iwe_stream_add_point(cev, end_buf, &iwe, NULL);
|
cev = iwe_stream_add_point(info, cev, end_buf, &iwe, NULL);
|
||||||
|
|
||||||
devdbg(usbdev, "RATES:");
|
devdbg(usbdev, "RATES:");
|
||||||
current_val = cev + IW_EV_LCP_LEN;
|
current_val = cev + iwe_stream_lcp_len(info);
|
||||||
iwe.cmd = SIOCGIWRATE;
|
iwe.cmd = SIOCGIWRATE;
|
||||||
for (i = 0; i < sizeof(bssid->rates); i++) {
|
for (i = 0; i < sizeof(bssid->rates); i++) {
|
||||||
if (bssid->rates[i] & 0x7f) {
|
if (bssid->rates[i] & 0x7f) {
|
||||||
@ -1725,13 +1727,13 @@ static char *rndis_translate_scan(struct net_device *dev,
|
|||||||
((bssid->rates[i] & 0x7f) *
|
((bssid->rates[i] & 0x7f) *
|
||||||
500000);
|
500000);
|
||||||
devdbg(usbdev, " %d", iwe.u.bitrate.value);
|
devdbg(usbdev, " %d", iwe.u.bitrate.value);
|
||||||
current_val = iwe_stream_add_value(cev,
|
current_val = iwe_stream_add_value(info, cev,
|
||||||
current_val, end_buf, &iwe,
|
current_val, end_buf, &iwe,
|
||||||
IW_EV_PARAM_LEN);
|
IW_EV_PARAM_LEN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((current_val - cev) > IW_EV_LCP_LEN)
|
if ((current_val - cev) > iwe_stream_lcp_len(info))
|
||||||
cev = current_val;
|
cev = current_val;
|
||||||
|
|
||||||
beacon = le32_to_cpu(bssid->config.beacon_period);
|
beacon = le32_to_cpu(bssid->config.beacon_period);
|
||||||
@ -1739,14 +1741,14 @@ static char *rndis_translate_scan(struct net_device *dev,
|
|||||||
iwe.cmd = IWEVCUSTOM;
|
iwe.cmd = IWEVCUSTOM;
|
||||||
snprintf(sbuf, sizeof(sbuf), "bcn_int=%d", beacon);
|
snprintf(sbuf, sizeof(sbuf), "bcn_int=%d", beacon);
|
||||||
iwe.u.data.length = strlen(sbuf);
|
iwe.u.data.length = strlen(sbuf);
|
||||||
cev = iwe_stream_add_point(cev, end_buf, &iwe, sbuf);
|
cev = iwe_stream_add_point(info, cev, end_buf, &iwe, sbuf);
|
||||||
|
|
||||||
atim = le32_to_cpu(bssid->config.atim_window);
|
atim = le32_to_cpu(bssid->config.atim_window);
|
||||||
devdbg(usbdev, "ATIM %d", atim);
|
devdbg(usbdev, "ATIM %d", atim);
|
||||||
iwe.cmd = IWEVCUSTOM;
|
iwe.cmd = IWEVCUSTOM;
|
||||||
snprintf(sbuf, sizeof(sbuf), "atim=%u", atim);
|
snprintf(sbuf, sizeof(sbuf), "atim=%u", atim);
|
||||||
iwe.u.data.length = strlen(sbuf);
|
iwe.u.data.length = strlen(sbuf);
|
||||||
cev = iwe_stream_add_point(cev, end_buf, &iwe, sbuf);
|
cev = iwe_stream_add_point(info, cev, end_buf, &iwe, sbuf);
|
||||||
|
|
||||||
ie = (void *)(bssid->ies + sizeof(struct ndis_80211_fixed_ies));
|
ie = (void *)(bssid->ies + sizeof(struct ndis_80211_fixed_ies));
|
||||||
ie_len = min(bssid_len - (int)sizeof(*bssid),
|
ie_len = min(bssid_len - (int)sizeof(*bssid),
|
||||||
@ -1760,7 +1762,7 @@ static char *rndis_translate_scan(struct net_device *dev,
|
|||||||
(ie->id == MFIE_TYPE_RSN) ? 2 : 1);
|
(ie->id == MFIE_TYPE_RSN) ? 2 : 1);
|
||||||
iwe.cmd = IWEVGENIE;
|
iwe.cmd = IWEVGENIE;
|
||||||
iwe.u.data.length = min(ie->len + 2, MAX_WPA_IE_LEN);
|
iwe.u.data.length = min(ie->len + 2, MAX_WPA_IE_LEN);
|
||||||
cev = iwe_stream_add_point(cev, end_buf, &iwe,
|
cev = iwe_stream_add_point(info, cev, end_buf, &iwe,
|
||||||
(u8 *)ie);
|
(u8 *)ie);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1803,8 +1805,8 @@ static int rndis_iw_get_scan(struct net_device *dev,
|
|||||||
devdbg(usbdev, "SIOCGIWSCAN: %d BSSIDs found", count);
|
devdbg(usbdev, "SIOCGIWSCAN: %d BSSIDs found", count);
|
||||||
|
|
||||||
while (count && ((void *)bssid + bssid_len) <= (buf + len)) {
|
while (count && ((void *)bssid + bssid_len) <= (buf + len)) {
|
||||||
cev = rndis_translate_scan(dev, cev, extra + IW_SCAN_MAX_DATA,
|
cev = rndis_translate_scan(dev, info, cev,
|
||||||
bssid);
|
extra + IW_SCAN_MAX_DATA, bssid);
|
||||||
bssid = (void *)bssid + bssid_len;
|
bssid = (void *)bssid + bssid_len;
|
||||||
bssid_len = le32_to_cpu(bssid->length);
|
bssid_len = le32_to_cpu(bssid->length);
|
||||||
count--;
|
count--;
|
||||||
|
@ -1624,25 +1624,25 @@ static int wl3501_get_scan(struct net_device *dev, struct iw_request_info *info,
|
|||||||
iwe.cmd = SIOCGIWAP;
|
iwe.cmd = SIOCGIWAP;
|
||||||
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
|
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
|
||||||
memcpy(iwe.u.ap_addr.sa_data, this->bss_set[i].bssid, ETH_ALEN);
|
memcpy(iwe.u.ap_addr.sa_data, this->bss_set[i].bssid, ETH_ALEN);
|
||||||
current_ev = iwe_stream_add_event(current_ev,
|
current_ev = iwe_stream_add_event(info, current_ev,
|
||||||
extra + IW_SCAN_MAX_DATA,
|
extra + IW_SCAN_MAX_DATA,
|
||||||
&iwe, IW_EV_ADDR_LEN);
|
&iwe, IW_EV_ADDR_LEN);
|
||||||
iwe.cmd = SIOCGIWESSID;
|
iwe.cmd = SIOCGIWESSID;
|
||||||
iwe.u.data.flags = 1;
|
iwe.u.data.flags = 1;
|
||||||
iwe.u.data.length = this->bss_set[i].ssid.el.len;
|
iwe.u.data.length = this->bss_set[i].ssid.el.len;
|
||||||
current_ev = iwe_stream_add_point(current_ev,
|
current_ev = iwe_stream_add_point(info, current_ev,
|
||||||
extra + IW_SCAN_MAX_DATA,
|
extra + IW_SCAN_MAX_DATA,
|
||||||
&iwe,
|
&iwe,
|
||||||
this->bss_set[i].ssid.essid);
|
this->bss_set[i].ssid.essid);
|
||||||
iwe.cmd = SIOCGIWMODE;
|
iwe.cmd = SIOCGIWMODE;
|
||||||
iwe.u.mode = this->bss_set[i].bss_type;
|
iwe.u.mode = this->bss_set[i].bss_type;
|
||||||
current_ev = iwe_stream_add_event(current_ev,
|
current_ev = iwe_stream_add_event(info, current_ev,
|
||||||
extra + IW_SCAN_MAX_DATA,
|
extra + IW_SCAN_MAX_DATA,
|
||||||
&iwe, IW_EV_UINT_LEN);
|
&iwe, IW_EV_UINT_LEN);
|
||||||
iwe.cmd = SIOCGIWFREQ;
|
iwe.cmd = SIOCGIWFREQ;
|
||||||
iwe.u.freq.m = this->bss_set[i].ds_pset.chan;
|
iwe.u.freq.m = this->bss_set[i].ds_pset.chan;
|
||||||
iwe.u.freq.e = 0;
|
iwe.u.freq.e = 0;
|
||||||
current_ev = iwe_stream_add_event(current_ev,
|
current_ev = iwe_stream_add_event(info, current_ev,
|
||||||
extra + IW_SCAN_MAX_DATA,
|
extra + IW_SCAN_MAX_DATA,
|
||||||
&iwe, IW_EV_FREQ_LEN);
|
&iwe, IW_EV_FREQ_LEN);
|
||||||
iwe.cmd = SIOCGIWENCODE;
|
iwe.cmd = SIOCGIWENCODE;
|
||||||
@ -1651,7 +1651,7 @@ static int wl3501_get_scan(struct net_device *dev, struct iw_request_info *info,
|
|||||||
else
|
else
|
||||||
iwe.u.data.flags = IW_ENCODE_DISABLED;
|
iwe.u.data.flags = IW_ENCODE_DISABLED;
|
||||||
iwe.u.data.length = 0;
|
iwe.u.data.length = 0;
|
||||||
current_ev = iwe_stream_add_point(current_ev,
|
current_ev = iwe_stream_add_point(info, current_ev,
|
||||||
extra + IW_SCAN_MAX_DATA,
|
extra + IW_SCAN_MAX_DATA,
|
||||||
&iwe, NULL);
|
&iwe, NULL);
|
||||||
}
|
}
|
||||||
|
@ -1152,32 +1152,36 @@ static int zd1201_get_scan(struct net_device *dev,
|
|||||||
iwe.cmd = SIOCGIWAP;
|
iwe.cmd = SIOCGIWAP;
|
||||||
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
|
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
|
||||||
memcpy(iwe.u.ap_addr.sa_data, zd->rxdata+i+6, 6);
|
memcpy(iwe.u.ap_addr.sa_data, zd->rxdata+i+6, 6);
|
||||||
cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_ADDR_LEN);
|
cev = iwe_stream_add_event(info, cev, end_buf,
|
||||||
|
&iwe, IW_EV_ADDR_LEN);
|
||||||
|
|
||||||
iwe.cmd = SIOCGIWESSID;
|
iwe.cmd = SIOCGIWESSID;
|
||||||
iwe.u.data.length = zd->rxdata[i+16];
|
iwe.u.data.length = zd->rxdata[i+16];
|
||||||
iwe.u.data.flags = 1;
|
iwe.u.data.flags = 1;
|
||||||
cev = iwe_stream_add_point(cev, end_buf, &iwe, zd->rxdata+i+18);
|
cev = iwe_stream_add_point(info, cev, end_buf,
|
||||||
|
&iwe, zd->rxdata+i+18);
|
||||||
|
|
||||||
iwe.cmd = SIOCGIWMODE;
|
iwe.cmd = SIOCGIWMODE;
|
||||||
if (zd->rxdata[i+14]&0x01)
|
if (zd->rxdata[i+14]&0x01)
|
||||||
iwe.u.mode = IW_MODE_MASTER;
|
iwe.u.mode = IW_MODE_MASTER;
|
||||||
else
|
else
|
||||||
iwe.u.mode = IW_MODE_ADHOC;
|
iwe.u.mode = IW_MODE_ADHOC;
|
||||||
cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_UINT_LEN);
|
cev = iwe_stream_add_event(info, cev, end_buf,
|
||||||
|
&iwe, IW_EV_UINT_LEN);
|
||||||
|
|
||||||
iwe.cmd = SIOCGIWFREQ;
|
iwe.cmd = SIOCGIWFREQ;
|
||||||
iwe.u.freq.m = zd->rxdata[i+0];
|
iwe.u.freq.m = zd->rxdata[i+0];
|
||||||
iwe.u.freq.e = 0;
|
iwe.u.freq.e = 0;
|
||||||
cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_FREQ_LEN);
|
cev = iwe_stream_add_event(info, cev, end_buf,
|
||||||
|
&iwe, IW_EV_FREQ_LEN);
|
||||||
|
|
||||||
iwe.cmd = SIOCGIWRATE;
|
iwe.cmd = SIOCGIWRATE;
|
||||||
iwe.u.bitrate.fixed = 0;
|
iwe.u.bitrate.fixed = 0;
|
||||||
iwe.u.bitrate.disabled = 0;
|
iwe.u.bitrate.disabled = 0;
|
||||||
for (j=0; j<10; j++) if (zd->rxdata[i+50+j]) {
|
for (j=0; j<10; j++) if (zd->rxdata[i+50+j]) {
|
||||||
iwe.u.bitrate.value = (zd->rxdata[i+50+j]&0x7f)*500000;
|
iwe.u.bitrate.value = (zd->rxdata[i+50+j]&0x7f)*500000;
|
||||||
cev=iwe_stream_add_event(cev, end_buf, &iwe,
|
cev = iwe_stream_add_event(info, cev, end_buf,
|
||||||
IW_EV_PARAM_LEN);
|
&iwe, IW_EV_PARAM_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
iwe.cmd = SIOCGIWENCODE;
|
iwe.cmd = SIOCGIWENCODE;
|
||||||
@ -1186,14 +1190,15 @@ static int zd1201_get_scan(struct net_device *dev,
|
|||||||
iwe.u.data.flags = IW_ENCODE_ENABLED;
|
iwe.u.data.flags = IW_ENCODE_ENABLED;
|
||||||
else
|
else
|
||||||
iwe.u.data.flags = IW_ENCODE_DISABLED;
|
iwe.u.data.flags = IW_ENCODE_DISABLED;
|
||||||
cev = iwe_stream_add_point(cev, end_buf, &iwe, NULL);
|
cev = iwe_stream_add_point(info, cev, end_buf, &iwe, NULL);
|
||||||
|
|
||||||
iwe.cmd = IWEVQUAL;
|
iwe.cmd = IWEVQUAL;
|
||||||
iwe.u.qual.qual = zd->rxdata[i+4];
|
iwe.u.qual.qual = zd->rxdata[i+4];
|
||||||
iwe.u.qual.noise= zd->rxdata[i+2]/10-100;
|
iwe.u.qual.noise= zd->rxdata[i+2]/10-100;
|
||||||
iwe.u.qual.level = (256+zd->rxdata[i+4]*100)/255-100;
|
iwe.u.qual.level = (256+zd->rxdata[i+4]*100)/255-100;
|
||||||
iwe.u.qual.updated = 7;
|
iwe.u.qual.updated = 7;
|
||||||
cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_QUAL_LEN);
|
cev = iwe_stream_add_event(info, cev, end_buf,
|
||||||
|
&iwe, IW_EV_QUAL_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!enabled_save)
|
if (!enabled_save)
|
||||||
|
@ -58,7 +58,6 @@
|
|||||||
#include <linux/syscalls.h>
|
#include <linux/syscalls.h>
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
#include <linux/i2c-dev.h>
|
#include <linux/i2c-dev.h>
|
||||||
#include <linux/wireless.h>
|
|
||||||
#include <linux/atalk.h>
|
#include <linux/atalk.h>
|
||||||
#include <linux/loop.h>
|
#include <linux/loop.h>
|
||||||
|
|
||||||
@ -1757,64 +1756,6 @@ static int do_i2c_smbus_ioctl(unsigned int fd, unsigned int cmd, unsigned long a
|
|||||||
return sys_ioctl(fd, cmd, (unsigned long)tdata);
|
return sys_ioctl(fd, cmd, (unsigned long)tdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct compat_iw_point {
|
|
||||||
compat_caddr_t pointer;
|
|
||||||
__u16 length;
|
|
||||||
__u16 flags;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int do_wireless_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
|
|
||||||
{
|
|
||||||
struct iwreq __user *iwr;
|
|
||||||
struct iwreq __user *iwr_u;
|
|
||||||
struct iw_point __user *iwp;
|
|
||||||
struct compat_iw_point __user *iwp_u;
|
|
||||||
compat_caddr_t pointer_u;
|
|
||||||
void __user *pointer;
|
|
||||||
__u16 length, flags;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
iwr_u = compat_ptr(arg);
|
|
||||||
iwp_u = (struct compat_iw_point __user *) &iwr_u->u.data;
|
|
||||||
iwr = compat_alloc_user_space(sizeof(*iwr));
|
|
||||||
if (iwr == NULL)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
iwp = &iwr->u.data;
|
|
||||||
|
|
||||||
if (!access_ok(VERIFY_WRITE, iwr, sizeof(*iwr)))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
if (__copy_in_user(&iwr->ifr_ifrn.ifrn_name[0],
|
|
||||||
&iwr_u->ifr_ifrn.ifrn_name[0],
|
|
||||||
sizeof(iwr->ifr_ifrn.ifrn_name)))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
if (__get_user(pointer_u, &iwp_u->pointer) ||
|
|
||||||
__get_user(length, &iwp_u->length) ||
|
|
||||||
__get_user(flags, &iwp_u->flags))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
if (__put_user(compat_ptr(pointer_u), &iwp->pointer) ||
|
|
||||||
__put_user(length, &iwp->length) ||
|
|
||||||
__put_user(flags, &iwp->flags))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
ret = sys_ioctl(fd, cmd, (unsigned long) iwr);
|
|
||||||
|
|
||||||
if (__get_user(pointer, &iwp->pointer) ||
|
|
||||||
__get_user(length, &iwp->length) ||
|
|
||||||
__get_user(flags, &iwp->flags))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
if (__put_user(ptr_to_compat(pointer), &iwp_u->pointer) ||
|
|
||||||
__put_user(length, &iwp_u->length) ||
|
|
||||||
__put_user(flags, &iwp_u->flags))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Since old style bridge ioctl's endup using SIOCDEVPRIVATE
|
/* Since old style bridge ioctl's endup using SIOCDEVPRIVATE
|
||||||
* for some operations; this forces use of the newer bridge-utils that
|
* for some operations; this forces use of the newer bridge-utils that
|
||||||
* use compatiable ioctls
|
* use compatiable ioctls
|
||||||
@ -2495,36 +2436,6 @@ COMPATIBLE_IOCTL(I2C_TENBIT)
|
|||||||
COMPATIBLE_IOCTL(I2C_PEC)
|
COMPATIBLE_IOCTL(I2C_PEC)
|
||||||
COMPATIBLE_IOCTL(I2C_RETRIES)
|
COMPATIBLE_IOCTL(I2C_RETRIES)
|
||||||
COMPATIBLE_IOCTL(I2C_TIMEOUT)
|
COMPATIBLE_IOCTL(I2C_TIMEOUT)
|
||||||
/* wireless */
|
|
||||||
COMPATIBLE_IOCTL(SIOCSIWCOMMIT)
|
|
||||||
COMPATIBLE_IOCTL(SIOCGIWNAME)
|
|
||||||
COMPATIBLE_IOCTL(SIOCSIWNWID)
|
|
||||||
COMPATIBLE_IOCTL(SIOCGIWNWID)
|
|
||||||
COMPATIBLE_IOCTL(SIOCSIWFREQ)
|
|
||||||
COMPATIBLE_IOCTL(SIOCGIWFREQ)
|
|
||||||
COMPATIBLE_IOCTL(SIOCSIWMODE)
|
|
||||||
COMPATIBLE_IOCTL(SIOCGIWMODE)
|
|
||||||
COMPATIBLE_IOCTL(SIOCSIWSENS)
|
|
||||||
COMPATIBLE_IOCTL(SIOCGIWSENS)
|
|
||||||
COMPATIBLE_IOCTL(SIOCSIWRANGE)
|
|
||||||
COMPATIBLE_IOCTL(SIOCSIWPRIV)
|
|
||||||
COMPATIBLE_IOCTL(SIOCSIWSTATS)
|
|
||||||
COMPATIBLE_IOCTL(SIOCSIWAP)
|
|
||||||
COMPATIBLE_IOCTL(SIOCGIWAP)
|
|
||||||
COMPATIBLE_IOCTL(SIOCSIWRATE)
|
|
||||||
COMPATIBLE_IOCTL(SIOCGIWRATE)
|
|
||||||
COMPATIBLE_IOCTL(SIOCSIWRTS)
|
|
||||||
COMPATIBLE_IOCTL(SIOCGIWRTS)
|
|
||||||
COMPATIBLE_IOCTL(SIOCSIWFRAG)
|
|
||||||
COMPATIBLE_IOCTL(SIOCGIWFRAG)
|
|
||||||
COMPATIBLE_IOCTL(SIOCSIWTXPOW)
|
|
||||||
COMPATIBLE_IOCTL(SIOCGIWTXPOW)
|
|
||||||
COMPATIBLE_IOCTL(SIOCSIWRETRY)
|
|
||||||
COMPATIBLE_IOCTL(SIOCGIWRETRY)
|
|
||||||
COMPATIBLE_IOCTL(SIOCSIWPOWER)
|
|
||||||
COMPATIBLE_IOCTL(SIOCGIWPOWER)
|
|
||||||
COMPATIBLE_IOCTL(SIOCSIWAUTH)
|
|
||||||
COMPATIBLE_IOCTL(SIOCGIWAUTH)
|
|
||||||
/* hiddev */
|
/* hiddev */
|
||||||
COMPATIBLE_IOCTL(HIDIOCGVERSION)
|
COMPATIBLE_IOCTL(HIDIOCGVERSION)
|
||||||
COMPATIBLE_IOCTL(HIDIOCAPPLICATION)
|
COMPATIBLE_IOCTL(HIDIOCAPPLICATION)
|
||||||
@ -2755,29 +2666,7 @@ COMPATIBLE_IOCTL(USBDEVFS_IOCTL32)
|
|||||||
HANDLE_IOCTL(I2C_FUNCS, w_long)
|
HANDLE_IOCTL(I2C_FUNCS, w_long)
|
||||||
HANDLE_IOCTL(I2C_RDWR, do_i2c_rdwr_ioctl)
|
HANDLE_IOCTL(I2C_RDWR, do_i2c_rdwr_ioctl)
|
||||||
HANDLE_IOCTL(I2C_SMBUS, do_i2c_smbus_ioctl)
|
HANDLE_IOCTL(I2C_SMBUS, do_i2c_smbus_ioctl)
|
||||||
/* wireless */
|
/* bridge */
|
||||||
HANDLE_IOCTL(SIOCGIWRANGE, do_wireless_ioctl)
|
|
||||||
HANDLE_IOCTL(SIOCGIWPRIV, do_wireless_ioctl)
|
|
||||||
HANDLE_IOCTL(SIOCGIWSTATS, do_wireless_ioctl)
|
|
||||||
HANDLE_IOCTL(SIOCSIWSPY, do_wireless_ioctl)
|
|
||||||
HANDLE_IOCTL(SIOCGIWSPY, do_wireless_ioctl)
|
|
||||||
HANDLE_IOCTL(SIOCSIWTHRSPY, do_wireless_ioctl)
|
|
||||||
HANDLE_IOCTL(SIOCGIWTHRSPY, do_wireless_ioctl)
|
|
||||||
HANDLE_IOCTL(SIOCSIWMLME, do_wireless_ioctl)
|
|
||||||
HANDLE_IOCTL(SIOCGIWAPLIST, do_wireless_ioctl)
|
|
||||||
HANDLE_IOCTL(SIOCSIWSCAN, do_wireless_ioctl)
|
|
||||||
HANDLE_IOCTL(SIOCGIWSCAN, do_wireless_ioctl)
|
|
||||||
HANDLE_IOCTL(SIOCSIWESSID, do_wireless_ioctl)
|
|
||||||
HANDLE_IOCTL(SIOCGIWESSID, do_wireless_ioctl)
|
|
||||||
HANDLE_IOCTL(SIOCSIWNICKN, do_wireless_ioctl)
|
|
||||||
HANDLE_IOCTL(SIOCGIWNICKN, do_wireless_ioctl)
|
|
||||||
HANDLE_IOCTL(SIOCSIWENCODE, do_wireless_ioctl)
|
|
||||||
HANDLE_IOCTL(SIOCGIWENCODE, do_wireless_ioctl)
|
|
||||||
HANDLE_IOCTL(SIOCSIWGENIE, do_wireless_ioctl)
|
|
||||||
HANDLE_IOCTL(SIOCGIWGENIE, do_wireless_ioctl)
|
|
||||||
HANDLE_IOCTL(SIOCSIWENCODEEXT, do_wireless_ioctl)
|
|
||||||
HANDLE_IOCTL(SIOCGIWENCODEEXT, do_wireless_ioctl)
|
|
||||||
HANDLE_IOCTL(SIOCSIWPMKSA, do_wireless_ioctl)
|
|
||||||
HANDLE_IOCTL(SIOCSIFBR, old_bridge_ioctl)
|
HANDLE_IOCTL(SIOCSIFBR, old_bridge_ioctl)
|
||||||
HANDLE_IOCTL(SIOCGIFBR, old_bridge_ioctl)
|
HANDLE_IOCTL(SIOCGIFBR, old_bridge_ioctl)
|
||||||
/* Not implemented in the native kernel */
|
/* Not implemented in the native kernel */
|
||||||
|
@ -677,6 +677,19 @@ struct iw_point
|
|||||||
__u16 flags; /* Optional params */
|
__u16 flags; /* Optional params */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef __KERNEL__
|
||||||
|
#ifdef CONFIG_COMPAT
|
||||||
|
|
||||||
|
#include <linux/compat.h>
|
||||||
|
|
||||||
|
struct compat_iw_point {
|
||||||
|
compat_caddr_t pointer;
|
||||||
|
__u16 length;
|
||||||
|
__u16 flags;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A frequency
|
* A frequency
|
||||||
* For numbers lower than 10^9, we encode the number in 'm' and
|
* For numbers lower than 10^9, we encode the number in 'm' and
|
||||||
@ -1100,6 +1113,21 @@ struct iw_event
|
|||||||
#define IW_EV_POINT_LEN (IW_EV_LCP_LEN + sizeof(struct iw_point) - \
|
#define IW_EV_POINT_LEN (IW_EV_LCP_LEN + sizeof(struct iw_point) - \
|
||||||
IW_EV_POINT_OFF)
|
IW_EV_POINT_OFF)
|
||||||
|
|
||||||
|
#ifdef __KERNEL__
|
||||||
|
#ifdef CONFIG_COMPAT
|
||||||
|
struct __compat_iw_event {
|
||||||
|
__u16 len; /* Real length of this stuff */
|
||||||
|
__u16 cmd; /* Wireless IOCTL */
|
||||||
|
compat_caddr_t pointer;
|
||||||
|
};
|
||||||
|
#define IW_EV_COMPAT_LCP_LEN offsetof(struct __compat_iw_event, pointer)
|
||||||
|
#define IW_EV_COMPAT_POINT_OFF offsetof(struct compat_iw_point, length)
|
||||||
|
#define IW_EV_COMPAT_POINT_LEN \
|
||||||
|
(IW_EV_COMPAT_LCP_LEN + sizeof(struct compat_iw_point) - \
|
||||||
|
IW_EV_COMPAT_POINT_OFF)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Size of the Event prefix when packed in stream */
|
/* Size of the Event prefix when packed in stream */
|
||||||
#define IW_EV_LCP_PK_LEN (4)
|
#define IW_EV_LCP_PK_LEN (4)
|
||||||
/* Size of the various events when packed in stream */
|
/* Size of the various events when packed in stream */
|
||||||
|
@ -256,7 +256,7 @@
|
|||||||
#define EIWCOMMIT EINPROGRESS
|
#define EIWCOMMIT EINPROGRESS
|
||||||
|
|
||||||
/* Flags available in struct iw_request_info */
|
/* Flags available in struct iw_request_info */
|
||||||
#define IW_REQUEST_FLAG_NONE 0x0000 /* No flag so far */
|
#define IW_REQUEST_FLAG_COMPAT 0x0001 /* Compat ioctl call */
|
||||||
|
|
||||||
/* Type of headers we know about (basically union iwreq_data) */
|
/* Type of headers we know about (basically union iwreq_data) */
|
||||||
#define IW_HEADER_TYPE_NULL 0 /* Not available */
|
#define IW_HEADER_TYPE_NULL 0 /* Not available */
|
||||||
@ -478,24 +478,56 @@ extern void wireless_spy_update(struct net_device * dev,
|
|||||||
* Function that are so simple that it's more efficient inlining them
|
* Function that are so simple that it's more efficient inlining them
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static inline int iwe_stream_lcp_len(struct iw_request_info *info)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_COMPAT
|
||||||
|
if (info->flags & IW_REQUEST_FLAG_COMPAT)
|
||||||
|
return IW_EV_COMPAT_LCP_LEN;
|
||||||
|
#endif
|
||||||
|
return IW_EV_LCP_LEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int iwe_stream_point_len(struct iw_request_info *info)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_COMPAT
|
||||||
|
if (info->flags & IW_REQUEST_FLAG_COMPAT)
|
||||||
|
return IW_EV_COMPAT_POINT_LEN;
|
||||||
|
#endif
|
||||||
|
return IW_EV_POINT_LEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int iwe_stream_event_len_adjust(struct iw_request_info *info,
|
||||||
|
int event_len)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_COMPAT
|
||||||
|
if (info->flags & IW_REQUEST_FLAG_COMPAT) {
|
||||||
|
event_len -= IW_EV_LCP_LEN;
|
||||||
|
event_len += IW_EV_COMPAT_LCP_LEN;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return event_len;
|
||||||
|
}
|
||||||
|
|
||||||
/*------------------------------------------------------------------*/
|
/*------------------------------------------------------------------*/
|
||||||
/*
|
/*
|
||||||
* Wrapper to add an Wireless Event to a stream of events.
|
* Wrapper to add an Wireless Event to a stream of events.
|
||||||
*/
|
*/
|
||||||
static inline char *
|
static inline char *
|
||||||
iwe_stream_add_event(char * stream, /* Stream of events */
|
iwe_stream_add_event(struct iw_request_info *info, char *stream, char *ends,
|
||||||
char * ends, /* End of stream */
|
struct iw_event *iwe, int event_len)
|
||||||
struct iw_event *iwe, /* Payload */
|
|
||||||
int event_len) /* Real size of payload */
|
|
||||||
{
|
{
|
||||||
|
int lcp_len = iwe_stream_lcp_len(info);
|
||||||
|
|
||||||
|
event_len = iwe_stream_event_len_adjust(info, event_len);
|
||||||
|
|
||||||
/* Check if it's possible */
|
/* Check if it's possible */
|
||||||
if(likely((stream + event_len) < ends)) {
|
if(likely((stream + event_len) < ends)) {
|
||||||
iwe->len = event_len;
|
iwe->len = event_len;
|
||||||
/* Beware of alignement issues on 64 bits */
|
/* Beware of alignement issues on 64 bits */
|
||||||
memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
|
memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
|
||||||
memcpy(stream + IW_EV_LCP_LEN,
|
memcpy(stream + lcp_len, &iwe->u,
|
||||||
((char *) iwe) + IW_EV_LCP_LEN,
|
event_len - lcp_len);
|
||||||
event_len - IW_EV_LCP_LEN);
|
|
||||||
stream += event_len;
|
stream += event_len;
|
||||||
}
|
}
|
||||||
return stream;
|
return stream;
|
||||||
@ -507,20 +539,21 @@ iwe_stream_add_event(char * stream, /* Stream of events */
|
|||||||
* stream of events.
|
* stream of events.
|
||||||
*/
|
*/
|
||||||
static inline char *
|
static inline char *
|
||||||
iwe_stream_add_point(char * stream, /* Stream of events */
|
iwe_stream_add_point(struct iw_request_info *info, char *stream, char *ends,
|
||||||
char * ends, /* End of stream */
|
struct iw_event *iwe, char *extra)
|
||||||
struct iw_event *iwe, /* Payload length + flags */
|
|
||||||
char * extra) /* More payload */
|
|
||||||
{
|
{
|
||||||
int event_len = IW_EV_POINT_LEN + iwe->u.data.length;
|
int event_len = iwe_stream_point_len(info) + iwe->u.data.length;
|
||||||
|
int point_len = iwe_stream_point_len(info);
|
||||||
|
int lcp_len = iwe_stream_lcp_len(info);
|
||||||
|
|
||||||
/* Check if it's possible */
|
/* Check if it's possible */
|
||||||
if(likely((stream + event_len) < ends)) {
|
if(likely((stream + event_len) < ends)) {
|
||||||
iwe->len = event_len;
|
iwe->len = event_len;
|
||||||
memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
|
memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
|
||||||
memcpy(stream + IW_EV_LCP_LEN,
|
memcpy(stream + lcp_len,
|
||||||
((char *) iwe) + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
|
((char *) &iwe->u) + IW_EV_POINT_OFF,
|
||||||
IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
|
IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
|
||||||
memcpy(stream + IW_EV_POINT_LEN, extra, iwe->u.data.length);
|
memcpy(stream + point_len, extra, iwe->u.data.length);
|
||||||
stream += event_len;
|
stream += event_len;
|
||||||
}
|
}
|
||||||
return stream;
|
return stream;
|
||||||
@ -533,110 +566,24 @@ iwe_stream_add_point(char * stream, /* Stream of events */
|
|||||||
* At the first run, you need to have (value = event + IW_EV_LCP_LEN).
|
* At the first run, you need to have (value = event + IW_EV_LCP_LEN).
|
||||||
*/
|
*/
|
||||||
static inline char *
|
static inline char *
|
||||||
iwe_stream_add_value(char * event, /* Event in the stream */
|
iwe_stream_add_value(struct iw_request_info *info, char *event, char *value,
|
||||||
char * value, /* Value in event */
|
char *ends, struct iw_event *iwe, int event_len)
|
||||||
char * ends, /* End of stream */
|
|
||||||
struct iw_event *iwe, /* Payload */
|
|
||||||
int event_len) /* Real size of payload */
|
|
||||||
{
|
{
|
||||||
|
int lcp_len = iwe_stream_lcp_len(info);
|
||||||
|
|
||||||
/* Don't duplicate LCP */
|
/* Don't duplicate LCP */
|
||||||
event_len -= IW_EV_LCP_LEN;
|
event_len -= IW_EV_LCP_LEN;
|
||||||
|
|
||||||
/* Check if it's possible */
|
/* Check if it's possible */
|
||||||
if(likely((value + event_len) < ends)) {
|
if(likely((value + event_len) < ends)) {
|
||||||
/* Add new value */
|
/* Add new value */
|
||||||
memcpy(value, (char *) iwe + IW_EV_LCP_LEN, event_len);
|
memcpy(value, &iwe->u, event_len);
|
||||||
value += event_len;
|
value += event_len;
|
||||||
/* Patch LCP */
|
/* Patch LCP */
|
||||||
iwe->len = value - event;
|
iwe->len = value - event;
|
||||||
memcpy(event, (char *) iwe, IW_EV_LCP_LEN);
|
memcpy(event, (char *) iwe, lcp_len);
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*------------------------------------------------------------------*/
|
|
||||||
/*
|
|
||||||
* Wrapper to add an Wireless Event to a stream of events.
|
|
||||||
* Same as above, with explicit error check...
|
|
||||||
*/
|
|
||||||
static inline char *
|
|
||||||
iwe_stream_check_add_event(char * stream, /* Stream of events */
|
|
||||||
char * ends, /* End of stream */
|
|
||||||
struct iw_event *iwe, /* Payload */
|
|
||||||
int event_len, /* Size of payload */
|
|
||||||
int * perr) /* Error report */
|
|
||||||
{
|
|
||||||
/* Check if it's possible, set error if not */
|
|
||||||
if(likely((stream + event_len) < ends)) {
|
|
||||||
iwe->len = event_len;
|
|
||||||
/* Beware of alignement issues on 64 bits */
|
|
||||||
memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
|
|
||||||
memcpy(stream + IW_EV_LCP_LEN,
|
|
||||||
((char *) iwe) + IW_EV_LCP_LEN,
|
|
||||||
event_len - IW_EV_LCP_LEN);
|
|
||||||
stream += event_len;
|
|
||||||
} else
|
|
||||||
*perr = -E2BIG;
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------*/
|
|
||||||
/*
|
|
||||||
* Wrapper to add an short Wireless Event containing a pointer to a
|
|
||||||
* stream of events.
|
|
||||||
* Same as above, with explicit error check...
|
|
||||||
*/
|
|
||||||
static inline char *
|
|
||||||
iwe_stream_check_add_point(char * stream, /* Stream of events */
|
|
||||||
char * ends, /* End of stream */
|
|
||||||
struct iw_event *iwe, /* Payload length + flags */
|
|
||||||
char * extra, /* More payload */
|
|
||||||
int * perr) /* Error report */
|
|
||||||
{
|
|
||||||
int event_len = IW_EV_POINT_LEN + iwe->u.data.length;
|
|
||||||
/* Check if it's possible */
|
|
||||||
if(likely((stream + event_len) < ends)) {
|
|
||||||
iwe->len = event_len;
|
|
||||||
memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
|
|
||||||
memcpy(stream + IW_EV_LCP_LEN,
|
|
||||||
((char *) iwe) + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
|
|
||||||
IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
|
|
||||||
memcpy(stream + IW_EV_POINT_LEN, extra, iwe->u.data.length);
|
|
||||||
stream += event_len;
|
|
||||||
} else
|
|
||||||
*perr = -E2BIG;
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------*/
|
|
||||||
/*
|
|
||||||
* Wrapper to add a value to a Wireless Event in a stream of events.
|
|
||||||
* Be careful, this one is tricky to use properly :
|
|
||||||
* At the first run, you need to have (value = event + IW_EV_LCP_LEN).
|
|
||||||
* Same as above, with explicit error check...
|
|
||||||
*/
|
|
||||||
static inline char *
|
|
||||||
iwe_stream_check_add_value(char * event, /* Event in the stream */
|
|
||||||
char * value, /* Value in event */
|
|
||||||
char * ends, /* End of stream */
|
|
||||||
struct iw_event *iwe, /* Payload */
|
|
||||||
int event_len, /* Size of payload */
|
|
||||||
int * perr) /* Error report */
|
|
||||||
{
|
|
||||||
/* Don't duplicate LCP */
|
|
||||||
event_len -= IW_EV_LCP_LEN;
|
|
||||||
|
|
||||||
/* Check if it's possible */
|
|
||||||
if(likely((value + event_len) < ends)) {
|
|
||||||
/* Add new value */
|
|
||||||
memcpy(value, (char *) iwe + IW_EV_LCP_LEN, event_len);
|
|
||||||
value += event_len;
|
|
||||||
/* Patch LCP */
|
|
||||||
iwe->len = value - event;
|
|
||||||
memcpy(event, (char *) iwe, IW_EV_LCP_LEN);
|
|
||||||
} else
|
|
||||||
*perr = -E2BIG;
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* _IW_HANDLER_H */
|
#endif /* _IW_HANDLER_H */
|
||||||
|
@ -12,6 +12,8 @@ extern int wext_proc_init(struct net *net);
|
|||||||
extern void wext_proc_exit(struct net *net);
|
extern void wext_proc_exit(struct net *net);
|
||||||
extern int wext_handle_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd,
|
extern int wext_handle_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd,
|
||||||
void __user *arg);
|
void __user *arg);
|
||||||
|
extern int compat_wext_handle_ioctl(struct net *net, unsigned int cmd,
|
||||||
|
unsigned long arg);
|
||||||
#else
|
#else
|
||||||
static inline int wext_proc_init(struct net *net)
|
static inline int wext_proc_init(struct net *net)
|
||||||
{
|
{
|
||||||
@ -26,6 +28,11 @@ static inline int wext_handle_ioctl(struct net *net, struct ifreq *ifr, unsigned
|
|||||||
{
|
{
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
static inline int compat_wext_handle_ioctl(struct net *net, unsigned int cmd,
|
||||||
|
unsigned long arg)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* __NET_WEXT_H */
|
#endif /* __NET_WEXT_H */
|
||||||
|
@ -44,7 +44,8 @@ static const char *ieee80211_modes[] = {
|
|||||||
#define MAX_CUSTOM_LEN 64
|
#define MAX_CUSTOM_LEN 64
|
||||||
static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
|
static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
|
||||||
char *start, char *stop,
|
char *start, char *stop,
|
||||||
struct ieee80211_network *network)
|
struct ieee80211_network *network,
|
||||||
|
struct iw_request_info *info)
|
||||||
{
|
{
|
||||||
char custom[MAX_CUSTOM_LEN];
|
char custom[MAX_CUSTOM_LEN];
|
||||||
char *p;
|
char *p;
|
||||||
@ -57,7 +58,7 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
|
|||||||
iwe.cmd = SIOCGIWAP;
|
iwe.cmd = SIOCGIWAP;
|
||||||
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
|
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
|
||||||
memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN);
|
memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN);
|
||||||
start = iwe_stream_add_event(start, stop, &iwe, IW_EV_ADDR_LEN);
|
start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
|
||||||
|
|
||||||
/* Remaining entries will be displayed in the order we provide them */
|
/* Remaining entries will be displayed in the order we provide them */
|
||||||
|
|
||||||
@ -66,17 +67,19 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
|
|||||||
iwe.u.data.flags = 1;
|
iwe.u.data.flags = 1;
|
||||||
if (network->flags & NETWORK_EMPTY_ESSID) {
|
if (network->flags & NETWORK_EMPTY_ESSID) {
|
||||||
iwe.u.data.length = sizeof("<hidden>");
|
iwe.u.data.length = sizeof("<hidden>");
|
||||||
start = iwe_stream_add_point(start, stop, &iwe, "<hidden>");
|
start = iwe_stream_add_point(info, start, stop,
|
||||||
|
&iwe, "<hidden>");
|
||||||
} else {
|
} else {
|
||||||
iwe.u.data.length = min(network->ssid_len, (u8) 32);
|
iwe.u.data.length = min(network->ssid_len, (u8) 32);
|
||||||
start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
|
start = iwe_stream_add_point(info, start, stop,
|
||||||
|
&iwe, network->ssid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add the protocol name */
|
/* Add the protocol name */
|
||||||
iwe.cmd = SIOCGIWNAME;
|
iwe.cmd = SIOCGIWNAME;
|
||||||
snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11%s",
|
snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11%s",
|
||||||
ieee80211_modes[network->mode]);
|
ieee80211_modes[network->mode]);
|
||||||
start = iwe_stream_add_event(start, stop, &iwe, IW_EV_CHAR_LEN);
|
start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
|
||||||
|
|
||||||
/* Add mode */
|
/* Add mode */
|
||||||
iwe.cmd = SIOCGIWMODE;
|
iwe.cmd = SIOCGIWMODE;
|
||||||
@ -86,7 +89,8 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
|
|||||||
else
|
else
|
||||||
iwe.u.mode = IW_MODE_ADHOC;
|
iwe.u.mode = IW_MODE_ADHOC;
|
||||||
|
|
||||||
start = iwe_stream_add_event(start, stop, &iwe, IW_EV_UINT_LEN);
|
start = iwe_stream_add_event(info, start, stop,
|
||||||
|
&iwe, IW_EV_UINT_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add channel and frequency */
|
/* Add channel and frequency */
|
||||||
@ -95,7 +99,7 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
|
|||||||
iwe.u.freq.m = ieee80211_channel_to_freq(ieee, network->channel);
|
iwe.u.freq.m = ieee80211_channel_to_freq(ieee, network->channel);
|
||||||
iwe.u.freq.e = 6;
|
iwe.u.freq.e = 6;
|
||||||
iwe.u.freq.i = 0;
|
iwe.u.freq.i = 0;
|
||||||
start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN);
|
start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
|
||||||
|
|
||||||
/* Add encryption capability */
|
/* Add encryption capability */
|
||||||
iwe.cmd = SIOCGIWENCODE;
|
iwe.cmd = SIOCGIWENCODE;
|
||||||
@ -104,12 +108,13 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
|
|||||||
else
|
else
|
||||||
iwe.u.data.flags = IW_ENCODE_DISABLED;
|
iwe.u.data.flags = IW_ENCODE_DISABLED;
|
||||||
iwe.u.data.length = 0;
|
iwe.u.data.length = 0;
|
||||||
start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
|
start = iwe_stream_add_point(info, start, stop,
|
||||||
|
&iwe, network->ssid);
|
||||||
|
|
||||||
/* Add basic and extended rates */
|
/* Add basic and extended rates */
|
||||||
/* Rate : stuffing multiple values in a single event require a bit
|
/* Rate : stuffing multiple values in a single event require a bit
|
||||||
* more of magic - Jean II */
|
* more of magic - Jean II */
|
||||||
current_val = start + IW_EV_LCP_LEN;
|
current_val = start + iwe_stream_lcp_len(info);
|
||||||
iwe.cmd = SIOCGIWRATE;
|
iwe.cmd = SIOCGIWRATE;
|
||||||
/* Those two flags are ignored... */
|
/* Those two flags are ignored... */
|
||||||
iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
|
iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
|
||||||
@ -124,17 +129,19 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
|
|||||||
/* Bit rate given in 500 kb/s units (+ 0x80) */
|
/* Bit rate given in 500 kb/s units (+ 0x80) */
|
||||||
iwe.u.bitrate.value = ((rate & 0x7f) * 500000);
|
iwe.u.bitrate.value = ((rate & 0x7f) * 500000);
|
||||||
/* Add new value to event */
|
/* Add new value to event */
|
||||||
current_val = iwe_stream_add_value(start, current_val, stop, &iwe, IW_EV_PARAM_LEN);
|
current_val = iwe_stream_add_value(info, start, current_val,
|
||||||
|
stop, &iwe, IW_EV_PARAM_LEN);
|
||||||
}
|
}
|
||||||
for (; j < network->rates_ex_len; j++) {
|
for (; j < network->rates_ex_len; j++) {
|
||||||
rate = network->rates_ex[j] & 0x7F;
|
rate = network->rates_ex[j] & 0x7F;
|
||||||
/* Bit rate given in 500 kb/s units (+ 0x80) */
|
/* Bit rate given in 500 kb/s units (+ 0x80) */
|
||||||
iwe.u.bitrate.value = ((rate & 0x7f) * 500000);
|
iwe.u.bitrate.value = ((rate & 0x7f) * 500000);
|
||||||
/* Add new value to event */
|
/* Add new value to event */
|
||||||
current_val = iwe_stream_add_value(start, current_val, stop, &iwe, IW_EV_PARAM_LEN);
|
current_val = iwe_stream_add_value(info, start, current_val,
|
||||||
|
stop, &iwe, IW_EV_PARAM_LEN);
|
||||||
}
|
}
|
||||||
/* Check if we added any rate */
|
/* Check if we added any rate */
|
||||||
if((current_val - start) > IW_EV_LCP_LEN)
|
if ((current_val - start) > iwe_stream_lcp_len(info))
|
||||||
start = current_val;
|
start = current_val;
|
||||||
|
|
||||||
/* Add quality statistics */
|
/* Add quality statistics */
|
||||||
@ -181,14 +188,14 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
|
|||||||
iwe.u.qual.level = network->stats.signal;
|
iwe.u.qual.level = network->stats.signal;
|
||||||
}
|
}
|
||||||
|
|
||||||
start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN);
|
start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
|
||||||
|
|
||||||
iwe.cmd = IWEVCUSTOM;
|
iwe.cmd = IWEVCUSTOM;
|
||||||
p = custom;
|
p = custom;
|
||||||
|
|
||||||
iwe.u.data.length = p - custom;
|
iwe.u.data.length = p - custom;
|
||||||
if (iwe.u.data.length)
|
if (iwe.u.data.length)
|
||||||
start = iwe_stream_add_point(start, stop, &iwe, custom);
|
start = iwe_stream_add_point(info, start, stop, &iwe, custom);
|
||||||
|
|
||||||
memset(&iwe, 0, sizeof(iwe));
|
memset(&iwe, 0, sizeof(iwe));
|
||||||
if (network->wpa_ie_len) {
|
if (network->wpa_ie_len) {
|
||||||
@ -196,7 +203,7 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
|
|||||||
memcpy(buf, network->wpa_ie, network->wpa_ie_len);
|
memcpy(buf, network->wpa_ie, network->wpa_ie_len);
|
||||||
iwe.cmd = IWEVGENIE;
|
iwe.cmd = IWEVGENIE;
|
||||||
iwe.u.data.length = network->wpa_ie_len;
|
iwe.u.data.length = network->wpa_ie_len;
|
||||||
start = iwe_stream_add_point(start, stop, &iwe, buf);
|
start = iwe_stream_add_point(info, start, stop, &iwe, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&iwe, 0, sizeof(iwe));
|
memset(&iwe, 0, sizeof(iwe));
|
||||||
@ -205,7 +212,7 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
|
|||||||
memcpy(buf, network->rsn_ie, network->rsn_ie_len);
|
memcpy(buf, network->rsn_ie, network->rsn_ie_len);
|
||||||
iwe.cmd = IWEVGENIE;
|
iwe.cmd = IWEVGENIE;
|
||||||
iwe.u.data.length = network->rsn_ie_len;
|
iwe.u.data.length = network->rsn_ie_len;
|
||||||
start = iwe_stream_add_point(start, stop, &iwe, buf);
|
start = iwe_stream_add_point(info, start, stop, &iwe, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add EXTRA: Age to display seconds since last beacon/probe response
|
/* Add EXTRA: Age to display seconds since last beacon/probe response
|
||||||
@ -217,7 +224,7 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
|
|||||||
jiffies_to_msecs(jiffies - network->last_scanned));
|
jiffies_to_msecs(jiffies - network->last_scanned));
|
||||||
iwe.u.data.length = p - custom;
|
iwe.u.data.length = p - custom;
|
||||||
if (iwe.u.data.length)
|
if (iwe.u.data.length)
|
||||||
start = iwe_stream_add_point(start, stop, &iwe, custom);
|
start = iwe_stream_add_point(info, start, stop, &iwe, custom);
|
||||||
|
|
||||||
/* Add spectrum management information */
|
/* Add spectrum management information */
|
||||||
iwe.cmd = -1;
|
iwe.cmd = -1;
|
||||||
@ -238,7 +245,7 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
|
|||||||
|
|
||||||
if (iwe.cmd == IWEVCUSTOM) {
|
if (iwe.cmd == IWEVCUSTOM) {
|
||||||
iwe.u.data.length = p - custom;
|
iwe.u.data.length = p - custom;
|
||||||
start = iwe_stream_add_point(start, stop, &iwe, custom);
|
start = iwe_stream_add_point(info, start, stop, &iwe, custom);
|
||||||
}
|
}
|
||||||
|
|
||||||
return start;
|
return start;
|
||||||
@ -272,7 +279,8 @@ int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
|
|||||||
|
|
||||||
if (ieee->scan_age == 0 ||
|
if (ieee->scan_age == 0 ||
|
||||||
time_after(network->last_scanned + ieee->scan_age, jiffies))
|
time_after(network->last_scanned + ieee->scan_age, jiffies))
|
||||||
ev = ieee80211_translate_scan(ieee, ev, stop, network);
|
ev = ieee80211_translate_scan(ieee, ev, stop, network,
|
||||||
|
info);
|
||||||
else
|
else
|
||||||
IEEE80211_DEBUG_SCAN("Not showing network '%s ("
|
IEEE80211_DEBUG_SCAN("Not showing network '%s ("
|
||||||
"%s)' due to age (%dms).\n",
|
"%s)' due to age (%dms).\n",
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/etherdevice.h>
|
#include <linux/etherdevice.h>
|
||||||
#include <net/wireless.h>
|
#include <net/wireless.h>
|
||||||
|
#include <net/iw_handler.h>
|
||||||
#include "key.h"
|
#include "key.h"
|
||||||
#include "sta_info.h"
|
#include "sta_info.h"
|
||||||
|
|
||||||
@ -867,7 +868,9 @@ int ieee80211_sta_set_bssid(struct net_device *dev, u8 *bssid);
|
|||||||
int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len);
|
int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len);
|
||||||
void ieee80211_sta_req_auth(struct net_device *dev,
|
void ieee80211_sta_req_auth(struct net_device *dev,
|
||||||
struct ieee80211_if_sta *ifsta);
|
struct ieee80211_if_sta *ifsta);
|
||||||
int ieee80211_sta_scan_results(struct net_device *dev, char *buf, size_t len);
|
int ieee80211_sta_scan_results(struct net_device *dev,
|
||||||
|
struct iw_request_info *info,
|
||||||
|
char *buf, size_t len);
|
||||||
ieee80211_rx_result ieee80211_sta_rx_scan(
|
ieee80211_rx_result ieee80211_sta_rx_scan(
|
||||||
struct net_device *dev, struct sk_buff *skb,
|
struct net_device *dev, struct sk_buff *skb,
|
||||||
struct ieee80211_rx_status *rx_status);
|
struct ieee80211_rx_status *rx_status);
|
||||||
|
@ -4087,6 +4087,7 @@ int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len)
|
|||||||
|
|
||||||
static char *
|
static char *
|
||||||
ieee80211_sta_scan_result(struct net_device *dev,
|
ieee80211_sta_scan_result(struct net_device *dev,
|
||||||
|
struct iw_request_info *info,
|
||||||
struct ieee80211_sta_bss *bss,
|
struct ieee80211_sta_bss *bss,
|
||||||
char *current_ev, char *end_buf)
|
char *current_ev, char *end_buf)
|
||||||
{
|
{
|
||||||
@ -4101,7 +4102,7 @@ ieee80211_sta_scan_result(struct net_device *dev,
|
|||||||
iwe.cmd = SIOCGIWAP;
|
iwe.cmd = SIOCGIWAP;
|
||||||
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
|
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
|
||||||
memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
|
memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
|
||||||
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
|
current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
|
||||||
IW_EV_ADDR_LEN);
|
IW_EV_ADDR_LEN);
|
||||||
|
|
||||||
memset(&iwe, 0, sizeof(iwe));
|
memset(&iwe, 0, sizeof(iwe));
|
||||||
@ -4109,13 +4110,13 @@ ieee80211_sta_scan_result(struct net_device *dev,
|
|||||||
if (bss_mesh_cfg(bss)) {
|
if (bss_mesh_cfg(bss)) {
|
||||||
iwe.u.data.length = bss_mesh_id_len(bss);
|
iwe.u.data.length = bss_mesh_id_len(bss);
|
||||||
iwe.u.data.flags = 1;
|
iwe.u.data.flags = 1;
|
||||||
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
|
current_ev = iwe_stream_add_point(info, current_ev, end_buf,
|
||||||
bss_mesh_id(bss));
|
&iwe, bss_mesh_id(bss));
|
||||||
} else {
|
} else {
|
||||||
iwe.u.data.length = bss->ssid_len;
|
iwe.u.data.length = bss->ssid_len;
|
||||||
iwe.u.data.flags = 1;
|
iwe.u.data.flags = 1;
|
||||||
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
|
current_ev = iwe_stream_add_point(info, current_ev, end_buf,
|
||||||
bss->ssid);
|
&iwe, bss->ssid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bss->capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)
|
if (bss->capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)
|
||||||
@ -4128,22 +4129,22 @@ ieee80211_sta_scan_result(struct net_device *dev,
|
|||||||
iwe.u.mode = IW_MODE_MASTER;
|
iwe.u.mode = IW_MODE_MASTER;
|
||||||
else
|
else
|
||||||
iwe.u.mode = IW_MODE_ADHOC;
|
iwe.u.mode = IW_MODE_ADHOC;
|
||||||
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
|
current_ev = iwe_stream_add_event(info, current_ev, end_buf,
|
||||||
IW_EV_UINT_LEN);
|
&iwe, IW_EV_UINT_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&iwe, 0, sizeof(iwe));
|
memset(&iwe, 0, sizeof(iwe));
|
||||||
iwe.cmd = SIOCGIWFREQ;
|
iwe.cmd = SIOCGIWFREQ;
|
||||||
iwe.u.freq.m = ieee80211_frequency_to_channel(bss->freq);
|
iwe.u.freq.m = ieee80211_frequency_to_channel(bss->freq);
|
||||||
iwe.u.freq.e = 0;
|
iwe.u.freq.e = 0;
|
||||||
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
|
current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
|
||||||
IW_EV_FREQ_LEN);
|
IW_EV_FREQ_LEN);
|
||||||
|
|
||||||
memset(&iwe, 0, sizeof(iwe));
|
memset(&iwe, 0, sizeof(iwe));
|
||||||
iwe.cmd = SIOCGIWFREQ;
|
iwe.cmd = SIOCGIWFREQ;
|
||||||
iwe.u.freq.m = bss->freq;
|
iwe.u.freq.m = bss->freq;
|
||||||
iwe.u.freq.e = 6;
|
iwe.u.freq.e = 6;
|
||||||
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
|
current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
|
||||||
IW_EV_FREQ_LEN);
|
IW_EV_FREQ_LEN);
|
||||||
memset(&iwe, 0, sizeof(iwe));
|
memset(&iwe, 0, sizeof(iwe));
|
||||||
iwe.cmd = IWEVQUAL;
|
iwe.cmd = IWEVQUAL;
|
||||||
@ -4151,7 +4152,7 @@ ieee80211_sta_scan_result(struct net_device *dev,
|
|||||||
iwe.u.qual.level = bss->signal;
|
iwe.u.qual.level = bss->signal;
|
||||||
iwe.u.qual.noise = bss->noise;
|
iwe.u.qual.noise = bss->noise;
|
||||||
iwe.u.qual.updated = local->wstats_flags;
|
iwe.u.qual.updated = local->wstats_flags;
|
||||||
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
|
current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
|
||||||
IW_EV_QUAL_LEN);
|
IW_EV_QUAL_LEN);
|
||||||
|
|
||||||
memset(&iwe, 0, sizeof(iwe));
|
memset(&iwe, 0, sizeof(iwe));
|
||||||
@ -4161,35 +4162,36 @@ ieee80211_sta_scan_result(struct net_device *dev,
|
|||||||
else
|
else
|
||||||
iwe.u.data.flags = IW_ENCODE_DISABLED;
|
iwe.u.data.flags = IW_ENCODE_DISABLED;
|
||||||
iwe.u.data.length = 0;
|
iwe.u.data.length = 0;
|
||||||
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, "");
|
current_ev = iwe_stream_add_point(info, current_ev, end_buf,
|
||||||
|
&iwe, "");
|
||||||
|
|
||||||
if (bss && bss->wpa_ie) {
|
if (bss && bss->wpa_ie) {
|
||||||
memset(&iwe, 0, sizeof(iwe));
|
memset(&iwe, 0, sizeof(iwe));
|
||||||
iwe.cmd = IWEVGENIE;
|
iwe.cmd = IWEVGENIE;
|
||||||
iwe.u.data.length = bss->wpa_ie_len;
|
iwe.u.data.length = bss->wpa_ie_len;
|
||||||
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
|
current_ev = iwe_stream_add_point(info, current_ev, end_buf,
|
||||||
bss->wpa_ie);
|
&iwe, bss->wpa_ie);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bss && bss->rsn_ie) {
|
if (bss && bss->rsn_ie) {
|
||||||
memset(&iwe, 0, sizeof(iwe));
|
memset(&iwe, 0, sizeof(iwe));
|
||||||
iwe.cmd = IWEVGENIE;
|
iwe.cmd = IWEVGENIE;
|
||||||
iwe.u.data.length = bss->rsn_ie_len;
|
iwe.u.data.length = bss->rsn_ie_len;
|
||||||
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
|
current_ev = iwe_stream_add_point(info, current_ev, end_buf,
|
||||||
bss->rsn_ie);
|
&iwe, bss->rsn_ie);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bss && bss->ht_ie) {
|
if (bss && bss->ht_ie) {
|
||||||
memset(&iwe, 0, sizeof(iwe));
|
memset(&iwe, 0, sizeof(iwe));
|
||||||
iwe.cmd = IWEVGENIE;
|
iwe.cmd = IWEVGENIE;
|
||||||
iwe.u.data.length = bss->ht_ie_len;
|
iwe.u.data.length = bss->ht_ie_len;
|
||||||
current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
|
current_ev = iwe_stream_add_point(info, current_ev, end_buf,
|
||||||
bss->ht_ie);
|
&iwe, bss->ht_ie);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bss && bss->supp_rates_len > 0) {
|
if (bss && bss->supp_rates_len > 0) {
|
||||||
/* display all supported rates in readable format */
|
/* display all supported rates in readable format */
|
||||||
char *p = current_ev + IW_EV_LCP_LEN;
|
char *p = current_ev + iwe_stream_lcp_len(info);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
memset(&iwe, 0, sizeof(iwe));
|
memset(&iwe, 0, sizeof(iwe));
|
||||||
@ -4200,7 +4202,7 @@ ieee80211_sta_scan_result(struct net_device *dev,
|
|||||||
for (i = 0; i < bss->supp_rates_len; i++) {
|
for (i = 0; i < bss->supp_rates_len; i++) {
|
||||||
iwe.u.bitrate.value = ((bss->supp_rates[i] &
|
iwe.u.bitrate.value = ((bss->supp_rates[i] &
|
||||||
0x7f) * 500000);
|
0x7f) * 500000);
|
||||||
p = iwe_stream_add_value(current_ev, p,
|
p = iwe_stream_add_value(info, current_ev, p,
|
||||||
end_buf, &iwe, IW_EV_PARAM_LEN);
|
end_buf, &iwe, IW_EV_PARAM_LEN);
|
||||||
}
|
}
|
||||||
current_ev = p;
|
current_ev = p;
|
||||||
@ -4214,7 +4216,8 @@ ieee80211_sta_scan_result(struct net_device *dev,
|
|||||||
iwe.cmd = IWEVCUSTOM;
|
iwe.cmd = IWEVCUSTOM;
|
||||||
sprintf(buf, "tsf=%016llx", (unsigned long long)(bss->timestamp));
|
sprintf(buf, "tsf=%016llx", (unsigned long long)(bss->timestamp));
|
||||||
iwe.u.data.length = strlen(buf);
|
iwe.u.data.length = strlen(buf);
|
||||||
current_ev = iwe_stream_add_point(current_ev, end_buf,
|
current_ev = iwe_stream_add_point(info, current_ev,
|
||||||
|
end_buf,
|
||||||
&iwe, buf);
|
&iwe, buf);
|
||||||
kfree(buf);
|
kfree(buf);
|
||||||
}
|
}
|
||||||
@ -4229,31 +4232,36 @@ ieee80211_sta_scan_result(struct net_device *dev,
|
|||||||
iwe.cmd = IWEVCUSTOM;
|
iwe.cmd = IWEVCUSTOM;
|
||||||
sprintf(buf, "Mesh network (version %d)", cfg[0]);
|
sprintf(buf, "Mesh network (version %d)", cfg[0]);
|
||||||
iwe.u.data.length = strlen(buf);
|
iwe.u.data.length = strlen(buf);
|
||||||
current_ev = iwe_stream_add_point(current_ev, end_buf,
|
current_ev = iwe_stream_add_point(info, current_ev,
|
||||||
|
end_buf,
|
||||||
&iwe, buf);
|
&iwe, buf);
|
||||||
sprintf(buf, "Path Selection Protocol ID: "
|
sprintf(buf, "Path Selection Protocol ID: "
|
||||||
"0x%02X%02X%02X%02X", cfg[1], cfg[2], cfg[3],
|
"0x%02X%02X%02X%02X", cfg[1], cfg[2], cfg[3],
|
||||||
cfg[4]);
|
cfg[4]);
|
||||||
iwe.u.data.length = strlen(buf);
|
iwe.u.data.length = strlen(buf);
|
||||||
current_ev = iwe_stream_add_point(current_ev, end_buf,
|
current_ev = iwe_stream_add_point(info, current_ev,
|
||||||
|
end_buf,
|
||||||
&iwe, buf);
|
&iwe, buf);
|
||||||
sprintf(buf, "Path Selection Metric ID: "
|
sprintf(buf, "Path Selection Metric ID: "
|
||||||
"0x%02X%02X%02X%02X", cfg[5], cfg[6], cfg[7],
|
"0x%02X%02X%02X%02X", cfg[5], cfg[6], cfg[7],
|
||||||
cfg[8]);
|
cfg[8]);
|
||||||
iwe.u.data.length = strlen(buf);
|
iwe.u.data.length = strlen(buf);
|
||||||
current_ev = iwe_stream_add_point(current_ev, end_buf,
|
current_ev = iwe_stream_add_point(info, current_ev,
|
||||||
|
end_buf,
|
||||||
&iwe, buf);
|
&iwe, buf);
|
||||||
sprintf(buf, "Congestion Control Mode ID: "
|
sprintf(buf, "Congestion Control Mode ID: "
|
||||||
"0x%02X%02X%02X%02X", cfg[9], cfg[10],
|
"0x%02X%02X%02X%02X", cfg[9], cfg[10],
|
||||||
cfg[11], cfg[12]);
|
cfg[11], cfg[12]);
|
||||||
iwe.u.data.length = strlen(buf);
|
iwe.u.data.length = strlen(buf);
|
||||||
current_ev = iwe_stream_add_point(current_ev, end_buf,
|
current_ev = iwe_stream_add_point(info, current_ev,
|
||||||
|
end_buf,
|
||||||
&iwe, buf);
|
&iwe, buf);
|
||||||
sprintf(buf, "Channel Precedence: "
|
sprintf(buf, "Channel Precedence: "
|
||||||
"0x%02X%02X%02X%02X", cfg[13], cfg[14],
|
"0x%02X%02X%02X%02X", cfg[13], cfg[14],
|
||||||
cfg[15], cfg[16]);
|
cfg[15], cfg[16]);
|
||||||
iwe.u.data.length = strlen(buf);
|
iwe.u.data.length = strlen(buf);
|
||||||
current_ev = iwe_stream_add_point(current_ev, end_buf,
|
current_ev = iwe_stream_add_point(info, current_ev,
|
||||||
|
end_buf,
|
||||||
&iwe, buf);
|
&iwe, buf);
|
||||||
kfree(buf);
|
kfree(buf);
|
||||||
}
|
}
|
||||||
@ -4263,7 +4271,9 @@ ieee80211_sta_scan_result(struct net_device *dev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int ieee80211_sta_scan_results(struct net_device *dev, char *buf, size_t len)
|
int ieee80211_sta_scan_results(struct net_device *dev,
|
||||||
|
struct iw_request_info *info,
|
||||||
|
char *buf, size_t len)
|
||||||
{
|
{
|
||||||
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
|
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
|
||||||
char *current_ev = buf;
|
char *current_ev = buf;
|
||||||
@ -4276,8 +4286,8 @@ int ieee80211_sta_scan_results(struct net_device *dev, char *buf, size_t len)
|
|||||||
spin_unlock_bh(&local->sta_bss_lock);
|
spin_unlock_bh(&local->sta_bss_lock);
|
||||||
return -E2BIG;
|
return -E2BIG;
|
||||||
}
|
}
|
||||||
current_ev = ieee80211_sta_scan_result(dev, bss, current_ev,
|
current_ev = ieee80211_sta_scan_result(dev, info, bss,
|
||||||
end_buf);
|
current_ev, end_buf);
|
||||||
}
|
}
|
||||||
spin_unlock_bh(&local->sta_bss_lock);
|
spin_unlock_bh(&local->sta_bss_lock);
|
||||||
return current_ev - buf;
|
return current_ev - buf;
|
||||||
|
@ -567,7 +567,7 @@ static int ieee80211_ioctl_giwscan(struct net_device *dev,
|
|||||||
if (local->sta_sw_scanning || local->sta_hw_scanning)
|
if (local->sta_sw_scanning || local->sta_hw_scanning)
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
|
|
||||||
res = ieee80211_sta_scan_results(dev, extra, data->length);
|
res = ieee80211_sta_scan_results(dev, info, extra, data->length);
|
||||||
if (res >= 0) {
|
if (res >= 0) {
|
||||||
data->length = res;
|
data->length = res;
|
||||||
return 0;
|
return 0;
|
||||||
|
10
net/socket.c
10
net/socket.c
@ -90,6 +90,7 @@
|
|||||||
#include <asm/unistd.h>
|
#include <asm/unistd.h>
|
||||||
|
|
||||||
#include <net/compat.h>
|
#include <net/compat.h>
|
||||||
|
#include <net/wext.h>
|
||||||
|
|
||||||
#include <net/sock.h>
|
#include <net/sock.h>
|
||||||
#include <linux/netfilter.h>
|
#include <linux/netfilter.h>
|
||||||
@ -2210,10 +2211,19 @@ static long compat_sock_ioctl(struct file *file, unsigned cmd,
|
|||||||
{
|
{
|
||||||
struct socket *sock = file->private_data;
|
struct socket *sock = file->private_data;
|
||||||
int ret = -ENOIOCTLCMD;
|
int ret = -ENOIOCTLCMD;
|
||||||
|
struct sock *sk;
|
||||||
|
struct net *net;
|
||||||
|
|
||||||
|
sk = sock->sk;
|
||||||
|
net = sock_net(sk);
|
||||||
|
|
||||||
if (sock->ops->compat_ioctl)
|
if (sock->ops->compat_ioctl)
|
||||||
ret = sock->ops->compat_ioctl(sock, cmd, arg);
|
ret = sock->ops->compat_ioctl(sock, cmd, arg);
|
||||||
|
|
||||||
|
if (ret == -ENOIOCTLCMD &&
|
||||||
|
(cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST))
|
||||||
|
ret = compat_wext_handle_ioctl(net, cmd, arg);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -500,7 +500,7 @@ static int call_commit_handler(struct net_device *dev)
|
|||||||
/*
|
/*
|
||||||
* Calculate size of private arguments
|
* Calculate size of private arguments
|
||||||
*/
|
*/
|
||||||
static inline int get_priv_size(__u16 args)
|
static int get_priv_size(__u16 args)
|
||||||
{
|
{
|
||||||
int num = args & IW_PRIV_SIZE_MASK;
|
int num = args & IW_PRIV_SIZE_MASK;
|
||||||
int type = (args & IW_PRIV_TYPE_MASK) >> 12;
|
int type = (args & IW_PRIV_TYPE_MASK) >> 12;
|
||||||
@ -512,10 +512,9 @@ static inline int get_priv_size(__u16 args)
|
|||||||
/*
|
/*
|
||||||
* Re-calculate the size of private arguments
|
* Re-calculate the size of private arguments
|
||||||
*/
|
*/
|
||||||
static inline int adjust_priv_size(__u16 args,
|
static int adjust_priv_size(__u16 args, struct iw_point *iwp)
|
||||||
union iwreq_data * wrqu)
|
|
||||||
{
|
{
|
||||||
int num = wrqu->data.length;
|
int num = iwp->length;
|
||||||
int max = args & IW_PRIV_SIZE_MASK;
|
int max = args & IW_PRIV_SIZE_MASK;
|
||||||
int type = (args & IW_PRIV_TYPE_MASK) >> 12;
|
int type = (args & IW_PRIV_TYPE_MASK) >> 12;
|
||||||
|
|
||||||
@ -695,49 +694,17 @@ void wext_proc_exit(struct net *net)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
/*
|
static int ioctl_standard_iw_point(struct iw_point *iwp, unsigned int cmd,
|
||||||
* Wrapper to call a standard Wireless Extension handler.
|
const struct iw_ioctl_description *descr,
|
||||||
* We do various checks and also take care of moving data between
|
iw_handler handler, struct net_device *dev,
|
||||||
* user space and kernel space.
|
struct iw_request_info *info)
|
||||||
*/
|
|
||||||
static int ioctl_standard_call(struct net_device * dev,
|
|
||||||
struct ifreq * ifr,
|
|
||||||
unsigned int cmd,
|
|
||||||
iw_handler handler)
|
|
||||||
{
|
{
|
||||||
struct iwreq * iwr = (struct iwreq *) ifr;
|
int err, extra_size, user_length = 0, essid_compat = 0;
|
||||||
const struct iw_ioctl_description * descr;
|
|
||||||
struct iw_request_info info;
|
|
||||||
int ret = -EINVAL;
|
|
||||||
|
|
||||||
/* Get the description of the IOCTL */
|
|
||||||
if ((cmd - SIOCIWFIRST) >= standard_ioctl_num)
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
descr = &(standard_ioctl[cmd - SIOCIWFIRST]);
|
|
||||||
|
|
||||||
/* Prepare the call */
|
|
||||||
info.cmd = cmd;
|
|
||||||
info.flags = 0;
|
|
||||||
|
|
||||||
/* Check if we have a pointer to user space data or not */
|
|
||||||
if (descr->header_type != IW_HEADER_TYPE_POINT) {
|
|
||||||
|
|
||||||
/* No extra arguments. Trivial to handle */
|
|
||||||
ret = handler(dev, &info, &(iwr->u), NULL);
|
|
||||||
|
|
||||||
/* Generate an event to notify listeners of the change */
|
|
||||||
if ((descr->flags & IW_DESCR_FLAG_EVENT) &&
|
|
||||||
((ret == 0) || (ret == -EIWCOMMIT)))
|
|
||||||
wireless_send_event(dev, cmd, &(iwr->u), NULL);
|
|
||||||
} else {
|
|
||||||
char *extra;
|
char *extra;
|
||||||
int extra_size;
|
|
||||||
int user_length = 0;
|
|
||||||
int err;
|
|
||||||
int essid_compat = 0;
|
|
||||||
|
|
||||||
/* Calculate space needed by arguments. Always allocate
|
/* Calculate space needed by arguments. Always allocate
|
||||||
* for max space. Easier, and won't last long... */
|
* for max space.
|
||||||
|
*/
|
||||||
extra_size = descr->max_tokens * descr->token_size;
|
extra_size = descr->max_tokens * descr->token_size;
|
||||||
|
|
||||||
/* Check need for ESSID compatibility for WE < 21 */
|
/* Check need for ESSID compatibility for WE < 21 */
|
||||||
@ -746,18 +713,18 @@ static int ioctl_standard_call(struct net_device * dev,
|
|||||||
case SIOCGIWESSID:
|
case SIOCGIWESSID:
|
||||||
case SIOCSIWNICKN:
|
case SIOCSIWNICKN:
|
||||||
case SIOCGIWNICKN:
|
case SIOCGIWNICKN:
|
||||||
if (iwr->u.data.length == descr->max_tokens + 1)
|
if (iwp->length == descr->max_tokens + 1)
|
||||||
essid_compat = 1;
|
essid_compat = 1;
|
||||||
else if (IW_IS_SET(cmd) && (iwr->u.data.length != 0)) {
|
else if (IW_IS_SET(cmd) && (iwp->length != 0)) {
|
||||||
char essid[IW_ESSID_MAX_SIZE + 1];
|
char essid[IW_ESSID_MAX_SIZE + 1];
|
||||||
|
|
||||||
err = copy_from_user(essid, iwr->u.data.pointer,
|
err = copy_from_user(essid, iwp->pointer,
|
||||||
iwr->u.data.length *
|
iwp->length *
|
||||||
descr->token_size);
|
descr->token_size);
|
||||||
if (err)
|
if (err)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
if (essid[iwr->u.data.length - 1] == '\0')
|
if (essid[iwp->length - 1] == '\0')
|
||||||
essid_compat = 1;
|
essid_compat = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -765,95 +732,132 @@ static int ioctl_standard_call(struct net_device * dev,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
iwr->u.data.length -= essid_compat;
|
iwp->length -= essid_compat;
|
||||||
|
|
||||||
/* Check what user space is giving us */
|
/* Check what user space is giving us */
|
||||||
if (IW_IS_SET(cmd)) {
|
if (IW_IS_SET(cmd)) {
|
||||||
/* Check NULL pointer */
|
/* Check NULL pointer */
|
||||||
if ((iwr->u.data.pointer == NULL) &&
|
if (!iwp->pointer && iwp->length != 0)
|
||||||
(iwr->u.data.length != 0))
|
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
/* Check if number of token fits within bounds */
|
/* Check if number of token fits within bounds */
|
||||||
if (iwr->u.data.length > descr->max_tokens)
|
if (iwp->length > descr->max_tokens)
|
||||||
return -E2BIG;
|
return -E2BIG;
|
||||||
if (iwr->u.data.length < descr->min_tokens)
|
if (iwp->length < descr->min_tokens)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
} else {
|
} else {
|
||||||
/* Check NULL pointer */
|
/* Check NULL pointer */
|
||||||
if (iwr->u.data.pointer == NULL)
|
if (!iwp->pointer)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
/* Save user space buffer size for checking */
|
/* Save user space buffer size for checking */
|
||||||
user_length = iwr->u.data.length;
|
user_length = iwp->length;
|
||||||
|
|
||||||
/* Don't check if user_length > max to allow forward
|
/* Don't check if user_length > max to allow forward
|
||||||
* compatibility. The test user_length < min is
|
* compatibility. The test user_length < min is
|
||||||
* implied by the test at the end. */
|
* implied by the test at the end.
|
||||||
|
*/
|
||||||
|
|
||||||
/* Support for very large requests */
|
/* Support for very large requests */
|
||||||
if ((descr->flags & IW_DESCR_FLAG_NOMAX) &&
|
if ((descr->flags & IW_DESCR_FLAG_NOMAX) &&
|
||||||
(user_length > descr->max_tokens)) {
|
(user_length > descr->max_tokens)) {
|
||||||
/* Allow userspace to GET more than max so
|
/* Allow userspace to GET more than max so
|
||||||
* we can support any size GET requests.
|
* we can support any size GET requests.
|
||||||
* There is still a limit : -ENOMEM. */
|
* There is still a limit : -ENOMEM.
|
||||||
|
*/
|
||||||
extra_size = user_length * descr->token_size;
|
extra_size = user_length * descr->token_size;
|
||||||
|
|
||||||
/* Note : user_length is originally a __u16,
|
/* Note : user_length is originally a __u16,
|
||||||
* and token_size is controlled by us,
|
* and token_size is controlled by us,
|
||||||
* so extra_size won't get negative and
|
* so extra_size won't get negative and
|
||||||
* won't overflow... */
|
* won't overflow...
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create the kernel buffer */
|
/* kzalloc() ensures NULL-termination for essid_compat. */
|
||||||
/* kzalloc ensures NULL-termination for essid_compat */
|
|
||||||
extra = kzalloc(extra_size, GFP_KERNEL);
|
extra = kzalloc(extra_size, GFP_KERNEL);
|
||||||
if (extra == NULL)
|
if (!extra)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
/* If it is a SET, get all the extra data in here */
|
/* If it is a SET, get all the extra data in here */
|
||||||
if (IW_IS_SET(cmd) && (iwr->u.data.length != 0)) {
|
if (IW_IS_SET(cmd) && (iwp->length != 0)) {
|
||||||
err = copy_from_user(extra, iwr->u.data.pointer,
|
if (copy_from_user(extra, iwp->pointer,
|
||||||
iwr->u.data.length *
|
iwp->length *
|
||||||
descr->token_size);
|
descr->token_size)) {
|
||||||
if (err) {
|
err = -EFAULT;
|
||||||
kfree(extra);
|
goto out;
|
||||||
return -EFAULT;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Call the handler */
|
err = handler(dev, info, (union iwreq_data *) iwp, extra);
|
||||||
ret = handler(dev, &info, &(iwr->u), extra);
|
|
||||||
|
|
||||||
iwr->u.data.length += essid_compat;
|
iwp->length += essid_compat;
|
||||||
|
|
||||||
/* If we have something to return to the user */
|
/* If we have something to return to the user */
|
||||||
if (!ret && IW_IS_GET(cmd)) {
|
if (!err && IW_IS_GET(cmd)) {
|
||||||
/* Check if there is enough buffer up there */
|
/* Check if there is enough buffer up there */
|
||||||
if (user_length < iwr->u.data.length) {
|
if (user_length < iwp->length) {
|
||||||
kfree(extra);
|
err = -E2BIG;
|
||||||
return -E2BIG;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = copy_to_user(iwr->u.data.pointer, extra,
|
if (copy_to_user(iwp->pointer, extra,
|
||||||
iwr->u.data.length *
|
iwp->length *
|
||||||
descr->token_size);
|
descr->token_size)) {
|
||||||
if (err)
|
err = -EFAULT;
|
||||||
ret = -EFAULT;
|
goto out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generate an event to notify listeners of the change */
|
/* Generate an event to notify listeners of the change */
|
||||||
if ((descr->flags & IW_DESCR_FLAG_EVENT) &&
|
if ((descr->flags & IW_DESCR_FLAG_EVENT) && err == -EIWCOMMIT) {
|
||||||
((ret == 0) || (ret == -EIWCOMMIT))) {
|
union iwreq_data *data = (union iwreq_data *) iwp;
|
||||||
|
|
||||||
if (descr->flags & IW_DESCR_FLAG_RESTRICT)
|
if (descr->flags & IW_DESCR_FLAG_RESTRICT)
|
||||||
/* If the event is restricted, don't
|
/* If the event is restricted, don't
|
||||||
* export the payload */
|
* export the payload.
|
||||||
wireless_send_event(dev, cmd, &(iwr->u), NULL);
|
*/
|
||||||
|
wireless_send_event(dev, cmd, data, NULL);
|
||||||
else
|
else
|
||||||
wireless_send_event(dev, cmd, &(iwr->u),
|
wireless_send_event(dev, cmd, data, extra);
|
||||||
extra);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cleanup - I told you it wasn't that long ;-) */
|
out:
|
||||||
kfree(extra);
|
kfree(extra);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wrapper to call a standard Wireless Extension handler.
|
||||||
|
* We do various checks and also take care of moving data between
|
||||||
|
* user space and kernel space.
|
||||||
|
*/
|
||||||
|
static int ioctl_standard_call(struct net_device * dev,
|
||||||
|
struct iwreq *iwr,
|
||||||
|
unsigned int cmd,
|
||||||
|
struct iw_request_info *info,
|
||||||
|
iw_handler handler)
|
||||||
|
{
|
||||||
|
const struct iw_ioctl_description * descr;
|
||||||
|
int ret = -EINVAL;
|
||||||
|
|
||||||
|
/* Get the description of the IOCTL */
|
||||||
|
if ((cmd - SIOCIWFIRST) >= standard_ioctl_num)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
descr = &(standard_ioctl[cmd - SIOCIWFIRST]);
|
||||||
|
|
||||||
|
/* Check if we have a pointer to user space data or not */
|
||||||
|
if (descr->header_type != IW_HEADER_TYPE_POINT) {
|
||||||
|
|
||||||
|
/* No extra arguments. Trivial to handle */
|
||||||
|
ret = handler(dev, info, &(iwr->u), NULL);
|
||||||
|
|
||||||
|
/* Generate an event to notify listeners of the change */
|
||||||
|
if ((descr->flags & IW_DESCR_FLAG_EVENT) &&
|
||||||
|
((ret == 0) || (ret == -EIWCOMMIT)))
|
||||||
|
wireless_send_event(dev, cmd, &(iwr->u), NULL);
|
||||||
|
} else {
|
||||||
|
ret = ioctl_standard_iw_point(&iwr->u.data, cmd, descr,
|
||||||
|
handler, dev, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Call commit handler if needed and defined */
|
/* Call commit handler if needed and defined */
|
||||||
@ -881,25 +885,22 @@ static int ioctl_standard_call(struct net_device * dev,
|
|||||||
* a iw_handler but process it in your ioctl handler (i.e. use the
|
* a iw_handler but process it in your ioctl handler (i.e. use the
|
||||||
* old driver API).
|
* old driver API).
|
||||||
*/
|
*/
|
||||||
static int ioctl_private_call(struct net_device *dev, struct ifreq *ifr,
|
static int get_priv_descr_and_size(struct net_device *dev, unsigned int cmd,
|
||||||
unsigned int cmd, iw_handler handler)
|
const struct iw_priv_args **descrp)
|
||||||
{
|
{
|
||||||
struct iwreq * iwr = (struct iwreq *) ifr;
|
const struct iw_priv_args *descr;
|
||||||
const struct iw_priv_args * descr = NULL;
|
int i, extra_size;
|
||||||
struct iw_request_info info;
|
|
||||||
int extra_size = 0;
|
|
||||||
int i;
|
|
||||||
int ret = -EINVAL;
|
|
||||||
|
|
||||||
/* Get the description of the IOCTL */
|
descr = NULL;
|
||||||
for (i = 0; i < dev->wireless_handlers->num_private_args; i++)
|
for (i = 0; i < dev->wireless_handlers->num_private_args; i++) {
|
||||||
if (cmd == dev->wireless_handlers->private_args[i].cmd) {
|
if (cmd == dev->wireless_handlers->private_args[i].cmd) {
|
||||||
descr = &(dev->wireless_handlers->private_args[i]);
|
descr = &dev->wireless_handlers->private_args[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Compute the size of the set/get arguments */
|
extra_size = 0;
|
||||||
if (descr != NULL) {
|
if (descr) {
|
||||||
if (IW_IS_SET(cmd)) {
|
if (IW_IS_SET(cmd)) {
|
||||||
int offset = 0; /* For sub-ioctls */
|
int offset = 0; /* For sub-ioctls */
|
||||||
/* Check for sub-ioctl handler */
|
/* Check for sub-ioctl handler */
|
||||||
@ -924,72 +925,77 @@ static int ioctl_private_call(struct net_device *dev, struct ifreq *ifr,
|
|||||||
extra_size = 0;
|
extra_size = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*descrp = descr;
|
||||||
|
return extra_size;
|
||||||
|
}
|
||||||
|
|
||||||
/* Prepare the call */
|
static int ioctl_private_iw_point(struct iw_point *iwp, unsigned int cmd,
|
||||||
info.cmd = cmd;
|
const struct iw_priv_args *descr,
|
||||||
info.flags = 0;
|
iw_handler handler, struct net_device *dev,
|
||||||
|
struct iw_request_info *info, int extra_size)
|
||||||
/* Check if we have a pointer to user space data or not. */
|
{
|
||||||
if (extra_size == 0) {
|
|
||||||
/* No extra arguments. Trivial to handle */
|
|
||||||
ret = handler(dev, &info, &(iwr->u), (char *) &(iwr->u));
|
|
||||||
} else {
|
|
||||||
char *extra;
|
char *extra;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* Check what user space is giving us */
|
/* Check what user space is giving us */
|
||||||
if (IW_IS_SET(cmd)) {
|
if (IW_IS_SET(cmd)) {
|
||||||
/* Check NULL pointer */
|
if (!iwp->pointer && iwp->length != 0)
|
||||||
if ((iwr->u.data.pointer == NULL) &&
|
|
||||||
(iwr->u.data.length != 0))
|
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
/* Does it fits within bounds ? */
|
if (iwp->length > (descr->set_args & IW_PRIV_SIZE_MASK))
|
||||||
if (iwr->u.data.length > (descr->set_args &
|
|
||||||
IW_PRIV_SIZE_MASK))
|
|
||||||
return -E2BIG;
|
return -E2BIG;
|
||||||
} else if (iwr->u.data.pointer == NULL)
|
} else if (!iwp->pointer)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
/* Always allocate for max space. Easier, and won't last
|
|
||||||
* long... */
|
|
||||||
extra = kmalloc(extra_size, GFP_KERNEL);
|
extra = kmalloc(extra_size, GFP_KERNEL);
|
||||||
if (extra == NULL)
|
if (!extra)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
/* If it is a SET, get all the extra data in here */
|
/* If it is a SET, get all the extra data in here */
|
||||||
if (IW_IS_SET(cmd) && (iwr->u.data.length != 0)) {
|
if (IW_IS_SET(cmd) && (iwp->length != 0)) {
|
||||||
err = copy_from_user(extra, iwr->u.data.pointer,
|
if (copy_from_user(extra, iwp->pointer, extra_size)) {
|
||||||
extra_size);
|
err = -EFAULT;
|
||||||
if (err) {
|
goto out;
|
||||||
kfree(extra);
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Call the handler */
|
/* Call the handler */
|
||||||
ret = handler(dev, &info, &(iwr->u), extra);
|
err = handler(dev, info, (union iwreq_data *) iwp, extra);
|
||||||
|
|
||||||
/* If we have something to return to the user */
|
/* If we have something to return to the user */
|
||||||
if (!ret && IW_IS_GET(cmd)) {
|
if (!err && IW_IS_GET(cmd)) {
|
||||||
|
|
||||||
/* Adjust for the actual length if it's variable,
|
/* Adjust for the actual length if it's variable,
|
||||||
* avoid leaking kernel bits outside. */
|
* avoid leaking kernel bits outside.
|
||||||
if (!(descr->get_args & IW_PRIV_SIZE_FIXED)) {
|
*/
|
||||||
extra_size = adjust_priv_size(descr->get_args,
|
if (!(descr->get_args & IW_PRIV_SIZE_FIXED))
|
||||||
&(iwr->u));
|
extra_size = adjust_priv_size(descr->get_args, iwp);
|
||||||
|
|
||||||
|
if (copy_to_user(iwp->pointer, extra, extra_size))
|
||||||
|
err = -EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = copy_to_user(iwr->u.data.pointer, extra,
|
out:
|
||||||
extra_size);
|
|
||||||
if (err)
|
|
||||||
ret = -EFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Cleanup - I told you it wasn't that long ;-) */
|
|
||||||
kfree(extra);
|
kfree(extra);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ioctl_private_call(struct net_device *dev, struct iwreq *iwr,
|
||||||
|
unsigned int cmd, struct iw_request_info *info,
|
||||||
|
iw_handler handler)
|
||||||
|
{
|
||||||
|
int extra_size = 0, ret = -EINVAL;
|
||||||
|
const struct iw_priv_args *descr;
|
||||||
|
|
||||||
|
extra_size = get_priv_descr_and_size(dev, cmd, &descr);
|
||||||
|
|
||||||
|
/* Check if we have a pointer to user space data or not. */
|
||||||
|
if (extra_size == 0) {
|
||||||
|
/* No extra arguments. Trivial to handle */
|
||||||
|
ret = handler(dev, info, &(iwr->u), (char *) &(iwr->u));
|
||||||
|
} else {
|
||||||
|
ret = ioctl_private_iw_point(&iwr->u.data, cmd, descr,
|
||||||
|
handler, dev, info, extra_size);
|
||||||
|
}
|
||||||
|
|
||||||
/* Call commit handler if needed and defined */
|
/* Call commit handler if needed and defined */
|
||||||
if (ret == -EIWCOMMIT)
|
if (ret == -EIWCOMMIT)
|
||||||
@ -999,12 +1005,21 @@ static int ioctl_private_call(struct net_device *dev, struct ifreq *ifr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- */
|
/* ---------------------------------------------------------------- */
|
||||||
|
typedef int (*wext_ioctl_func)(struct net_device *, struct iwreq *,
|
||||||
|
unsigned int, struct iw_request_info *,
|
||||||
|
iw_handler);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Main IOCTl dispatcher.
|
* Main IOCTl dispatcher.
|
||||||
* Check the type of IOCTL and call the appropriate wrapper...
|
* Check the type of IOCTL and call the appropriate wrapper...
|
||||||
*/
|
*/
|
||||||
static int wireless_process_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd)
|
static int wireless_process_ioctl(struct net *net, struct ifreq *ifr,
|
||||||
|
unsigned int cmd,
|
||||||
|
struct iw_request_info *info,
|
||||||
|
wext_ioctl_func standard,
|
||||||
|
wext_ioctl_func private)
|
||||||
{
|
{
|
||||||
|
struct iwreq *iwr = (struct iwreq *) ifr;
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
iw_handler handler;
|
iw_handler handler;
|
||||||
|
|
||||||
@ -1019,11 +1034,11 @@ static int wireless_process_ioctl(struct net *net, struct ifreq *ifr, unsigned i
|
|||||||
* Note that 'cmd' is already filtered in dev_ioctl() with
|
* Note that 'cmd' is already filtered in dev_ioctl() with
|
||||||
* (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) */
|
* (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) */
|
||||||
if (cmd == SIOCGIWSTATS)
|
if (cmd == SIOCGIWSTATS)
|
||||||
return ioctl_standard_call(dev, ifr, cmd,
|
return standard(dev, iwr, cmd, info,
|
||||||
&iw_handler_get_iwstats);
|
&iw_handler_get_iwstats);
|
||||||
|
|
||||||
if (cmd == SIOCGIWPRIV && dev->wireless_handlers)
|
if (cmd == SIOCGIWPRIV && dev->wireless_handlers)
|
||||||
return ioctl_standard_call(dev, ifr, cmd,
|
return standard(dev, iwr, cmd, info,
|
||||||
&iw_handler_get_private);
|
&iw_handler_get_private);
|
||||||
|
|
||||||
/* Basic check */
|
/* Basic check */
|
||||||
@ -1035,9 +1050,9 @@ static int wireless_process_ioctl(struct net *net, struct ifreq *ifr, unsigned i
|
|||||||
if (handler) {
|
if (handler) {
|
||||||
/* Standard and private are not the same */
|
/* Standard and private are not the same */
|
||||||
if (cmd < SIOCIWFIRSTPRIV)
|
if (cmd < SIOCIWFIRSTPRIV)
|
||||||
return ioctl_standard_call(dev, ifr, cmd, handler);
|
return standard(dev, iwr, cmd, info, handler);
|
||||||
else
|
else
|
||||||
return ioctl_private_call(dev, ifr, cmd, handler);
|
return private(dev, iwr, cmd, info, handler);
|
||||||
}
|
}
|
||||||
/* Old driver API : call driver ioctl handler */
|
/* Old driver API : call driver ioctl handler */
|
||||||
if (dev->do_ioctl)
|
if (dev->do_ioctl)
|
||||||
@ -1045,28 +1060,155 @@ static int wireless_process_ioctl(struct net *net, struct ifreq *ifr, unsigned i
|
|||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* entry point from dev ioctl */
|
/* If command is `set a parameter', or `get the encoding parameters',
|
||||||
int wext_handle_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd,
|
* check if the user has the right to do it.
|
||||||
void __user *arg)
|
*/
|
||||||
|
static int wext_permission_check(unsigned int cmd)
|
||||||
{
|
{
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* If command is `set a parameter', or
|
|
||||||
* `get the encoding parameters', check if
|
|
||||||
* the user has the right to do it */
|
|
||||||
if ((IW_IS_SET(cmd) || cmd == SIOCGIWENCODE || cmd == SIOCGIWENCODEEXT)
|
if ((IW_IS_SET(cmd) || cmd == SIOCGIWENCODE || cmd == SIOCGIWENCODEEXT)
|
||||||
&& !capable(CAP_NET_ADMIN))
|
&& !capable(CAP_NET_ADMIN))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* entry point from dev ioctl */
|
||||||
|
static int wext_ioctl_dispatch(struct net *net, struct ifreq *ifr,
|
||||||
|
unsigned int cmd, struct iw_request_info *info,
|
||||||
|
wext_ioctl_func standard,
|
||||||
|
wext_ioctl_func private)
|
||||||
|
{
|
||||||
|
int ret = wext_permission_check(cmd);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
dev_load(net, ifr->ifr_name);
|
dev_load(net, ifr->ifr_name);
|
||||||
rtnl_lock();
|
rtnl_lock();
|
||||||
ret = wireless_process_ioctl(net, ifr, cmd);
|
ret = wireless_process_ioctl(net, ifr, cmd, info, standard, private);
|
||||||
rtnl_unlock();
|
rtnl_unlock();
|
||||||
if (IW_IS_GET(cmd) && copy_to_user(arg, ifr, sizeof(struct iwreq)))
|
|
||||||
return -EFAULT;
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int wext_handle_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd,
|
||||||
|
void __user *arg)
|
||||||
|
{
|
||||||
|
struct iw_request_info info = { .cmd = cmd, .flags = 0 };
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = wext_ioctl_dispatch(net, ifr, cmd, &info,
|
||||||
|
ioctl_standard_call,
|
||||||
|
ioctl_private_call);
|
||||||
|
if (ret >= 0 &&
|
||||||
|
IW_IS_GET(cmd) &&
|
||||||
|
copy_to_user(arg, ifr, sizeof(struct iwreq)))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_COMPAT
|
||||||
|
static int compat_standard_call(struct net_device *dev,
|
||||||
|
struct iwreq *iwr,
|
||||||
|
unsigned int cmd,
|
||||||
|
struct iw_request_info *info,
|
||||||
|
iw_handler handler)
|
||||||
|
{
|
||||||
|
const struct iw_ioctl_description *descr;
|
||||||
|
struct compat_iw_point *iwp_compat;
|
||||||
|
struct iw_point iwp;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
descr = standard_ioctl + (cmd - SIOCIWFIRST);
|
||||||
|
|
||||||
|
if (descr->header_type != IW_HEADER_TYPE_POINT)
|
||||||
|
return ioctl_standard_call(dev, iwr, cmd, info, handler);
|
||||||
|
|
||||||
|
iwp_compat = (struct compat_iw_point *) &iwr->u.data;
|
||||||
|
iwp.pointer = compat_ptr(iwp_compat->pointer);
|
||||||
|
iwp.length = iwp_compat->length;
|
||||||
|
iwp.flags = iwp_compat->flags;
|
||||||
|
|
||||||
|
err = ioctl_standard_iw_point(&iwp, cmd, descr, handler, dev, info);
|
||||||
|
|
||||||
|
iwp_compat->pointer = ptr_to_compat(iwp.pointer);
|
||||||
|
iwp_compat->length = iwp.length;
|
||||||
|
iwp_compat->flags = iwp.flags;
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int compat_private_call(struct net_device *dev, struct iwreq *iwr,
|
||||||
|
unsigned int cmd, struct iw_request_info *info,
|
||||||
|
iw_handler handler)
|
||||||
|
{
|
||||||
|
const struct iw_priv_args *descr;
|
||||||
|
int ret, extra_size;
|
||||||
|
|
||||||
|
extra_size = get_priv_descr_and_size(dev, cmd, &descr);
|
||||||
|
|
||||||
|
/* Check if we have a pointer to user space data or not. */
|
||||||
|
if (extra_size == 0) {
|
||||||
|
/* No extra arguments. Trivial to handle */
|
||||||
|
ret = handler(dev, info, &(iwr->u), (char *) &(iwr->u));
|
||||||
|
} else {
|
||||||
|
struct compat_iw_point *iwp_compat;
|
||||||
|
struct iw_point iwp;
|
||||||
|
|
||||||
|
iwp_compat = (struct compat_iw_point *) &iwr->u.data;
|
||||||
|
iwp.pointer = compat_ptr(iwp_compat->pointer);
|
||||||
|
iwp.length = iwp_compat->length;
|
||||||
|
iwp.flags = iwp_compat->flags;
|
||||||
|
|
||||||
|
ret = ioctl_private_iw_point(&iwp, cmd, descr,
|
||||||
|
handler, dev, info, extra_size);
|
||||||
|
|
||||||
|
iwp_compat->pointer = ptr_to_compat(iwp.pointer);
|
||||||
|
iwp_compat->length = iwp.length;
|
||||||
|
iwp_compat->flags = iwp.flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Call commit handler if needed and defined */
|
||||||
|
if (ret == -EIWCOMMIT)
|
||||||
|
ret = call_commit_handler(dev);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int compat_wext_handle_ioctl(struct net *net, unsigned int cmd,
|
||||||
|
unsigned long arg)
|
||||||
|
{
|
||||||
|
void __user *argp = (void __user *)arg;
|
||||||
|
struct iw_request_info info;
|
||||||
|
struct iwreq iwr;
|
||||||
|
char *colon;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (copy_from_user(&iwr, argp, sizeof(struct iwreq)))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
iwr.ifr_name[IFNAMSIZ-1] = 0;
|
||||||
|
colon = strchr(iwr.ifr_name, ':');
|
||||||
|
if (colon)
|
||||||
|
*colon = 0;
|
||||||
|
|
||||||
|
info.cmd = cmd;
|
||||||
|
info.flags = IW_REQUEST_FLAG_COMPAT;
|
||||||
|
|
||||||
|
ret = wext_ioctl_dispatch(net, (struct ifreq *) &iwr, cmd, &info,
|
||||||
|
compat_standard_call,
|
||||||
|
compat_private_call);
|
||||||
|
|
||||||
|
if (ret >= 0 &&
|
||||||
|
IW_IS_GET(cmd) &&
|
||||||
|
copy_to_user(argp, &iwr, sizeof(struct iwreq)))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/************************* EVENT PROCESSING *************************/
|
/************************* EVENT PROCESSING *************************/
|
||||||
/*
|
/*
|
||||||
* Process events generated by the wireless layer or the driver.
|
* Process events generated by the wireless layer or the driver.
|
||||||
|
Loading…
Reference in New Issue
Block a user