drv_callbacks.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  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)
  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. struct wpabuf *wps;
  149. wps = ieee802_11_vendor_ie_concat(ie, ielen,
  150. WPS_IE_VENDOR_TYPE);
  151. if (wps && wps_validate_assoc_req(wps) < 0) {
  152. hostapd_drv_sta_disassoc(hapd, sta->addr,
  153. WLAN_REASON_INVALID_IE);
  154. ap_free_sta(hapd, sta);
  155. wpabuf_free(wps);
  156. return -1;
  157. }
  158. wpabuf_free(wps);
  159. #endif /* CONFIG_WPS_STRICT */
  160. if (ie && ielen > 4 && ie[0] == 0xdd && ie[1] >= 4 &&
  161. os_memcmp(ie + 2, "\x00\x50\xf2\x04", 4) == 0) {
  162. sta->flags |= WLAN_STA_WPS;
  163. } else
  164. sta->flags |= WLAN_STA_MAYBE_WPS;
  165. }
  166. skip_wpa_check:
  167. new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0;
  168. sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC;
  169. wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC);
  170. hostapd_new_assoc_sta(hapd, sta, !new_assoc);
  171. ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
  172. #ifdef CONFIG_P2P
  173. p2p_group_notif_assoc(hapd->p2p_group, sta->addr,
  174. all_ies, all_ies_len);
  175. #endif /* CONFIG_P2P */
  176. return 0;
  177. }
  178. void hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr)
  179. {
  180. struct sta_info *sta;
  181. if (addr == NULL) {
  182. /*
  183. * This could potentially happen with unexpected event from the
  184. * driver wrapper. This was seen at least in one case where the
  185. * driver ended up reporting a station mode event while hostapd
  186. * was running, so better make sure we stop processing such an
  187. * event here.
  188. */
  189. wpa_printf(MSG_DEBUG, "hostapd_notif_disassoc: Skip event "
  190. "with no address");
  191. return;
  192. }
  193. hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
  194. HOSTAPD_LEVEL_INFO, "disassociated");
  195. sta = ap_get_sta(hapd, addr);
  196. if (sta == NULL) {
  197. wpa_printf(MSG_DEBUG, "Disassociation notification for "
  198. "unknown STA " MACSTR, MAC2STR(addr));
  199. return;
  200. }
  201. sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
  202. wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED MACSTR,
  203. MAC2STR(sta->addr));
  204. wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
  205. sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
  206. ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
  207. ap_free_sta(hapd, sta);
  208. }
  209. void hostapd_event_sta_low_ack(struct hostapd_data *hapd, const u8 *addr)
  210. {
  211. struct sta_info *sta = ap_get_sta(hapd, addr);
  212. if (!sta || !hapd->conf->disassoc_low_ack)
  213. return;
  214. hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
  215. HOSTAPD_LEVEL_INFO, "disconnected due to excessive "
  216. "missing ACKs");
  217. hostapd_drv_sta_disassoc(hapd, addr, WLAN_REASON_DISASSOC_LOW_ACK);
  218. if (sta)
  219. ap_sta_disassociate(hapd, sta, WLAN_REASON_DISASSOC_LOW_ACK);
  220. }
  221. int hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa,
  222. const u8 *ie, size_t ie_len)
  223. {
  224. size_t i;
  225. int ret = 0;
  226. if (sa)
  227. random_add_randomness(sa, ETH_ALEN);
  228. for (i = 0; hapd->probereq_cb && i < hapd->num_probereq_cb; i++) {
  229. if (hapd->probereq_cb[i].cb(hapd->probereq_cb[i].ctx,
  230. sa, ie, ie_len) > 0) {
  231. ret = 1;
  232. break;
  233. }
  234. }
  235. return ret;
  236. }
  237. #ifdef HOSTAPD
  238. #ifdef NEED_AP_MLME
  239. static const u8 * get_hdr_bssid(const struct ieee80211_hdr *hdr, size_t len)
  240. {
  241. u16 fc, type, stype;
  242. /*
  243. * PS-Poll frames are 16 bytes. All other frames are
  244. * 24 bytes or longer.
  245. */
  246. if (len < 16)
  247. return NULL;
  248. fc = le_to_host16(hdr->frame_control);
  249. type = WLAN_FC_GET_TYPE(fc);
  250. stype = WLAN_FC_GET_STYPE(fc);
  251. switch (type) {
  252. case WLAN_FC_TYPE_DATA:
  253. if (len < 24)
  254. return NULL;
  255. switch (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) {
  256. case WLAN_FC_FROMDS | WLAN_FC_TODS:
  257. case WLAN_FC_TODS:
  258. return hdr->addr1;
  259. case WLAN_FC_FROMDS:
  260. return hdr->addr2;
  261. default:
  262. return NULL;
  263. }
  264. case WLAN_FC_TYPE_CTRL:
  265. if (stype != WLAN_FC_STYPE_PSPOLL)
  266. return NULL;
  267. return hdr->addr1;
  268. case WLAN_FC_TYPE_MGMT:
  269. return hdr->addr3;
  270. default:
  271. return NULL;
  272. }
  273. }
  274. #define HAPD_BROADCAST ((struct hostapd_data *) -1)
  275. static struct hostapd_data * get_hapd_bssid(struct hostapd_iface *iface,
  276. const u8 *bssid)
  277. {
  278. size_t i;
  279. if (bssid == NULL)
  280. return NULL;
  281. if (bssid[0] == 0xff && bssid[1] == 0xff && bssid[2] == 0xff &&
  282. bssid[3] == 0xff && bssid[4] == 0xff && bssid[5] == 0xff)
  283. return HAPD_BROADCAST;
  284. for (i = 0; i < iface->num_bss; i++) {
  285. if (os_memcmp(bssid, iface->bss[i]->own_addr, ETH_ALEN) == 0)
  286. return iface->bss[i];
  287. }
  288. return NULL;
  289. }
  290. static void hostapd_rx_from_unknown_sta(struct hostapd_data *hapd,
  291. const u8 *frame, size_t len)
  292. {
  293. const struct ieee80211_hdr *hdr = (const struct ieee80211_hdr *) frame;
  294. u16 fc = le_to_host16(hdr->frame_control);
  295. hapd = get_hapd_bssid(hapd->iface, get_hdr_bssid(hdr, len));
  296. if (hapd == NULL || hapd == HAPD_BROADCAST)
  297. return;
  298. ieee802_11_rx_from_unknown(hapd, hdr->addr2,
  299. (fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) ==
  300. (WLAN_FC_TODS | WLAN_FC_FROMDS));
  301. }
  302. static void hostapd_mgmt_rx(struct hostapd_data *hapd, struct rx_mgmt *rx_mgmt)
  303. {
  304. struct hostapd_iface *iface = hapd->iface;
  305. const struct ieee80211_hdr *hdr;
  306. const u8 *bssid;
  307. struct hostapd_frame_info fi;
  308. hdr = (const struct ieee80211_hdr *) rx_mgmt->frame;
  309. bssid = get_hdr_bssid(hdr, rx_mgmt->frame_len);
  310. if (bssid == NULL)
  311. return;
  312. hapd = get_hapd_bssid(iface, bssid);
  313. if (hapd == NULL) {
  314. u16 fc;
  315. fc = le_to_host16(hdr->frame_control);
  316. /*
  317. * Drop frames to unknown BSSIDs except for Beacon frames which
  318. * could be used to update neighbor information.
  319. */
  320. if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
  321. WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON)
  322. hapd = iface->bss[0];
  323. else
  324. return;
  325. }
  326. os_memset(&fi, 0, sizeof(fi));
  327. fi.datarate = rx_mgmt->datarate;
  328. fi.ssi_signal = rx_mgmt->ssi_signal;
  329. if (hapd == HAPD_BROADCAST) {
  330. size_t i;
  331. for (i = 0; i < iface->num_bss; i++)
  332. ieee802_11_mgmt(iface->bss[i], rx_mgmt->frame,
  333. rx_mgmt->frame_len, &fi);
  334. } else
  335. ieee802_11_mgmt(hapd, rx_mgmt->frame, rx_mgmt->frame_len, &fi);
  336. random_add_randomness(&fi, sizeof(fi));
  337. }
  338. static void hostapd_mgmt_tx_cb(struct hostapd_data *hapd, const u8 *buf,
  339. size_t len, u16 stype, int ok)
  340. {
  341. struct ieee80211_hdr *hdr;
  342. hdr = (struct ieee80211_hdr *) buf;
  343. hapd = get_hapd_bssid(hapd->iface, get_hdr_bssid(hdr, len));
  344. if (hapd == NULL || hapd == HAPD_BROADCAST)
  345. return;
  346. ieee802_11_mgmt_cb(hapd, buf, len, stype, ok);
  347. }
  348. #endif /* NEED_AP_MLME */
  349. static int hostapd_event_new_sta(struct hostapd_data *hapd, const u8 *addr)
  350. {
  351. struct sta_info *sta = ap_get_sta(hapd, addr);
  352. if (sta)
  353. return 0;
  354. wpa_printf(MSG_DEBUG, "Data frame from unknown STA " MACSTR
  355. " - adding a new STA", MAC2STR(addr));
  356. sta = ap_sta_add(hapd, addr);
  357. if (sta) {
  358. hostapd_new_assoc_sta(hapd, sta, 0);
  359. } else {
  360. wpa_printf(MSG_DEBUG, "Failed to add STA entry for " MACSTR,
  361. MAC2STR(addr));
  362. return -1;
  363. }
  364. return 0;
  365. }
  366. static void hostapd_event_eapol_rx(struct hostapd_data *hapd, const u8 *src,
  367. const u8 *data, size_t data_len)
  368. {
  369. struct hostapd_iface *iface = hapd->iface;
  370. size_t j;
  371. for (j = 0; j < iface->num_bss; j++) {
  372. if (ap_get_sta(iface->bss[j], src)) {
  373. hapd = iface->bss[j];
  374. break;
  375. }
  376. }
  377. ieee802_1x_receive(hapd, src, data, data_len);
  378. }
  379. void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
  380. union wpa_event_data *data)
  381. {
  382. struct hostapd_data *hapd = ctx;
  383. switch (event) {
  384. case EVENT_MICHAEL_MIC_FAILURE:
  385. michael_mic_failure(hapd, data->michael_mic_failure.src, 1);
  386. break;
  387. case EVENT_SCAN_RESULTS:
  388. if (hapd->iface->scan_cb)
  389. hapd->iface->scan_cb(hapd->iface);
  390. break;
  391. #ifdef CONFIG_IEEE80211R
  392. case EVENT_FT_RRB_RX:
  393. wpa_ft_rrb_rx(hapd->wpa_auth, data->ft_rrb_rx.src,
  394. data->ft_rrb_rx.data, data->ft_rrb_rx.data_len);
  395. break;
  396. #endif /* CONFIG_IEEE80211R */
  397. case EVENT_WPS_BUTTON_PUSHED:
  398. hostapd_wps_button_pushed(hapd, NULL);
  399. break;
  400. #ifdef NEED_AP_MLME
  401. case EVENT_TX_STATUS:
  402. switch (data->tx_status.type) {
  403. case WLAN_FC_TYPE_MGMT:
  404. hostapd_mgmt_tx_cb(hapd, data->tx_status.data,
  405. data->tx_status.data_len,
  406. data->tx_status.stype,
  407. data->tx_status.ack);
  408. break;
  409. case WLAN_FC_TYPE_DATA:
  410. hostapd_tx_status(hapd, data->tx_status.dst,
  411. data->tx_status.data,
  412. data->tx_status.data_len,
  413. data->tx_status.ack);
  414. break;
  415. }
  416. break;
  417. case EVENT_RX_FROM_UNKNOWN:
  418. hostapd_rx_from_unknown_sta(hapd, data->rx_from_unknown.frame,
  419. data->rx_from_unknown.len);
  420. break;
  421. case EVENT_RX_MGMT:
  422. hostapd_mgmt_rx(hapd, &data->rx_mgmt);
  423. break;
  424. #endif /* NEED_AP_MLME */
  425. case EVENT_RX_PROBE_REQ:
  426. hostapd_probe_req_rx(hapd, data->rx_probe_req.sa,
  427. data->rx_probe_req.ie,
  428. data->rx_probe_req.ie_len);
  429. break;
  430. case EVENT_NEW_STA:
  431. hostapd_event_new_sta(hapd, data->new_sta.addr);
  432. break;
  433. case EVENT_EAPOL_RX:
  434. hostapd_event_eapol_rx(hapd, data->eapol_rx.src,
  435. data->eapol_rx.data,
  436. data->eapol_rx.data_len);
  437. break;
  438. case EVENT_ASSOC:
  439. hostapd_notif_assoc(hapd, data->assoc_info.addr,
  440. data->assoc_info.req_ies,
  441. data->assoc_info.req_ies_len);
  442. break;
  443. case EVENT_DISASSOC:
  444. if (data)
  445. hostapd_notif_disassoc(hapd, data->disassoc_info.addr);
  446. break;
  447. case EVENT_DEAUTH:
  448. if (data)
  449. hostapd_notif_disassoc(hapd, data->deauth_info.addr);
  450. break;
  451. case EVENT_STATION_LOW_ACK:
  452. if (!data)
  453. break;
  454. hostapd_event_sta_low_ack(hapd, data->low_ack.addr);
  455. break;
  456. default:
  457. wpa_printf(MSG_DEBUG, "Unknown event %d", event);
  458. break;
  459. }
  460. }
  461. #endif /* HOSTAPD */