aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/wext.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-07-01 15:26:56 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-07-10 15:01:51 -0400
commitf21293549f60f88c74fcb9944737f11048896dc4 (patch)
treed4a00663f87816c0c742e74d7b2c9bad31a18816 /net/mac80211/wext.c
parent6829c878ecd24ff0ae41b4668c7e9d0f11b66942 (diff)
cfg80211: managed mode wext compatibility
This adds code to make it possible to use the cfg80211 connect() API with wireless extensions, and because the previous patch added emulation of that API with auth() and assoc(), by extension also supports wext on that. At the same time, removes code from mac80211 for wext, but doesn't yet clean up mac80211's mlme code more. Signed-off-by: Samuel Ortiz <samuel.ortiz@intel.com> Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
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 */