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 if (!bss
->igtk_set
[bss
->igtk_idx
])
92 os_memset(dummy
, 0x11, sizeof(dummy
));
93 inc_byte_array(bss
->ipn
[bss
->igtk_idx
], 6);
95 prot
= bip_protect(incorrect_key
? dummy
: bss
->igtk
[bss
->igtk_idx
],
96 frame
, len
, bss
->ipn
[bss
->igtk_idx
],
97 bss
->igtk_idx
, &plen
);
102 ret
= inject_frame(wt
->monitor_sock
, prot
, plen
);
105 return (ret
< 0) ? -1 : 0;
109 static int wlantest_inject_prot_bc(struct wlantest
*wt
,
110 struct wlantest_bss
*bss
,
111 u8
*frame
, size_t len
, int incorrect_key
)
118 struct ieee80211_hdr
*hdr
;
122 hdr
= (struct ieee80211_hdr
*) frame
;
124 fc
= le_to_host16(hdr
->frame_control
);
126 if (!bss
->gtk_len
[bss
->gtk_idx
])
129 if ((fc
& (WLAN_FC_TODS
| WLAN_FC_FROMDS
)) ==
130 (WLAN_FC_TODS
| WLAN_FC_FROMDS
))
132 pn
= bss
->rsc
[bss
->gtk_idx
];
133 inc_byte_array(pn
, 6);
135 os_memset(dummy
, 0x11, sizeof(dummy
));
136 if (bss
->group_cipher
== WPA_CIPHER_TKIP
)
137 crypt
= tkip_encrypt(incorrect_key
? dummy
:
138 bss
->gtk
[bss
->gtk_idx
],
139 frame
, len
, hdrlen
, NULL
, pn
,
140 bss
->gtk_idx
, &crypt_len
);
142 crypt
= ccmp_encrypt(incorrect_key
? dummy
:
143 bss
->gtk
[bss
->gtk_idx
],
144 frame
, len
, hdrlen
, NULL
, pn
,
145 bss
->gtk_idx
, &crypt_len
);
150 ret
= inject_frame(wt
->monitor_sock
, crypt
, crypt_len
);
153 return (ret
< 0) ? -1 : 0;
157 static int wlantest_inject_prot(struct wlantest
*wt
, struct wlantest_bss
*bss
,
158 struct wlantest_sta
*sta
, u8
*frame
,
159 size_t len
, int incorrect_key
)
166 struct ieee80211_hdr
*hdr
;
171 struct wlantest_tdls
*tdls
= NULL
;
174 hdr
= (struct ieee80211_hdr
*) frame
;
176 fc
= le_to_host16(hdr
->frame_control
);
178 if (WLAN_FC_GET_TYPE(fc
) == WLAN_FC_TYPE_DATA
&&
179 (fc
& (WLAN_FC_TODS
| WLAN_FC_FROMDS
)) == 0) {
180 struct wlantest_sta
*sta2
;
181 bss
= bss_get(wt
, hdr
->addr3
);
183 wpa_printf(MSG_DEBUG
, "No BSS found for TDLS "
187 sta
= sta_find(bss
, hdr
->addr2
);
188 sta2
= sta_find(bss
, hdr
->addr1
);
189 if (sta
== NULL
|| sta2
== NULL
) {
190 wpa_printf(MSG_DEBUG
, "No stations found for TDLS "
194 dl_list_for_each(tdls
, &bss
->tdls
, struct wlantest_tdls
, list
)
196 if ((tdls
->init
== sta
&& tdls
->resp
== sta2
) ||
197 (tdls
->init
== sta2
&& tdls
->resp
== sta
)) {
199 wpa_printf(MSG_DEBUG
, "TDLS: Link not "
200 "up, but injecting Data "
201 "frame on direct link");
208 if (tk
== NULL
&& sta
== NULL
) {
209 if (WLAN_FC_GET_TYPE(fc
) == WLAN_FC_TYPE_MGMT
)
210 return wlantest_inject_bip(wt
, bss
, frame
, len
,
212 return wlantest_inject_prot_bc(wt
, bss
, frame
, len
,
216 if (tk
== NULL
&& !sta
->ptk_set
) {
217 wpa_printf(MSG_DEBUG
, "No key known for injection");
221 if (WLAN_FC_GET_TYPE(fc
) == WLAN_FC_TYPE_MGMT
)
223 else if (WLAN_FC_GET_TYPE(fc
) == WLAN_FC_TYPE_DATA
) {
224 if ((fc
& (WLAN_FC_TODS
| WLAN_FC_FROMDS
)) ==
225 (WLAN_FC_TODS
| WLAN_FC_FROMDS
))
227 if (WLAN_FC_GET_STYPE(fc
) & 0x08) {
228 qos
= frame
+ hdrlen
;
234 if (os_memcmp(hdr
->addr2
, tdls
->init
->addr
, ETH_ALEN
) == 0)
235 pn
= tdls
->rsc_init
[tid
];
237 pn
= tdls
->rsc_resp
[tid
];
238 } else if (os_memcmp(hdr
->addr2
, bss
->bssid
, ETH_ALEN
) == 0)
239 pn
= sta
->rsc_fromds
[tid
];
241 pn
= sta
->rsc_tods
[tid
];
242 inc_byte_array(pn
, 6);
244 os_memset(dummy
, 0x11, sizeof(dummy
));
246 crypt
= ccmp_encrypt(incorrect_key
? dummy
: tk
,
247 frame
, len
, hdrlen
, qos
, pn
, 0,
249 else if (sta
->pairwise_cipher
== WPA_CIPHER_TKIP
)
250 crypt
= tkip_encrypt(incorrect_key
? dummy
: sta
->ptk
.tk1
,
251 frame
, len
, hdrlen
, qos
, pn
, 0,
254 crypt
= ccmp_encrypt(incorrect_key
? dummy
: sta
->ptk
.tk1
,
255 frame
, len
, hdrlen
, qos
, pn
, 0,
259 wpa_printf(MSG_DEBUG
, "Frame encryption failed");
263 wpa_hexdump(MSG_DEBUG
, "Inject frame (encrypted)", crypt
, crypt_len
);
264 ret
= inject_frame(wt
->monitor_sock
, crypt
, crypt_len
);
266 wpa_printf(MSG_DEBUG
, "inject_frame for protected frame: %d", ret
);
268 return (ret
< 0) ? -1 : 0;
272 int wlantest_inject(struct wlantest
*wt
, struct wlantest_bss
*bss
,
273 struct wlantest_sta
*sta
, u8
*frame
, size_t len
,
274 enum wlantest_inject_protection prot
)
277 struct ieee80211_hdr
*hdr
;
279 int protectable
, protect
= 0;
281 wpa_hexdump(MSG_DEBUG
, "Inject frame", frame
, len
);
282 if (wt
->monitor_sock
< 0) {
283 wpa_printf(MSG_INFO
, "Cannot inject frames when monitor "
284 "interface is not in use");
288 if (prot
!= WLANTEST_INJECT_UNPROTECTED
&& bss
== NULL
) {
289 wpa_printf(MSG_INFO
, "No BSS information to inject "
294 hdr
= (struct ieee80211_hdr
*) frame
;
295 fc
= le_to_host16(hdr
->frame_control
);
296 protectable
= WLAN_FC_GET_TYPE(fc
) == WLAN_FC_TYPE_DATA
||
297 is_robust_mgmt(frame
, len
);
299 if ((prot
== WLANTEST_INJECT_PROTECTED
||
300 prot
== WLANTEST_INJECT_INCORRECT_KEY
) && bss
) {
302 ((WLAN_FC_GET_TYPE(fc
) == WLAN_FC_TYPE_MGMT
&&
303 !bss
->igtk_set
[bss
->igtk_idx
]) ||
304 (WLAN_FC_GET_TYPE(fc
) == WLAN_FC_TYPE_DATA
&&
305 !bss
->gtk_len
[bss
->gtk_idx
]))) {
306 wpa_printf(MSG_INFO
, "No GTK/IGTK known for "
307 MACSTR
" to protect the injected "
308 "frame", MAC2STR(bss
->bssid
));
311 if (sta
&& !sta
->ptk_set
) {
312 wpa_printf(MSG_INFO
, "No PTK known for the STA " MACSTR
313 " to encrypt the injected frame",
318 } else if (protectable
&& prot
!= WLANTEST_INJECT_UNPROTECTED
&& bss
) {
319 if (sta
&& sta
->ptk_set
)
322 if (WLAN_FC_GET_TYPE(fc
) == WLAN_FC_TYPE_DATA
&&
323 bss
->gtk_len
[bss
->gtk_idx
])
325 if (WLAN_FC_GET_TYPE(fc
) == WLAN_FC_TYPE_MGMT
&&
326 bss
->igtk_set
[bss
->igtk_idx
])
332 return wlantest_inject_prot(
333 wt
, bss
, sta
, frame
, len
,
334 prot
== WLANTEST_INJECT_INCORRECT_KEY
);
336 ret
= inject_frame(wt
->monitor_sock
, frame
, len
);
337 wpa_printf(MSG_DEBUG
, "inject_frame for unprotected frame: %d", ret
);
338 return (ret
< 0) ? -1 : 0;