2 * wpa_supplicant/hostapd / Debug prints
3 * Copyright (c) 2002-2013, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
13 #ifdef CONFIG_DEBUG_SYSLOG
16 static int wpa_debug_syslog
= 0;
17 #endif /* CONFIG_DEBUG_SYSLOG */
19 #ifdef CONFIG_DEBUG_LINUX_TRACING
20 #include <sys/types.h>
26 static FILE *wpa_debug_tracing_file
= NULL
;
28 #define WPAS_TRACE_PFX "wpas <%d>: "
29 #endif /* CONFIG_DEBUG_LINUX_TRACING */
32 int wpa_debug_level
= MSG_INFO
;
33 int wpa_debug_show_keys
= 0;
34 int wpa_debug_timestamp
= 0;
37 #ifdef CONFIG_ANDROID_LOG
39 #include <android/log.h>
41 #ifndef ANDROID_LOG_NAME
42 #define ANDROID_LOG_NAME "wpa_supplicant"
43 #endif /* ANDROID_LOG_NAME */
45 static int wpa_to_android_level(int level
)
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
;
56 #endif /* CONFIG_ANDROID_LOG */
58 #ifndef CONFIG_NO_STDOUT_DEBUG
60 #ifdef CONFIG_DEBUG_FILE
61 static FILE *out_file
= NULL
;
62 #endif /* CONFIG_DEBUG_FILE */
65 void wpa_debug_print_timestamp(void)
67 #ifndef CONFIG_ANDROID_LOG
70 if (!wpa_debug_timestamp
)
74 #ifdef CONFIG_DEBUG_FILE
76 fprintf(out_file
, "%ld.%06u: ", (long) tv
.sec
,
77 (unsigned int) tv
.usec
);
79 #endif /* CONFIG_DEBUG_FILE */
80 printf("%ld.%06u: ", (long) tv
.sec
, (unsigned int) tv
.usec
);
81 #endif /* CONFIG_ANDROID_LOG */
85 #ifdef CONFIG_DEBUG_SYSLOG
87 #define LOG_HOSTAPD LOG_DAEMON
88 #endif /* LOG_HOSTAPD */
90 void wpa_debug_open_syslog(void)
92 openlog("wpa_supplicant", LOG_PID
| LOG_NDELAY
, LOG_HOSTAPD
);
97 void wpa_debug_close_syslog(void)
104 static int syslog_priority(int level
)
119 #endif /* CONFIG_DEBUG_SYSLOG */
122 #ifdef CONFIG_DEBUG_LINUX_TRACING
124 int wpa_debug_open_linux_tracing(void)
126 int mounts
, trace_fd
;
129 char *line
, *tmp1
, *path
= NULL
;
131 mounts
= open("/proc/mounts", O_RDONLY
);
133 printf("no /proc/mounts\n");
137 buflen
= read(mounts
, buf
, sizeof(buf
) - 1);
140 printf("failed to read /proc/mounts\n");
144 line
= strtok_r(buf
, "\n", &tmp1
);
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
);
151 if (strcmp(fstype
, "debugfs") == 0) {
156 line
= strtok_r(NULL
, "\n", &tmp1
);
160 printf("debugfs mountpoint not found\n");
164 snprintf(buf
, sizeof(buf
) - 1, "%s/tracing/trace_marker", path
);
166 trace_fd
= open(buf
, O_WRONLY
);
168 printf("failed to open trace_marker file\n");
171 wpa_debug_tracing_file
= fdopen(trace_fd
, "w");
172 if (wpa_debug_tracing_file
== NULL
) {
174 printf("failed to fdopen()\n");
182 void wpa_debug_close_linux_tracing(void)
184 if (wpa_debug_tracing_file
== NULL
)
186 fclose(wpa_debug_tracing_file
);
187 wpa_debug_tracing_file
= NULL
;
190 #endif /* CONFIG_DEBUG_LINUX_TRACING */
194 * wpa_printf - conditional printf
195 * @level: priority level (MSG_*) of the message
196 * @fmt: printf format string, followed by optional arguments
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
202 * Note: New line '\n' is added to the end of the text when printing to stdout.
204 void wpa_printf(int level
, const char *fmt
, ...)
209 if (level
>= wpa_debug_level
) {
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 */
214 #ifdef CONFIG_DEBUG_SYSLOG
215 if (wpa_debug_syslog
) {
216 vsyslog(syslog_priority(level
), fmt
, ap
);
218 #endif /* CONFIG_DEBUG_SYSLOG */
219 wpa_debug_print_timestamp();
220 #ifdef CONFIG_DEBUG_FILE
222 vfprintf(out_file
, fmt
, ap
);
223 fprintf(out_file
, "\n");
225 #endif /* CONFIG_DEBUG_FILE */
228 #ifdef CONFIG_DEBUG_FILE
230 #endif /* CONFIG_DEBUG_FILE */
231 #ifdef CONFIG_DEBUG_SYSLOG
233 #endif /* CONFIG_DEBUG_SYSLOG */
234 #endif /* CONFIG_ANDROID_LOG */
238 #ifdef CONFIG_DEBUG_LINUX_TRACING
239 if (wpa_debug_tracing_file
!= NULL
) {
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
);
247 #endif /* CONFIG_DEBUG_LINUX_TRACING */
251 static void _wpa_hexdump(int level
, const char *title
, const u8
*buf
,
252 size_t len
, int show
)
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
);
262 fprintf(wpa_debug_tracing_file
, " [NULL]\n");
264 fprintf(wpa_debug_tracing_file
, " [REMOVED]\n");
266 for (i
= 0; i
< len
; i
++)
267 fprintf(wpa_debug_tracing_file
,
270 fflush(wpa_debug_tracing_file
);
272 #endif /* CONFIG_DEBUG_LINUX_TRACING */
274 if (level
< wpa_debug_level
)
276 #ifdef CONFIG_ANDROID_LOG
283 } else if (len
== 0) {
285 } else if (show
&& len
) {
286 /* Limit debug message length for Android log */
289 strbuf
= os_malloc(1 + 3 * slen
);
290 if (strbuf
== NULL
) {
291 wpa_printf(MSG_ERROR
, "wpa_hexdump: Failed to "
292 "allocate message buffer");
296 for (i
= 0; i
< slen
; i
++)
297 os_snprintf(&strbuf
[i
* 3], 4, " %02x",
302 display
= " [REMOVED]";
305 __android_log_print(wpa_to_android_level(level
),
307 "%s - hexdump(len=%lu):%s%s",
308 title
, (long unsigned int) len
, display
,
309 len
> slen
? " ..." : "");
310 bin_clear_free(strbuf
, 1 + 3 * slen
);
313 #else /* CONFIG_ANDROID_LOG */
314 #ifdef CONFIG_DEBUG_SYSLOG
315 if (wpa_debug_syslog
) {
321 } else if (len
== 0) {
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");
331 for (i
= 0; i
< len
; i
++)
332 os_snprintf(&strbuf
[i
* 3], 4, " %02x",
337 display
= " [REMOVED]";
340 syslog(syslog_priority(level
), "%s - hexdump(len=%lu):%s",
341 title
, (unsigned long) len
, display
);
342 bin_clear_free(strbuf
, 1 + 3 * len
);
345 #endif /* CONFIG_DEBUG_SYSLOG */
346 wpa_debug_print_timestamp();
347 #ifdef CONFIG_DEBUG_FILE
349 fprintf(out_file
, "%s - hexdump(len=%lu):",
350 title
, (unsigned long) len
);
352 fprintf(out_file
, " [NULL]");
354 for (i
= 0; i
< len
; i
++)
355 fprintf(out_file
, " %02x", buf
[i
]);
357 fprintf(out_file
, " [REMOVED]");
359 fprintf(out_file
, "\n");
361 #endif /* CONFIG_DEBUG_FILE */
362 printf("%s - hexdump(len=%lu):", title
, (unsigned long) len
);
366 for (i
= 0; i
< len
; i
++)
367 printf(" %02x", buf
[i
]);
369 printf(" [REMOVED]");
372 #ifdef CONFIG_DEBUG_FILE
374 #endif /* CONFIG_DEBUG_FILE */
375 #endif /* CONFIG_ANDROID_LOG */
378 void wpa_hexdump(int level
, const char *title
, const void *buf
, size_t len
)
380 _wpa_hexdump(level
, title
, buf
, len
, 1);
384 void wpa_hexdump_key(int level
, const char *title
, const void *buf
, size_t len
)
386 _wpa_hexdump(level
, title
, buf
, len
, wpa_debug_show_keys
);
390 static void _wpa_hexdump_ascii(int level
, const char *title
, const void *buf
,
391 size_t len
, int show
)
395 const size_t line_len
= 16;
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
);
403 fprintf(wpa_debug_tracing_file
, " [NULL]\n");
405 fprintf(wpa_debug_tracing_file
, " [REMOVED]\n");
407 /* can do ascii processing in userspace */
408 for (i
= 0; i
< len
; i
++)
409 fprintf(wpa_debug_tracing_file
,
412 fflush(wpa_debug_tracing_file
);
414 #endif /* CONFIG_DEBUG_LINUX_TRACING */
416 if (level
< wpa_debug_level
)
418 #ifdef CONFIG_ANDROID_LOG
419 _wpa_hexdump(level
, title
, buf
, len
, show
);
420 #else /* CONFIG_ANDROID_LOG */
421 wpa_debug_print_timestamp();
422 #ifdef CONFIG_DEBUG_FILE
426 "%s - hexdump_ascii(len=%lu): [REMOVED]\n",
427 title
, (unsigned long) len
);
432 "%s - hexdump_ascii(len=%lu): [NULL]\n",
433 title
, (unsigned long) len
);
436 fprintf(out_file
, "%s - hexdump_ascii(len=%lu):\n",
437 title
, (unsigned long) 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
++) {
448 fprintf(out_file
, "%c", pos
[i
]);
450 fprintf(out_file
, "_");
452 for (i
= llen
; i
< line_len
; i
++)
453 fprintf(out_file
, " ");
454 fprintf(out_file
, "\n");
459 #endif /* CONFIG_DEBUG_FILE */
461 printf("%s - hexdump_ascii(len=%lu): [REMOVED]\n",
462 title
, (unsigned long) len
);
466 printf("%s - hexdump_ascii(len=%lu): [NULL]\n",
467 title
, (unsigned long) len
);
470 printf("%s - hexdump_ascii(len=%lu):\n", title
, (unsigned long) len
);
472 llen
= len
> line_len
? line_len
: len
;
474 for (i
= 0; i
< llen
; i
++)
475 printf(" %02x", pos
[i
]);
476 for (i
= llen
; i
< line_len
; i
++)
479 for (i
= 0; i
< llen
; i
++) {
481 printf("%c", pos
[i
]);
485 for (i
= llen
; i
< line_len
; i
++)
491 #ifdef CONFIG_DEBUG_FILE
493 #endif /* CONFIG_DEBUG_FILE */
494 #endif /* CONFIG_ANDROID_LOG */
498 void wpa_hexdump_ascii(int level
, const char *title
, const void *buf
,
501 _wpa_hexdump_ascii(level
, title
, buf
, len
, 1);
505 void wpa_hexdump_ascii_key(int level
, const char *title
, const void *buf
,
508 _wpa_hexdump_ascii(level
, title
, buf
, len
, wpa_debug_show_keys
);
512 #ifdef CONFIG_DEBUG_FILE
513 static char *last_path
= NULL
;
514 #endif /* CONFIG_DEBUG_FILE */
516 int wpa_debug_reopen_file(void)
518 #ifdef CONFIG_DEBUG_FILE
521 char *tmp
= os_strdup(last_path
);
522 wpa_debug_close_file();
523 rv
= wpa_debug_open_file(tmp
);
526 wpa_printf(MSG_ERROR
, "Last-path was not set, cannot "
527 "re-open log file.");
531 #else /* CONFIG_DEBUG_FILE */
533 #endif /* CONFIG_DEBUG_FILE */
537 int wpa_debug_open_file(const char *path
)
539 #ifdef CONFIG_DEBUG_FILE
543 if (last_path
== NULL
|| os_strcmp(last_path
, path
) != 0) {
544 /* Save our path to enable re-open */
546 last_path
= os_strdup(path
);
549 out_file
= fopen(path
, "a");
550 if (out_file
== NULL
) {
551 wpa_printf(MSG_ERROR
, "wpa_debug_open_file: Failed to open "
552 "output file, using standard output");
556 setvbuf(out_file
, NULL
, _IOLBF
, 0);
558 #else /* CONFIG_DEBUG_FILE */
560 #endif /* CONFIG_DEBUG_FILE */
565 void wpa_debug_close_file(void)
567 #ifdef CONFIG_DEBUG_FILE
574 #endif /* CONFIG_DEBUG_FILE */
578 void wpa_debug_setup_stdout(void)
581 setvbuf(stdout
, NULL
, _IOLBF
, 0);
585 #endif /* CONFIG_NO_STDOUT_DEBUG */
588 #ifndef CONFIG_NO_WPA_MSG
589 static wpa_msg_cb_func wpa_msg_cb
= NULL
;
591 void wpa_msg_register_cb(wpa_msg_cb_func func
)
597 static wpa_msg_get_ifname_func wpa_msg_ifname_cb
= NULL
;
599 void wpa_msg_register_ifname_cb(wpa_msg_get_ifname_func func
)
601 wpa_msg_ifname_cb
= func
;
605 void wpa_msg(void *ctx
, int level
, const char *fmt
, ...)
614 buflen
= vsnprintf(NULL
, 0, fmt
, ap
) + 1;
617 buf
= os_malloc(buflen
);
619 wpa_printf(MSG_ERROR
, "wpa_msg: Failed to allocate message "
625 if (wpa_msg_ifname_cb
) {
626 const char *ifname
= wpa_msg_ifname_cb(ctx
);
628 int res
= os_snprintf(prefix
, sizeof(prefix
), "%s: ",
630 if (os_snprintf_error(sizeof(prefix
), res
))
634 len
= vsnprintf(buf
, buflen
, fmt
, ap
);
636 wpa_printf(level
, "%s%s", prefix
, buf
);
638 wpa_msg_cb(ctx
, level
, WPA_MSG_PER_INTERFACE
, buf
, len
);
639 bin_clear_free(buf
, buflen
);
643 void wpa_msg_ctrl(void *ctx
, int level
, const char *fmt
, ...)
654 buflen
= vsnprintf(NULL
, 0, fmt
, ap
) + 1;
657 buf
= os_malloc(buflen
);
659 wpa_printf(MSG_ERROR
, "wpa_msg_ctrl: Failed to allocate "
664 len
= vsnprintf(buf
, buflen
, fmt
, ap
);
666 wpa_msg_cb(ctx
, level
, WPA_MSG_PER_INTERFACE
, buf
, len
);
667 bin_clear_free(buf
, buflen
);
671 void wpa_msg_global(void *ctx
, int level
, const char *fmt
, ...)
679 buflen
= vsnprintf(NULL
, 0, fmt
, ap
) + 1;
682 buf
= os_malloc(buflen
);
684 wpa_printf(MSG_ERROR
, "wpa_msg_global: Failed to allocate "
689 len
= vsnprintf(buf
, buflen
, fmt
, ap
);
691 wpa_printf(level
, "%s", buf
);
693 wpa_msg_cb(ctx
, level
, WPA_MSG_GLOBAL
, buf
, len
);
694 bin_clear_free(buf
, buflen
);
698 void wpa_msg_global_ctrl(void *ctx
, int level
, const char *fmt
, ...)
709 buflen
= vsnprintf(NULL
, 0, fmt
, ap
) + 1;
712 buf
= os_malloc(buflen
);
714 wpa_printf(MSG_ERROR
,
715 "wpa_msg_global_ctrl: Failed to allocate message buffer");
719 len
= vsnprintf(buf
, buflen
, fmt
, ap
);
721 wpa_msg_cb(ctx
, level
, WPA_MSG_GLOBAL
, buf
, len
);
722 bin_clear_free(buf
, buflen
);
726 void wpa_msg_no_global(void *ctx
, int level
, const char *fmt
, ...)
734 buflen
= vsnprintf(NULL
, 0, fmt
, ap
) + 1;
737 buf
= os_malloc(buflen
);
739 wpa_printf(MSG_ERROR
, "wpa_msg_no_global: Failed to allocate "
744 len
= vsnprintf(buf
, buflen
, fmt
, ap
);
746 wpa_printf(level
, "%s", buf
);
748 wpa_msg_cb(ctx
, level
, WPA_MSG_NO_GLOBAL
, buf
, len
);
749 bin_clear_free(buf
, buflen
);
753 void wpa_msg_global_only(void *ctx
, int level
, const char *fmt
, ...)
761 buflen
= vsnprintf(NULL
, 0, fmt
, ap
) + 1;
764 buf
= os_malloc(buflen
);
766 wpa_printf(MSG_ERROR
, "%s: Failed to allocate message buffer",
771 len
= vsnprintf(buf
, buflen
, fmt
, ap
);
773 wpa_printf(level
, "%s", buf
);
775 wpa_msg_cb(ctx
, level
, WPA_MSG_ONLY_GLOBAL
, buf
, len
);
779 #endif /* CONFIG_NO_WPA_MSG */
782 #ifndef CONFIG_NO_HOSTAPD_LOGGER
783 static hostapd_logger_cb_func hostapd_logger_cb
= NULL
;
785 void hostapd_logger_register_cb(hostapd_logger_cb_func func
)
787 hostapd_logger_cb
= func
;
791 void hostapd_logger(void *ctx
, const u8
*addr
, unsigned int module
, int level
,
792 const char *fmt
, ...)
800 buflen
= vsnprintf(NULL
, 0, fmt
, ap
) + 1;
803 buf
= os_malloc(buflen
);
805 wpa_printf(MSG_ERROR
, "hostapd_logger: Failed to allocate "
810 len
= vsnprintf(buf
, buflen
, fmt
, ap
);
812 if (hostapd_logger_cb
)
813 hostapd_logger_cb(ctx
, addr
, module
, level
, buf
, len
);
815 wpa_printf(MSG_DEBUG
, "hostapd_logger: STA " MACSTR
" - %s",
818 wpa_printf(MSG_DEBUG
, "hostapd_logger: %s", buf
);
819 bin_clear_free(buf
, buflen
);
821 #endif /* CONFIG_NO_HOSTAPD_LOGGER */