2 * wlantest frame injection
3 * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
9 #include "utils/includes.h"
11 #include "utils/common.h"
12 #include "common/defs.h"
13 #include "common/ieee802_11_defs.h"
14 #include "crypto/aes_wrap.h"
18 static int inject_frame(int s
, const void *data
, size_t len
)
20 #define IEEE80211_RADIOTAP_F_FRAG 0x08
21 unsigned char rtap_hdr
[] = {
22 0x00, 0x00, /* radiotap version */
23 0x0e, 0x00, /* radiotap length */
24 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
25 IEEE80211_RADIOTAP_F_FRAG
, /* F_FRAG (fragment if required) */
27 0x00, 0x00, /* RX and TX flags to indicate that */
28 0x00, 0x00, /* this is the injected frame directly */
30 struct iovec iov
[2] = {
32 .iov_base
= &rtap_hdr
,
33 .iov_len
= sizeof(rtap_hdr
),
36 .iov_base
= (void *) data
,
51 ret
= sendmsg(s
, &msg
, 0);
58 static int is_robust_mgmt(u8
*frame
, size_t len
)
60 struct ieee80211_mgmt
*mgmt
;
64 mgmt
= (struct ieee80211_mgmt
*) frame
;
65 fc
= le_to_host16(mgmt
->frame_control
);
66 if (WLAN_FC_GET_TYPE(fc
) != WLAN_FC_TYPE_MGMT
)
68 stype
= WLAN_FC_GET_STYPE(fc
);
69 if (stype
== WLAN_FC_STYPE_DEAUTH
|| stype
== WLAN_FC_STYPE_DISASSOC
)
71 if (stype
== WLAN_FC_STYPE_ACTION
) {
74 if (mgmt
->u
.action
.category
!= WLAN_ACTION_PUBLIC
)
81 static int wlantest_inject_bip(struct wlantest
*wt
, struct wlantest_bss
*bss
,
82 u8
*frame
, size_t len
, int incorrect_key
)
89 struct ieee80211_hdr
*hdr
;
92 if (!bss
->igtk_set
[bss
->igtk_idx
])
96 prot
= os_malloc(plen
);
99 os_memcpy(prot
, frame
, len
);
101 *pos
++ = WLAN_EID_MMIE
;
103 WPA_PUT_LE16(pos
, bss
->igtk_idx
);
105 inc_byte_array(bss
->ipn
[bss
->igtk_idx
], 6);
106 os_memcpy(pos
, bss
->ipn
[bss
->igtk_idx
], 6);
108 os_memset(pos
, 0, 8); /* MIC */
110 buf
= os_malloc(plen
+ 20 - 24);
116 /* BIP AAD: FC(masked) A1 A2 A3 */
117 hdr
= (struct ieee80211_hdr
*) frame
;
118 fc
= le_to_host16(hdr
->frame_control
);
119 fc
&= ~(WLAN_FC_RETRY
| WLAN_FC_PWRMGT
| WLAN_FC_MOREDATA
);
120 WPA_PUT_LE16(buf
, fc
);
121 os_memcpy(buf
+ 2, hdr
->addr1
, 3 * ETH_ALEN
);
122 os_memcpy(buf
+ 20, prot
+ 24, plen
- 24);
123 wpa_hexdump(MSG_MSGDUMP
, "BIP: AAD|Body(masked)", buf
, plen
+ 20 - 24);
124 /* MIC = L(AES-128-CMAC(AAD || Frame Body(masked)), 0, 64) */
125 os_memset(dummy
, 0x11, sizeof(dummy
));
126 if (omac1_aes_128(incorrect_key
? dummy
: bss
->igtk
[bss
->igtk_idx
],
127 buf
, plen
+ 20 - 24, mic
) < 0) {
134 os_memcpy(pos
, mic
, 8);
135 wpa_hexdump(MSG_DEBUG
, "BIP MMIE MIC", pos
, 8);
137 ret
= inject_frame(wt
->monitor_sock
, prot
, plen
);
140 return (ret
< 0) ? -1 : 0;
144 static int wlantest_inject_prot_bc(struct wlantest
*wt
,
145 struct wlantest_bss
*bss
,
146 u8
*frame
, size_t len
, int incorrect_key
)
153 struct ieee80211_hdr
*hdr
;
157 hdr
= (struct ieee80211_hdr
*) frame
;
159 fc
= le_to_host16(hdr
->frame_control
);
161 if (!bss
->gtk_len
[bss
->gtk_idx
])
164 if ((fc
& (WLAN_FC_TODS
| WLAN_FC_FROMDS
)) ==
165 (WLAN_FC_TODS
| WLAN_FC_FROMDS
))
167 pn
= bss
->rsc
[bss
->gtk_idx
];
168 inc_byte_array(pn
, 6);
170 os_memset(dummy
, 0x11, sizeof(dummy
));
171 if (bss
->group_cipher
== WPA_CIPHER_TKIP
)
172 crypt
= tkip_encrypt(incorrect_key
? dummy
:
173 bss
->gtk
[bss
->gtk_idx
],
174 frame
, len
, hdrlen
, NULL
, pn
,
175 bss
->gtk_idx
, &crypt_len
);
177 crypt
= ccmp_encrypt(incorrect_key
? dummy
:
178 bss
->gtk
[bss
->gtk_idx
],
179 frame
, len
, hdrlen
, NULL
, pn
,
180 bss
->gtk_idx
, &crypt_len
);
185 ret
= inject_frame(wt
->monitor_sock
, crypt
, crypt_len
);
188 return (ret
< 0) ? -1 : 0;
192 static int wlantest_inject_prot(struct wlantest
*wt
, struct wlantest_bss
*bss
,
193 struct wlantest_sta
*sta
, u8
*frame
,
194 size_t len
, int incorrect_key
)
201 struct ieee80211_hdr
*hdr
;
206 struct wlantest_tdls
*tdls
= NULL
;
209 hdr
= (struct ieee80211_hdr
*) frame
;
211 fc
= le_to_host16(hdr
->frame_control
);
213 if (WLAN_FC_GET_TYPE(fc
) == WLAN_FC_TYPE_DATA
&&
214 (fc
& (WLAN_FC_TODS
| WLAN_FC_FROMDS
)) == 0) {
215 struct wlantest_sta
*sta2
;
216 bss
= bss_get(wt
, hdr
->addr3
);
218 wpa_printf(MSG_DEBUG
, "No BSS found for TDLS "
222 sta
= sta_find(bss
, hdr
->addr2
);
223 sta2
= sta_find(bss
, hdr
->addr1
);
224 if (sta
== NULL
|| sta2
== NULL
) {
225 wpa_printf(MSG_DEBUG
, "No stations found for TDLS "
229 dl_list_for_each(tdls
, &bss
->tdls
, struct wlantest_tdls
, list
)
231 if ((tdls
->init
== sta
&& tdls
->resp
== sta2
) ||
232 (tdls
->init
== sta2
&& tdls
->resp
== sta
)) {
234 wpa_printf(MSG_DEBUG
, "TDLS: Link not "
235 "up, but injecting Data "
236 "frame on direct link");
243 if (tk
== NULL
&& sta
== NULL
) {
244 if (WLAN_FC_GET_TYPE(fc
) == WLAN_FC_TYPE_MGMT
)
245 return wlantest_inject_bip(wt
, bss
, frame
, len
,
247 return wlantest_inject_prot_bc(wt
, bss
, frame
, len
,
251 if (tk
== NULL
&& !sta
->ptk_set
) {
252 wpa_printf(MSG_DEBUG
, "No key known for injection");
256 if (WLAN_FC_GET_TYPE(fc
) == WLAN_FC_TYPE_MGMT
)
258 else if (WLAN_FC_GET_TYPE(fc
) == WLAN_FC_TYPE_DATA
) {
259 if ((fc
& (WLAN_FC_TODS
| WLAN_FC_FROMDS
)) ==
260 (WLAN_FC_TODS
| WLAN_FC_FROMDS
))
262 if (WLAN_FC_GET_STYPE(fc
) & 0x08) {
263 qos
= frame
+ hdrlen
;
269 if (os_memcmp(hdr
->addr2
, tdls
->init
->addr
, ETH_ALEN
) == 0)
270 pn
= tdls
->rsc_init
[tid
];
272 pn
= tdls
->rsc_resp
[tid
];
273 } else if (os_memcmp(hdr
->addr2
, bss
->bssid
, ETH_ALEN
) == 0)
274 pn
= sta
->rsc_fromds
[tid
];
276 pn
= sta
->rsc_tods
[tid
];
277 inc_byte_array(pn
, 6);
279 os_memset(dummy
, 0x11, sizeof(dummy
));
281 crypt
= ccmp_encrypt(incorrect_key
? dummy
: tk
,
282 frame
, len
, hdrlen
, qos
, pn
, 0,
284 else if (sta
->pairwise_cipher
== WPA_CIPHER_TKIP
)
285 crypt
= tkip_encrypt(incorrect_key
? dummy
: sta
->ptk
.tk1
,
286 frame
, len
, hdrlen
, qos
, pn
, 0,
289 crypt
= ccmp_encrypt(incorrect_key
? dummy
: sta
->ptk
.tk1
,
290 frame
, len
, hdrlen
, qos
, pn
, 0,
294 wpa_printf(MSG_DEBUG
, "Frame encryption failed");
298 wpa_hexdump(MSG_DEBUG
, "Inject frame (encrypted)", crypt
, crypt_len
);
299 ret
= inject_frame(wt
->monitor_sock
, crypt
, crypt_len
);
301 wpa_printf(MSG_DEBUG
, "inject_frame for protected frame: %d", ret
);
303 return (ret
< 0) ? -1 : 0;
307 int wlantest_inject(struct wlantest
*wt
, struct wlantest_bss
*bss
,
308 struct wlantest_sta
*sta
, u8
*frame
, size_t len
,
309 enum wlantest_inject_protection prot
)
312 struct ieee80211_hdr
*hdr
;
314 int protectable
, protect
= 0;
316 wpa_hexdump(MSG_DEBUG
, "Inject frame", frame
, len
);
317 if (wt
->monitor_sock
< 0) {
318 wpa_printf(MSG_INFO
, "Cannot inject frames when monitor "
319 "interface is not in use");
323 if (prot
!= WLANTEST_INJECT_UNPROTECTED
&&
324 (bss
== NULL
|| sta
== NULL
)) {
325 wpa_printf(MSG_INFO
, "No BSS/STA information to inject "
330 hdr
= (struct ieee80211_hdr
*) frame
;
331 fc
= le_to_host16(hdr
->frame_control
);
332 protectable
= WLAN_FC_GET_TYPE(fc
) == WLAN_FC_TYPE_DATA
||
333 is_robust_mgmt(frame
, len
);
335 if ((prot
== WLANTEST_INJECT_PROTECTED
||
336 prot
== WLANTEST_INJECT_INCORRECT_KEY
) && bss
) {
338 ((WLAN_FC_GET_TYPE(fc
) == WLAN_FC_TYPE_MGMT
&&
339 !bss
->igtk_set
[bss
->igtk_idx
]) ||
340 (WLAN_FC_GET_TYPE(fc
) == WLAN_FC_TYPE_DATA
&&
341 !bss
->gtk_len
[bss
->gtk_idx
]))) {
342 wpa_printf(MSG_INFO
, "No GTK/IGTK known for "
343 MACSTR
" to protect the injected "
344 "frame", MAC2STR(bss
->bssid
));
347 if (sta
&& !sta
->ptk_set
) {
348 wpa_printf(MSG_INFO
, "No PTK known for the STA " MACSTR
349 " to encrypt the injected frame",
354 } else if (protectable
&& prot
!= WLANTEST_INJECT_UNPROTECTED
&& bss
) {
355 if (sta
&& sta
->ptk_set
)
358 if (WLAN_FC_GET_TYPE(fc
) == WLAN_FC_TYPE_DATA
&&
359 bss
->gtk_len
[bss
->gtk_idx
])
361 if (WLAN_FC_GET_TYPE(fc
) == WLAN_FC_TYPE_MGMT
&&
362 bss
->igtk_set
[bss
->igtk_idx
])
368 return wlantest_inject_prot(
369 wt
, bss
, sta
, frame
, len
,
370 prot
== WLANTEST_INJECT_INCORRECT_KEY
);
372 ret
= inject_frame(wt
->monitor_sock
, frame
, len
);
373 wpa_printf(MSG_DEBUG
, "inject_frame for unprotected frame: %d", ret
);
374 return (ret
< 0) ? -1 : 0;