aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/nl80211.h36
-rw-r--r--include/net/cfg80211.h46
-rw-r--r--net/mac80211/mlme.c9
-rw-r--r--net/wireless/Makefile2
-rw-r--r--net/wireless/mlme.c46
-rw-r--r--net/wireless/nl80211.c72
-rw-r--r--net/wireless/nl80211.h12
7 files changed, 219 insertions, 4 deletions
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 3700d927e245..5ce68ae8314e 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -161,6 +161,25 @@
161 * %NL80211_REG_TYPE_COUNTRY the alpha2 to which we have moved on 161 * %NL80211_REG_TYPE_COUNTRY the alpha2 to which we have moved on
162 * to (%NL80211_ATTR_REG_ALPHA2). 162 * to (%NL80211_ATTR_REG_ALPHA2).
163 * 163 *
164 * @NL80211_CMD_AUTHENTICATE: authentication notification (on the "mlme"
165 * multicast group). This event reports reception of an Authentication
166 * frame in station and IBSS modes when the local MLME processed the
167 * frame, i.e., it was for the local STA and was received in correct
168 * state. This is similar to MLME-AUTHENTICATE.confirm primitive in the
169 * MLME SAP interface (kernel providing MLME, userspace SME). The
170 * included NL80211_ATTR_FRAME attribute contains the management frame
171 * (including both the header and frame body, but not FCS).
172 * @NL80211_CMD_ASSOCIATE: association notification; like
173 * NL80211_CMD_AUTHENTICATE but for Association Response and Reassociation
174 * Response frames (similar to MLME-ASSOCIATE.confirm or
175 * MLME-REASSOCIATE.confirm primitives).
176 * @NL80211_CMD_DEAUTHENTICATE: deauthentication notification; like
177 * NL80211_CMD_AUTHENTICATE but for Deauthentication frames (similar to
178 * MLME-DEAUTHENTICATE.indication primitive).
179 * @NL80211_CMD_DISASSOCIATE: disassociation notification; like
180 * NL80211_CMD_AUTHENTICATE but for Disassociation frames (similar to
181 * MLME-DISASSOCIATE.indication primitive).
182 *
164 * @NL80211_CMD_MAX: highest used command number 183 * @NL80211_CMD_MAX: highest used command number
165 * @__NL80211_CMD_AFTER_LAST: internal use 184 * @__NL80211_CMD_AFTER_LAST: internal use
166 */ 185 */
@@ -217,6 +236,11 @@ enum nl80211_commands {
217 236
218 NL80211_CMD_REG_CHANGE, 237 NL80211_CMD_REG_CHANGE,
219 238
239 NL80211_CMD_AUTHENTICATE,
240 NL80211_CMD_ASSOCIATE,
241 NL80211_CMD_DEAUTHENTICATE,
242 NL80211_CMD_DISASSOCIATE,
243
220 /* add new commands above here */ 244 /* add new commands above here */
221 245
222 /* used to define NL80211_CMD_MAX below */ 246 /* used to define NL80211_CMD_MAX below */
@@ -230,8 +254,11 @@ enum nl80211_commands {
230 */ 254 */
231#define NL80211_CMD_SET_BSS NL80211_CMD_SET_BSS 255#define NL80211_CMD_SET_BSS NL80211_CMD_SET_BSS
232#define NL80211_CMD_SET_MGMT_EXTRA_IE NL80211_CMD_SET_MGMT_EXTRA_IE 256#define NL80211_CMD_SET_MGMT_EXTRA_IE NL80211_CMD_SET_MGMT_EXTRA_IE
233
234#define NL80211_CMD_REG_CHANGE NL80211_CMD_REG_CHANGE 257#define NL80211_CMD_REG_CHANGE NL80211_CMD_REG_CHANGE
258#define NL80211_CMD_AUTHENTICATE NL80211_CMD_AUTHENTICATE
259#define NL80211_CMD_ASSOCIATE NL80211_CMD_ASSOCIATE
260#define NL80211_CMD_DEAUTHENTICATE NL80211_CMD_DEAUTHENTICATE
261#define NL80211_CMD_DISASSOCIATE NL80211_CMD_DISASSOCIATE
235 262
236/** 263/**
237 * enum nl80211_attrs - nl80211 netlink attributes 264 * enum nl80211_attrs - nl80211 netlink attributes
@@ -353,6 +380,10 @@ enum nl80211_commands {
353 * an array of command numbers (i.e. a mapping index to command number) 380 * an array of command numbers (i.e. a mapping index to command number)
354 * that the driver for the given wiphy supports. 381 * that the driver for the given wiphy supports.
355 * 382 *
383 * @NL80211_ATTR_FRAME: frame data (binary attribute), including frame header
384 * and body, but not FCS; used, e.g., with NL80211_CMD_AUTHENTICATE and
385 * NL80211_CMD_ASSOCIATE events
386 *
356 * @NL80211_ATTR_MAX: highest attribute number currently defined 387 * @NL80211_ATTR_MAX: highest attribute number currently defined
357 * @__NL80211_ATTR_AFTER_LAST: internal use 388 * @__NL80211_ATTR_AFTER_LAST: internal use
358 */ 389 */
@@ -432,6 +463,8 @@ enum nl80211_attrs {
432 463
433 NL80211_ATTR_SUPPORTED_COMMANDS, 464 NL80211_ATTR_SUPPORTED_COMMANDS,
434 465
466 NL80211_ATTR_FRAME,
467
435 /* add attributes here, update the policy in nl80211.c */ 468 /* add attributes here, update the policy in nl80211.c */
436 469
437 __NL80211_ATTR_AFTER_LAST, 470 __NL80211_ATTR_AFTER_LAST,
@@ -451,6 +484,7 @@ enum nl80211_attrs {
451#define NL80211_ATTR_IE NL80211_ATTR_IE 484#define NL80211_ATTR_IE NL80211_ATTR_IE
452#define NL80211_ATTR_REG_INITIATOR NL80211_ATTR_REG_INITIATOR 485#define NL80211_ATTR_REG_INITIATOR NL80211_ATTR_REG_INITIATOR
453#define NL80211_ATTR_REG_TYPE NL80211_ATTR_REG_TYPE 486#define NL80211_ATTR_REG_TYPE NL80211_ATTR_REG_TYPE
487#define NL80211_ATTR_FRAME NL80211_ATTR_FRAME
454 488
455#define NL80211_MAX_SUPP_RATES 32 489#define NL80211_MAX_SUPP_RATES 32
456#define NL80211_MAX_SUPP_REG_RULES 32 490#define NL80211_MAX_SUPP_REG_RULES 32
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 50f3fd9ff524..ad44016021b1 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -807,4 +807,50 @@ void cfg80211_put_bss(struct cfg80211_bss *bss);
807 */ 807 */
808void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *bss); 808void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *bss);
809 809
810/**
811 * cfg80211_send_rx_auth - notification of processed authentication
812 * @dev: network device
813 * @buf: authentication frame (header + body)
814 * @len: length of the frame data
815 *
816 * This function is called whenever an authentication has been processed in
817 * station mode.
818 */
819void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len);
820
821/**
822 * cfg80211_send_rx_assoc - notification of processed association
823 * @dev: network device
824 * @buf: (re)association response frame (header + body)
825 * @len: length of the frame data
826 *
827 * This function is called whenever a (re)association response has been
828 * processed in station mode.
829 */
830void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len);
831
832/**
833 * cfg80211_send_rx_deauth - notification of processed deauthentication
834 * @dev: network device
835 * @buf: deauthentication frame (header + body)
836 * @len: length of the frame data
837 *
838 * This function is called whenever deauthentication has been processed in
839 * station mode.
840 */
841void cfg80211_send_rx_deauth(struct net_device *dev, const u8 *buf,
842 size_t len);
843
844/**
845 * cfg80211_send_rx_disassoc - notification of processed disassociation
846 * @dev: network device
847 * @buf: disassociation response frame (header + body)
848 * @len: length of the frame data
849 *
850 * This function is called whenever disassociation has been processed in
851 * station mode.
852 */
853void cfg80211_send_rx_disassoc(struct net_device *dev, const u8 *buf,
854 size_t len);
855
810#endif /* __NET_CFG80211_H */ 856#endif /* __NET_CFG80211_H */
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 1f49b63d8dd2..6dc7a61bc18b 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1085,11 +1085,13 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
1085 case WLAN_AUTH_OPEN: 1085 case WLAN_AUTH_OPEN:
1086 case WLAN_AUTH_LEAP: 1086 case WLAN_AUTH_LEAP:
1087 ieee80211_auth_completed(sdata); 1087 ieee80211_auth_completed(sdata);
1088 cfg80211_send_rx_auth(sdata->dev, (u8 *) mgmt, len);
1088 break; 1089 break;
1089 case WLAN_AUTH_SHARED_KEY: 1090 case WLAN_AUTH_SHARED_KEY:
1090 if (ifmgd->auth_transaction == 4) 1091 if (ifmgd->auth_transaction == 4) {
1091 ieee80211_auth_completed(sdata); 1092 ieee80211_auth_completed(sdata);
1092 else 1093 cfg80211_send_rx_auth(sdata->dev, (u8 *) mgmt, len);
1094 } else
1093 ieee80211_auth_challenge(sdata, mgmt, len); 1095 ieee80211_auth_challenge(sdata, mgmt, len);
1094 break; 1096 break;
1095 } 1097 }
@@ -1125,6 +1127,7 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
1125 1127
1126 ieee80211_set_disassoc(sdata, true, false, 0); 1128 ieee80211_set_disassoc(sdata, true, false, 0);
1127 ifmgd->flags &= ~IEEE80211_STA_AUTHENTICATED; 1129 ifmgd->flags &= ~IEEE80211_STA_AUTHENTICATED;
1130 cfg80211_send_rx_deauth(sdata->dev, (u8 *) mgmt, len);
1128} 1131}
1129 1132
1130 1133
@@ -1154,6 +1157,7 @@ static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
1154 } 1157 }
1155 1158
1156 ieee80211_set_disassoc(sdata, false, false, reason_code); 1159 ieee80211_set_disassoc(sdata, false, false, reason_code);
1160 cfg80211_send_rx_disassoc(sdata->dev, (u8 *) mgmt, len);
1157} 1161}
1158 1162
1159 1163
@@ -1370,6 +1374,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1370 ieee80211_set_associated(sdata, changed); 1374 ieee80211_set_associated(sdata, changed);
1371 1375
1372 ieee80211_associated(sdata); 1376 ieee80211_associated(sdata);
1377 cfg80211_send_rx_assoc(sdata->dev, (u8 *) mgmt, len);
1373} 1378}
1374 1379
1375 1380
diff --git a/net/wireless/Makefile b/net/wireless/Makefile
index c157b4d8014b..6d1e7b27b752 100644
--- a/net/wireless/Makefile
+++ b/net/wireless/Makefile
@@ -5,7 +5,7 @@ obj-$(CONFIG_LIB80211_CRYPT_WEP) += lib80211_crypt_wep.o
5obj-$(CONFIG_LIB80211_CRYPT_CCMP) += lib80211_crypt_ccmp.o 5obj-$(CONFIG_LIB80211_CRYPT_CCMP) += lib80211_crypt_ccmp.o
6obj-$(CONFIG_LIB80211_CRYPT_TKIP) += lib80211_crypt_tkip.o 6obj-$(CONFIG_LIB80211_CRYPT_TKIP) += lib80211_crypt_tkip.o
7 7
8cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o 8cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o mlme.o
9cfg80211-$(CONFIG_WIRELESS_EXT) += wext-compat.o 9cfg80211-$(CONFIG_WIRELESS_EXT) += wext-compat.o
10 10
11ccflags-y += -D__CHECK_ENDIAN__ 11ccflags-y += -D__CHECK_ENDIAN__
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
new file mode 100644
index 000000000000..bec5721b6f99
--- /dev/null
+++ b/net/wireless/mlme.c
@@ -0,0 +1,46 @@
1/*
2 * cfg80211 MLME SAP interface
3 *
4 * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
5 */
6
7#include <linux/kernel.h>
8#include <linux/module.h>
9#include <linux/netdevice.h>
10#include <linux/nl80211.h>
11#include <net/cfg80211.h>
12#include "core.h"
13#include "nl80211.h"
14
15void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len)
16{
17 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
18 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
19 nl80211_send_rx_auth(rdev, dev, buf, len);
20}
21EXPORT_SYMBOL(cfg80211_send_rx_auth);
22
23void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len)
24{
25 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
26 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
27 nl80211_send_rx_assoc(rdev, dev, buf, len);
28}
29EXPORT_SYMBOL(cfg80211_send_rx_assoc);
30
31void cfg80211_send_rx_deauth(struct net_device *dev, const u8 *buf, size_t len)
32{
33 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
34 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
35 nl80211_send_rx_deauth(rdev, dev, buf, len);
36}
37EXPORT_SYMBOL(cfg80211_send_rx_deauth);
38
39void cfg80211_send_rx_disassoc(struct net_device *dev, const u8 *buf,
40 size_t len)
41{
42 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
43 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
44 nl80211_send_rx_disassoc(rdev, dev, buf, len);
45}
46EXPORT_SYMBOL(cfg80211_send_rx_disassoc);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index a3ecf8d73898..c034c2418cb3 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -2830,6 +2830,9 @@ static struct genl_ops nl80211_ops[] = {
2830 .dumpit = nl80211_dump_scan, 2830 .dumpit = nl80211_dump_scan,
2831 }, 2831 },
2832}; 2832};
2833static struct genl_multicast_group nl80211_mlme_mcgrp = {
2834 .name = "mlme",
2835};
2833 2836
2834/* multicast groups */ 2837/* multicast groups */
2835static struct genl_multicast_group nl80211_config_mcgrp = { 2838static struct genl_multicast_group nl80211_config_mcgrp = {
@@ -2975,6 +2978,71 @@ nla_put_failure:
2975 nlmsg_free(msg); 2978 nlmsg_free(msg);
2976} 2979}
2977 2980
2981static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
2982 struct net_device *netdev,
2983 const u8 *buf, size_t len,
2984 enum nl80211_commands cmd)
2985{
2986 struct sk_buff *msg;
2987 void *hdr;
2988
2989 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
2990 if (!msg)
2991 return;
2992
2993 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
2994 if (!hdr) {
2995 nlmsg_free(msg);
2996 return;
2997 }
2998
2999 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
3000 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
3001 NLA_PUT(msg, NL80211_ATTR_FRAME, len, buf);
3002
3003 if (genlmsg_end(msg, hdr) < 0) {
3004 nlmsg_free(msg);
3005 return;
3006 }
3007
3008 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, GFP_KERNEL);
3009 return;
3010
3011 nla_put_failure:
3012 genlmsg_cancel(msg, hdr);
3013 nlmsg_free(msg);
3014}
3015
3016void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
3017 struct net_device *netdev, const u8 *buf, size_t len)
3018{
3019 nl80211_send_mlme_event(rdev, netdev, buf, len,
3020 NL80211_CMD_AUTHENTICATE);
3021}
3022
3023void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
3024 struct net_device *netdev, const u8 *buf,
3025 size_t len)
3026{
3027 nl80211_send_mlme_event(rdev, netdev, buf, len, NL80211_CMD_ASSOCIATE);
3028}
3029
3030void nl80211_send_rx_deauth(struct cfg80211_registered_device *rdev,
3031 struct net_device *netdev, const u8 *buf,
3032 size_t len)
3033{
3034 nl80211_send_mlme_event(rdev, netdev, buf, len,
3035 NL80211_CMD_DEAUTHENTICATE);
3036}
3037
3038void nl80211_send_rx_disassoc(struct cfg80211_registered_device *rdev,
3039 struct net_device *netdev, const u8 *buf,
3040 size_t len)
3041{
3042 nl80211_send_mlme_event(rdev, netdev, buf, len,
3043 NL80211_CMD_DISASSOCIATE);
3044}
3045
2978/* initialisation/exit functions */ 3046/* initialisation/exit functions */
2979 3047
2980int nl80211_init(void) 3048int nl80211_init(void)
@@ -3003,6 +3071,10 @@ int nl80211_init(void)
3003 if (err) 3071 if (err)
3004 goto err_out; 3072 goto err_out;
3005 3073
3074 err = genl_register_mc_group(&nl80211_fam, &nl80211_mlme_mcgrp);
3075 if (err)
3076 goto err_out;
3077
3006 return 0; 3078 return 0;
3007 err_out: 3079 err_out:
3008 genl_unregister_family(&nl80211_fam); 3080 genl_unregister_family(&nl80211_fam);
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index 5b5fe1339de0..b77af4ab80be 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -11,5 +11,17 @@ extern void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
11extern void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev, 11extern void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
12 struct net_device *netdev); 12 struct net_device *netdev);
13extern void nl80211_send_reg_change_event(struct regulatory_request *request); 13extern void nl80211_send_reg_change_event(struct regulatory_request *request);
14extern void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
15 struct net_device *netdev,
16 const u8 *buf, size_t len);
17extern void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
18 struct net_device *netdev,
19 const u8 *buf, size_t len);
20extern void nl80211_send_rx_deauth(struct cfg80211_registered_device *rdev,
21 struct net_device *netdev,
22 const u8 *buf, size_t len);
23extern void nl80211_send_rx_disassoc(struct cfg80211_registered_device *rdev,
24 struct net_device *netdev,
25 const u8 *buf, size_t len);
14 26
15#endif /* __NET_WIRELESS_NL80211_H */ 27#endif /* __NET_WIRELESS_NL80211_H */