diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2009-07-02 03:13:27 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-07-10 15:01:51 -0400 |
commit | 6829c878ecd24ff0ae41b4668c7e9d0f11b66942 (patch) | |
tree | acf78b685d60694040953b4f61d768b95b79e45d /net/wireless/mlme.c | |
parent | b23aa676ab9d54469cda9f7151f51a2851c6f36e (diff) |
cfg80211: emulate connect with auth/assoc
This adds code to cfg80211 so that drivers (mac80211 right
now) that don't implement connect but rather auth/assoc can
still be used with the nl80211 connect command. This will
also be necessary for the wext compat code.
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/wireless/mlme.c')
-rw-r--r-- | net/wireless/mlme.c | 79 |
1 files changed, 63 insertions, 16 deletions
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index c4e6d4b84a46..3427fe73d3c3 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c | |||
@@ -16,58 +16,105 @@ void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len, gf | |||
16 | { | 16 | { |
17 | struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; | 17 | struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; |
18 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 18 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
19 | |||
19 | nl80211_send_rx_auth(rdev, dev, buf, len, gfp); | 20 | nl80211_send_rx_auth(rdev, dev, buf, len, gfp); |
21 | cfg80211_sme_rx_auth(dev, buf, len); | ||
20 | } | 22 | } |
21 | EXPORT_SYMBOL(cfg80211_send_rx_auth); | 23 | EXPORT_SYMBOL(cfg80211_send_rx_auth); |
22 | 24 | ||
23 | void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len, gfp_t gfp) | 25 | void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len, gfp_t gfp) |
24 | { | 26 | { |
25 | struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; | 27 | u16 status_code; |
28 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
29 | struct wiphy *wiphy = wdev->wiphy; | ||
26 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 30 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
31 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf; | ||
32 | u8 *ie = mgmt->u.assoc_resp.variable; | ||
33 | int ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable); | ||
34 | |||
35 | status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code); | ||
36 | |||
27 | nl80211_send_rx_assoc(rdev, dev, buf, len, gfp); | 37 | nl80211_send_rx_assoc(rdev, dev, buf, len, gfp); |
38 | |||
39 | cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs, | ||
40 | status_code, gfp); | ||
28 | } | 41 | } |
29 | EXPORT_SYMBOL(cfg80211_send_rx_assoc); | 42 | EXPORT_SYMBOL(cfg80211_send_rx_assoc); |
30 | 43 | ||
31 | void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len, gfp_t gfp) | 44 | void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len, gfp_t gfp) |
32 | { | 45 | { |
33 | struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; | 46 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
47 | struct wiphy *wiphy = wdev->wiphy; | ||
34 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 48 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
49 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf; | ||
50 | |||
35 | nl80211_send_deauth(rdev, dev, buf, len, gfp); | 51 | nl80211_send_deauth(rdev, dev, buf, len, gfp); |
52 | |||
53 | if (wdev->sme_state == CFG80211_SME_CONNECTED) { | ||
54 | u16 reason_code; | ||
55 | bool from_ap; | ||
56 | |||
57 | reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); | ||
58 | |||
59 | from_ap = memcmp(mgmt->da, dev->dev_addr, ETH_ALEN) == 0; | ||
60 | __cfg80211_disconnected(dev, gfp, NULL, 0, | ||
61 | reason_code, from_ap); | ||
62 | |||
63 | wdev->sme_state = CFG80211_SME_IDLE; | ||
64 | } else if (wdev->sme_state == CFG80211_SME_CONNECTING) { | ||
65 | cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0, | ||
66 | WLAN_STATUS_UNSPECIFIED_FAILURE, gfp); | ||
67 | } | ||
36 | } | 68 | } |
37 | EXPORT_SYMBOL(cfg80211_send_deauth); | 69 | EXPORT_SYMBOL(cfg80211_send_deauth); |
38 | 70 | ||
39 | void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len, gfp_t gfp) | 71 | void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len, gfp_t gfp) |
40 | { | 72 | { |
41 | struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; | 73 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
74 | struct wiphy *wiphy = wdev->wiphy; | ||
42 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 75 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
76 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf; | ||
77 | |||
43 | nl80211_send_disassoc(rdev, dev, buf, len, gfp); | 78 | nl80211_send_disassoc(rdev, dev, buf, len, gfp); |
44 | } | ||
45 | EXPORT_SYMBOL(cfg80211_send_disassoc); | ||
46 | 79 | ||
47 | static void cfg80211_wext_disconnected(struct net_device *dev) | 80 | if (wdev->sme_state == CFG80211_SME_CONNECTED) { |
48 | { | 81 | u16 reason_code; |
49 | #ifdef CONFIG_WIRELESS_EXT | 82 | bool from_ap; |
50 | union iwreq_data wrqu; | 83 | |
51 | memset(&wrqu, 0, sizeof(wrqu)); | 84 | reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); |
52 | wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); | 85 | |
53 | #endif | 86 | from_ap = memcmp(mgmt->da, dev->dev_addr, ETH_ALEN) == 0; |
87 | __cfg80211_disconnected(dev, gfp, NULL, 0, | ||
88 | reason_code, from_ap); | ||
89 | |||
90 | wdev->sme_state = CFG80211_SME_IDLE; | ||
91 | } | ||
54 | } | 92 | } |
93 | EXPORT_SYMBOL(cfg80211_send_disassoc); | ||
55 | 94 | ||
56 | void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr, gfp_t gfp) | 95 | void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr, gfp_t gfp) |
57 | { | 96 | { |
58 | struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; | 97 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
98 | struct wiphy *wiphy = wdev->wiphy; | ||
59 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 99 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
60 | nl80211_send_auth_timeout(rdev, dev, addr, gfp); | 100 | nl80211_send_auth_timeout(rdev, dev, addr, gfp); |
61 | cfg80211_wext_disconnected(dev); | 101 | if (wdev->sme_state == CFG80211_SME_CONNECTING) |
102 | cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0, | ||
103 | WLAN_STATUS_UNSPECIFIED_FAILURE, gfp); | ||
104 | wdev->sme_state = CFG80211_SME_IDLE; | ||
62 | } | 105 | } |
63 | EXPORT_SYMBOL(cfg80211_send_auth_timeout); | 106 | EXPORT_SYMBOL(cfg80211_send_auth_timeout); |
64 | 107 | ||
65 | void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr, gfp_t gfp) | 108 | void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr, gfp_t gfp) |
66 | { | 109 | { |
67 | struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; | 110 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
111 | struct wiphy *wiphy = wdev->wiphy; | ||
68 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 112 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
69 | nl80211_send_assoc_timeout(rdev, dev, addr, gfp); | 113 | nl80211_send_assoc_timeout(rdev, dev, addr, gfp); |
70 | cfg80211_wext_disconnected(dev); | 114 | if (wdev->sme_state == CFG80211_SME_CONNECTING) |
115 | cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0, | ||
116 | WLAN_STATUS_UNSPECIFIED_FAILURE, gfp); | ||
117 | wdev->sme_state = CFG80211_SME_IDLE; | ||
71 | } | 118 | } |
72 | EXPORT_SYMBOL(cfg80211_send_assoc_timeout); | 119 | EXPORT_SYMBOL(cfg80211_send_assoc_timeout); |
73 | 120 | ||