]>
Commit | Line | Data |
---|---|---|
6fc6879b JM |
1 | /* |
2 | * wpa_supplicant/hostapd / Debug prints | |
47bfe49c | 3 | * Copyright (c) 2002-2013, Jouni Malinen <j@w1.fi> |
6fc6879b | 4 | * |
0f3d578e JM |
5 | * This software may be distributed under the terms of the BSD license. |
6 | * See README for more details. | |
6fc6879b JM |
7 | */ |
8 | ||
9 | #include "includes.h" | |
10 | ||
11 | #include "common.h" | |
12 | ||
daa70d49 SL |
13 | #ifdef CONFIG_DEBUG_SYSLOG |
14 | #include <syslog.h> | |
15 | ||
cc3dae85 | 16 | int wpa_debug_syslog = 0; |
daa70d49 SL |
17 | #endif /* CONFIG_DEBUG_SYSLOG */ |
18 | ||
4f68895e JB |
19 | #ifdef CONFIG_DEBUG_LINUX_TRACING |
20 | #include <sys/types.h> | |
21 | #include <sys/stat.h> | |
22 | #include <fcntl.h> | |
23 | #include <string.h> | |
24 | #include <stdio.h> | |
25 | ||
26 | static FILE *wpa_debug_tracing_file = NULL; | |
27 | ||
28 | #define WPAS_TRACE_PFX "wpas <%d>: " | |
29 | #endif /* CONFIG_DEBUG_LINUX_TRACING */ | |
30 | ||
6fc6879b | 31 | |
6fc6879b JM |
32 | int wpa_debug_level = MSG_INFO; |
33 | int wpa_debug_show_keys = 0; | |
34 | int wpa_debug_timestamp = 0; | |
35 | ||
36 | ||
193f439a DS |
37 | #ifdef CONFIG_ANDROID_LOG |
38 | ||
39 | #include <android/log.h> | |
40 | ||
8f5b9aa1 DS |
41 | #ifndef ANDROID_LOG_NAME |
42 | #define ANDROID_LOG_NAME "wpa_supplicant" | |
43 | #endif /* ANDROID_LOG_NAME */ | |
44 | ||
4a0d25f0 | 45 | static int wpa_to_android_level(int level) |
193f439a | 46 | { |
4a0d25f0 JM |
47 | if (level == MSG_ERROR) |
48 | return ANDROID_LOG_ERROR; | |
49 | if (level == MSG_WARNING) | |
50 | return ANDROID_LOG_WARN; | |
51 | if (level == MSG_INFO) | |
52 | return ANDROID_LOG_INFO; | |
53 | return ANDROID_LOG_DEBUG; | |
193f439a DS |
54 | } |
55 | ||
4a0d25f0 | 56 | #endif /* CONFIG_ANDROID_LOG */ |
193f439a | 57 | |
6fc6879b JM |
58 | #ifndef CONFIG_NO_STDOUT_DEBUG |
59 | ||
50b16da1 JM |
60 | #ifdef CONFIG_DEBUG_FILE |
61 | static FILE *out_file = NULL; | |
62 | #endif /* CONFIG_DEBUG_FILE */ | |
63 | ||
64 | ||
6fc6879b JM |
65 | void wpa_debug_print_timestamp(void) |
66 | { | |
4a0d25f0 | 67 | #ifndef CONFIG_ANDROID_LOG |
6fc6879b JM |
68 | struct os_time tv; |
69 | ||
70 | if (!wpa_debug_timestamp) | |
71 | return; | |
72 | ||
73 | os_get_time(&tv); | |
74 | #ifdef CONFIG_DEBUG_FILE | |
75 | if (out_file) { | |
76 | fprintf(out_file, "%ld.%06u: ", (long) tv.sec, | |
77 | (unsigned int) tv.usec); | |
78 | } else | |
79 | #endif /* CONFIG_DEBUG_FILE */ | |
80 | printf("%ld.%06u: ", (long) tv.sec, (unsigned int) tv.usec); | |
4a0d25f0 | 81 | #endif /* CONFIG_ANDROID_LOG */ |
6fc6879b JM |
82 | } |
83 | ||
84 | ||
daa70d49 | 85 | #ifdef CONFIG_DEBUG_SYSLOG |
3e199621 SL |
86 | #ifndef LOG_HOSTAPD |
87 | #define LOG_HOSTAPD LOG_DAEMON | |
88 | #endif /* LOG_HOSTAPD */ | |
89 | ||
daa70d49 SL |
90 | void wpa_debug_open_syslog(void) |
91 | { | |
3e199621 | 92 | openlog("wpa_supplicant", LOG_PID | LOG_NDELAY, LOG_HOSTAPD); |
daa70d49 SL |
93 | wpa_debug_syslog++; |
94 | } | |
95 | ||
96 | ||
97 | void wpa_debug_close_syslog(void) | |
98 | { | |
99 | if (wpa_debug_syslog) | |
100 | closelog(); | |
101 | } | |
102 | ||
103 | ||
104 | static int syslog_priority(int level) | |
105 | { | |
106 | switch (level) { | |
107 | case MSG_MSGDUMP: | |
108 | case MSG_DEBUG: | |
109 | return LOG_DEBUG; | |
110 | case MSG_INFO: | |
111 | return LOG_NOTICE; | |
112 | case MSG_WARNING: | |
113 | return LOG_WARNING; | |
114 | case MSG_ERROR: | |
115 | return LOG_ERR; | |
116 | } | |
117 | return LOG_INFO; | |
118 | } | |
119 | #endif /* CONFIG_DEBUG_SYSLOG */ | |
120 | ||
121 | ||
4f68895e JB |
122 | #ifdef CONFIG_DEBUG_LINUX_TRACING |
123 | ||
124 | int wpa_debug_open_linux_tracing(void) | |
125 | { | |
126 | int mounts, trace_fd; | |
127 | char buf[4096] = {}; | |
128 | ssize_t buflen; | |
129 | char *line, *tmp1, *path = NULL; | |
130 | ||
131 | mounts = open("/proc/mounts", O_RDONLY); | |
132 | if (mounts < 0) { | |
133 | printf("no /proc/mounts\n"); | |
134 | return -1; | |
135 | } | |
136 | ||
137 | buflen = read(mounts, buf, sizeof(buf) - 1); | |
138 | close(mounts); | |
139 | if (buflen < 0) { | |
140 | printf("failed to read /proc/mounts\n"); | |
141 | return -1; | |
142 | } | |
143 | ||
144 | line = strtok_r(buf, "\n", &tmp1); | |
145 | while (line) { | |
146 | char *tmp2, *tmp_path, *fstype; | |
147 | /* "<dev> <mountpoint> <fs type> ..." */ | |
148 | strtok_r(line, " ", &tmp2); | |
149 | tmp_path = strtok_r(NULL, " ", &tmp2); | |
150 | fstype = strtok_r(NULL, " ", &tmp2); | |
819ad5b7 | 151 | if (fstype && strcmp(fstype, "debugfs") == 0) { |
4f68895e JB |
152 | path = tmp_path; |
153 | break; | |
154 | } | |
155 | ||
156 | line = strtok_r(NULL, "\n", &tmp1); | |
157 | } | |
158 | ||
159 | if (path == NULL) { | |
160 | printf("debugfs mountpoint not found\n"); | |
161 | return -1; | |
162 | } | |
163 | ||
164 | snprintf(buf, sizeof(buf) - 1, "%s/tracing/trace_marker", path); | |
165 | ||
166 | trace_fd = open(buf, O_WRONLY); | |
167 | if (trace_fd < 0) { | |
168 | printf("failed to open trace_marker file\n"); | |
169 | return -1; | |
170 | } | |
171 | wpa_debug_tracing_file = fdopen(trace_fd, "w"); | |
172 | if (wpa_debug_tracing_file == NULL) { | |
173 | close(trace_fd); | |
174 | printf("failed to fdopen()\n"); | |
175 | return -1; | |
176 | } | |
177 | ||
178 | return 0; | |
179 | } | |
180 | ||
181 | ||
182 | void wpa_debug_close_linux_tracing(void) | |
183 | { | |
184 | if (wpa_debug_tracing_file == NULL) | |
185 | return; | |
186 | fclose(wpa_debug_tracing_file); | |
187 | wpa_debug_tracing_file = NULL; | |
188 | } | |
189 | ||
190 | #endif /* CONFIG_DEBUG_LINUX_TRACING */ | |
191 | ||
192 | ||
6fc6879b JM |
193 | /** |
194 | * wpa_printf - conditional printf | |
195 | * @level: priority level (MSG_*) of the message | |
196 | * @fmt: printf format string, followed by optional arguments | |
197 | * | |
198 | * This function is used to print conditional debugging and error messages. The | |
199 | * output may be directed to stdout, stderr, and/or syslog based on | |
200 | * configuration. | |
201 | * | |
202 | * Note: New line '\n' is added to the end of the text when printing to stdout. | |
203 | */ | |
0de4da91 | 204 | void wpa_printf(int level, const char *fmt, ...) |
6fc6879b JM |
205 | { |
206 | va_list ap; | |
207 | ||
208 | va_start(ap, fmt); | |
209 | if (level >= wpa_debug_level) { | |
4a0d25f0 JM |
210 | #ifdef CONFIG_ANDROID_LOG |
211 | __android_log_vprint(wpa_to_android_level(level), | |
212 | ANDROID_LOG_NAME, fmt, ap); | |
213 | #else /* CONFIG_ANDROID_LOG */ | |
daa70d49 SL |
214 | #ifdef CONFIG_DEBUG_SYSLOG |
215 | if (wpa_debug_syslog) { | |
216 | vsyslog(syslog_priority(level), fmt, ap); | |
217 | } else { | |
218 | #endif /* CONFIG_DEBUG_SYSLOG */ | |
6fc6879b JM |
219 | wpa_debug_print_timestamp(); |
220 | #ifdef CONFIG_DEBUG_FILE | |
221 | if (out_file) { | |
222 | vfprintf(out_file, fmt, ap); | |
223 | fprintf(out_file, "\n"); | |
224 | } else { | |
225 | #endif /* CONFIG_DEBUG_FILE */ | |
226 | vprintf(fmt, ap); | |
227 | printf("\n"); | |
228 | #ifdef CONFIG_DEBUG_FILE | |
229 | } | |
230 | #endif /* CONFIG_DEBUG_FILE */ | |
daa70d49 SL |
231 | #ifdef CONFIG_DEBUG_SYSLOG |
232 | } | |
233 | #endif /* CONFIG_DEBUG_SYSLOG */ | |
4a0d25f0 | 234 | #endif /* CONFIG_ANDROID_LOG */ |
6fc6879b JM |
235 | } |
236 | va_end(ap); | |
4f68895e JB |
237 | |
238 | #ifdef CONFIG_DEBUG_LINUX_TRACING | |
239 | if (wpa_debug_tracing_file != NULL) { | |
240 | va_start(ap, fmt); | |
241 | fprintf(wpa_debug_tracing_file, WPAS_TRACE_PFX, level); | |
242 | vfprintf(wpa_debug_tracing_file, fmt, ap); | |
243 | fprintf(wpa_debug_tracing_file, "\n"); | |
244 | fflush(wpa_debug_tracing_file); | |
245 | va_end(ap); | |
246 | } | |
247 | #endif /* CONFIG_DEBUG_LINUX_TRACING */ | |
6fc6879b JM |
248 | } |
249 | ||
250 | ||
251 | static void _wpa_hexdump(int level, const char *title, const u8 *buf, | |
252 | size_t len, int show) | |
253 | { | |
254 | size_t i; | |
4f68895e JB |
255 | |
256 | #ifdef CONFIG_DEBUG_LINUX_TRACING | |
257 | if (wpa_debug_tracing_file != NULL) { | |
258 | fprintf(wpa_debug_tracing_file, | |
259 | WPAS_TRACE_PFX "%s - hexdump(len=%lu):", | |
260 | level, title, (unsigned long) len); | |
261 | if (buf == NULL) { | |
262 | fprintf(wpa_debug_tracing_file, " [NULL]\n"); | |
263 | } else if (!show) { | |
264 | fprintf(wpa_debug_tracing_file, " [REMOVED]\n"); | |
265 | } else { | |
266 | for (i = 0; i < len; i++) | |
267 | fprintf(wpa_debug_tracing_file, | |
268 | " %02x", buf[i]); | |
269 | } | |
270 | fflush(wpa_debug_tracing_file); | |
271 | } | |
272 | #endif /* CONFIG_DEBUG_LINUX_TRACING */ | |
273 | ||
6fc6879b JM |
274 | if (level < wpa_debug_level) |
275 | return; | |
4a0d25f0 JM |
276 | #ifdef CONFIG_ANDROID_LOG |
277 | { | |
278 | const char *display; | |
279 | char *strbuf = NULL; | |
280 | size_t slen = len; | |
281 | if (buf == NULL) { | |
282 | display = " [NULL]"; | |
283 | } else if (len == 0) { | |
284 | display = ""; | |
285 | } else if (show && len) { | |
286 | /* Limit debug message length for Android log */ | |
287 | if (slen > 32) | |
288 | slen = 32; | |
289 | strbuf = os_malloc(1 + 3 * slen); | |
290 | if (strbuf == NULL) { | |
291 | wpa_printf(MSG_ERROR, "wpa_hexdump: Failed to " | |
292 | "allocate message buffer"); | |
293 | return; | |
294 | } | |
295 | ||
296 | for (i = 0; i < slen; i++) | |
297 | os_snprintf(&strbuf[i * 3], 4, " %02x", | |
298 | buf[i]); | |
299 | ||
300 | display = strbuf; | |
301 | } else { | |
302 | display = " [REMOVED]"; | |
303 | } | |
304 | ||
305 | __android_log_print(wpa_to_android_level(level), | |
306 | ANDROID_LOG_NAME, | |
307 | "%s - hexdump(len=%lu):%s%s", | |
308 | title, (long unsigned int) len, display, | |
309 | len > slen ? " ..." : ""); | |
b4c0f584 | 310 | bin_clear_free(strbuf, 1 + 3 * slen); |
4a0d25f0 JM |
311 | return; |
312 | } | |
313 | #else /* CONFIG_ANDROID_LOG */ | |
f31e19df NC |
314 | #ifdef CONFIG_DEBUG_SYSLOG |
315 | if (wpa_debug_syslog) { | |
316 | const char *display; | |
317 | char *strbuf = NULL; | |
318 | ||
319 | if (buf == NULL) { | |
320 | display = " [NULL]"; | |
321 | } else if (len == 0) { | |
322 | display = ""; | |
323 | } else if (show && len) { | |
324 | strbuf = os_malloc(1 + 3 * len); | |
325 | if (strbuf == NULL) { | |
326 | wpa_printf(MSG_ERROR, "wpa_hexdump: Failed to " | |
327 | "allocate message buffer"); | |
328 | return; | |
329 | } | |
330 | ||
331 | for (i = 0; i < len; i++) | |
332 | os_snprintf(&strbuf[i * 3], 4, " %02x", | |
333 | buf[i]); | |
334 | ||
335 | display = strbuf; | |
336 | } else { | |
337 | display = " [REMOVED]"; | |
338 | } | |
339 | ||
340 | syslog(syslog_priority(level), "%s - hexdump(len=%lu):%s", | |
e09e61c2 | 341 | title, (unsigned long) len, display); |
b4c0f584 | 342 | bin_clear_free(strbuf, 1 + 3 * len); |
f31e19df NC |
343 | return; |
344 | } | |
345 | #endif /* CONFIG_DEBUG_SYSLOG */ | |
6fc6879b JM |
346 | wpa_debug_print_timestamp(); |
347 | #ifdef CONFIG_DEBUG_FILE | |
348 | if (out_file) { | |
349 | fprintf(out_file, "%s - hexdump(len=%lu):", | |
350 | title, (unsigned long) len); | |
351 | if (buf == NULL) { | |
352 | fprintf(out_file, " [NULL]"); | |
353 | } else if (show) { | |
354 | for (i = 0; i < len; i++) | |
355 | fprintf(out_file, " %02x", buf[i]); | |
356 | } else { | |
357 | fprintf(out_file, " [REMOVED]"); | |
358 | } | |
359 | fprintf(out_file, "\n"); | |
360 | } else { | |
361 | #endif /* CONFIG_DEBUG_FILE */ | |
362 | printf("%s - hexdump(len=%lu):", title, (unsigned long) len); | |
363 | if (buf == NULL) { | |
364 | printf(" [NULL]"); | |
365 | } else if (show) { | |
366 | for (i = 0; i < len; i++) | |
367 | printf(" %02x", buf[i]); | |
368 | } else { | |
369 | printf(" [REMOVED]"); | |
370 | } | |
371 | printf("\n"); | |
372 | #ifdef CONFIG_DEBUG_FILE | |
373 | } | |
374 | #endif /* CONFIG_DEBUG_FILE */ | |
4a0d25f0 | 375 | #endif /* CONFIG_ANDROID_LOG */ |
6fc6879b JM |
376 | } |
377 | ||
35c20062 | 378 | void wpa_hexdump(int level, const char *title, const void *buf, size_t len) |
6fc6879b JM |
379 | { |
380 | _wpa_hexdump(level, title, buf, len, 1); | |
381 | } | |
382 | ||
383 | ||
35c20062 | 384 | void wpa_hexdump_key(int level, const char *title, const void *buf, size_t len) |
6fc6879b JM |
385 | { |
386 | _wpa_hexdump(level, title, buf, len, wpa_debug_show_keys); | |
387 | } | |
388 | ||
389 | ||
35c20062 | 390 | static void _wpa_hexdump_ascii(int level, const char *title, const void *buf, |
6fc6879b JM |
391 | size_t len, int show) |
392 | { | |
393 | size_t i, llen; | |
394 | const u8 *pos = buf; | |
395 | const size_t line_len = 16; | |
396 | ||
4f68895e JB |
397 | #ifdef CONFIG_DEBUG_LINUX_TRACING |
398 | if (wpa_debug_tracing_file != NULL) { | |
399 | fprintf(wpa_debug_tracing_file, | |
400 | WPAS_TRACE_PFX "%s - hexdump_ascii(len=%lu):", | |
401 | level, title, (unsigned long) len); | |
402 | if (buf == NULL) { | |
403 | fprintf(wpa_debug_tracing_file, " [NULL]\n"); | |
404 | } else if (!show) { | |
405 | fprintf(wpa_debug_tracing_file, " [REMOVED]\n"); | |
406 | } else { | |
407 | /* can do ascii processing in userspace */ | |
408 | for (i = 0; i < len; i++) | |
409 | fprintf(wpa_debug_tracing_file, | |
35c20062 | 410 | " %02x", pos[i]); |
4f68895e JB |
411 | } |
412 | fflush(wpa_debug_tracing_file); | |
413 | } | |
414 | #endif /* CONFIG_DEBUG_LINUX_TRACING */ | |
415 | ||
6fc6879b JM |
416 | if (level < wpa_debug_level) |
417 | return; | |
4a0d25f0 JM |
418 | #ifdef CONFIG_ANDROID_LOG |
419 | _wpa_hexdump(level, title, buf, len, show); | |
420 | #else /* CONFIG_ANDROID_LOG */ | |
6fc6879b JM |
421 | wpa_debug_print_timestamp(); |
422 | #ifdef CONFIG_DEBUG_FILE | |
423 | if (out_file) { | |
424 | if (!show) { | |
425 | fprintf(out_file, | |
426 | "%s - hexdump_ascii(len=%lu): [REMOVED]\n", | |
427 | title, (unsigned long) len); | |
428 | return; | |
429 | } | |
430 | if (buf == NULL) { | |
431 | fprintf(out_file, | |
432 | "%s - hexdump_ascii(len=%lu): [NULL]\n", | |
433 | title, (unsigned long) len); | |
434 | return; | |
435 | } | |
436 | fprintf(out_file, "%s - hexdump_ascii(len=%lu):\n", | |
437 | title, (unsigned long) len); | |
438 | while (len) { | |
439 | llen = len > line_len ? line_len : len; | |
440 | fprintf(out_file, " "); | |
441 | for (i = 0; i < llen; i++) | |
442 | fprintf(out_file, " %02x", pos[i]); | |
443 | for (i = llen; i < line_len; i++) | |
444 | fprintf(out_file, " "); | |
445 | fprintf(out_file, " "); | |
446 | for (i = 0; i < llen; i++) { | |
447 | if (isprint(pos[i])) | |
448 | fprintf(out_file, "%c", pos[i]); | |
449 | else | |
450 | fprintf(out_file, "_"); | |
451 | } | |
452 | for (i = llen; i < line_len; i++) | |
453 | fprintf(out_file, " "); | |
454 | fprintf(out_file, "\n"); | |
455 | pos += llen; | |
456 | len -= llen; | |
457 | } | |
458 | } else { | |
459 | #endif /* CONFIG_DEBUG_FILE */ | |
460 | if (!show) { | |
461 | printf("%s - hexdump_ascii(len=%lu): [REMOVED]\n", | |
462 | title, (unsigned long) len); | |
463 | return; | |
464 | } | |
465 | if (buf == NULL) { | |
466 | printf("%s - hexdump_ascii(len=%lu): [NULL]\n", | |
467 | title, (unsigned long) len); | |
468 | return; | |
469 | } | |
470 | printf("%s - hexdump_ascii(len=%lu):\n", title, (unsigned long) len); | |
471 | while (len) { | |
472 | llen = len > line_len ? line_len : len; | |
473 | printf(" "); | |
474 | for (i = 0; i < llen; i++) | |
475 | printf(" %02x", pos[i]); | |
476 | for (i = llen; i < line_len; i++) | |
477 | printf(" "); | |
478 | printf(" "); | |
479 | for (i = 0; i < llen; i++) { | |
480 | if (isprint(pos[i])) | |
481 | printf("%c", pos[i]); | |
482 | else | |
483 | printf("_"); | |
484 | } | |
485 | for (i = llen; i < line_len; i++) | |
486 | printf(" "); | |
487 | printf("\n"); | |
488 | pos += llen; | |
489 | len -= llen; | |
490 | } | |
491 | #ifdef CONFIG_DEBUG_FILE | |
492 | } | |
493 | #endif /* CONFIG_DEBUG_FILE */ | |
4a0d25f0 | 494 | #endif /* CONFIG_ANDROID_LOG */ |
6fc6879b JM |
495 | } |
496 | ||
497 | ||
35c20062 JM |
498 | void wpa_hexdump_ascii(int level, const char *title, const void *buf, |
499 | size_t len) | |
6fc6879b JM |
500 | { |
501 | _wpa_hexdump_ascii(level, title, buf, len, 1); | |
502 | } | |
503 | ||
504 | ||
35c20062 | 505 | void wpa_hexdump_ascii_key(int level, const char *title, const void *buf, |
6fc6879b JM |
506 | size_t len) |
507 | { | |
508 | _wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys); | |
509 | } | |
510 | ||
511 | ||
ac6912b5 BG |
512 | #ifdef CONFIG_DEBUG_FILE |
513 | static char *last_path = NULL; | |
514 | #endif /* CONFIG_DEBUG_FILE */ | |
515 | ||
516 | int wpa_debug_reopen_file(void) | |
517 | { | |
518 | #ifdef CONFIG_DEBUG_FILE | |
519 | int rv; | |
d8fd633e JM |
520 | char *tmp; |
521 | ||
522 | if (!last_path) | |
523 | return 0; /* logfile not used */ | |
524 | ||
525 | tmp = os_strdup(last_path); | |
526 | if (!tmp) | |
527 | return -1; | |
528 | ||
529 | wpa_debug_close_file(); | |
530 | rv = wpa_debug_open_file(tmp); | |
531 | os_free(tmp); | |
ac6912b5 BG |
532 | return rv; |
533 | #else /* CONFIG_DEBUG_FILE */ | |
534 | return 0; | |
535 | #endif /* CONFIG_DEBUG_FILE */ | |
536 | } | |
537 | ||
538 | ||
6fc6879b JM |
539 | int wpa_debug_open_file(const char *path) |
540 | { | |
541 | #ifdef CONFIG_DEBUG_FILE | |
542 | if (!path) | |
543 | return 0; | |
ac6912b5 BG |
544 | |
545 | if (last_path == NULL || os_strcmp(last_path, path) != 0) { | |
546 | /* Save our path to enable re-open */ | |
547 | os_free(last_path); | |
548 | last_path = os_strdup(path); | |
549 | } | |
550 | ||
6fc6879b JM |
551 | out_file = fopen(path, "a"); |
552 | if (out_file == NULL) { | |
553 | wpa_printf(MSG_ERROR, "wpa_debug_open_file: Failed to open " | |
554 | "output file, using standard output"); | |
555 | return -1; | |
556 | } | |
557 | #ifndef _WIN32 | |
558 | setvbuf(out_file, NULL, _IOLBF, 0); | |
559 | #endif /* _WIN32 */ | |
f5c649b7 TG |
560 | #else /* CONFIG_DEBUG_FILE */ |
561 | (void)path; | |
6fc6879b JM |
562 | #endif /* CONFIG_DEBUG_FILE */ |
563 | return 0; | |
564 | } | |
565 | ||
566 | ||
567 | void wpa_debug_close_file(void) | |
568 | { | |
569 | #ifdef CONFIG_DEBUG_FILE | |
570 | if (!out_file) | |
571 | return; | |
572 | fclose(out_file); | |
573 | out_file = NULL; | |
ac6912b5 BG |
574 | os_free(last_path); |
575 | last_path = NULL; | |
6fc6879b JM |
576 | #endif /* CONFIG_DEBUG_FILE */ |
577 | } | |
578 | ||
de27bc76 PS |
579 | |
580 | void wpa_debug_setup_stdout(void) | |
581 | { | |
582 | #ifndef _WIN32 | |
583 | setvbuf(stdout, NULL, _IOLBF, 0); | |
584 | #endif /* _WIN32 */ | |
585 | } | |
586 | ||
6fc6879b JM |
587 | #endif /* CONFIG_NO_STDOUT_DEBUG */ |
588 | ||
589 | ||
590 | #ifndef CONFIG_NO_WPA_MSG | |
591 | static wpa_msg_cb_func wpa_msg_cb = NULL; | |
592 | ||
593 | void wpa_msg_register_cb(wpa_msg_cb_func func) | |
594 | { | |
595 | wpa_msg_cb = func; | |
596 | } | |
597 | ||
598 | ||
4f1495ae BG |
599 | static wpa_msg_get_ifname_func wpa_msg_ifname_cb = NULL; |
600 | ||
601 | void wpa_msg_register_ifname_cb(wpa_msg_get_ifname_func func) | |
602 | { | |
603 | wpa_msg_ifname_cb = func; | |
604 | } | |
605 | ||
606 | ||
0de4da91 | 607 | void wpa_msg(void *ctx, int level, const char *fmt, ...) |
6fc6879b JM |
608 | { |
609 | va_list ap; | |
610 | char *buf; | |
9e388364 | 611 | int buflen; |
6fc6879b | 612 | int len; |
4f1495ae | 613 | char prefix[130]; |
6fc6879b | 614 | |
9e388364 AK |
615 | va_start(ap, fmt); |
616 | buflen = vsnprintf(NULL, 0, fmt, ap) + 1; | |
617 | va_end(ap); | |
618 | ||
6fc6879b JM |
619 | buf = os_malloc(buflen); |
620 | if (buf == NULL) { | |
621 | wpa_printf(MSG_ERROR, "wpa_msg: Failed to allocate message " | |
622 | "buffer"); | |
623 | return; | |
624 | } | |
625 | va_start(ap, fmt); | |
4f1495ae BG |
626 | prefix[0] = '\0'; |
627 | if (wpa_msg_ifname_cb) { | |
628 | const char *ifname = wpa_msg_ifname_cb(ctx); | |
629 | if (ifname) { | |
630 | int res = os_snprintf(prefix, sizeof(prefix), "%s: ", | |
631 | ifname); | |
d85e1fc8 | 632 | if (os_snprintf_error(sizeof(prefix), res)) |
4f1495ae BG |
633 | prefix[0] = '\0'; |
634 | } | |
635 | } | |
6fc6879b JM |
636 | len = vsnprintf(buf, buflen, fmt, ap); |
637 | va_end(ap); | |
4f1495ae | 638 | wpa_printf(level, "%s%s", prefix, buf); |
6fc6879b | 639 | if (wpa_msg_cb) |
995a3a06 | 640 | wpa_msg_cb(ctx, level, WPA_MSG_PER_INTERFACE, buf, len); |
b4c0f584 | 641 | bin_clear_free(buf, buflen); |
6fc6879b | 642 | } |
69856fad JM |
643 | |
644 | ||
0de4da91 | 645 | void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) |
69856fad JM |
646 | { |
647 | va_list ap; | |
648 | char *buf; | |
9e388364 | 649 | int buflen; |
69856fad JM |
650 | int len; |
651 | ||
652 | if (!wpa_msg_cb) | |
653 | return; | |
654 | ||
9e388364 AK |
655 | va_start(ap, fmt); |
656 | buflen = vsnprintf(NULL, 0, fmt, ap) + 1; | |
657 | va_end(ap); | |
658 | ||
69856fad JM |
659 | buf = os_malloc(buflen); |
660 | if (buf == NULL) { | |
661 | wpa_printf(MSG_ERROR, "wpa_msg_ctrl: Failed to allocate " | |
662 | "message buffer"); | |
663 | return; | |
664 | } | |
665 | va_start(ap, fmt); | |
666 | len = vsnprintf(buf, buflen, fmt, ap); | |
667 | va_end(ap); | |
995a3a06 | 668 | wpa_msg_cb(ctx, level, WPA_MSG_PER_INTERFACE, buf, len); |
b4c0f584 | 669 | bin_clear_free(buf, buflen); |
69856fad | 670 | } |
47bfe49c JM |
671 | |
672 | ||
673 | void wpa_msg_global(void *ctx, int level, const char *fmt, ...) | |
674 | { | |
675 | va_list ap; | |
676 | char *buf; | |
9e388364 | 677 | int buflen; |
47bfe49c JM |
678 | int len; |
679 | ||
9e388364 AK |
680 | va_start(ap, fmt); |
681 | buflen = vsnprintf(NULL, 0, fmt, ap) + 1; | |
682 | va_end(ap); | |
683 | ||
47bfe49c JM |
684 | buf = os_malloc(buflen); |
685 | if (buf == NULL) { | |
686 | wpa_printf(MSG_ERROR, "wpa_msg_global: Failed to allocate " | |
687 | "message buffer"); | |
688 | return; | |
689 | } | |
690 | va_start(ap, fmt); | |
691 | len = vsnprintf(buf, buflen, fmt, ap); | |
692 | va_end(ap); | |
693 | wpa_printf(level, "%s", buf); | |
694 | if (wpa_msg_cb) | |
995a3a06 | 695 | wpa_msg_cb(ctx, level, WPA_MSG_GLOBAL, buf, len); |
b4c0f584 | 696 | bin_clear_free(buf, buflen); |
47bfe49c JM |
697 | } |
698 | ||
c4bf83a7 | 699 | |
905c7223 JM |
700 | void wpa_msg_global_ctrl(void *ctx, int level, const char *fmt, ...) |
701 | { | |
702 | va_list ap; | |
703 | char *buf; | |
704 | int buflen; | |
705 | int len; | |
706 | ||
707 | if (!wpa_msg_cb) | |
708 | return; | |
709 | ||
710 | va_start(ap, fmt); | |
711 | buflen = vsnprintf(NULL, 0, fmt, ap) + 1; | |
712 | va_end(ap); | |
713 | ||
714 | buf = os_malloc(buflen); | |
715 | if (buf == NULL) { | |
716 | wpa_printf(MSG_ERROR, | |
717 | "wpa_msg_global_ctrl: Failed to allocate message buffer"); | |
718 | return; | |
719 | } | |
720 | va_start(ap, fmt); | |
721 | len = vsnprintf(buf, buflen, fmt, ap); | |
722 | va_end(ap); | |
995a3a06 | 723 | wpa_msg_cb(ctx, level, WPA_MSG_GLOBAL, buf, len); |
b4c0f584 | 724 | bin_clear_free(buf, buflen); |
905c7223 JM |
725 | } |
726 | ||
727 | ||
c4bf83a7 JM |
728 | void wpa_msg_no_global(void *ctx, int level, const char *fmt, ...) |
729 | { | |
730 | va_list ap; | |
731 | char *buf; | |
9e388364 | 732 | int buflen; |
c4bf83a7 JM |
733 | int len; |
734 | ||
9e388364 AK |
735 | va_start(ap, fmt); |
736 | buflen = vsnprintf(NULL, 0, fmt, ap) + 1; | |
737 | va_end(ap); | |
738 | ||
c4bf83a7 JM |
739 | buf = os_malloc(buflen); |
740 | if (buf == NULL) { | |
741 | wpa_printf(MSG_ERROR, "wpa_msg_no_global: Failed to allocate " | |
742 | "message buffer"); | |
743 | return; | |
744 | } | |
745 | va_start(ap, fmt); | |
746 | len = vsnprintf(buf, buflen, fmt, ap); | |
747 | va_end(ap); | |
748 | wpa_printf(level, "%s", buf); | |
749 | if (wpa_msg_cb) | |
995a3a06 | 750 | wpa_msg_cb(ctx, level, WPA_MSG_NO_GLOBAL, buf, len); |
b4c0f584 | 751 | bin_clear_free(buf, buflen); |
c4bf83a7 JM |
752 | } |
753 | ||
ee1e3f57 AN |
754 | |
755 | void wpa_msg_global_only(void *ctx, int level, const char *fmt, ...) | |
756 | { | |
757 | va_list ap; | |
758 | char *buf; | |
759 | int buflen; | |
760 | int len; | |
761 | ||
762 | va_start(ap, fmt); | |
763 | buflen = vsnprintf(NULL, 0, fmt, ap) + 1; | |
764 | va_end(ap); | |
765 | ||
766 | buf = os_malloc(buflen); | |
767 | if (buf == NULL) { | |
768 | wpa_printf(MSG_ERROR, "%s: Failed to allocate message buffer", | |
769 | __func__); | |
770 | return; | |
771 | } | |
772 | va_start(ap, fmt); | |
773 | len = vsnprintf(buf, buflen, fmt, ap); | |
774 | va_end(ap); | |
775 | wpa_printf(level, "%s", buf); | |
776 | if (wpa_msg_cb) | |
777 | wpa_msg_cb(ctx, level, WPA_MSG_ONLY_GLOBAL, buf, len); | |
778 | os_free(buf); | |
779 | } | |
780 | ||
6fc6879b JM |
781 | #endif /* CONFIG_NO_WPA_MSG */ |
782 | ||
783 | ||
784 | #ifndef CONFIG_NO_HOSTAPD_LOGGER | |
785 | static hostapd_logger_cb_func hostapd_logger_cb = NULL; | |
786 | ||
787 | void hostapd_logger_register_cb(hostapd_logger_cb_func func) | |
788 | { | |
789 | hostapd_logger_cb = func; | |
790 | } | |
791 | ||
792 | ||
793 | void hostapd_logger(void *ctx, const u8 *addr, unsigned int module, int level, | |
794 | const char *fmt, ...) | |
795 | { | |
796 | va_list ap; | |
797 | char *buf; | |
9e388364 | 798 | int buflen; |
6fc6879b JM |
799 | int len; |
800 | ||
9e388364 AK |
801 | va_start(ap, fmt); |
802 | buflen = vsnprintf(NULL, 0, fmt, ap) + 1; | |
803 | va_end(ap); | |
804 | ||
6fc6879b JM |
805 | buf = os_malloc(buflen); |
806 | if (buf == NULL) { | |
807 | wpa_printf(MSG_ERROR, "hostapd_logger: Failed to allocate " | |
808 | "message buffer"); | |
809 | return; | |
810 | } | |
811 | va_start(ap, fmt); | |
812 | len = vsnprintf(buf, buflen, fmt, ap); | |
813 | va_end(ap); | |
814 | if (hostapd_logger_cb) | |
815 | hostapd_logger_cb(ctx, addr, module, level, buf, len); | |
ade07077 JM |
816 | else if (addr) |
817 | wpa_printf(MSG_DEBUG, "hostapd_logger: STA " MACSTR " - %s", | |
818 | MAC2STR(addr), buf); | |
6fc6879b JM |
819 | else |
820 | wpa_printf(MSG_DEBUG, "hostapd_logger: %s", buf); | |
b4c0f584 | 821 | bin_clear_free(buf, buflen); |
6fc6879b JM |
822 | } |
823 | #endif /* CONFIG_NO_HOSTAPD_LOGGER */ | |
ab62f96f JM |
824 | |
825 | ||
826 | const char * debug_level_str(int level) | |
827 | { | |
828 | switch (level) { | |
829 | case MSG_EXCESSIVE: | |
830 | return "EXCESSIVE"; | |
831 | case MSG_MSGDUMP: | |
832 | return "MSGDUMP"; | |
833 | case MSG_DEBUG: | |
834 | return "DEBUG"; | |
835 | case MSG_INFO: | |
836 | return "INFO"; | |
837 | case MSG_WARNING: | |
838 | return "WARNING"; | |
839 | case MSG_ERROR: | |
840 | return "ERROR"; | |
841 | default: | |
842 | return "?"; | |
843 | } | |
844 | } | |
845 | ||
846 | ||
847 | int str_to_debug_level(const char *s) | |
848 | { | |
849 | if (os_strcasecmp(s, "EXCESSIVE") == 0) | |
850 | return MSG_EXCESSIVE; | |
851 | if (os_strcasecmp(s, "MSGDUMP") == 0) | |
852 | return MSG_MSGDUMP; | |
853 | if (os_strcasecmp(s, "DEBUG") == 0) | |
854 | return MSG_DEBUG; | |
855 | if (os_strcasecmp(s, "INFO") == 0) | |
856 | return MSG_INFO; | |
857 | if (os_strcasecmp(s, "WARNING") == 0) | |
858 | return MSG_WARNING; | |
859 | if (os_strcasecmp(s, "ERROR") == 0) | |
860 | return MSG_ERROR; | |
861 | return -1; | |
862 | } |