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
? " ..." : "");
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
);
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 #endif /* CONFIG_DEBUG_FILE */
563 void wpa_debug_close_file(void)
565 #ifdef CONFIG_DEBUG_FILE
572 #endif /* CONFIG_DEBUG_FILE */
575 #endif /* CONFIG_NO_STDOUT_DEBUG */
578 #ifndef CONFIG_NO_WPA_MSG
579 static wpa_msg_cb_func wpa_msg_cb
= NULL
;
581 void wpa_msg_register_cb(wpa_msg_cb_func func
)
587 static wpa_msg_get_ifname_func wpa_msg_ifname_cb
= NULL
;
589 void wpa_msg_register_ifname_cb(wpa_msg_get_ifname_func func
)
591 wpa_msg_ifname_cb
= func
;
595 void wpa_msg(void *ctx
, int level
, const char *fmt
, ...)
599 const int buflen
= 2048;
603 buf
= os_malloc(buflen
);
605 wpa_printf(MSG_ERROR
, "wpa_msg: Failed to allocate message "
611 if (wpa_msg_ifname_cb
) {
612 const char *ifname
= wpa_msg_ifname_cb(ctx
);
614 int res
= os_snprintf(prefix
, sizeof(prefix
), "%s: ",
616 if (res
< 0 || res
>= (int) sizeof(prefix
))
620 len
= vsnprintf(buf
, buflen
, fmt
, ap
);
622 wpa_printf(level
, "%s%s", prefix
, buf
);
624 wpa_msg_cb(ctx
, level
, 0, buf
, len
);
629 void wpa_msg_ctrl(void *ctx
, int level
, const char *fmt
, ...)
633 const int buflen
= 2048;
639 buf
= os_malloc(buflen
);
641 wpa_printf(MSG_ERROR
, "wpa_msg_ctrl: Failed to allocate "
646 len
= vsnprintf(buf
, buflen
, fmt
, ap
);
648 wpa_msg_cb(ctx
, level
, 0, buf
, len
);
653 void wpa_msg_global(void *ctx
, int level
, const char *fmt
, ...)
657 const int buflen
= 2048;
660 buf
= os_malloc(buflen
);
662 wpa_printf(MSG_ERROR
, "wpa_msg_global: Failed to allocate "
667 len
= vsnprintf(buf
, buflen
, fmt
, ap
);
669 wpa_printf(level
, "%s", buf
);
671 wpa_msg_cb(ctx
, level
, 1, buf
, len
);
676 void wpa_msg_no_global(void *ctx
, int level
, const char *fmt
, ...)
680 const int buflen
= 2048;
683 buf
= os_malloc(buflen
);
685 wpa_printf(MSG_ERROR
, "wpa_msg_no_global: Failed to allocate "
690 len
= vsnprintf(buf
, buflen
, fmt
, ap
);
692 wpa_printf(level
, "%s", buf
);
694 wpa_msg_cb(ctx
, level
, 2, buf
, len
);
698 #endif /* CONFIG_NO_WPA_MSG */
701 #ifndef CONFIG_NO_HOSTAPD_LOGGER
702 static hostapd_logger_cb_func hostapd_logger_cb
= NULL
;
704 void hostapd_logger_register_cb(hostapd_logger_cb_func func
)
706 hostapd_logger_cb
= func
;
710 void hostapd_logger(void *ctx
, const u8
*addr
, unsigned int module
, int level
,
711 const char *fmt
, ...)
715 const int buflen
= 2048;
718 buf
= os_malloc(buflen
);
720 wpa_printf(MSG_ERROR
, "hostapd_logger: Failed to allocate "
725 len
= vsnprintf(buf
, buflen
, fmt
, ap
);
727 if (hostapd_logger_cb
)
728 hostapd_logger_cb(ctx
, addr
, module
, level
, buf
, len
);
730 wpa_printf(MSG_DEBUG
, "hostapd_logger: STA " MACSTR
" - %s",
733 wpa_printf(MSG_DEBUG
, "hostapd_logger: %s", buf
);
736 #endif /* CONFIG_NO_HOSTAPD_LOGGER */