rx_data.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  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/defs.h"
  17. #include "common/ieee802_11_defs.h"
  18. #include "wlantest.h"
  19. static const char * data_stype(u16 stype)
  20. {
  21. switch (stype) {
  22. case WLAN_FC_STYPE_DATA:
  23. return "DATA";
  24. case WLAN_FC_STYPE_DATA_CFACK:
  25. return "DATA-CFACK";
  26. case WLAN_FC_STYPE_DATA_CFPOLL:
  27. return "DATA-CFPOLL";
  28. case WLAN_FC_STYPE_DATA_CFACKPOLL:
  29. return "DATA-CFACKPOLL";
  30. case WLAN_FC_STYPE_NULLFUNC:
  31. return "NULLFUNC";
  32. case WLAN_FC_STYPE_CFACK:
  33. return "CFACK";
  34. case WLAN_FC_STYPE_CFPOLL:
  35. return "CFPOLL";
  36. case WLAN_FC_STYPE_CFACKPOLL:
  37. return "CFACKPOLL";
  38. case WLAN_FC_STYPE_QOS_DATA:
  39. return "QOSDATA";
  40. case WLAN_FC_STYPE_QOS_DATA_CFACK:
  41. return "QOSDATA-CFACK";
  42. case WLAN_FC_STYPE_QOS_DATA_CFPOLL:
  43. return "QOSDATA-CFPOLL";
  44. case WLAN_FC_STYPE_QOS_DATA_CFACKPOLL:
  45. return "QOSDATA-CFACKPOLL";
  46. case WLAN_FC_STYPE_QOS_NULL:
  47. return "QOS-NULL";
  48. case WLAN_FC_STYPE_QOS_CFPOLL:
  49. return "QOS-CFPOLL";
  50. case WLAN_FC_STYPE_QOS_CFACKPOLL:
  51. return "QOS-CFACKPOLL";
  52. }
  53. return "??";
  54. }
  55. static void rx_data_eth(struct wlantest *wt, const u8 *dst, const u8 *src,
  56. u16 ethertype, const u8 *data, size_t len, int prot)
  57. {
  58. if (ethertype == ETH_P_PAE)
  59. rx_data_eapol(wt, dst, src, data, len, prot);
  60. }
  61. static void rx_data_process(struct wlantest *wt, const u8 *dst, const u8 *src,
  62. const u8 *data, size_t len, int prot)
  63. {
  64. if (len == 0)
  65. return;
  66. if (len >= 8 && os_memcmp(data, "\xaa\xaa\x03\x00\x00\x00", 6) == 0) {
  67. rx_data_eth(wt, dst, src, WPA_GET_BE16(data + 6),
  68. data + 8, len - 8, prot);
  69. return;
  70. }
  71. wpa_hexdump(MSG_DEBUG, "Unrecognized LLC", data, len > 8 ? 8 : len);
  72. }
  73. static void rx_data_bss_prot_group(struct wlantest *wt,
  74. const struct ieee80211_hdr *hdr,
  75. const u8 *qos, const u8 *dst, const u8 *src,
  76. const u8 *data, size_t len)
  77. {
  78. struct wlantest_bss *bss;
  79. int keyid;
  80. u8 *decrypted;
  81. size_t dlen;
  82. u8 pn[6];
  83. bss = bss_get(wt, hdr->addr2);
  84. if (bss == NULL)
  85. return;
  86. if (len < 4) {
  87. wpa_printf(MSG_INFO, "Too short group addressed data frame");
  88. return;
  89. }
  90. if (bss->group_cipher & (WPA_CIPHER_TKIP | WPA_CIPHER_CCMP) &&
  91. !(data[3] & 0x20)) {
  92. wpa_printf(MSG_INFO, "Expected TKIP/CCMP frame from "
  93. MACSTR " did not have ExtIV bit set to 1",
  94. MAC2STR(bss->bssid));
  95. return;
  96. }
  97. if (bss->group_cipher == WPA_CIPHER_TKIP) {
  98. if (data[3] & 0x1f) {
  99. wpa_printf(MSG_INFO, "TKIP frame from " MACSTR " used "
  100. "non-zero reserved bit",
  101. MAC2STR(bss->bssid));
  102. }
  103. if (data[1] != ((data[0] | 0x20) & 0x7f)) {
  104. wpa_printf(MSG_INFO, "TKIP frame from " MACSTR " used "
  105. "incorrect WEPSeed[1] (was 0x%x, expected "
  106. "0x%x)",
  107. MAC2STR(bss->bssid), data[1],
  108. (data[0] | 0x20) & 0x7f);
  109. }
  110. } else if (bss->group_cipher == WPA_CIPHER_CCMP) {
  111. if (data[2] != 0 || (data[3] & 0x1f) != 0) {
  112. wpa_printf(MSG_INFO, "CCMP frame from " MACSTR " used "
  113. "non-zero reserved bit",
  114. MAC2STR(bss->bssid));
  115. }
  116. }
  117. keyid = data[3] >> 6;
  118. if (bss->gtk_len[keyid] == 0) {
  119. wpa_printf(MSG_MSGDUMP, "No GTK known to decrypt the frame "
  120. "(A2=" MACSTR " KeyID=%d)",
  121. MAC2STR(hdr->addr2), keyid);
  122. return;
  123. }
  124. if (bss->group_cipher == WPA_CIPHER_TKIP)
  125. tkip_get_pn(pn, data);
  126. else
  127. ccmp_get_pn(pn, data);
  128. if (os_memcmp(pn, bss->rsc[keyid], 6) <= 0) {
  129. wpa_printf(MSG_INFO, "CCMP/TKIP replay detected: SA=" MACSTR,
  130. MAC2STR(hdr->addr2));
  131. wpa_hexdump(MSG_INFO, "RX PN", pn, 6);
  132. wpa_hexdump(MSG_INFO, "RSC", bss->rsc[keyid], 6);
  133. }
  134. if (bss->group_cipher == WPA_CIPHER_TKIP)
  135. decrypted = tkip_decrypt(bss->gtk[keyid], hdr, data, len,
  136. &dlen);
  137. else
  138. decrypted = ccmp_decrypt(bss->gtk[keyid], hdr, data, len,
  139. &dlen);
  140. if (decrypted) {
  141. rx_data_process(wt, dst, src, decrypted, dlen, 1);
  142. os_memcpy(bss->rsc[keyid], pn, 6);
  143. write_pcap_decrypted(wt, (const u8 *) hdr, 24 + (qos ? 2 : 0),
  144. decrypted, dlen);
  145. }
  146. os_free(decrypted);
  147. }
  148. static void rx_data_bss_prot(struct wlantest *wt,
  149. const struct ieee80211_hdr *hdr, const u8 *qos,
  150. const u8 *dst, const u8 *src, const u8 *data,
  151. size_t len)
  152. {
  153. struct wlantest_bss *bss;
  154. struct wlantest_sta *sta;
  155. int keyid;
  156. u16 fc = le_to_host16(hdr->frame_control);
  157. u8 *decrypted;
  158. size_t dlen;
  159. int tid;
  160. u8 pn[6], *rsc;
  161. if (hdr->addr1[0] & 0x01) {
  162. rx_data_bss_prot_group(wt, hdr, qos, dst, src, data, len);
  163. return;
  164. }
  165. if (fc & WLAN_FC_TODS) {
  166. bss = bss_get(wt, hdr->addr1);
  167. if (bss == NULL)
  168. return;
  169. sta = sta_get(bss, hdr->addr2);
  170. } else {
  171. bss = bss_get(wt, hdr->addr2);
  172. if (bss == NULL)
  173. return;
  174. sta = sta_get(bss, hdr->addr1);
  175. }
  176. if (sta == NULL || !sta->ptk_set) {
  177. wpa_printf(MSG_MSGDUMP, "No PTK known to decrypt the frame");
  178. return;
  179. }
  180. if (len < 4) {
  181. wpa_printf(MSG_INFO, "Too short encrypted data frame");
  182. return;
  183. }
  184. if (sta->pairwise_cipher & (WPA_CIPHER_TKIP | WPA_CIPHER_CCMP) &&
  185. !(data[3] & 0x20)) {
  186. wpa_printf(MSG_INFO, "Expected TKIP/CCMP frame from "
  187. MACSTR " did not have ExtIV bit set to 1",
  188. MAC2STR(src));
  189. return;
  190. }
  191. if (sta->pairwise_cipher == WPA_CIPHER_TKIP) {
  192. if (data[3] & 0x1f) {
  193. wpa_printf(MSG_INFO, "TKIP frame from " MACSTR " used "
  194. "non-zero reserved bit",
  195. MAC2STR(hdr->addr2));
  196. }
  197. if (data[1] != ((data[0] | 0x20) & 0x7f)) {
  198. wpa_printf(MSG_INFO, "TKIP frame from " MACSTR " used "
  199. "incorrect WEPSeed[1] (was 0x%x, expected "
  200. "0x%x)",
  201. MAC2STR(hdr->addr2), data[1],
  202. (data[0] | 0x20) & 0x7f);
  203. }
  204. } else if (sta->pairwise_cipher == WPA_CIPHER_CCMP) {
  205. if (data[2] != 0 || (data[3] & 0x1f) != 0) {
  206. wpa_printf(MSG_INFO, "CCMP frame from " MACSTR " used "
  207. "non-zero reserved bit",
  208. MAC2STR(hdr->addr2));
  209. }
  210. }
  211. keyid = data[3] >> 6;
  212. if (keyid != 0) {
  213. wpa_printf(MSG_INFO, "Unexpected non-zero KeyID %d in "
  214. "individually addressed Data frame from " MACSTR,
  215. keyid, MAC2STR(hdr->addr2));
  216. }
  217. if (qos)
  218. tid = qos[0] & 0x0f;
  219. else
  220. tid = 0;
  221. if (fc & WLAN_FC_TODS)
  222. rsc = sta->rsc_tods[tid];
  223. else
  224. rsc = sta->rsc_fromds[tid];
  225. if (sta->pairwise_cipher == WPA_CIPHER_TKIP)
  226. tkip_get_pn(pn, data);
  227. else
  228. ccmp_get_pn(pn, data);
  229. if (os_memcmp(pn, rsc, 6) <= 0) {
  230. wpa_printf(MSG_INFO, "CCMP/TKIP replay detected: SA=" MACSTR,
  231. MAC2STR(hdr->addr2));
  232. wpa_hexdump(MSG_INFO, "RX PN", pn, 6);
  233. wpa_hexdump(MSG_INFO, "RSC", rsc, 6);
  234. }
  235. if (sta->pairwise_cipher == WPA_CIPHER_TKIP)
  236. decrypted = tkip_decrypt(sta->ptk.tk1, hdr, data, len, &dlen);
  237. else
  238. decrypted = ccmp_decrypt(sta->ptk.tk1, hdr, data, len, &dlen);
  239. if (decrypted) {
  240. rx_data_process(wt, dst, src, decrypted, dlen, 1);
  241. os_memcpy(rsc, pn, 6);
  242. write_pcap_decrypted(wt, (const u8 *) hdr, 24 + (qos ? 2 : 0),
  243. decrypted, dlen);
  244. }
  245. os_free(decrypted);
  246. }
  247. static void rx_data_bss(struct wlantest *wt, const struct ieee80211_hdr *hdr,
  248. const u8 *qos, const u8 *dst, const u8 *src,
  249. const u8 *data, size_t len)
  250. {
  251. u16 fc = le_to_host16(hdr->frame_control);
  252. int prot = !!(fc & WLAN_FC_ISWEP);
  253. if (qos) {
  254. u8 ack = (qos[0] & 0x60) >> 5;
  255. wpa_printf(MSG_MSGDUMP, "BSS DATA: " MACSTR " -> " MACSTR
  256. " len=%u%s tid=%u%s%s",
  257. MAC2STR(src), MAC2STR(dst), (unsigned int) len,
  258. prot ? " Prot" : "", qos[0] & 0x0f,
  259. (qos[0] & 0x10) ? " EOSP" : "",
  260. ack == 0 ? "" :
  261. (ack == 1 ? " NoAck" :
  262. (ack == 2 ? " NoExpAck" : " BA")));
  263. } else {
  264. wpa_printf(MSG_MSGDUMP, "BSS DATA: " MACSTR " -> " MACSTR
  265. " len=%u%s",
  266. MAC2STR(src), MAC2STR(dst), (unsigned int) len,
  267. prot ? " Prot" : "");
  268. }
  269. if (prot)
  270. rx_data_bss_prot(wt, hdr, qos, dst, src, data, len);
  271. else
  272. rx_data_process(wt, dst, src, data, len, 0);
  273. }
  274. void rx_data(struct wlantest *wt, const u8 *data, size_t len)
  275. {
  276. const struct ieee80211_hdr *hdr;
  277. u16 fc, stype;
  278. size_t hdrlen;
  279. const u8 *qos = NULL;
  280. if (len < 24)
  281. return;
  282. hdr = (const struct ieee80211_hdr *) data;
  283. fc = le_to_host16(hdr->frame_control);
  284. stype = WLAN_FC_GET_STYPE(fc);
  285. hdrlen = 24;
  286. if ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) ==
  287. (WLAN_FC_TODS | WLAN_FC_FROMDS))
  288. hdrlen += ETH_ALEN;
  289. if (stype & 0x08) {
  290. qos = data + hdrlen;
  291. hdrlen += 2;
  292. }
  293. if (len < hdrlen)
  294. return;
  295. wt->rx_data++;
  296. switch (fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) {
  297. case 0:
  298. wpa_printf(MSG_EXCESSIVE, "DATA %s%s%s IBSS DA=" MACSTR " SA="
  299. MACSTR " BSSID=" MACSTR,
  300. data_stype(WLAN_FC_GET_STYPE(fc)),
  301. fc & WLAN_FC_PWRMGT ? " PwrMgt" : "",
  302. fc & WLAN_FC_ISWEP ? " Prot" : "",
  303. MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
  304. MAC2STR(hdr->addr3));
  305. break;
  306. case WLAN_FC_FROMDS:
  307. wpa_printf(MSG_EXCESSIVE, "DATA %s%s%s FromDS DA=" MACSTR
  308. " BSSID=" MACSTR " SA=" MACSTR,
  309. data_stype(WLAN_FC_GET_STYPE(fc)),
  310. fc & WLAN_FC_PWRMGT ? " PwrMgt" : "",
  311. fc & WLAN_FC_ISWEP ? " Prot" : "",
  312. MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
  313. MAC2STR(hdr->addr3));
  314. rx_data_bss(wt, hdr, qos, hdr->addr1, hdr->addr2,
  315. data + hdrlen, len - hdrlen);
  316. break;
  317. case WLAN_FC_TODS:
  318. wpa_printf(MSG_EXCESSIVE, "DATA %s%s%s ToDS BSSID=" MACSTR
  319. " SA=" MACSTR " DA=" MACSTR,
  320. data_stype(WLAN_FC_GET_STYPE(fc)),
  321. fc & WLAN_FC_PWRMGT ? " PwrMgt" : "",
  322. fc & WLAN_FC_ISWEP ? " Prot" : "",
  323. MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
  324. MAC2STR(hdr->addr3));
  325. rx_data_bss(wt, hdr, qos, hdr->addr3, hdr->addr2,
  326. data + hdrlen, len - hdrlen);
  327. break;
  328. case WLAN_FC_TODS | WLAN_FC_FROMDS:
  329. wpa_printf(MSG_EXCESSIVE, "DATA %s%s%s WDS RA=" MACSTR " TA="
  330. MACSTR " DA=" 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. MAC2STR((const u8 *) (hdr + 1)));
  337. break;
  338. }
  339. }