rx_data.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
  1. /*
  2. * Received Data frame processing
  3. * Copyright (c) 2010, 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 "crypto/aes_wrap.h"
  17. #include "crypto/crypto.h"
  18. #include "common/ieee802_11_defs.h"
  19. #include "common/eapol_common.h"
  20. #include "common/wpa_common.h"
  21. #include "wlantest.h"
  22. static const char * data_stype(u16 stype)
  23. {
  24. switch (stype) {
  25. case WLAN_FC_STYPE_DATA:
  26. return "DATA";
  27. case WLAN_FC_STYPE_DATA_CFACK:
  28. return "DATA-CFACK";
  29. case WLAN_FC_STYPE_DATA_CFPOLL:
  30. return "DATA-CFPOLL";
  31. case WLAN_FC_STYPE_DATA_CFACKPOLL:
  32. return "DATA-CFACKPOLL";
  33. case WLAN_FC_STYPE_NULLFUNC:
  34. return "NULLFUNC";
  35. case WLAN_FC_STYPE_CFACK:
  36. return "CFACK";
  37. case WLAN_FC_STYPE_CFPOLL:
  38. return "CFPOLL";
  39. case WLAN_FC_STYPE_CFACKPOLL:
  40. return "CFACKPOLL";
  41. case WLAN_FC_STYPE_QOS_DATA:
  42. return "QOSDATA";
  43. case WLAN_FC_STYPE_QOS_DATA_CFACK:
  44. return "QOSDATA-CFACK";
  45. case WLAN_FC_STYPE_QOS_DATA_CFPOLL:
  46. return "QOSDATA-CFPOLL";
  47. case WLAN_FC_STYPE_QOS_DATA_CFACKPOLL:
  48. return "QOSDATA-CFACKPOLL";
  49. case WLAN_FC_STYPE_QOS_NULL:
  50. return "QOS-NULL";
  51. case WLAN_FC_STYPE_QOS_CFPOLL:
  52. return "QOS-CFPOLL";
  53. case WLAN_FC_STYPE_QOS_CFACKPOLL:
  54. return "QOS-CFACKPOLL";
  55. }
  56. return "??";
  57. }
  58. static int check_mic(const u8 *kck, int ver, const u8 *data, size_t len)
  59. {
  60. u8 *buf;
  61. int ret = -1;
  62. struct ieee802_1x_hdr *hdr;
  63. struct wpa_eapol_key *key;
  64. u8 rx_mic[16];
  65. buf = os_malloc(len);
  66. if (buf == NULL)
  67. return -1;
  68. os_memcpy(buf, data, len);
  69. hdr = (struct ieee802_1x_hdr *) buf;
  70. key = (struct wpa_eapol_key *) (hdr + 1);
  71. os_memcpy(rx_mic, key->key_mic, 16);
  72. os_memset(key->key_mic, 0, 16);
  73. if (wpa_eapol_key_mic(kck, ver, buf, len, key->key_mic) == 0 &&
  74. os_memcmp(rx_mic, key->key_mic, 16) == 0)
  75. ret = 0;
  76. os_free(buf);
  77. return ret;
  78. }
  79. static void rx_data_eapol_key_1_of_4(struct wlantest *wt, const u8 *dst,
  80. const u8 *src, const u8 *data, size_t len)
  81. {
  82. struct wlantest_bss *bss;
  83. struct wlantest_sta *sta;
  84. const struct ieee802_1x_hdr *eapol;
  85. const struct wpa_eapol_key *hdr;
  86. wpa_printf(MSG_DEBUG, "EAPOL-Key 1/4 " MACSTR " -> " MACSTR,
  87. MAC2STR(src), MAC2STR(dst));
  88. bss = bss_get(wt, src);
  89. if (bss == NULL)
  90. return;
  91. sta = sta_get(bss, dst);
  92. if (sta == NULL)
  93. return;
  94. eapol = (const struct ieee802_1x_hdr *) data;
  95. hdr = (const struct wpa_eapol_key *) (eapol + 1);
  96. os_memcpy(sta->anonce, hdr->key_nonce, WPA_NONCE_LEN);
  97. }
  98. static int try_pmk(struct wlantest_bss *bss, struct wlantest_sta *sta,
  99. u16 ver, const u8 *data, size_t len,
  100. struct wlantest_pmk *pmk)
  101. {
  102. struct wpa_ptk ptk;
  103. size_t ptk_len = 48; /* FIX: 64 for TKIP */
  104. wpa_pmk_to_ptk(pmk->pmk, sizeof(pmk->pmk),
  105. "Pairwise key expansion",
  106. bss->bssid, sta->addr, sta->anonce, sta->snonce,
  107. (u8 *) &ptk, ptk_len,
  108. 0 /* FIX: SHA256 based on AKM */);
  109. if (check_mic(ptk.kck, ver,
  110. data, len) < 0)
  111. return -1;
  112. wpa_printf(MSG_INFO, "Derived PTK for STA " MACSTR " BSSID " MACSTR
  113. ")", MAC2STR(sta->addr), MAC2STR(bss->bssid));
  114. os_memcpy(&sta->ptk, &ptk, sizeof(ptk));
  115. sta->ptk_set = 1;
  116. return 0;
  117. }
  118. static void derive_ptk(struct wlantest *wt, struct wlantest_bss *bss,
  119. struct wlantest_sta *sta, u16 ver,
  120. const u8 *data, size_t len)
  121. {
  122. struct wlantest_pmk *pmk;
  123. dl_list_for_each(pmk, &bss->pmk, struct wlantest_pmk, list) {
  124. if (try_pmk(bss, sta, ver, data, len, pmk) == 0)
  125. return;
  126. }
  127. dl_list_for_each(pmk, &wt->pmk, struct wlantest_pmk, list) {
  128. if (try_pmk(bss, sta, ver, data, len, pmk) == 0)
  129. return;
  130. }
  131. }
  132. static void rx_data_eapol_key_2_of_4(struct wlantest *wt, const u8 *dst,
  133. const u8 *src, const u8 *data, size_t len)
  134. {
  135. struct wlantest_bss *bss;
  136. struct wlantest_sta *sta;
  137. const struct ieee802_1x_hdr *eapol;
  138. const struct wpa_eapol_key *hdr;
  139. u16 key_info;
  140. wpa_printf(MSG_DEBUG, "EAPOL-Key 2/4 " MACSTR " -> " MACSTR,
  141. MAC2STR(src), MAC2STR(dst));
  142. bss = bss_get(wt, dst);
  143. if (bss == NULL)
  144. return;
  145. sta = sta_get(bss, src);
  146. if (sta == NULL)
  147. return;
  148. eapol = (const struct ieee802_1x_hdr *) data;
  149. hdr = (const struct wpa_eapol_key *) (eapol + 1);
  150. os_memcpy(sta->snonce, hdr->key_nonce, WPA_NONCE_LEN);
  151. key_info = WPA_GET_BE16(hdr->key_info);
  152. derive_ptk(wt, bss, sta, key_info & WPA_KEY_INFO_TYPE_MASK, data, len);
  153. }
  154. static u8 * decrypt_eapol_key_data_rc4(const u8 *kek,
  155. const struct wpa_eapol_key *hdr,
  156. size_t *len)
  157. {
  158. u8 ek[32], *buf;
  159. u16 keydatalen = WPA_GET_BE16(hdr->key_data_length);
  160. buf = os_malloc(keydatalen);
  161. if (buf == NULL)
  162. return NULL;
  163. os_memcpy(ek, hdr->key_iv, 16);
  164. os_memcpy(ek + 16, kek, 16);
  165. os_memcpy(buf, hdr + 1, keydatalen);
  166. if (rc4_skip(ek, 32, 256, buf, keydatalen)) {
  167. wpa_printf(MSG_INFO, "RC4 failed");
  168. os_free(buf);
  169. return NULL;
  170. }
  171. *len = keydatalen;
  172. return buf;
  173. }
  174. static u8 * decrypt_eapol_key_data_aes(const u8 *kek,
  175. const struct wpa_eapol_key *hdr,
  176. size_t *len)
  177. {
  178. u8 *buf;
  179. u16 keydatalen = WPA_GET_BE16(hdr->key_data_length);
  180. if (keydatalen % 8) {
  181. wpa_printf(MSG_INFO, "Unsupported AES-WRAP len %d",
  182. keydatalen);
  183. return NULL;
  184. }
  185. keydatalen -= 8; /* AES-WRAP adds 8 bytes */
  186. buf = os_malloc(keydatalen);
  187. if (buf == NULL)
  188. return NULL;
  189. if (aes_unwrap(kek, keydatalen / 8, (u8 *) (hdr + 1), buf)) {
  190. os_free(buf);
  191. wpa_printf(MSG_INFO, "AES unwrap failed - "
  192. "could not decrypt EAPOL-Key key data");
  193. return NULL;
  194. }
  195. *len = keydatalen;
  196. return buf;
  197. }
  198. static u8 * decrypt_eapol_key_data(const u8 *kek, u16 ver,
  199. const struct wpa_eapol_key *hdr,
  200. size_t *len)
  201. {
  202. switch (ver) {
  203. case WPA_KEY_INFO_TYPE_HMAC_MD5_RC4:
  204. return decrypt_eapol_key_data_rc4(kek, hdr, len);
  205. case WPA_KEY_INFO_TYPE_HMAC_SHA1_AES:
  206. case WPA_KEY_INFO_TYPE_AES_128_CMAC:
  207. return decrypt_eapol_key_data_aes(kek, hdr, len);
  208. default:
  209. wpa_printf(MSG_INFO, "Unsupported EAPOL-Key Key Descriptor "
  210. "Version %u", ver);
  211. return NULL;
  212. }
  213. }
  214. static void rx_data_eapol_key_3_of_4(struct wlantest *wt, const u8 *dst,
  215. const u8 *src, const u8 *data, size_t len)
  216. {
  217. struct wlantest_bss *bss;
  218. struct wlantest_sta *sta;
  219. const struct ieee802_1x_hdr *eapol;
  220. const struct wpa_eapol_key *hdr;
  221. const u8 *key_data;
  222. int recalc = 0;
  223. u16 key_info, ver, key_data_len;
  224. u8 *decrypted;
  225. size_t decrypted_len = 0;
  226. wpa_printf(MSG_DEBUG, "EAPOL-Key 3/4 " MACSTR " -> " MACSTR,
  227. MAC2STR(src), MAC2STR(dst));
  228. bss = bss_get(wt, src);
  229. if (bss == NULL)
  230. return;
  231. sta = sta_get(bss, dst);
  232. if (sta == NULL)
  233. return;
  234. eapol = (const struct ieee802_1x_hdr *) data;
  235. hdr = (const struct wpa_eapol_key *) (eapol + 1);
  236. key_info = WPA_GET_BE16(hdr->key_info);
  237. key_data_len = WPA_GET_BE16(hdr->key_data_length);
  238. if (os_memcmp(sta->anonce, hdr->key_nonce, WPA_NONCE_LEN) != 0) {
  239. wpa_printf(MSG_INFO, "EAPOL-Key ANonce mismatch between 1/4 "
  240. "and 3/4");
  241. recalc = 1;
  242. }
  243. os_memcpy(sta->anonce, hdr->key_nonce, WPA_NONCE_LEN);
  244. if (recalc) {
  245. derive_ptk(wt, bss, sta, key_info & WPA_KEY_INFO_TYPE_MASK,
  246. data, len);
  247. }
  248. if (!sta->ptk_set) {
  249. wpa_printf(MSG_DEBUG, "No PTK known to process EAPOL-Key 3/4");
  250. return;
  251. }
  252. if (check_mic(sta->ptk.kck, key_info & WPA_KEY_INFO_TYPE_MASK,
  253. data, len) < 0) {
  254. wpa_printf(MSG_INFO, "Mismatch in EAPOL-Key 3/4 MIC");
  255. return;
  256. }
  257. wpa_printf(MSG_DEBUG, "Valid MIC found in EAPOL-Key 3/4");
  258. key_data = (const u8 *) (hdr + 1);
  259. /* TODO: handle WPA without EncrKeyData bit */
  260. if (!(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
  261. wpa_printf(MSG_INFO, "EAPOL-Key 3/4 without EncrKeyData bit");
  262. return;
  263. }
  264. ver = key_info & WPA_KEY_INFO_TYPE_MASK;
  265. decrypted = decrypt_eapol_key_data(sta->ptk.kek, ver, hdr,
  266. &decrypted_len);
  267. if (decrypted == NULL) {
  268. wpa_printf(MSG_INFO, "Failed to decrypt EAPOL-Key Key Data");
  269. return;
  270. }
  271. wpa_hexdump(MSG_DEBUG, "Decrypted EAPOL-Key Key Data",
  272. decrypted, decrypted_len);
  273. /* TODO: parse KDEs and store GTK, IGTK */
  274. os_free(decrypted);
  275. }
  276. static void rx_data_eapol_key_4_of_4(struct wlantest *wt, const u8 *dst,
  277. const u8 *src, const u8 *data, size_t len)
  278. {
  279. struct wlantest_bss *bss;
  280. struct wlantest_sta *sta;
  281. const struct ieee802_1x_hdr *eapol;
  282. const struct wpa_eapol_key *hdr;
  283. u16 key_info;
  284. wpa_printf(MSG_DEBUG, "EAPOL-Key 4/4 " MACSTR " -> " MACSTR,
  285. MAC2STR(src), MAC2STR(dst));
  286. bss = bss_get(wt, dst);
  287. if (bss == NULL)
  288. return;
  289. sta = sta_get(bss, src);
  290. if (sta == NULL)
  291. return;
  292. eapol = (const struct ieee802_1x_hdr *) data;
  293. hdr = (const struct wpa_eapol_key *) (eapol + 1);
  294. key_info = WPA_GET_BE16(hdr->key_info);
  295. if (!sta->ptk_set) {
  296. wpa_printf(MSG_DEBUG, "No PTK known to process EAPOL-Key 4/4");
  297. return;
  298. }
  299. if (sta->ptk_set &&
  300. check_mic(sta->ptk.kck, key_info & WPA_KEY_INFO_TYPE_MASK,
  301. data, len) < 0) {
  302. wpa_printf(MSG_INFO, "Mismatch in EAPOL-Key 4/4 MIC");
  303. return;
  304. }
  305. wpa_printf(MSG_DEBUG, "Valid MIC found in EAPOL-Key 4/4");
  306. }
  307. static void rx_data_eapol_key_1_of_2(struct wlantest *wt, const u8 *dst,
  308. const u8 *src, const u8 *data, size_t len)
  309. {
  310. wpa_printf(MSG_DEBUG, "EAPOL-Key 1/2 " MACSTR " -> " MACSTR,
  311. MAC2STR(src), MAC2STR(dst));
  312. }
  313. static void rx_data_eapol_key_2_of_2(struct wlantest *wt, const u8 *dst,
  314. const u8 *src, const u8 *data, size_t len)
  315. {
  316. wpa_printf(MSG_DEBUG, "EAPOL-Key 2/2 " MACSTR " -> " MACSTR,
  317. MAC2STR(src), MAC2STR(dst));
  318. }
  319. static void rx_data_eapol_key(struct wlantest *wt, const u8 *dst,
  320. const u8 *src, const u8 *data, size_t len,
  321. int prot)
  322. {
  323. const struct ieee802_1x_hdr *eapol;
  324. const struct wpa_eapol_key *hdr;
  325. const u8 *key_data;
  326. u16 key_info, key_length, ver, key_data_length;
  327. eapol = (const struct ieee802_1x_hdr *) data;
  328. hdr = (const struct wpa_eapol_key *) (eapol + 1);
  329. wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key",
  330. (const u8 *) hdr, len - sizeof(*eapol));
  331. if (len < sizeof(*hdr)) {
  332. wpa_printf(MSG_INFO, "Too short EAPOL-Key frame from " MACSTR,
  333. MAC2STR(src));
  334. return;
  335. }
  336. if (hdr->type == EAPOL_KEY_TYPE_RC4) {
  337. /* TODO: EAPOL-Key RC4 for WEP */
  338. return;
  339. }
  340. if (hdr->type != EAPOL_KEY_TYPE_RSN &&
  341. hdr->type != EAPOL_KEY_TYPE_WPA) {
  342. wpa_printf(MSG_DEBUG, "Unsupported EAPOL-Key type %u",
  343. hdr->type);
  344. return;
  345. }
  346. key_info = WPA_GET_BE16(hdr->key_info);
  347. key_length = WPA_GET_BE16(hdr->key_length);
  348. key_data_length = WPA_GET_BE16(hdr->key_data_length);
  349. key_data = (const u8 *) (hdr + 1);
  350. if (key_data + key_data_length > data + len) {
  351. wpa_printf(MSG_INFO, "Truncated EAPOL-Key from " MACSTR,
  352. MAC2STR(src));
  353. return;
  354. }
  355. if (key_data + key_data_length < data + len) {
  356. wpa_hexdump(MSG_DEBUG, "Extra data after EAPOL-Key Key Data "
  357. "field", key_data + key_data_length,
  358. data + len - key_data - key_data_length);
  359. }
  360. ver = key_info & WPA_KEY_INFO_TYPE_MASK;
  361. wpa_printf(MSG_DEBUG, "EAPOL-Key ver=%u %c idx=%u%s%s%s%s%s%s%s%s "
  362. "datalen=%u",
  363. ver, key_info & WPA_KEY_INFO_KEY_TYPE ? 'P' : 'G',
  364. (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
  365. WPA_KEY_INFO_KEY_INDEX_SHIFT,
  366. (key_info & WPA_KEY_INFO_INSTALL) ? " Install" : "",
  367. (key_info & WPA_KEY_INFO_ACK) ? " ACK" : "",
  368. (key_info & WPA_KEY_INFO_MIC) ? " MIC" : "",
  369. (key_info & WPA_KEY_INFO_SECURE) ? " Secure" : "",
  370. (key_info & WPA_KEY_INFO_ERROR) ? " Error" : "",
  371. (key_info & WPA_KEY_INFO_REQUEST) ? " Request" : "",
  372. (key_info & WPA_KEY_INFO_ENCR_KEY_DATA) ? " Encr" : "",
  373. (key_info & WPA_KEY_INFO_SMK_MESSAGE) ? " SMK" : "",
  374. key_data_length);
  375. if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 &&
  376. ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES &&
  377. ver != WPA_KEY_INFO_TYPE_AES_128_CMAC) {
  378. wpa_printf(MSG_DEBUG, "Unsupported EAPOL-Key Key Descriptor "
  379. "Version %u", ver);
  380. return;
  381. }
  382. wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Replay Counter",
  383. hdr->replay_counter, WPA_REPLAY_COUNTER_LEN);
  384. wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Nonce",
  385. hdr->key_nonce, WPA_NONCE_LEN);
  386. wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key IV",
  387. hdr->key_iv, 16);
  388. wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key RSC",
  389. hdr->key_nonce, WPA_KEY_RSC_LEN);
  390. wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key MIC",
  391. hdr->key_mic, 16);
  392. wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data",
  393. key_data, key_data_length);
  394. if (key_info & (WPA_KEY_INFO_ERROR | WPA_KEY_INFO_REQUEST))
  395. return;
  396. if (key_info & WPA_KEY_INFO_SMK_MESSAGE)
  397. return;
  398. if (key_info & WPA_KEY_INFO_KEY_TYPE) {
  399. /* 4-Way Handshake */
  400. switch (key_info & (WPA_KEY_INFO_SECURE |
  401. WPA_KEY_INFO_MIC |
  402. WPA_KEY_INFO_ACK |
  403. WPA_KEY_INFO_INSTALL)) {
  404. case WPA_KEY_INFO_ACK:
  405. rx_data_eapol_key_1_of_4(wt, dst, src, data, len);
  406. break;
  407. case WPA_KEY_INFO_MIC:
  408. rx_data_eapol_key_2_of_4(wt, dst, src, data, len);
  409. break;
  410. case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
  411. WPA_KEY_INFO_ACK | WPA_KEY_INFO_INSTALL:
  412. rx_data_eapol_key_3_of_4(wt, dst, src, data, len);
  413. break;
  414. case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC:
  415. rx_data_eapol_key_4_of_4(wt, dst, src, data, len);
  416. break;
  417. default:
  418. wpa_printf(MSG_DEBUG, "Unsupported EAPOL-Key frame");
  419. break;
  420. }
  421. } else {
  422. /* Group Key Handshake */
  423. switch (key_info & (WPA_KEY_INFO_SECURE |
  424. WPA_KEY_INFO_MIC |
  425. WPA_KEY_INFO_ACK)) {
  426. case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
  427. WPA_KEY_INFO_ACK:
  428. rx_data_eapol_key_1_of_2(wt, dst, src, data, len);
  429. break;
  430. case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC:
  431. rx_data_eapol_key_2_of_2(wt, dst, src, data, len);
  432. break;
  433. default:
  434. wpa_printf(MSG_DEBUG, "Unsupported EAPOL-Key frame");
  435. break;
  436. }
  437. }
  438. }
  439. static void rx_data_eapol(struct wlantest *wt, const u8 *dst, const u8 *src,
  440. const u8 *data, size_t len, int prot)
  441. {
  442. const struct ieee802_1x_hdr *hdr;
  443. u16 length;
  444. const u8 *p;
  445. wpa_hexdump(MSG_EXCESSIVE, "EAPOL", data, len);
  446. if (len < sizeof(*hdr)) {
  447. wpa_printf(MSG_INFO, "Too short EAPOL frame from " MACSTR,
  448. MAC2STR(src));
  449. return;
  450. }
  451. hdr = (const struct ieee802_1x_hdr *) data;
  452. length = be_to_host16(hdr->length);
  453. wpa_printf(MSG_DEBUG, "RX EAPOL: " MACSTR " -> " MACSTR "%s ver=%u "
  454. "type=%u len=%u",
  455. MAC2STR(src), MAC2STR(dst), prot ? " Prot" : "",
  456. hdr->version, hdr->type, length);
  457. if (sizeof(*hdr) + length > len) {
  458. wpa_printf(MSG_INFO, "Truncated EAPOL frame from " MACSTR,
  459. MAC2STR(src));
  460. return;
  461. }
  462. if (sizeof(*hdr) + length < len) {
  463. wpa_printf(MSG_INFO, "EAPOL frame with %d extra bytes",
  464. (int) (len - sizeof(*hdr) - length));
  465. }
  466. p = (const u8 *) (hdr + 1);
  467. switch (hdr->type) {
  468. case IEEE802_1X_TYPE_EAP_PACKET:
  469. wpa_hexdump(MSG_MSGDUMP, "EAPOL - EAP packet", p, length);
  470. break;
  471. case IEEE802_1X_TYPE_EAPOL_START:
  472. wpa_hexdump(MSG_MSGDUMP, "EAPOL-Start", p, length);
  473. break;
  474. case IEEE802_1X_TYPE_EAPOL_LOGOFF:
  475. wpa_hexdump(MSG_MSGDUMP, "EAPOL-Logoff", p, length);
  476. break;
  477. case IEEE802_1X_TYPE_EAPOL_KEY:
  478. rx_data_eapol_key(wt, dst, src, data, sizeof(*hdr) + length,
  479. prot);
  480. break;
  481. case IEEE802_1X_TYPE_EAPOL_ENCAPSULATED_ASF_ALERT:
  482. wpa_hexdump(MSG_MSGDUMP, "EAPOL - Encapsulated ASF alert",
  483. p, length);
  484. break;
  485. default:
  486. wpa_hexdump(MSG_MSGDUMP, "Unknown EAPOL payload", p, length);
  487. break;
  488. }
  489. }
  490. static void rx_data_eth(struct wlantest *wt, const u8 *dst, const u8 *src,
  491. u16 ethertype, const u8 *data, size_t len, int prot)
  492. {
  493. if (ethertype == ETH_P_PAE)
  494. rx_data_eapol(wt, dst, src, data, len, prot);
  495. }
  496. static void rx_data_process(struct wlantest *wt, const u8 *dst, const u8 *src,
  497. const u8 *data, size_t len, int prot)
  498. {
  499. if (len == 0)
  500. return;
  501. if (len >= 8 && os_memcmp(data, "\xaa\xaa\x03\x00\x00\x00", 6) == 0) {
  502. rx_data_eth(wt, dst, src, WPA_GET_BE16(data + 6),
  503. data + 8, len - 8, prot);
  504. return;
  505. }
  506. wpa_hexdump(MSG_DEBUG, "Unrecognized LLC", data, len > 8 ? 8 : len);
  507. }
  508. static void rx_data_bss_prot(struct wlantest *wt,
  509. const struct ieee80211_hdr *hdr, const u8 *qos,
  510. const u8 *dst, const u8 *src, const u8 *data,
  511. size_t len)
  512. {
  513. /* TODO: Try to decrypt and if success, call rx_data_process() with
  514. * prot = 1 */
  515. }
  516. static void rx_data_bss(struct wlantest *wt, const struct ieee80211_hdr *hdr,
  517. const u8 *qos, const u8 *dst, const u8 *src,
  518. const u8 *data, size_t len)
  519. {
  520. u16 fc = le_to_host16(hdr->frame_control);
  521. int prot = !!(fc & WLAN_FC_ISWEP);
  522. if (qos) {
  523. u8 ack = (qos[0] & 0x60) >> 5;
  524. wpa_printf(MSG_MSGDUMP, "BSS DATA: " MACSTR " -> " MACSTR
  525. " len=%u%s tid=%u%s%s",
  526. MAC2STR(src), MAC2STR(dst), (unsigned int) len,
  527. prot ? " Prot" : "", qos[0] & 0x0f,
  528. (qos[0] & 0x10) ? " EOSP" : "",
  529. ack == 0 ? "" :
  530. (ack == 1 ? " NoAck" :
  531. (ack == 2 ? " NoExpAck" : " BA")));
  532. } else {
  533. wpa_printf(MSG_MSGDUMP, "BSS DATA: " MACSTR " -> " MACSTR
  534. " len=%u%s",
  535. MAC2STR(src), MAC2STR(dst), (unsigned int) len,
  536. prot ? " Prot" : "");
  537. }
  538. if (prot)
  539. rx_data_bss_prot(wt, hdr, qos, dst, src, data, len);
  540. else
  541. rx_data_process(wt, dst, src, data, len, 0);
  542. }
  543. void rx_data(struct wlantest *wt, const u8 *data, size_t len)
  544. {
  545. const struct ieee80211_hdr *hdr;
  546. u16 fc, stype;
  547. size_t hdrlen;
  548. const u8 *qos = NULL;
  549. if (len < 24)
  550. return;
  551. hdr = (const struct ieee80211_hdr *) data;
  552. fc = le_to_host16(hdr->frame_control);
  553. stype = WLAN_FC_GET_STYPE(fc);
  554. hdrlen = 24;
  555. if ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) ==
  556. (WLAN_FC_TODS | WLAN_FC_FROMDS))
  557. hdrlen += ETH_ALEN;
  558. if (stype & 0x08) {
  559. qos = data + hdrlen;
  560. hdrlen += 2;
  561. }
  562. if (len < hdrlen)
  563. return;
  564. wt->rx_data++;
  565. switch (fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) {
  566. case 0:
  567. wpa_printf(MSG_EXCESSIVE, "DATA %s%s%s IBSS DA=" MACSTR " SA="
  568. MACSTR " BSSID=" MACSTR,
  569. data_stype(WLAN_FC_GET_STYPE(fc)),
  570. fc & WLAN_FC_PWRMGT ? " PwrMgt" : "",
  571. fc & WLAN_FC_ISWEP ? " Prot" : "",
  572. MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
  573. MAC2STR(hdr->addr3));
  574. break;
  575. case WLAN_FC_FROMDS:
  576. wpa_printf(MSG_EXCESSIVE, "DATA %s%s%s FromDS DA=" MACSTR
  577. " BSSID=" MACSTR " SA=" MACSTR,
  578. data_stype(WLAN_FC_GET_STYPE(fc)),
  579. fc & WLAN_FC_PWRMGT ? " PwrMgt" : "",
  580. fc & WLAN_FC_ISWEP ? " Prot" : "",
  581. MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
  582. MAC2STR(hdr->addr3));
  583. rx_data_bss(wt, hdr, qos, hdr->addr1, hdr->addr2,
  584. data + hdrlen, len - hdrlen);
  585. break;
  586. case WLAN_FC_TODS:
  587. wpa_printf(MSG_EXCESSIVE, "DATA %s%s%s ToDS BSSID=" MACSTR
  588. " SA=" MACSTR " DA=" MACSTR,
  589. data_stype(WLAN_FC_GET_STYPE(fc)),
  590. fc & WLAN_FC_PWRMGT ? " PwrMgt" : "",
  591. fc & WLAN_FC_ISWEP ? " Prot" : "",
  592. MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
  593. MAC2STR(hdr->addr3));
  594. rx_data_bss(wt, hdr, qos, hdr->addr3, hdr->addr2,
  595. data + hdrlen, len - hdrlen);
  596. break;
  597. case WLAN_FC_TODS | WLAN_FC_FROMDS:
  598. wpa_printf(MSG_EXCESSIVE, "DATA %s%s%s WDS RA=" MACSTR " TA="
  599. MACSTR " DA=" MACSTR " SA=" MACSTR,
  600. data_stype(WLAN_FC_GET_STYPE(fc)),
  601. fc & WLAN_FC_PWRMGT ? " PwrMgt" : "",
  602. fc & WLAN_FC_ISWEP ? " Prot" : "",
  603. MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
  604. MAC2STR(hdr->addr3),
  605. MAC2STR((const u8 *) (hdr + 1)));
  606. break;
  607. }
  608. }