aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/wext.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/wext.c')
-rw-r--r--net/mac80211/wext.c215
1 files changed, 20 insertions, 195 deletions
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index 1da81f456744..d4e61dc903e8 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -27,29 +27,6 @@
27#include "aes_ccm.h" 27#include "aes_ccm.h"
28 28
29 29
30static int ieee80211_ioctl_siwgenie(struct net_device *dev,
31 struct iw_request_info *info,
32 struct iw_point *data, char *extra)
33{
34 struct ieee80211_sub_if_data *sdata;
35
36 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
37
38 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
39 int ret = ieee80211_sta_set_extra_ie(sdata, extra, data->length);
40 if (ret && ret != -EALREADY)
41 return ret;
42 sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL;
43 sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME;
44 sdata->u.mgd.flags &= ~IEEE80211_STA_CONTROL_PORT;
45 if (ret != -EALREADY)
46 ieee80211_sta_req_auth(sdata);
47 return 0;
48 }
49
50 return -EOPNOTSUPP;
51}
52
53static int ieee80211_ioctl_siwfreq(struct net_device *dev, 30static int ieee80211_ioctl_siwfreq(struct net_device *dev,
54 struct iw_request_info *info, 31 struct iw_request_info *info,
55 struct iw_freq *freq, char *extra) 32 struct iw_freq *freq, char *extra)
@@ -61,16 +38,13 @@ static int ieee80211_ioctl_siwfreq(struct net_device *dev,
61 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) 38 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
62 return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra); 39 return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra);
63 else if (sdata->vif.type == NL80211_IFTYPE_STATION) 40 else if (sdata->vif.type == NL80211_IFTYPE_STATION)
64 sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_CHANNEL_SEL; 41 return cfg80211_mgd_wext_siwfreq(dev, info, freq, extra);
65 42
66 /* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */ 43 /* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */
67 if (freq->e == 0) { 44 if (freq->e == 0) {
68 if (freq->m < 0) { 45 if (freq->m < 0)
69 if (sdata->vif.type == NL80211_IFTYPE_STATION) 46 return -EINVAL;
70 sdata->u.mgd.flags |= 47 else
71 IEEE80211_STA_AUTO_CHANNEL_SEL;
72 return 0;
73 } else
74 chan = ieee80211_get_channel(local->hw.wiphy, 48 chan = ieee80211_get_channel(local->hw.wiphy,
75 ieee80211_channel_to_frequency(freq->m)); 49 ieee80211_channel_to_frequency(freq->m));
76 } else { 50 } else {
@@ -95,9 +69,6 @@ static int ieee80211_ioctl_siwfreq(struct net_device *dev,
95 if (local->oper_channel == chan) 69 if (local->oper_channel == chan)
96 return 0; 70 return 0;
97 71
98 if (sdata->vif.type == NL80211_IFTYPE_STATION)
99 ieee80211_sta_req_auth(sdata);
100
101 local->oper_channel = chan; 72 local->oper_channel = chan;
102 local->oper_channel_type = NL80211_CHAN_NO_HT; 73 local->oper_channel_type = NL80211_CHAN_NO_HT;
103 ieee80211_hw_config(local, 0); 74 ieee80211_hw_config(local, 0);
@@ -115,6 +86,8 @@ static int ieee80211_ioctl_giwfreq(struct net_device *dev,
115 86
116 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) 87 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
117 return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra); 88 return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra);
89 else if (sdata->vif.type == NL80211_IFTYPE_STATION)
90 return cfg80211_mgd_wext_giwfreq(dev, info, freq, extra);
118 91
119 freq->m = local->oper_channel->center_freq; 92 freq->m = local->oper_channel->center_freq;
120 freq->e = 6; 93 freq->e = 6;
@@ -128,31 +101,11 @@ static int ieee80211_ioctl_siwessid(struct net_device *dev,
128 struct iw_point *data, char *ssid) 101 struct iw_point *data, char *ssid)
129{ 102{
130 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 103 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
131 size_t len = data->length;
132 int ret;
133 104
134 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) 105 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
135 return cfg80211_ibss_wext_siwessid(dev, info, data, ssid); 106 return cfg80211_ibss_wext_siwessid(dev, info, data, ssid);
136 107 else if (sdata->vif.type == NL80211_IFTYPE_STATION)
137 /* iwconfig uses nul termination in SSID.. */ 108 return cfg80211_mgd_wext_siwessid(dev, info, data, ssid);
138 if (len > 0 && ssid[len - 1] == '\0')
139 len--;
140
141 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
142 if (data->flags)
143 sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_SSID_SEL;
144 else
145 sdata->u.mgd.flags |= IEEE80211_STA_AUTO_SSID_SEL;
146
147 ret = ieee80211_sta_set_ssid(sdata, ssid, len);
148 if (ret)
149 return ret;
150
151 sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME;
152 sdata->u.mgd.flags &= ~IEEE80211_STA_CONTROL_PORT;
153 ieee80211_sta_req_auth(sdata);
154 return 0;
155 }
156 109
157 return -EOPNOTSUPP; 110 return -EOPNOTSUPP;
158} 111}
@@ -162,23 +115,14 @@ static int ieee80211_ioctl_giwessid(struct net_device *dev,
162 struct iw_request_info *info, 115 struct iw_request_info *info,
163 struct iw_point *data, char *ssid) 116 struct iw_point *data, char *ssid)
164{ 117{
165 size_t len;
166 struct ieee80211_sub_if_data *sdata; 118 struct ieee80211_sub_if_data *sdata;
167 119
168 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 120 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
169 121
170 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) 122 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
171 return cfg80211_ibss_wext_giwessid(dev, info, data, ssid); 123 return cfg80211_ibss_wext_giwessid(dev, info, data, ssid);
172 124 else if (sdata->vif.type == NL80211_IFTYPE_STATION)
173 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 125 return cfg80211_mgd_wext_giwessid(dev, info, data, ssid);
174 int res = ieee80211_sta_get_ssid(sdata, ssid, &len);
175 if (res == 0) {
176 data->length = len;
177 data->flags = 1;
178 } else
179 data->flags = 0;
180 return res;
181 }
182 126
183 return -EOPNOTSUPP; 127 return -EOPNOTSUPP;
184} 128}
@@ -193,24 +137,10 @@ static int ieee80211_ioctl_siwap(struct net_device *dev,
193 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) 137 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
194 return cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra); 138 return cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra);
195 139
196 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 140 if (sdata->vif.type == NL80211_IFTYPE_STATION)
197 int ret; 141 return cfg80211_mgd_wext_siwap(dev, info, ap_addr, extra);
198 142
199 if (is_zero_ether_addr((u8 *) &ap_addr->sa_data)) 143 if (sdata->vif.type == NL80211_IFTYPE_WDS) {
200 sdata->u.mgd.flags |= IEEE80211_STA_AUTO_BSSID_SEL |
201 IEEE80211_STA_AUTO_CHANNEL_SEL;
202 else if (is_broadcast_ether_addr((u8 *) &ap_addr->sa_data))
203 sdata->u.mgd.flags |= IEEE80211_STA_AUTO_BSSID_SEL;
204 else
205 sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL;
206 ret = ieee80211_sta_set_bssid(sdata, (u8 *) &ap_addr->sa_data);
207 if (ret)
208 return ret;
209 sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME;
210 sdata->u.mgd.flags &= ~IEEE80211_STA_CONTROL_PORT;
211 ieee80211_sta_req_auth(sdata);
212 return 0;
213 } else if (sdata->vif.type == NL80211_IFTYPE_WDS) {
214 /* 144 /*
215 * If it is necessary to update the WDS peer address 145 * If it is necessary to update the WDS peer address
216 * while the interface is running, then we need to do 146 * while the interface is running, then we need to do
@@ -240,14 +170,10 @@ static int ieee80211_ioctl_giwap(struct net_device *dev,
240 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) 170 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
241 return cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra); 171 return cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra);
242 172
243 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 173 if (sdata->vif.type == NL80211_IFTYPE_STATION)
244 if (sdata->u.mgd.state == IEEE80211_STA_MLME_ASSOCIATED) { 174 return cfg80211_mgd_wext_giwap(dev, info, ap_addr, extra);
245 ap_addr->sa_family = ARPHRD_ETHER; 175
246 memcpy(&ap_addr->sa_data, sdata->u.mgd.bssid, ETH_ALEN); 176 if (sdata->vif.type == NL80211_IFTYPE_WDS) {
247 } else
248 memset(&ap_addr->sa_data, 0, ETH_ALEN);
249 return 0;
250 } else if (sdata->vif.type == NL80211_IFTYPE_WDS) {
251 ap_addr->sa_family = ARPHRD_ETHER; 177 ap_addr->sa_family = ARPHRD_ETHER;
252 memcpy(&ap_addr->sa_data, sdata->u.wds.remote_addr, ETH_ALEN); 178 memcpy(&ap_addr->sa_data, sdata->u.wds.remote_addr, ETH_ALEN);
253 return 0; 179 return 0;
@@ -395,85 +321,6 @@ static int ieee80211_ioctl_giwpower(struct net_device *dev,
395 return 0; 321 return 0;
396} 322}
397 323
398static int ieee80211_ioctl_siwauth(struct net_device *dev,
399 struct iw_request_info *info,
400 struct iw_param *data, char *extra)
401{
402 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
403 int ret = 0;
404
405 switch (data->flags & IW_AUTH_INDEX) {
406 case IW_AUTH_WPA_VERSION:
407 case IW_AUTH_CIPHER_GROUP:
408 case IW_AUTH_WPA_ENABLED:
409 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
410 case IW_AUTH_KEY_MGMT:
411 case IW_AUTH_CIPHER_GROUP_MGMT:
412 break;
413 case IW_AUTH_CIPHER_PAIRWISE:
414 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
415 if (data->value & (IW_AUTH_CIPHER_WEP40 |
416 IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_TKIP))
417 sdata->u.mgd.flags |=
418 IEEE80211_STA_TKIP_WEP_USED;
419 else
420 sdata->u.mgd.flags &=
421 ~IEEE80211_STA_TKIP_WEP_USED;
422 }
423 break;
424 case IW_AUTH_DROP_UNENCRYPTED:
425 sdata->drop_unencrypted = !!data->value;
426 break;
427 case IW_AUTH_PRIVACY_INVOKED:
428 if (sdata->vif.type != NL80211_IFTYPE_STATION)
429 ret = -EINVAL;
430 else {
431 sdata->u.mgd.flags &= ~IEEE80211_STA_PRIVACY_INVOKED;
432 /*
433 * Privacy invoked by wpa_supplicant, store the
434 * value and allow associating to a protected
435 * network without having a key up front.
436 */
437 if (data->value)
438 sdata->u.mgd.flags |=
439 IEEE80211_STA_PRIVACY_INVOKED;
440 }
441 break;
442 case IW_AUTH_80211_AUTH_ALG:
443 if (sdata->vif.type == NL80211_IFTYPE_STATION)
444 sdata->u.mgd.auth_algs = data->value;
445 else
446 ret = -EOPNOTSUPP;
447 break;
448 case IW_AUTH_MFP:
449 if (!(sdata->local->hw.flags & IEEE80211_HW_MFP_CAPABLE)) {
450 ret = -EOPNOTSUPP;
451 break;
452 }
453 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
454 switch (data->value) {
455 case IW_AUTH_MFP_DISABLED:
456 sdata->u.mgd.mfp = IEEE80211_MFP_DISABLED;
457 break;
458 case IW_AUTH_MFP_OPTIONAL:
459 sdata->u.mgd.mfp = IEEE80211_MFP_OPTIONAL;
460 break;
461 case IW_AUTH_MFP_REQUIRED:
462 sdata->u.mgd.mfp = IEEE80211_MFP_REQUIRED;
463 break;
464 default:
465 ret = -EINVAL;
466 }
467 } else
468 ret = -EOPNOTSUPP;
469 break;
470 default:
471 ret = -EOPNOTSUPP;
472 break;
473 }
474 return ret;
475}
476
477/* Get wireless statistics. Called by /proc/net/wireless and by SIOCGIWSTATS */ 324/* Get wireless statistics. Called by /proc/net/wireless and by SIOCGIWSTATS */
478static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev) 325static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev)
479{ 326{
@@ -541,28 +388,6 @@ static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev
541 return wstats; 388 return wstats;
542} 389}
543 390
544static int ieee80211_ioctl_giwauth(struct net_device *dev,
545 struct iw_request_info *info,
546 struct iw_param *data, char *extra)
547{
548 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
549 int ret = 0;
550
551 switch (data->flags & IW_AUTH_INDEX) {
552 case IW_AUTH_80211_AUTH_ALG:
553 if (sdata->vif.type == NL80211_IFTYPE_STATION)
554 data->value = sdata->u.mgd.auth_algs;
555 else
556 ret = -EOPNOTSUPP;
557 break;
558 default:
559 ret = -EOPNOTSUPP;
560 break;
561 }
562 return ret;
563}
564
565
566/* Structures to export the Wireless Handlers */ 391/* Structures to export the Wireless Handlers */
567 392
568static const iw_handler ieee80211_handler[] = 393static const iw_handler ieee80211_handler[] =
@@ -615,10 +440,10 @@ static const iw_handler ieee80211_handler[] =
615 (iw_handler) ieee80211_ioctl_giwpower, /* SIOCGIWPOWER */ 440 (iw_handler) ieee80211_ioctl_giwpower, /* SIOCGIWPOWER */
616 (iw_handler) NULL, /* -- hole -- */ 441 (iw_handler) NULL, /* -- hole -- */
617 (iw_handler) NULL, /* -- hole -- */ 442 (iw_handler) NULL, /* -- hole -- */
618 (iw_handler) ieee80211_ioctl_siwgenie, /* SIOCSIWGENIE */ 443 (iw_handler) cfg80211_wext_siwgenie, /* SIOCSIWGENIE */
619 (iw_handler) NULL, /* SIOCGIWGENIE */ 444 (iw_handler) NULL, /* SIOCGIWGENIE */
620 (iw_handler) ieee80211_ioctl_siwauth, /* SIOCSIWAUTH */ 445 (iw_handler) cfg80211_wext_siwauth, /* SIOCSIWAUTH */
621 (iw_handler) ieee80211_ioctl_giwauth, /* SIOCGIWAUTH */ 446 (iw_handler) cfg80211_wext_giwauth, /* SIOCGIWAUTH */
622 (iw_handler) cfg80211_wext_siwencodeext, /* SIOCSIWENCODEEXT */ 447 (iw_handler) cfg80211_wext_siwencodeext, /* SIOCSIWENCODEEXT */
623 (iw_handler) NULL, /* SIOCGIWENCODEEXT */ 448 (iw_handler) NULL, /* SIOCGIWENCODEEXT */
624 (iw_handler) NULL, /* SIOCSIWPMKSA */ 449 (iw_handler) NULL, /* SIOCSIWPMKSA */