mlme.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /*
  2. * cfg80211 MLME SAP interface
  3. *
  4. * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
  5. */
  6. #include <linux/kernel.h>
  7. #include <linux/module.h>
  8. #include <linux/netdevice.h>
  9. #include <linux/nl80211.h>
  10. #include <net/cfg80211.h>
  11. #include "core.h"
  12. #include "nl80211.h"
  13. void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len, gfp_t gfp)
  14. {
  15. struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
  16. struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
  17. nl80211_send_rx_auth(rdev, dev, buf, len, gfp);
  18. cfg80211_sme_rx_auth(dev, buf, len);
  19. }
  20. EXPORT_SYMBOL(cfg80211_send_rx_auth);
  21. void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len, gfp_t gfp)
  22. {
  23. u16 status_code;
  24. struct wireless_dev *wdev = dev->ieee80211_ptr;
  25. struct wiphy *wiphy = wdev->wiphy;
  26. struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
  27. struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
  28. u8 *ie = mgmt->u.assoc_resp.variable;
  29. int ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
  30. status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
  31. nl80211_send_rx_assoc(rdev, dev, buf, len, gfp);
  32. cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs,
  33. status_code, gfp);
  34. }
  35. EXPORT_SYMBOL(cfg80211_send_rx_assoc);
  36. void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len, gfp_t gfp)
  37. {
  38. struct wireless_dev *wdev = dev->ieee80211_ptr;
  39. struct wiphy *wiphy = wdev->wiphy;
  40. struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
  41. struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
  42. nl80211_send_deauth(rdev, dev, buf, len, gfp);
  43. if (wdev->sme_state == CFG80211_SME_CONNECTED) {
  44. u16 reason_code;
  45. bool from_ap;
  46. reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
  47. from_ap = memcmp(mgmt->da, dev->dev_addr, ETH_ALEN) == 0;
  48. __cfg80211_disconnected(dev, gfp, NULL, 0,
  49. reason_code, from_ap);
  50. wdev->sme_state = CFG80211_SME_IDLE;
  51. } else if (wdev->sme_state == CFG80211_SME_CONNECTING) {
  52. cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0,
  53. WLAN_STATUS_UNSPECIFIED_FAILURE, gfp);
  54. }
  55. }
  56. EXPORT_SYMBOL(cfg80211_send_deauth);
  57. void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len, gfp_t gfp)
  58. {
  59. struct wireless_dev *wdev = dev->ieee80211_ptr;
  60. struct wiphy *wiphy = wdev->wiphy;
  61. struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
  62. struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
  63. nl80211_send_disassoc(rdev, dev, buf, len, gfp);
  64. if (wdev->sme_state == CFG80211_SME_CONNECTED) {
  65. u16 reason_code;
  66. bool from_ap;
  67. reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
  68. from_ap = memcmp(mgmt->da, dev->dev_addr, ETH_ALEN) == 0;
  69. __cfg80211_disconnected(dev, gfp, NULL, 0,
  70. reason_code, from_ap);
  71. wdev->sme_state = CFG80211_SME_IDLE;
  72. }
  73. }
  74. EXPORT_SYMBOL(cfg80211_send_disassoc);
  75. void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr, gfp_t gfp)
  76. {
  77. struct wireless_dev *wdev = dev->ieee80211_ptr;
  78. struct wiphy *wiphy = wdev->wiphy;
  79. struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
  80. nl80211_send_auth_timeout(rdev, dev, addr, gfp);
  81. if (wdev->sme_state == CFG80211_SME_CONNECTING)
  82. cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
  83. WLAN_STATUS_UNSPECIFIED_FAILURE, gfp);
  84. wdev->sme_state = CFG80211_SME_IDLE;
  85. }
  86. EXPORT_SYMBOL(cfg80211_send_auth_timeout);
  87. void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr, gfp_t gfp)
  88. {
  89. struct wireless_dev *wdev = dev->ieee80211_ptr;
  90. struct wiphy *wiphy = wdev->wiphy;
  91. struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
  92. nl80211_send_assoc_timeout(rdev, dev, addr, gfp);
  93. if (wdev->sme_state == CFG80211_SME_CONNECTING)
  94. cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
  95. WLAN_STATUS_UNSPECIFIED_FAILURE, gfp);
  96. wdev->sme_state = CFG80211_SME_IDLE;
  97. }
  98. EXPORT_SYMBOL(cfg80211_send_assoc_timeout);
  99. void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr,
  100. enum nl80211_key_type key_type, int key_id,
  101. const u8 *tsc, gfp_t gfp)
  102. {
  103. struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
  104. struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
  105. #ifdef CONFIG_WIRELESS_EXT
  106. union iwreq_data wrqu;
  107. char *buf = kmalloc(128, gfp);
  108. if (buf) {
  109. sprintf(buf, "MLME-MICHAELMICFAILURE.indication("
  110. "keyid=%d %scast addr=%pM)", key_id,
  111. key_type == NL80211_KEYTYPE_GROUP ? "broad" : "uni",
  112. addr);
  113. memset(&wrqu, 0, sizeof(wrqu));
  114. wrqu.data.length = strlen(buf);
  115. wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
  116. kfree(buf);
  117. }
  118. #endif
  119. nl80211_michael_mic_failure(rdev, dev, addr, key_type, key_id, tsc, gfp);
  120. }
  121. EXPORT_SYMBOL(cfg80211_michael_mic_failure);