You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

drv_callbacks.c 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539
  1. /*
  2. * hostapd / Callback functions for driver wrappers
  3. * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation.
  8. *
  9. * Alternatively, this software may be distributed under the terms of BSD
  10. * license.
  11. *
  12. * See README and COPYING for more details.
  13. */
  14. #include "utils/includes.h"
  15. #include "utils/common.h"
  16. #include "radius/radius.h"
  17. #include "drivers/driver.h"
  18. #include "common/ieee802_11_defs.h"
  19. #include "common/ieee802_11_common.h"
  20. #include "common/wpa_ctrl.h"
  21. #include "crypto/random.h"
  22. #include "p2p/p2p.h"
  23. #include "wps/wps.h"
  24. #include "hostapd.h"
  25. #include "ieee802_11.h"
  26. #include "sta_info.h"
  27. #include "accounting.h"
  28. #include "tkip_countermeasures.h"
  29. #include "iapp.h"
  30. #include "ieee802_1x.h"
  31. #include "wpa_auth.h"
  32. #include "wmm.h"
  33. #include "wps_hostapd.h"
  34. #include "ap_drv_ops.h"
  35. #include "ap_config.h"
  36. int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr,
  37. const u8 *ie, size_t ielen, int reassoc)
  38. {
  39. struct sta_info *sta;
  40. int new_assoc, res;
  41. struct ieee802_11_elems elems;
  42. #ifdef CONFIG_P2P
  43. const u8 *all_ies = ie;
  44. size_t all_ies_len = ielen;
  45. #endif /* CONFIG_P2P */
  46. if (addr == NULL) {
  47. /*
  48. * This could potentially happen with unexpected event from the
  49. * driver wrapper. This was seen at least in one case where the
  50. * driver ended up being set to station mode while hostapd was
  51. * running, so better make sure we stop processing such an
  52. * event here.
  53. */
  54. wpa_printf(MSG_DEBUG, "hostapd_notif_assoc: Skip event with "
  55. "no address");
  56. return -1;
  57. }
  58. random_add_randomness(addr, ETH_ALEN);
  59. hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
  60. HOSTAPD_LEVEL_INFO, "associated");
  61. ieee802_11_parse_elems(ie, ielen, &elems, 0);
  62. if (elems.wps_ie) {
  63. ie = elems.wps_ie - 2;
  64. ielen = elems.wps_ie_len + 2;
  65. wpa_printf(MSG_DEBUG, "STA included WPS IE in (Re)AssocReq");
  66. } else if (elems.rsn_ie) {
  67. ie = elems.rsn_ie - 2;
  68. ielen = elems.rsn_ie_len + 2;
  69. wpa_printf(MSG_DEBUG, "STA included RSN IE in (Re)AssocReq");
  70. } else if (elems.wpa_ie) {
  71. ie = elems.wpa_ie - 2;
  72. ielen = elems.wpa_ie_len + 2;
  73. wpa_printf(MSG_DEBUG, "STA included WPA IE in (Re)AssocReq");
  74. } else {
  75. ie = NULL;
  76. ielen = 0;
  77. wpa_printf(MSG_DEBUG, "STA did not include WPS/RSN/WPA IE in "
  78. "(Re)AssocReq");
  79. }
  80. sta = ap_get_sta(hapd, addr);
  81. if (sta) {
  82. accounting_sta_stop(hapd, sta);
  83. } else {
  84. sta = ap_sta_add(hapd, addr);
  85. if (sta == NULL)
  86. return -1;
  87. }
  88. sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS);
  89. #ifdef CONFIG_P2P
  90. if (elems.p2p) {
  91. wpabuf_free(sta->p2p_ie);
  92. sta->p2p_ie = ieee802_11_vendor_ie_concat(all_ies, all_ies_len,
  93. P2P_IE_VENDOR_TYPE);
  94. }
  95. #endif /* CONFIG_P2P */
  96. if (hapd->conf->wpa) {
  97. if (ie == NULL || ielen == 0) {
  98. if (hapd->conf->wps_state) {
  99. wpa_printf(MSG_DEBUG, "STA did not include "
  100. "WPA/RSN IE in (Re)Association "
  101. "Request - possible WPS use");
  102. sta->flags |= WLAN_STA_MAYBE_WPS;
  103. goto skip_wpa_check;
  104. }
  105. wpa_printf(MSG_DEBUG, "No WPA/RSN IE from STA");
  106. return -1;
  107. }
  108. if (hapd->conf->wps_state && ie[0] == 0xdd && ie[1] >= 4 &&
  109. os_memcmp(ie + 2, "\x00\x50\xf2\x04", 4) == 0) {
  110. sta->flags |= WLAN_STA_WPS;
  111. goto skip_wpa_check;
  112. }
  113. if (sta->wpa_sm == NULL)
  114. sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
  115. sta->addr);
  116. if (sta->wpa_sm == NULL) {
  117. wpa_printf(MSG_ERROR, "Failed to initialize WPA state "
  118. "machine");
  119. return -1;
  120. }
  121. res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
  122. ie, ielen, NULL, 0);
  123. if (res != WPA_IE_OK) {
  124. int resp;
  125. wpa_printf(MSG_DEBUG, "WPA/RSN information element "
  126. "rejected? (res %u)", res);
  127. wpa_hexdump(MSG_DEBUG, "IE", ie, ielen);
  128. if (res == WPA_INVALID_GROUP)
  129. resp = WLAN_REASON_GROUP_CIPHER_NOT_VALID;
  130. else if (res == WPA_INVALID_PAIRWISE)
  131. resp = WLAN_REASON_PAIRWISE_CIPHER_NOT_VALID;
  132. else if (res == WPA_INVALID_AKMP)
  133. resp = WLAN_REASON_AKMP_NOT_VALID;
  134. #ifdef CONFIG_IEEE80211W
  135. else if (res == WPA_MGMT_FRAME_PROTECTION_VIOLATION)
  136. resp = WLAN_REASON_INVALID_IE;
  137. else if (res == WPA_INVALID_MGMT_GROUP_CIPHER)
  138. resp = WLAN_REASON_GROUP_CIPHER_NOT_VALID;
  139. #endif /* CONFIG_IEEE80211W */
  140. else
  141. resp = WLAN_REASON_INVALID_IE;
  142. hostapd_drv_sta_disassoc(hapd, sta->addr, resp);
  143. ap_free_sta(hapd, sta);
  144. return -1;
  145. }
  146. } else if (hapd->conf->wps_state) {
  147. #ifdef CONFIG_WPS_STRICT
  148. if (ie) {
  149. struct wpabuf *wps;
  150. wps = ieee802_11_vendor_ie_concat(ie, ielen,
  151. WPS_IE_VENDOR_TYPE);
  152. if (wps && wps_validate_assoc_req(wps) < 0) {
  153. hostapd_drv_sta_disassoc(
  154. hapd, sta->addr,
  155. WLAN_REASON_INVALID_IE);
  156. ap_free_sta(hapd, sta);
  157. wpabuf_free(wps);
  158. return -1;
  159. }
  160. wpabuf_free(wps);
  161. }
  162. #endif /* CONFIG_WPS_STRICT */
  163. if (ie && ielen > 4 && ie[0] == 0xdd && ie[1] >= 4 &&
  164. os_memcmp(ie + 2, "\x00\x50\xf2\x04", 4) == 0) {
  165. sta->flags |= WLAN_STA_WPS;
  166. } else
  167. sta->flags |= WLAN_STA_MAYBE_WPS;
  168. }
  169. skip_wpa_check:
  170. new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0;
  171. sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC;
  172. wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC);
  173. hostapd_new_assoc_sta(hapd, sta, !new_assoc);
  174. ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
  175. #ifdef CONFIG_P2P
  176. p2p_group_notif_assoc(hapd->p2p_group, sta->addr,
  177. all_ies, all_ies_len);
  178. #endif /* CONFIG_P2P */
  179. return 0;
  180. }
  181. void hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr)
  182. {
  183. struct sta_info *sta;
  184. if (addr == NULL) {
  185. /*
  186. * This could potentially happen with unexpected event from the
  187. * driver wrapper. This was seen at least in one case where the
  188. * driver ended up reporting a station mode event while hostapd
  189. * was running, so better make sure we stop processing such an
  190. * event here.
  191. */
  192. wpa_printf(MSG_DEBUG, "hostapd_notif_disassoc: Skip event "
  193. "with no address");
  194. return;
  195. }
  196. hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
  197. HOSTAPD_LEVEL_INFO, "disassociated");
  198. sta = ap_get_sta(hapd, addr);
  199. if (sta == NULL) {
  200. wpa_printf(MSG_DEBUG, "Disassociation notification for "
  201. "unknown STA " MACSTR, MAC2STR(addr));
  202. return;
  203. }
  204. sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
  205. wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED MACSTR,
  206. MAC2STR(sta->addr));
  207. wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
  208. sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
  209. ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
  210. ap_free_sta(hapd, sta);
  211. }
  212. void hostapd_event_sta_low_ack(struct hostapd_data *hapd, const u8 *addr)
  213. {
  214. struct sta_info *sta = ap_get_sta(hapd, addr);
  215. if (!sta || !hapd->conf->disassoc_low_ack)
  216. return;
  217. hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
  218. HOSTAPD_LEVEL_INFO, "disconnected due to excessive "
  219. "missing ACKs");
  220. hostapd_drv_sta_disassoc(hapd, addr, WLAN_REASON_DISASSOC_LOW_ACK);
  221. if (sta)
  222. ap_sta_disassociate(hapd, sta, WLAN_REASON_DISASSOC_LOW_ACK);
  223. }
  224. int hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa,
  225. const u8 *ie, size_t ie_len)
  226. {
  227. size_t i;
  228. int ret = 0;
  229. if (sa == NULL || ie == NULL)
  230. return -1;
  231. random_add_randomness(sa, ETH_ALEN);
  232. for (i = 0; hapd->probereq_cb && i < hapd->num_probereq_cb; i++) {
  233. if (hapd->probereq_cb[i].cb(hapd->probereq_cb[i].ctx,
  234. sa, ie, ie_len) > 0) {
  235. ret = 1;
  236. break;
  237. }
  238. }
  239. return ret;
  240. }
  241. #ifdef HOSTAPD
  242. #ifdef NEED_AP_MLME
  243. static const u8 * get_hdr_bssid(const struct ieee80211_hdr *hdr, size_t len)
  244. {
  245. u16 fc, type, stype;
  246. /*
  247. * PS-Poll frames are 16 bytes. All other frames are
  248. * 24 bytes or longer.
  249. */
  250. if (len < 16)
  251. return NULL;
  252. fc = le_to_host16(hdr->frame_control);
  253. type = WLAN_FC_GET_TYPE(fc);
  254. stype = WLAN_FC_GET_STYPE(fc);
  255. switch (type) {
  256. case WLAN_FC_TYPE_DATA:
  257. if (len < 24)
  258. return NULL;
  259. switch (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) {
  260. case WLAN_FC_FROMDS | WLAN_FC_TODS:
  261. case WLAN_FC_TODS:
  262. return hdr->addr1;
  263. case WLAN_FC_FROMDS:
  264. return hdr->addr2;
  265. default:
  266. return NULL;
  267. }
  268. case WLAN_FC_TYPE_CTRL:
  269. if (stype != WLAN_FC_STYPE_PSPOLL)
  270. return NULL;
  271. return hdr->addr1;
  272. case WLAN_FC_TYPE_MGMT:
  273. return hdr->addr3;
  274. default:
  275. return NULL;
  276. }
  277. }
  278. #define HAPD_BROADCAST ((struct hostapd_data *) -1)
  279. static struct hostapd_data * get_hapd_bssid(struct hostapd_iface *iface,
  280. const u8 *bssid)
  281. {
  282. size_t i;
  283. if (bssid == NULL)
  284. return NULL;
  285. if (bssid[0] == 0xff && bssid[1] == 0xff && bssid[2] == 0xff &&
  286. bssid[3] == 0xff && bssid[4] == 0xff && bssid[5] == 0xff)
  287. return HAPD_BROADCAST;
  288. for (i = 0; i < iface->num_bss; i++) {
  289. if (os_memcmp(bssid, iface->bss[i]->own_addr, ETH_ALEN) == 0)
  290. return iface->bss[i];
  291. }
  292. return NULL;
  293. }
  294. static void hostapd_rx_from_unknown_sta(struct hostapd_data *hapd,
  295. const u8 *frame, size_t len)
  296. {
  297. const struct ieee80211_hdr *hdr = (const struct ieee80211_hdr *) frame;
  298. u16 fc = le_to_host16(hdr->frame_control);
  299. hapd = get_hapd_bssid(hapd->iface, get_hdr_bssid(hdr, len));
  300. if (hapd == NULL || hapd == HAPD_BROADCAST)
  301. return;
  302. ieee802_11_rx_from_unknown(hapd, hdr->addr2,
  303. (fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) ==
  304. (WLAN_FC_TODS | WLAN_FC_FROMDS));
  305. }
  306. static void hostapd_mgmt_rx(struct hostapd_data *hapd, struct rx_mgmt *rx_mgmt)
  307. {
  308. struct hostapd_iface *iface = hapd->iface;
  309. const struct ieee80211_hdr *hdr;
  310. const u8 *bssid;
  311. struct hostapd_frame_info fi;
  312. hdr = (const struct ieee80211_hdr *) rx_mgmt->frame;
  313. bssid = get_hdr_bssid(hdr, rx_mgmt->frame_len);
  314. if (bssid == NULL)
  315. return;
  316. hapd = get_hapd_bssid(iface, bssid);
  317. if (hapd == NULL) {
  318. u16 fc;
  319. fc = le_to_host16(hdr->frame_control);
  320. /*
  321. * Drop frames to unknown BSSIDs except for Beacon frames which
  322. * could be used to update neighbor information.
  323. */
  324. if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
  325. WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON)
  326. hapd = iface->bss[0];
  327. else
  328. return;
  329. }
  330. os_memset(&fi, 0, sizeof(fi));
  331. fi.datarate = rx_mgmt->datarate;
  332. fi.ssi_signal = rx_mgmt->ssi_signal;
  333. if (hapd == HAPD_BROADCAST) {
  334. size_t i;
  335. for (i = 0; i < iface->num_bss; i++)
  336. ieee802_11_mgmt(iface->bss[i], rx_mgmt->frame,
  337. rx_mgmt->frame_len, &fi);
  338. } else
  339. ieee802_11_mgmt(hapd, rx_mgmt->frame, rx_mgmt->frame_len, &fi);
  340. random_add_randomness(&fi, sizeof(fi));
  341. }
  342. static void hostapd_mgmt_tx_cb(struct hostapd_data *hapd, const u8 *buf,
  343. size_t len, u16 stype, int ok)
  344. {
  345. struct ieee80211_hdr *hdr;
  346. hdr = (struct ieee80211_hdr *) buf;
  347. hapd = get_hapd_bssid(hapd->iface, get_hdr_bssid(hdr, len));
  348. if (hapd == NULL || hapd == HAPD_BROADCAST)
  349. return;
  350. ieee802_11_mgmt_cb(hapd, buf, len, stype, ok);
  351. }
  352. #endif /* NEED_AP_MLME */
  353. static int hostapd_event_new_sta(struct hostapd_data *hapd, const u8 *addr)
  354. {
  355. struct sta_info *sta = ap_get_sta(hapd, addr);
  356. if (sta)
  357. return 0;
  358. wpa_printf(MSG_DEBUG, "Data frame from unknown STA " MACSTR
  359. " - adding a new STA", MAC2STR(addr));
  360. sta = ap_sta_add(hapd, addr);
  361. if (sta) {
  362. hostapd_new_assoc_sta(hapd, sta, 0);
  363. } else {
  364. wpa_printf(MSG_DEBUG, "Failed to add STA entry for " MACSTR,
  365. MAC2STR(addr));
  366. return -1;
  367. }
  368. return 0;
  369. }
  370. static void hostapd_event_eapol_rx(struct hostapd_data *hapd, const u8 *src,
  371. const u8 *data, size_t data_len)
  372. {
  373. struct hostapd_iface *iface = hapd->iface;
  374. size_t j;
  375. for (j = 0; j < iface->num_bss; j++) {
  376. if (ap_get_sta(iface->bss[j], src)) {
  377. hapd = iface->bss[j];
  378. break;
  379. }
  380. }
  381. ieee802_1x_receive(hapd, src, data, data_len);
  382. }
  383. void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
  384. union wpa_event_data *data)
  385. {
  386. struct hostapd_data *hapd = ctx;
  387. switch (event) {
  388. case EVENT_MICHAEL_MIC_FAILURE:
  389. michael_mic_failure(hapd, data->michael_mic_failure.src, 1);
  390. break;
  391. case EVENT_SCAN_RESULTS:
  392. if (hapd->iface->scan_cb)
  393. hapd->iface->scan_cb(hapd->iface);
  394. break;
  395. #ifdef CONFIG_IEEE80211R
  396. case EVENT_FT_RRB_RX:
  397. wpa_ft_rrb_rx(hapd->wpa_auth, data->ft_rrb_rx.src,
  398. data->ft_rrb_rx.data, data->ft_rrb_rx.data_len);
  399. break;
  400. #endif /* CONFIG_IEEE80211R */
  401. case EVENT_WPS_BUTTON_PUSHED:
  402. hostapd_wps_button_pushed(hapd, NULL);
  403. break;
  404. #ifdef NEED_AP_MLME
  405. case EVENT_TX_STATUS:
  406. switch (data->tx_status.type) {
  407. case WLAN_FC_TYPE_MGMT:
  408. hostapd_mgmt_tx_cb(hapd, data->tx_status.data,
  409. data->tx_status.data_len,
  410. data->tx_status.stype,
  411. data->tx_status.ack);
  412. break;
  413. case WLAN_FC_TYPE_DATA:
  414. hostapd_tx_status(hapd, data->tx_status.dst,
  415. data->tx_status.data,
  416. data->tx_status.data_len,
  417. data->tx_status.ack);
  418. break;
  419. }
  420. break;
  421. case EVENT_RX_FROM_UNKNOWN:
  422. hostapd_rx_from_unknown_sta(hapd, data->rx_from_unknown.frame,
  423. data->rx_from_unknown.len);
  424. break;
  425. case EVENT_RX_MGMT:
  426. hostapd_mgmt_rx(hapd, &data->rx_mgmt);
  427. break;
  428. #endif /* NEED_AP_MLME */
  429. case EVENT_RX_PROBE_REQ:
  430. if (data->rx_probe_req.sa == NULL ||
  431. data->rx_probe_req.ie == NULL)
  432. break;
  433. hostapd_probe_req_rx(hapd, data->rx_probe_req.sa,
  434. data->rx_probe_req.ie,
  435. data->rx_probe_req.ie_len);
  436. break;
  437. case EVENT_NEW_STA:
  438. hostapd_event_new_sta(hapd, data->new_sta.addr);
  439. break;
  440. case EVENT_EAPOL_RX:
  441. hostapd_event_eapol_rx(hapd, data->eapol_rx.src,
  442. data->eapol_rx.data,
  443. data->eapol_rx.data_len);
  444. break;
  445. case EVENT_ASSOC:
  446. hostapd_notif_assoc(hapd, data->assoc_info.addr,
  447. data->assoc_info.req_ies,
  448. data->assoc_info.req_ies_len,
  449. data->assoc_info.reassoc);
  450. break;
  451. case EVENT_DISASSOC:
  452. if (data)
  453. hostapd_notif_disassoc(hapd, data->disassoc_info.addr);
  454. break;
  455. case EVENT_DEAUTH:
  456. if (data)
  457. hostapd_notif_disassoc(hapd, data->deauth_info.addr);
  458. break;
  459. case EVENT_STATION_LOW_ACK:
  460. if (!data)
  461. break;
  462. hostapd_event_sta_low_ack(hapd, data->low_ack.addr);
  463. break;
  464. default:
  465. wpa_printf(MSG_DEBUG, "Unknown event %d", event);
  466. break;
  467. }
  468. }
  469. #endif /* HOSTAPD */