]>
git.ipfire.org Git - thirdparty/hostap.git/blob - wlantest/wlantest.c
2 * wlantest - IEEE 802.11 protocol monitoring and testing tool
3 * Copyright (c) 2010-2015, 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 "utils/eloop.h"
16 static void wlantest_terminate(int sig
, void *signal_ctx
)
22 static void usage(void)
24 printf("wlantest [-cddhqqFNt] [-i<ifname>] [-r<pcap file>] "
26 " [-I<wired ifname>] [-R<wired pcap file>] "
27 "[-P<RADIUS shared secret>]\n"
28 " [-n<write pcapng file>]\n"
29 " [-w<write pcap file>] [-f<MSK/PMK file>]\n"
30 " [-L<log file>] [-T<PTK file>]\n");
34 static void passphrase_deinit(struct wlantest_passphrase
*p
)
36 dl_list_del(&p
->list
);
41 static void secret_deinit(struct wlantest_radius_secret
*r
)
43 dl_list_del(&r
->list
);
48 static void wlantest_init(struct wlantest
*wt
)
51 os_memset(wt
, 0, sizeof(*wt
));
52 wt
->monitor_sock
= -1;
54 for (i
= 0; i
< MAX_CTRL_CONNECTIONS
; i
++)
55 wt
->ctrl_socks
[i
] = -1;
56 dl_list_init(&wt
->passphrase
);
57 dl_list_init(&wt
->bss
);
58 dl_list_init(&wt
->secret
);
59 dl_list_init(&wt
->radius
);
60 dl_list_init(&wt
->pmk
);
61 dl_list_init(&wt
->ptk
);
62 dl_list_init(&wt
->wep
);
66 void radius_deinit(struct wlantest_radius
*r
)
68 dl_list_del(&r
->list
);
73 static void ptk_deinit(struct wlantest_ptk
*ptk
)
75 dl_list_del(&ptk
->list
);
80 static void wlantest_deinit(struct wlantest
*wt
)
82 struct wlantest_passphrase
*p
, *pn
;
83 struct wlantest_radius_secret
*s
, *sn
;
84 struct wlantest_radius
*r
, *rn
;
85 struct wlantest_pmk
*pmk
, *np
;
86 struct wlantest_ptk
*ptk
, *npt
;
87 struct wlantest_wep
*wep
, *nw
;
89 if (wt
->ctrl_sock
>= 0)
91 if (wt
->monitor_sock
>= 0)
94 dl_list_for_each_safe(p
, pn
, &wt
->passphrase
,
95 struct wlantest_passphrase
, list
)
97 dl_list_for_each_safe(s
, sn
, &wt
->secret
,
98 struct wlantest_radius_secret
, list
)
100 dl_list_for_each_safe(r
, rn
, &wt
->radius
, struct wlantest_radius
, list
)
102 dl_list_for_each_safe(pmk
, np
, &wt
->pmk
, struct wlantest_pmk
, list
)
104 dl_list_for_each_safe(ptk
, npt
, &wt
->ptk
, struct wlantest_ptk
, list
)
106 dl_list_for_each_safe(wep
, nw
, &wt
->wep
, struct wlantest_wep
, list
)
108 write_pcap_deinit(wt
);
109 write_pcapng_deinit(wt
);
111 os_free(wt
->decrypted
);
112 wt
->decrypted
= NULL
;
116 static void add_passphrase(struct wlantest
*wt
, const char *passphrase
)
118 struct wlantest_passphrase
*p
;
119 size_t len
= os_strlen(passphrase
);
121 if (len
< 8 || len
> 63)
123 p
= os_zalloc(sizeof(*p
));
126 os_memcpy(p
->passphrase
, passphrase
, len
);
127 dl_list_add(&wt
->passphrase
, &p
->list
);
131 static void add_secret(struct wlantest
*wt
, const char *secret
)
133 struct wlantest_radius_secret
*s
;
134 size_t len
= os_strlen(secret
);
136 if (len
>= MAX_RADIUS_SECRET_LEN
)
138 s
= os_zalloc(sizeof(*s
));
141 os_memcpy(s
->secret
, secret
, len
);
142 dl_list_add(&wt
->secret
, &s
->list
);
146 static int add_pmk_file(struct wlantest
*wt
, const char *pmk_file
)
151 struct wlantest_pmk
*p
;
153 f
= fopen(pmk_file
, "r");
155 wpa_printf(MSG_ERROR
, "Could not open '%s'", pmk_file
);
159 while (fgets(buf
, sizeof(buf
), f
)) {
161 while (*pos
&& *pos
!= '\r' && *pos
!= '\n')
164 if (pos
- buf
< 2 * 32)
166 if (hexstr2bin(buf
, pmk
, 32) < 0)
168 p
= os_zalloc(sizeof(*p
));
171 os_memcpy(p
->pmk
, pmk
, 32);
172 dl_list_add(&wt
->pmk
, &p
->list
);
173 wpa_hexdump(MSG_DEBUG
, "Added PMK from file", pmk
, 32);
181 static int add_ptk_file(struct wlantest
*wt
, const char *ptk_file
)
187 struct wlantest_ptk
*p
;
189 f
= fopen(ptk_file
, "r");
191 wpa_printf(MSG_ERROR
, "Could not open '%s'", ptk_file
);
195 while (fgets(buf
, sizeof(buf
), f
)) {
197 while (*pos
&& *pos
!= '\r' && *pos
!= '\n')
204 if (ptk_len
!= 16 && ptk_len
!= 32 &&
205 ptk_len
!= 48 && ptk_len
!= 64)
207 if (hexstr2bin(buf
, ptk
, ptk_len
) < 0)
209 p
= os_zalloc(sizeof(*p
));
213 os_memcpy(p
->ptk
.tk
, ptk
, ptk_len
);
214 p
->ptk
.tk_len
= ptk_len
;
215 p
->ptk_len
= 32 + ptk_len
;
217 os_memcpy(p
->ptk
.kck
, ptk
, 16);
219 os_memcpy(p
->ptk
.kek
, ptk
+ 16, 16);
221 os_memcpy(p
->ptk
.tk
, ptk
+ 32, ptk_len
- 32);
222 p
->ptk
.tk_len
= ptk_len
- 32;
223 p
->ptk_len
= ptk_len
;
225 dl_list_add(&wt
->ptk
, &p
->list
);
226 wpa_hexdump(MSG_DEBUG
, "Added PTK from file", ptk
, ptk_len
);
234 int add_wep(struct wlantest
*wt
, const char *key
)
236 struct wlantest_wep
*w
;
237 size_t len
= os_strlen(key
);
239 if (len
!= 2 * 5 && len
!= 2 * 13) {
240 wpa_printf(MSG_INFO
, "Invalid WEP key '%s'", key
);
243 w
= os_zalloc(sizeof(*w
));
246 if (hexstr2bin(key
, w
->key
, len
/ 2) < 0) {
248 wpa_printf(MSG_INFO
, "Invalid WEP key '%s'", key
);
251 w
->key_len
= len
/ 2;
252 dl_list_add(&wt
->wep
, &w
->list
);
257 void add_note(struct wlantest
*wt
, int level
, const char *fmt
, ...)
263 if (wt
->num_notes
== MAX_NOTES
)
266 wt
->notes
[wt
->num_notes
] = os_malloc(len
);
267 if (wt
->notes
[wt
->num_notes
] == NULL
)
270 wlen
= vsnprintf(wt
->notes
[wt
->num_notes
], len
, fmt
, ap
);
273 os_free(wt
->notes
[wt
->num_notes
]);
274 wt
->notes
[wt
->num_notes
] = NULL
;
278 wt
->notes
[wt
->num_notes
][len
- 1] = '\0';
279 wpa_printf(level
, "%s", wt
->notes
[wt
->num_notes
]);
284 void clear_notes(struct wlantest
*wt
)
288 for (i
= 0; i
< wt
->num_notes
; i
++) {
289 os_free(wt
->notes
[i
]);
297 size_t notes_len(struct wlantest
*wt
, size_t hdrlen
)
300 size_t len
= wt
->num_notes
* hdrlen
;
302 for (i
= 0; i
< wt
->num_notes
; i
++)
303 len
+= os_strlen(wt
->notes
[i
]);
309 int wlantest_relog(struct wlantest
*wt
)
313 wpa_printf(MSG_INFO
, "Re-open log/capture files");
314 if (wpa_debug_reopen_file())
317 if (wt
->write_file
) {
318 write_pcap_deinit(wt
);
319 if (write_pcap_init(wt
, wt
->write_file
) < 0)
323 if (wt
->pcapng_file
) {
324 write_pcapng_deinit(wt
);
325 if (write_pcapng_init(wt
, wt
->pcapng_file
) < 0)
333 int main(int argc
, char *argv
[])
336 const char *read_file
= NULL
;
337 const char *read_wired_file
= NULL
;
338 const char *ifname
= NULL
;
339 const char *ifname_wired
= NULL
;
340 const char *logfile
= NULL
;
344 wpa_debug_level
= MSG_INFO
;
345 wpa_debug_show_keys
= 1;
347 if (os_program_init())
353 c
= getopt(argc
, argv
, "cdf:Fhi:I:L:n:Np:P:qr:R:tT:w:W:");
361 if (wpa_debug_level
> 0)
365 if (add_pmk_file(&wt
, optarg
) < 0)
378 ifname_wired
= optarg
;
384 wt
.pcapng_file
= optarg
;
387 wt
.pcap_no_buffer
= 1;
390 add_passphrase(&wt
, optarg
);
393 add_secret(&wt
, optarg
);
402 read_wired_file
= optarg
;
405 wpa_debug_timestamp
= 1;
408 if (add_ptk_file(&wt
, optarg
) < 0)
412 wt
.write_file
= optarg
;
415 if (add_wep(&wt
, optarg
) < 0)
424 if (ifname
== NULL
&& ifname_wired
== NULL
&&
425 read_file
== NULL
&& read_wired_file
== NULL
) {
434 wpa_debug_open_file(logfile
);
436 if (wt
.write_file
&& write_pcap_init(&wt
, wt
.write_file
) < 0)
439 if (wt
.pcapng_file
&& write_pcapng_init(&wt
, wt
.pcapng_file
) < 0)
442 if (read_wired_file
&& read_wired_cap_file(&wt
, read_wired_file
) < 0)
445 if (read_file
&& read_cap_file(&wt
, read_file
) < 0)
448 if (ifname
&& monitor_init(&wt
, ifname
) < 0)
451 if (ifname_wired
&& monitor_init_wired(&wt
, ifname_wired
) < 0)
454 if (ctrl_iface
&& ctrl_init(&wt
) < 0)
457 eloop_register_signal_terminate(wlantest_terminate
, &wt
);
461 wpa_printf(MSG_INFO
, "Processed: rx_mgmt=%u rx_ctrl=%u rx_data=%u "
463 wt
.rx_mgmt
, wt
.rx_ctrl
, wt
.rx_data
, wt
.fcs_error
);
465 wlantest_deinit(&wt
);
467 wpa_debug_close_file();