inject.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /*
  2. * wlantest frame injection
  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 int inject_frame(int s, const void *data, size_t len)
  20. {
  21. #define IEEE80211_RADIOTAP_F_FRAG 0x08
  22. unsigned char rtap_hdr[] = {
  23. 0x00, 0x00, /* radiotap version */
  24. 0x0e, 0x00, /* radiotap length */
  25. 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
  26. IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
  27. 0x00, /* padding */
  28. 0x00, 0x00, /* RX and TX flags to indicate that */
  29. 0x00, 0x00, /* this is the injected frame directly */
  30. };
  31. struct iovec iov[2] = {
  32. {
  33. .iov_base = &rtap_hdr,
  34. .iov_len = sizeof(rtap_hdr),
  35. },
  36. {
  37. .iov_base = (void *) data,
  38. .iov_len = len,
  39. }
  40. };
  41. struct msghdr msg = {
  42. .msg_name = NULL,
  43. .msg_namelen = 0,
  44. .msg_iov = iov,
  45. .msg_iovlen = 2,
  46. .msg_control = NULL,
  47. .msg_controllen = 0,
  48. .msg_flags = 0,
  49. };
  50. int ret;
  51. ret = sendmsg(s, &msg, 0);
  52. if (ret < 0)
  53. perror("sendmsg");
  54. return ret;
  55. }
  56. static int is_robust_mgmt(u8 *frame, size_t len)
  57. {
  58. struct ieee80211_mgmt *mgmt;
  59. u16 fc, stype;
  60. if (len < 24)
  61. return 0;
  62. mgmt = (struct ieee80211_mgmt *) frame;
  63. fc = le_to_host16(mgmt->frame_control);
  64. if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT)
  65. return 0;
  66. stype = WLAN_FC_GET_STYPE(fc);
  67. if (stype == WLAN_FC_STYPE_DEAUTH || stype == WLAN_FC_STYPE_DISASSOC)
  68. return 1;
  69. if (stype == WLAN_FC_STYPE_ACTION) {
  70. if (len < 25)
  71. return 0;
  72. if (mgmt->u.action.category != WLAN_ACTION_PUBLIC)
  73. return 1;
  74. }
  75. return 0;
  76. }
  77. static int wlantest_inject_prot(struct wlantest *wt, struct wlantest_bss *bss,
  78. struct wlantest_sta *sta, u8 *frame,
  79. size_t len, int incorrect_key)
  80. {
  81. u8 *crypt;
  82. size_t crypt_len;
  83. int ret;
  84. u8 dummy[64];
  85. u8 *pn;
  86. struct ieee80211_hdr *hdr;
  87. u16 fc;
  88. int tid = 0;
  89. u8 *qos = NULL;
  90. int hdrlen;
  91. if (sta == NULL)
  92. return -1; /* TODO: add support for group Data and BIP */
  93. if (!sta->ptk_set)
  94. return -1;
  95. hdr = (struct ieee80211_hdr *) frame;
  96. hdrlen = 24;
  97. fc = le_to_host16(hdr->frame_control);
  98. if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT)
  99. tid = 16;
  100. else if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA) {
  101. if ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) ==
  102. (WLAN_FC_TODS | WLAN_FC_FROMDS))
  103. hdrlen += ETH_ALEN;
  104. if (WLAN_FC_GET_STYPE(fc) & 0x08) {
  105. qos = frame + hdrlen;
  106. hdrlen += 2;
  107. tid = qos[0] & 0x0f;
  108. }
  109. }
  110. if (os_memcmp(hdr->addr2, bss->bssid, ETH_ALEN) == 0)
  111. pn = sta->rsc_fromds[tid];
  112. else
  113. pn = sta->rsc_tods[tid];
  114. inc_byte_array(pn, 6);
  115. os_memset(dummy, 0x11, sizeof(dummy));
  116. if (sta->pairwise_cipher == WPA_CIPHER_TKIP)
  117. crypt = tkip_encrypt(incorrect_key ? dummy : sta->ptk.tk1,
  118. frame, len, hdrlen, qos, pn, 0,
  119. &crypt_len);
  120. else
  121. crypt = ccmp_encrypt(incorrect_key ? dummy : sta->ptk.tk1,
  122. frame, len, hdrlen, qos, pn, 0,
  123. &crypt_len);
  124. if (crypt == NULL)
  125. return -1;
  126. ret = inject_frame(wt->monitor_sock, crypt, crypt_len);
  127. os_free(crypt);
  128. return (ret < 0) ? -1 : 0;
  129. }
  130. int wlantest_inject(struct wlantest *wt, struct wlantest_bss *bss,
  131. struct wlantest_sta *sta, u8 *frame, size_t len,
  132. enum wlantest_inject_protection prot)
  133. {
  134. int ret;
  135. struct ieee80211_hdr *hdr;
  136. u16 fc;
  137. int protectable, protect = 0;
  138. wpa_hexdump(MSG_DEBUG, "Inject frame", frame, len);
  139. if (wt->monitor_sock < 0) {
  140. wpa_printf(MSG_INFO, "Cannot inject frames when monitor "
  141. "interface is not in use");
  142. return -1;
  143. }
  144. hdr = (struct ieee80211_hdr *) frame;
  145. fc = le_to_host16(hdr->frame_control);
  146. protectable = WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA ||
  147. is_robust_mgmt(frame, len);
  148. if (prot == WLANTEST_INJECT_PROTECTED ||
  149. prot == WLANTEST_INJECT_INCORRECT_KEY) {
  150. if (!sta) {
  151. wpa_printf(MSG_INFO, "Broadcast protection not yet "
  152. "implemented");
  153. return -1;
  154. }
  155. if (sta && !sta->ptk_set) {
  156. wpa_printf(MSG_INFO, "No PTK known for the STA " MACSTR
  157. " to encrypt the injected frame",
  158. MAC2STR(sta->addr));
  159. return -1;
  160. }
  161. protect = 1;
  162. } else if (protectable && prot != WLANTEST_INJECT_UNPROTECTED) {
  163. if (sta && sta->ptk_set)
  164. protect = 1;
  165. else if (!sta) {
  166. if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA &&
  167. (bss->gtk_len[1] || bss->gtk_len[2]))
  168. protect = 1;
  169. if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
  170. (bss->igtk_set[4] || bss->igtk_set[5]))
  171. protect = 1;
  172. }
  173. }
  174. if ((prot == WLANTEST_INJECT_PROTECTED ||
  175. prot == WLANTEST_INJECT_INCORRECT_KEY) && !protect) {
  176. wpa_printf(MSG_INFO, "Cannot protect injected frame");
  177. return -1;
  178. }
  179. if (protect)
  180. return wlantest_inject_prot(
  181. wt, bss, sta, frame, len,
  182. prot == WLANTEST_INJECT_INCORRECT_KEY);
  183. ret = inject_frame(wt->monitor_sock, frame, len);
  184. return (ret < 0) ? -1 : 0;
  185. }