rx_data.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  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 "common/ieee802_11_defs.h"
  17. #include "common/eapol_common.h"
  18. #include "common/wpa_common.h"
  19. #include "wlantest.h"
  20. static const char * data_stype(u16 stype)
  21. {
  22. switch (stype) {
  23. case WLAN_FC_STYPE_DATA:
  24. return "DATA";
  25. case WLAN_FC_STYPE_DATA_CFACK:
  26. return "DATA-CFACK";
  27. case WLAN_FC_STYPE_DATA_CFPOLL:
  28. return "DATA-CFPOLL";
  29. case WLAN_FC_STYPE_DATA_CFACKPOLL:
  30. return "DATA-CFACKPOLL";
  31. case WLAN_FC_STYPE_NULLFUNC:
  32. return "NULLFUNC";
  33. case WLAN_FC_STYPE_CFACK:
  34. return "CFACK";
  35. case WLAN_FC_STYPE_CFPOLL:
  36. return "CFPOLL";
  37. case WLAN_FC_STYPE_CFACKPOLL:
  38. return "CFACKPOLL";
  39. case WLAN_FC_STYPE_QOS_DATA:
  40. return "QOSDATA";
  41. case WLAN_FC_STYPE_QOS_DATA_CFACK:
  42. return "QOSDATA-CFACK";
  43. case WLAN_FC_STYPE_QOS_DATA_CFPOLL:
  44. return "QOSDATA-CFPOLL";
  45. case WLAN_FC_STYPE_QOS_DATA_CFACKPOLL:
  46. return "QOSDATA-CFACKPOLL";
  47. case WLAN_FC_STYPE_QOS_NULL:
  48. return "QOS-NULL";
  49. case WLAN_FC_STYPE_QOS_CFPOLL:
  50. return "QOS-CFPOLL";
  51. case WLAN_FC_STYPE_QOS_CFACKPOLL:
  52. return "QOS-CFACKPOLL";
  53. }
  54. return "??";
  55. }
  56. static void rx_data_eapol_key_1_of_4(struct wlantest *wt, const u8 *dst,
  57. const u8 *src, const u8 *data, size_t len)
  58. {
  59. wpa_printf(MSG_DEBUG, "EAPOL-Key 1/4 " MACSTR " -> " MACSTR,
  60. MAC2STR(src), MAC2STR(dst));
  61. }
  62. static void rx_data_eapol_key_2_of_4(struct wlantest *wt, const u8 *dst,
  63. const u8 *src, const u8 *data, size_t len)
  64. {
  65. wpa_printf(MSG_DEBUG, "EAPOL-Key 2/4 " MACSTR " -> " MACSTR,
  66. MAC2STR(src), MAC2STR(dst));
  67. }
  68. static void rx_data_eapol_key_3_of_4(struct wlantest *wt, const u8 *dst,
  69. const u8 *src, const u8 *data, size_t len)
  70. {
  71. wpa_printf(MSG_DEBUG, "EAPOL-Key 3/4 " MACSTR " -> " MACSTR,
  72. MAC2STR(src), MAC2STR(dst));
  73. }
  74. static void rx_data_eapol_key_4_of_4(struct wlantest *wt, const u8 *dst,
  75. const u8 *src, const u8 *data, size_t len)
  76. {
  77. wpa_printf(MSG_DEBUG, "EAPOL-Key 4/4 " MACSTR " -> " MACSTR,
  78. MAC2STR(src), MAC2STR(dst));
  79. }
  80. static void rx_data_eapol_key_1_of_2(struct wlantest *wt, const u8 *dst,
  81. const u8 *src, const u8 *data, size_t len)
  82. {
  83. wpa_printf(MSG_DEBUG, "EAPOL-Key 1/2 " MACSTR " -> " MACSTR,
  84. MAC2STR(src), MAC2STR(dst));
  85. }
  86. static void rx_data_eapol_key_2_of_2(struct wlantest *wt, const u8 *dst,
  87. const u8 *src, const u8 *data, size_t len)
  88. {
  89. wpa_printf(MSG_DEBUG, "EAPOL-Key 2/2 " MACSTR " -> " MACSTR,
  90. MAC2STR(src), MAC2STR(dst));
  91. }
  92. static void rx_data_eapol_key(struct wlantest *wt, const u8 *dst,
  93. const u8 *src, const u8 *data, size_t len,
  94. int prot)
  95. {
  96. const struct wpa_eapol_key *hdr;
  97. u16 key_info, key_length, ver, key_data_length;
  98. wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key", data, len);
  99. if (len < sizeof(*hdr)) {
  100. wpa_printf(MSG_INFO, "Too short EAPOL-Key frame from " MACSTR,
  101. MAC2STR(src));
  102. return;
  103. }
  104. hdr = (const struct wpa_eapol_key *) data;
  105. if (hdr->type == EAPOL_KEY_TYPE_RC4) {
  106. /* TODO: EAPOL-Key RC4 for WEP */
  107. return;
  108. }
  109. if (hdr->type != EAPOL_KEY_TYPE_RSN &&
  110. hdr->type != EAPOL_KEY_TYPE_WPA) {
  111. wpa_printf(MSG_DEBUG, "Unsupported EAPOL-Key type %u",
  112. hdr->type);
  113. return;
  114. }
  115. key_info = WPA_GET_BE16(hdr->key_info);
  116. key_length = WPA_GET_BE16(hdr->key_length);
  117. key_data_length = WPA_GET_BE16(hdr->key_data_length);
  118. ver = key_info & WPA_KEY_INFO_TYPE_MASK;
  119. wpa_printf(MSG_DEBUG, "EAPOL-Key ver=%u %c idx=%u%s%s%s%s%s%s%s%s "
  120. "datalen=%u",
  121. ver, key_info & WPA_KEY_INFO_KEY_TYPE ? 'P' : 'G',
  122. (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
  123. WPA_KEY_INFO_KEY_INDEX_SHIFT,
  124. (key_info & WPA_KEY_INFO_INSTALL) ? " Install" : "",
  125. (key_info & WPA_KEY_INFO_ACK) ? " ACK" : "",
  126. (key_info & WPA_KEY_INFO_MIC) ? " MIC" : "",
  127. (key_info & WPA_KEY_INFO_SECURE) ? " Secure" : "",
  128. (key_info & WPA_KEY_INFO_ERROR) ? " Error" : "",
  129. (key_info & WPA_KEY_INFO_REQUEST) ? " Request" : "",
  130. (key_info & WPA_KEY_INFO_ENCR_KEY_DATA) ? " Encr" : "",
  131. (key_info & WPA_KEY_INFO_SMK_MESSAGE) ? " SMK" : "",
  132. key_data_length);
  133. if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 &&
  134. ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES &&
  135. ver != WPA_KEY_INFO_TYPE_AES_128_CMAC) {
  136. wpa_printf(MSG_DEBUG, "Unsupported EAPOL-Key Key Descriptor "
  137. "Version %u", ver);
  138. return;
  139. }
  140. wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Replay Counter",
  141. hdr->replay_counter, WPA_REPLAY_COUNTER_LEN);
  142. wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Nonce",
  143. hdr->key_nonce, WPA_NONCE_LEN);
  144. wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key IV",
  145. hdr->key_iv, 16);
  146. wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key RSC",
  147. hdr->key_nonce, WPA_KEY_RSC_LEN);
  148. wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key MIC",
  149. hdr->key_mic, 16);
  150. if (key_info & (WPA_KEY_INFO_ERROR | WPA_KEY_INFO_REQUEST))
  151. return;
  152. if (key_info & WPA_KEY_INFO_SMK_MESSAGE)
  153. return;
  154. if (key_info & WPA_KEY_INFO_KEY_TYPE) {
  155. /* 4-Way Handshake */
  156. switch (key_info & (WPA_KEY_INFO_SECURE |
  157. WPA_KEY_INFO_MIC |
  158. WPA_KEY_INFO_ACK |
  159. WPA_KEY_INFO_INSTALL)) {
  160. case WPA_KEY_INFO_ACK:
  161. rx_data_eapol_key_1_of_4(wt, dst, src, data, len);
  162. break;
  163. case WPA_KEY_INFO_MIC:
  164. rx_data_eapol_key_2_of_4(wt, dst, src, data, len);
  165. break;
  166. case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
  167. WPA_KEY_INFO_ACK | WPA_KEY_INFO_INSTALL:
  168. rx_data_eapol_key_3_of_4(wt, dst, src, data, len);
  169. break;
  170. case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC:
  171. rx_data_eapol_key_4_of_4(wt, dst, src, data, len);
  172. break;
  173. default:
  174. wpa_printf(MSG_DEBUG, "Unsupported EAPOL-Key frame");
  175. break;
  176. }
  177. } else {
  178. /* Group Key Handshake */
  179. switch (key_info & (WPA_KEY_INFO_SECURE |
  180. WPA_KEY_INFO_MIC |
  181. WPA_KEY_INFO_ACK)) {
  182. case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
  183. WPA_KEY_INFO_ACK:
  184. rx_data_eapol_key_1_of_2(wt, dst, src, data, len);
  185. break;
  186. case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC:
  187. rx_data_eapol_key_2_of_2(wt, dst, src, data, len);
  188. break;
  189. default:
  190. wpa_printf(MSG_DEBUG, "Unsupported EAPOL-Key frame");
  191. break;
  192. }
  193. }
  194. }
  195. static void rx_data_eapol(struct wlantest *wt, const u8 *dst, const u8 *src,
  196. const u8 *data, size_t len, int prot)
  197. {
  198. const struct ieee802_1x_hdr *hdr;
  199. u16 length;
  200. const u8 *p;
  201. wpa_hexdump(MSG_EXCESSIVE, "EAPOL", data, len);
  202. if (len < sizeof(*hdr)) {
  203. wpa_printf(MSG_INFO, "Too short EAPOL frame from " MACSTR,
  204. MAC2STR(src));
  205. return;
  206. }
  207. hdr = (const struct ieee802_1x_hdr *) data;
  208. length = be_to_host16(hdr->length);
  209. wpa_printf(MSG_DEBUG, "RX EAPOL: " MACSTR " -> " MACSTR "%s ver=%u "
  210. "type=%u len=%u",
  211. MAC2STR(src), MAC2STR(dst), prot ? " Prot" : "",
  212. hdr->version, hdr->type, length);
  213. if (sizeof(*hdr) + length > len) {
  214. wpa_printf(MSG_INFO, "Truncated EAPOL frame from " MACSTR,
  215. MAC2STR(src));
  216. return;
  217. }
  218. if (sizeof(*hdr) + length < len) {
  219. wpa_printf(MSG_INFO, "EAPOL frame with %d extra bytes",
  220. (int) (len - sizeof(*hdr) - length));
  221. }
  222. p = (const u8 *) (hdr + 1);
  223. switch (hdr->type) {
  224. case IEEE802_1X_TYPE_EAP_PACKET:
  225. wpa_hexdump(MSG_MSGDUMP, "EAPOL - EAP packet", p, length);
  226. break;
  227. case IEEE802_1X_TYPE_EAPOL_START:
  228. wpa_hexdump(MSG_MSGDUMP, "EAPOL-Start", p, length);
  229. break;
  230. case IEEE802_1X_TYPE_EAPOL_LOGOFF:
  231. wpa_hexdump(MSG_MSGDUMP, "EAPOL-Logoff", p, length);
  232. break;
  233. case IEEE802_1X_TYPE_EAPOL_KEY:
  234. rx_data_eapol_key(wt, dst, src, p, length, prot);
  235. break;
  236. case IEEE802_1X_TYPE_EAPOL_ENCAPSULATED_ASF_ALERT:
  237. wpa_hexdump(MSG_MSGDUMP, "EAPOL - Encapsulated ASF alert",
  238. p, length);
  239. break;
  240. default:
  241. wpa_hexdump(MSG_MSGDUMP, "Unknown EAPOL payload", p, length);
  242. break;
  243. }
  244. }
  245. static void rx_data_eth(struct wlantest *wt, const u8 *dst, const u8 *src,
  246. u16 ethertype, const u8 *data, size_t len, int prot)
  247. {
  248. if (ethertype == ETH_P_PAE)
  249. rx_data_eapol(wt, dst, src, data, len, prot);
  250. }
  251. static void rx_data_process(struct wlantest *wt, const u8 *dst, const u8 *src,
  252. const u8 *data, size_t len, int prot)
  253. {
  254. if (len >= 8 && os_memcmp(data, "\xaa\xaa\x03\x00\x00\x00", 6) == 0) {
  255. rx_data_eth(wt, dst, src, WPA_GET_BE16(data + 6),
  256. data + 8, len - 8, prot);
  257. return;
  258. }
  259. wpa_hexdump(MSG_DEBUG, "Unrecognized LLC", data, len > 8 ? len : 7);
  260. }
  261. static void rx_data_bss_prot(struct wlantest *wt,
  262. const struct ieee80211_hdr *hdr, const u8 *qos,
  263. const u8 *dst, const u8 *src, const u8 *data,
  264. size_t len)
  265. {
  266. /* TODO: Try to decrypt and if success, call rx_data_process() with
  267. * prot = 1 */
  268. }
  269. static void rx_data_bss(struct wlantest *wt, const struct ieee80211_hdr *hdr,
  270. const u8 *qos, const u8 *dst, const u8 *src,
  271. const u8 *data, size_t len)
  272. {
  273. u16 fc = le_to_host16(hdr->frame_control);
  274. int prot = !!(fc & WLAN_FC_ISWEP);
  275. if (qos) {
  276. u8 ack = (qos[0] & 0x60) >> 5;
  277. wpa_printf(MSG_MSGDUMP, "BSS DATA: " MACSTR " -> " MACSTR
  278. " len=%u%s tid=%u%s%s",
  279. MAC2STR(src), MAC2STR(dst), (unsigned int) len,
  280. prot ? " Prot" : "", qos[0] & 0x0f,
  281. (qos[0] & 0x10) ? " EOSP" : "",
  282. ack == 0 ? "" :
  283. (ack == 1 ? " NoAck" :
  284. (ack == 2 ? " NoExpAck" : " BA")));
  285. } else {
  286. wpa_printf(MSG_MSGDUMP, "BSS DATA: " MACSTR " -> " MACSTR
  287. " len=%u%s",
  288. MAC2STR(src), MAC2STR(dst), (unsigned int) len,
  289. prot ? " Prot" : "");
  290. }
  291. if (prot)
  292. rx_data_bss_prot(wt, hdr, qos, dst, src, data, len);
  293. else
  294. rx_data_process(wt, dst, src, data, len, 0);
  295. }
  296. void rx_data(struct wlantest *wt, const u8 *data, size_t len)
  297. {
  298. const struct ieee80211_hdr *hdr;
  299. u16 fc, stype;
  300. size_t hdrlen;
  301. const u8 *qos = NULL;
  302. if (len < 24)
  303. return;
  304. hdr = (const struct ieee80211_hdr *) data;
  305. fc = le_to_host16(hdr->frame_control);
  306. stype = WLAN_FC_GET_STYPE(fc);
  307. hdrlen = 24;
  308. if ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) ==
  309. (WLAN_FC_TODS | WLAN_FC_FROMDS))
  310. hdrlen += ETH_ALEN;
  311. if (stype & 0x08) {
  312. qos = data + hdrlen;
  313. hdrlen += 2;
  314. }
  315. if (len < hdrlen)
  316. return;
  317. wt->rx_data++;
  318. switch (fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) {
  319. case 0:
  320. wpa_printf(MSG_EXCESSIVE, "DATA %s%s%s IBSS DA=" MACSTR " SA="
  321. MACSTR " BSSID=" MACSTR,
  322. data_stype(WLAN_FC_GET_STYPE(fc)),
  323. fc & WLAN_FC_PWRMGT ? " PwrMgt" : "",
  324. fc & WLAN_FC_ISWEP ? " Prot" : "",
  325. MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
  326. MAC2STR(hdr->addr3));
  327. break;
  328. case WLAN_FC_FROMDS:
  329. wpa_printf(MSG_EXCESSIVE, "DATA %s%s%s FromDS DA=" MACSTR
  330. " BSSID=" MACSTR " SA=" MACSTR,
  331. data_stype(WLAN_FC_GET_STYPE(fc)),
  332. fc & WLAN_FC_PWRMGT ? " PwrMgt" : "",
  333. fc & WLAN_FC_ISWEP ? " Prot" : "",
  334. MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
  335. MAC2STR(hdr->addr3));
  336. rx_data_bss(wt, hdr, qos, hdr->addr1, hdr->addr2,
  337. data + hdrlen, len - hdrlen);
  338. break;
  339. case WLAN_FC_TODS:
  340. wpa_printf(MSG_EXCESSIVE, "DATA %s%s%s ToDS BSSID=" MACSTR
  341. " SA=" MACSTR " DA=" MACSTR,
  342. data_stype(WLAN_FC_GET_STYPE(fc)),
  343. fc & WLAN_FC_PWRMGT ? " PwrMgt" : "",
  344. fc & WLAN_FC_ISWEP ? " Prot" : "",
  345. MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
  346. MAC2STR(hdr->addr3));
  347. rx_data_bss(wt, hdr, qos, hdr->addr3, hdr->addr2,
  348. data + hdrlen, len - hdrlen);
  349. break;
  350. case WLAN_FC_TODS | WLAN_FC_FROMDS:
  351. wpa_printf(MSG_EXCESSIVE, "DATA %s%s%s WDS RA=" MACSTR " TA="
  352. MACSTR " DA=" MACSTR " SA=" MACSTR,
  353. data_stype(WLAN_FC_GET_STYPE(fc)),
  354. fc & WLAN_FC_PWRMGT ? " PwrMgt" : "",
  355. fc & WLAN_FC_ISWEP ? " Prot" : "",
  356. MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
  357. MAC2STR(hdr->addr3),
  358. MAC2STR((const u8 *) (hdr + 1)));
  359. break;
  360. }
  361. }