diff options
Diffstat (limited to 'net/mac80211/wext.c')
-rw-r--r-- | net/mac80211/wext.c | 215 |
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 | ||
30 | static 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 | |||
53 | static int ieee80211_ioctl_siwfreq(struct net_device *dev, | 30 | static 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 | ||
398 | static 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 */ |
478 | static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev) | 325 | static 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 | ||
544 | static 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 | ||
568 | static const iw_handler ieee80211_handler[] = | 393 | static 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 */ |