blob: a56462b8bbdc75724ad8117751414512d4f272a6 [file] [log] [blame]
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001/*
2 * wpa_supplicant/hostapd / Debug prints
Dmitry Shmidtb6e9aaf2013-05-20 14:49:44 -07003 * Copyright (c) 2002-2013, Jouni Malinen <j@w1.fi>
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004 *
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08005 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07007 */
8
9#include "includes.h"
10
11#include "common.h"
12
13#ifdef CONFIG_DEBUG_SYSLOG
14#include <syslog.h>
15
Paul Stewart092955c2017-02-06 09:13:09 -080016int wpa_debug_syslog = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070017#endif /* CONFIG_DEBUG_SYSLOG */
18
Dmitry Shmidt04949592012-07-19 12:16:46 -070019#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
26static FILE *wpa_debug_tracing_file = NULL;
27
28#define WPAS_TRACE_PFX "wpas <%d>: "
29#endif /* CONFIG_DEBUG_LINUX_TRACING */
30
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070031
32int wpa_debug_level = MSG_INFO;
33int wpa_debug_show_keys = 0;
34int wpa_debug_timestamp = 0;
35
36
37#ifdef CONFIG_ANDROID_LOG
38
39#include <android/log.h>
40
Dmitry Shmidt648b7492011-09-30 15:03:42 -070041#ifndef ANDROID_LOG_NAME
42#define ANDROID_LOG_NAME "wpa_supplicant"
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -080043#endif /* ANDROID_LOG_NAME */
Dmitry Shmidt648b7492011-09-30 15:03:42 -070044
Dmitry Shmidt04949592012-07-19 12:16:46 -070045static int wpa_to_android_level(int level)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070046{
Dmitry Shmidt04949592012-07-19 12:16:46 -070047 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;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070054}
55
Dmitry Shmidt04949592012-07-19 12:16:46 -070056#endif /* CONFIG_ANDROID_LOG */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070057
58#ifndef CONFIG_NO_STDOUT_DEBUG
59
60#ifdef CONFIG_DEBUG_FILE
Hai Shalom39ba6fc2019-01-22 12:40:38 -080061#include <sys/types.h>
62#include <sys/stat.h>
63#include <fcntl.h>
64
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070065static FILE *out_file = NULL;
66#endif /* CONFIG_DEBUG_FILE */
67
68
69void wpa_debug_print_timestamp(void)
70{
Dmitry Shmidt04949592012-07-19 12:16:46 -070071#ifndef CONFIG_ANDROID_LOG
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070072 struct os_time tv;
73
74 if (!wpa_debug_timestamp)
75 return;
76
77 os_get_time(&tv);
78#ifdef CONFIG_DEBUG_FILE
79 if (out_file) {
80 fprintf(out_file, "%ld.%06u: ", (long) tv.sec,
81 (unsigned int) tv.usec);
82 } else
83#endif /* CONFIG_DEBUG_FILE */
84 printf("%ld.%06u: ", (long) tv.sec, (unsigned int) tv.usec);
Dmitry Shmidt04949592012-07-19 12:16:46 -070085#endif /* CONFIG_ANDROID_LOG */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070086}
87
88
89#ifdef CONFIG_DEBUG_SYSLOG
90#ifndef LOG_HOSTAPD
91#define LOG_HOSTAPD LOG_DAEMON
92#endif /* LOG_HOSTAPD */
93
94void wpa_debug_open_syslog(void)
95{
96 openlog("wpa_supplicant", LOG_PID | LOG_NDELAY, LOG_HOSTAPD);
97 wpa_debug_syslog++;
98}
99
100
101void wpa_debug_close_syslog(void)
102{
103 if (wpa_debug_syslog)
104 closelog();
105}
106
107
108static int syslog_priority(int level)
109{
110 switch (level) {
111 case MSG_MSGDUMP:
112 case MSG_DEBUG:
113 return LOG_DEBUG;
114 case MSG_INFO:
115 return LOG_NOTICE;
116 case MSG_WARNING:
117 return LOG_WARNING;
118 case MSG_ERROR:
119 return LOG_ERR;
120 }
121 return LOG_INFO;
122}
123#endif /* CONFIG_DEBUG_SYSLOG */
124
125
Dmitry Shmidt04949592012-07-19 12:16:46 -0700126#ifdef CONFIG_DEBUG_LINUX_TRACING
127
128int wpa_debug_open_linux_tracing(void)
129{
130 int mounts, trace_fd;
131 char buf[4096] = {};
132 ssize_t buflen;
133 char *line, *tmp1, *path = NULL;
134
135 mounts = open("/proc/mounts", O_RDONLY);
136 if (mounts < 0) {
137 printf("no /proc/mounts\n");
138 return -1;
139 }
140
141 buflen = read(mounts, buf, sizeof(buf) - 1);
142 close(mounts);
143 if (buflen < 0) {
144 printf("failed to read /proc/mounts\n");
145 return -1;
146 }
147
148 line = strtok_r(buf, "\n", &tmp1);
149 while (line) {
150 char *tmp2, *tmp_path, *fstype;
151 /* "<dev> <mountpoint> <fs type> ..." */
152 strtok_r(line, " ", &tmp2);
153 tmp_path = strtok_r(NULL, " ", &tmp2);
154 fstype = strtok_r(NULL, " ", &tmp2);
Dmitry Shmidt0e58d9b2015-12-22 10:59:44 -0800155 if (fstype && strcmp(fstype, "debugfs") == 0) {
Dmitry Shmidt04949592012-07-19 12:16:46 -0700156 path = tmp_path;
157 break;
158 }
159
160 line = strtok_r(NULL, "\n", &tmp1);
161 }
162
163 if (path == NULL) {
164 printf("debugfs mountpoint not found\n");
165 return -1;
166 }
167
168 snprintf(buf, sizeof(buf) - 1, "%s/tracing/trace_marker", path);
169
170 trace_fd = open(buf, O_WRONLY);
171 if (trace_fd < 0) {
172 printf("failed to open trace_marker file\n");
173 return -1;
174 }
175 wpa_debug_tracing_file = fdopen(trace_fd, "w");
176 if (wpa_debug_tracing_file == NULL) {
177 close(trace_fd);
178 printf("failed to fdopen()\n");
179 return -1;
180 }
181
182 return 0;
183}
184
185
186void wpa_debug_close_linux_tracing(void)
187{
188 if (wpa_debug_tracing_file == NULL)
189 return;
190 fclose(wpa_debug_tracing_file);
191 wpa_debug_tracing_file = NULL;
192}
193
194#endif /* CONFIG_DEBUG_LINUX_TRACING */
195
196
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700197/**
198 * wpa_printf - conditional printf
199 * @level: priority level (MSG_*) of the message
200 * @fmt: printf format string, followed by optional arguments
201 *
202 * This function is used to print conditional debugging and error messages. The
203 * output may be directed to stdout, stderr, and/or syslog based on
204 * configuration.
205 *
206 * Note: New line '\n' is added to the end of the text when printing to stdout.
207 */
208void wpa_printf(int level, const char *fmt, ...)
209{
210 va_list ap;
211
212 va_start(ap, fmt);
213 if (level >= wpa_debug_level) {
Dmitry Shmidt04949592012-07-19 12:16:46 -0700214#ifdef CONFIG_ANDROID_LOG
215 __android_log_vprint(wpa_to_android_level(level),
216 ANDROID_LOG_NAME, fmt, ap);
217#else /* CONFIG_ANDROID_LOG */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700218#ifdef CONFIG_DEBUG_SYSLOG
219 if (wpa_debug_syslog) {
220 vsyslog(syslog_priority(level), fmt, ap);
221 } else {
222#endif /* CONFIG_DEBUG_SYSLOG */
223 wpa_debug_print_timestamp();
224#ifdef CONFIG_DEBUG_FILE
225 if (out_file) {
226 vfprintf(out_file, fmt, ap);
227 fprintf(out_file, "\n");
228 } else {
229#endif /* CONFIG_DEBUG_FILE */
230 vprintf(fmt, ap);
231 printf("\n");
232#ifdef CONFIG_DEBUG_FILE
233 }
234#endif /* CONFIG_DEBUG_FILE */
235#ifdef CONFIG_DEBUG_SYSLOG
236 }
237#endif /* CONFIG_DEBUG_SYSLOG */
Dmitry Shmidt04949592012-07-19 12:16:46 -0700238#endif /* CONFIG_ANDROID_LOG */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700239 }
240 va_end(ap);
Dmitry Shmidt04949592012-07-19 12:16:46 -0700241
242#ifdef CONFIG_DEBUG_LINUX_TRACING
243 if (wpa_debug_tracing_file != NULL) {
244 va_start(ap, fmt);
245 fprintf(wpa_debug_tracing_file, WPAS_TRACE_PFX, level);
246 vfprintf(wpa_debug_tracing_file, fmt, ap);
247 fprintf(wpa_debug_tracing_file, "\n");
248 fflush(wpa_debug_tracing_file);
249 va_end(ap);
250 }
251#endif /* CONFIG_DEBUG_LINUX_TRACING */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700252}
253
254
255static void _wpa_hexdump(int level, const char *title, const u8 *buf,
256 size_t len, int show)
257{
258 size_t i;
Dmitry Shmidt04949592012-07-19 12:16:46 -0700259
260#ifdef CONFIG_DEBUG_LINUX_TRACING
261 if (wpa_debug_tracing_file != NULL) {
262 fprintf(wpa_debug_tracing_file,
263 WPAS_TRACE_PFX "%s - hexdump(len=%lu):",
264 level, title, (unsigned long) len);
265 if (buf == NULL) {
266 fprintf(wpa_debug_tracing_file, " [NULL]\n");
267 } else if (!show) {
268 fprintf(wpa_debug_tracing_file, " [REMOVED]\n");
269 } else {
270 for (i = 0; i < len; i++)
271 fprintf(wpa_debug_tracing_file,
272 " %02x", buf[i]);
273 }
274 fflush(wpa_debug_tracing_file);
275 }
276#endif /* CONFIG_DEBUG_LINUX_TRACING */
277
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700278 if (level < wpa_debug_level)
279 return;
Dmitry Shmidt04949592012-07-19 12:16:46 -0700280#ifdef CONFIG_ANDROID_LOG
281 {
282 const char *display;
283 char *strbuf = NULL;
284 size_t slen = len;
285 if (buf == NULL) {
286 display = " [NULL]";
287 } else if (len == 0) {
288 display = "";
289 } else if (show && len) {
290 /* Limit debug message length for Android log */
291 if (slen > 32)
292 slen = 32;
293 strbuf = os_malloc(1 + 3 * slen);
294 if (strbuf == NULL) {
295 wpa_printf(MSG_ERROR, "wpa_hexdump: Failed to "
296 "allocate message buffer");
297 return;
298 }
299
300 for (i = 0; i < slen; i++)
301 os_snprintf(&strbuf[i * 3], 4, " %02x",
302 buf[i]);
303
304 display = strbuf;
305 } else {
306 display = " [REMOVED]";
307 }
308
309 __android_log_print(wpa_to_android_level(level),
310 ANDROID_LOG_NAME,
311 "%s - hexdump(len=%lu):%s%s",
312 title, (long unsigned int) len, display,
313 len > slen ? " ..." : "");
Dmitry Shmidta3dc3092015-06-23 11:21:28 -0700314 bin_clear_free(strbuf, 1 + 3 * slen);
Dmitry Shmidt04949592012-07-19 12:16:46 -0700315 return;
316 }
317#else /* CONFIG_ANDROID_LOG */
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -0800318#ifdef CONFIG_DEBUG_SYSLOG
319 if (wpa_debug_syslog) {
320 const char *display;
321 char *strbuf = NULL;
322
323 if (buf == NULL) {
324 display = " [NULL]";
325 } else if (len == 0) {
326 display = "";
327 } else if (show && len) {
328 strbuf = os_malloc(1 + 3 * len);
329 if (strbuf == NULL) {
330 wpa_printf(MSG_ERROR, "wpa_hexdump: Failed to "
331 "allocate message buffer");
332 return;
333 }
334
335 for (i = 0; i < len; i++)
336 os_snprintf(&strbuf[i * 3], 4, " %02x",
337 buf[i]);
338
339 display = strbuf;
340 } else {
341 display = " [REMOVED]";
342 }
343
344 syslog(syslog_priority(level), "%s - hexdump(len=%lu):%s",
Dmitry Shmidt04949592012-07-19 12:16:46 -0700345 title, (unsigned long) len, display);
Dmitry Shmidta3dc3092015-06-23 11:21:28 -0700346 bin_clear_free(strbuf, 1 + 3 * len);
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -0800347 return;
348 }
349#endif /* CONFIG_DEBUG_SYSLOG */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700350 wpa_debug_print_timestamp();
351#ifdef CONFIG_DEBUG_FILE
352 if (out_file) {
353 fprintf(out_file, "%s - hexdump(len=%lu):",
354 title, (unsigned long) len);
355 if (buf == NULL) {
356 fprintf(out_file, " [NULL]");
357 } else if (show) {
358 for (i = 0; i < len; i++)
359 fprintf(out_file, " %02x", buf[i]);
360 } else {
361 fprintf(out_file, " [REMOVED]");
362 }
363 fprintf(out_file, "\n");
364 } else {
365#endif /* CONFIG_DEBUG_FILE */
366 printf("%s - hexdump(len=%lu):", title, (unsigned long) len);
367 if (buf == NULL) {
368 printf(" [NULL]");
369 } else if (show) {
370 for (i = 0; i < len; i++)
371 printf(" %02x", buf[i]);
372 } else {
373 printf(" [REMOVED]");
374 }
375 printf("\n");
376#ifdef CONFIG_DEBUG_FILE
377 }
378#endif /* CONFIG_DEBUG_FILE */
Dmitry Shmidt04949592012-07-19 12:16:46 -0700379#endif /* CONFIG_ANDROID_LOG */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700380}
381
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800382void wpa_hexdump(int level, const char *title, const void *buf, size_t len)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700383{
384 _wpa_hexdump(level, title, buf, len, 1);
385}
386
387
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800388void wpa_hexdump_key(int level, const char *title, const void *buf, size_t len)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700389{
390 _wpa_hexdump(level, title, buf, len, wpa_debug_show_keys);
391}
392
393
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800394static void _wpa_hexdump_ascii(int level, const char *title, const void *buf,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700395 size_t len, int show)
396{
397 size_t i, llen;
398 const u8 *pos = buf;
399 const size_t line_len = 16;
400
Dmitry Shmidt04949592012-07-19 12:16:46 -0700401#ifdef CONFIG_DEBUG_LINUX_TRACING
402 if (wpa_debug_tracing_file != NULL) {
403 fprintf(wpa_debug_tracing_file,
404 WPAS_TRACE_PFX "%s - hexdump_ascii(len=%lu):",
405 level, title, (unsigned long) len);
406 if (buf == NULL) {
407 fprintf(wpa_debug_tracing_file, " [NULL]\n");
408 } else if (!show) {
409 fprintf(wpa_debug_tracing_file, " [REMOVED]\n");
410 } else {
411 /* can do ascii processing in userspace */
412 for (i = 0; i < len; i++)
413 fprintf(wpa_debug_tracing_file,
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800414 " %02x", pos[i]);
Dmitry Shmidt04949592012-07-19 12:16:46 -0700415 }
416 fflush(wpa_debug_tracing_file);
417 }
418#endif /* CONFIG_DEBUG_LINUX_TRACING */
419
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700420 if (level < wpa_debug_level)
421 return;
Dmitry Shmidt04949592012-07-19 12:16:46 -0700422#ifdef CONFIG_ANDROID_LOG
423 _wpa_hexdump(level, title, buf, len, show);
424#else /* CONFIG_ANDROID_LOG */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700425 wpa_debug_print_timestamp();
426#ifdef CONFIG_DEBUG_FILE
427 if (out_file) {
428 if (!show) {
429 fprintf(out_file,
430 "%s - hexdump_ascii(len=%lu): [REMOVED]\n",
431 title, (unsigned long) len);
432 return;
433 }
434 if (buf == NULL) {
435 fprintf(out_file,
436 "%s - hexdump_ascii(len=%lu): [NULL]\n",
437 title, (unsigned long) len);
438 return;
439 }
440 fprintf(out_file, "%s - hexdump_ascii(len=%lu):\n",
441 title, (unsigned long) len);
442 while (len) {
443 llen = len > line_len ? line_len : len;
444 fprintf(out_file, " ");
445 for (i = 0; i < llen; i++)
446 fprintf(out_file, " %02x", pos[i]);
447 for (i = llen; i < line_len; i++)
448 fprintf(out_file, " ");
449 fprintf(out_file, " ");
450 for (i = 0; i < llen; i++) {
451 if (isprint(pos[i]))
452 fprintf(out_file, "%c", pos[i]);
453 else
454 fprintf(out_file, "_");
455 }
456 for (i = llen; i < line_len; i++)
457 fprintf(out_file, " ");
458 fprintf(out_file, "\n");
459 pos += llen;
460 len -= llen;
461 }
462 } else {
463#endif /* CONFIG_DEBUG_FILE */
464 if (!show) {
465 printf("%s - hexdump_ascii(len=%lu): [REMOVED]\n",
466 title, (unsigned long) len);
467 return;
468 }
469 if (buf == NULL) {
470 printf("%s - hexdump_ascii(len=%lu): [NULL]\n",
471 title, (unsigned long) len);
472 return;
473 }
474 printf("%s - hexdump_ascii(len=%lu):\n", title, (unsigned long) len);
475 while (len) {
476 llen = len > line_len ? line_len : len;
477 printf(" ");
478 for (i = 0; i < llen; i++)
479 printf(" %02x", pos[i]);
480 for (i = llen; i < line_len; i++)
481 printf(" ");
482 printf(" ");
483 for (i = 0; i < llen; i++) {
484 if (isprint(pos[i]))
485 printf("%c", pos[i]);
486 else
487 printf("_");
488 }
489 for (i = llen; i < line_len; i++)
490 printf(" ");
491 printf("\n");
492 pos += llen;
493 len -= llen;
494 }
495#ifdef CONFIG_DEBUG_FILE
496 }
497#endif /* CONFIG_DEBUG_FILE */
Dmitry Shmidt04949592012-07-19 12:16:46 -0700498#endif /* CONFIG_ANDROID_LOG */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700499}
500
501
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800502void wpa_hexdump_ascii(int level, const char *title, const void *buf,
503 size_t len)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700504{
505 _wpa_hexdump_ascii(level, title, buf, len, 1);
506}
507
508
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800509void wpa_hexdump_ascii_key(int level, const char *title, const void *buf,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700510 size_t len)
511{
512 _wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys);
513}
514
515
516#ifdef CONFIG_DEBUG_FILE
517static char *last_path = NULL;
518#endif /* CONFIG_DEBUG_FILE */
519
520int wpa_debug_reopen_file(void)
521{
522#ifdef CONFIG_DEBUG_FILE
523 int rv;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800524 char *tmp;
525
526 if (!last_path)
527 return 0; /* logfile not used */
528
529 tmp = os_strdup(last_path);
530 if (!tmp)
531 return -1;
532
533 wpa_debug_close_file();
534 rv = wpa_debug_open_file(tmp);
535 os_free(tmp);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700536 return rv;
537#else /* CONFIG_DEBUG_FILE */
538 return 0;
539#endif /* CONFIG_DEBUG_FILE */
540}
541
542
543int wpa_debug_open_file(const char *path)
544{
545#ifdef CONFIG_DEBUG_FILE
Hai Shalom39ba6fc2019-01-22 12:40:38 -0800546 int out_fd;
547
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700548 if (!path)
549 return 0;
550
551 if (last_path == NULL || os_strcmp(last_path, path) != 0) {
552 /* Save our path to enable re-open */
553 os_free(last_path);
554 last_path = os_strdup(path);
555 }
556
Hai Shalom39ba6fc2019-01-22 12:40:38 -0800557 out_fd = open(path, O_CREAT | O_APPEND | O_WRONLY,
558 S_IRUSR | S_IWUSR | S_IRGRP);
559 if (out_fd < 0) {
560 wpa_printf(MSG_ERROR,
561 "%s: Failed to open output file descriptor, using standard output",
562 __func__);
563 return -1;
564 }
565
566#ifdef __linux__
567 if (fcntl(out_fd, F_SETFD, FD_CLOEXEC) < 0) {
568 wpa_printf(MSG_DEBUG,
569 "%s: Failed to set FD_CLOEXEC - continue without: %s",
570 __func__, strerror(errno));
571 }
572#endif /* __linux__ */
573
574 out_file = fdopen(out_fd, "a");
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700575 if (out_file == NULL) {
576 wpa_printf(MSG_ERROR, "wpa_debug_open_file: Failed to open "
577 "output file, using standard output");
Hai Shalom39ba6fc2019-01-22 12:40:38 -0800578 close(out_fd);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700579 return -1;
580 }
581#ifndef _WIN32
582 setvbuf(out_file, NULL, _IOLBF, 0);
583#endif /* _WIN32 */
Dmitry Shmidtfb45fd52015-01-05 13:08:17 -0800584#else /* CONFIG_DEBUG_FILE */
585 (void)path;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700586#endif /* CONFIG_DEBUG_FILE */
587 return 0;
588}
589
590
591void wpa_debug_close_file(void)
592{
593#ifdef CONFIG_DEBUG_FILE
594 if (!out_file)
595 return;
596 fclose(out_file);
597 out_file = NULL;
598 os_free(last_path);
599 last_path = NULL;
600#endif /* CONFIG_DEBUG_FILE */
601}
602
Dmitry Shmidtfb45fd52015-01-05 13:08:17 -0800603
604void wpa_debug_setup_stdout(void)
605{
606#ifndef _WIN32
607 setvbuf(stdout, NULL, _IOLBF, 0);
608#endif /* _WIN32 */
609}
610
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700611#endif /* CONFIG_NO_STDOUT_DEBUG */
612
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700613
614#ifndef CONFIG_NO_WPA_MSG
615static wpa_msg_cb_func wpa_msg_cb = NULL;
616
617void wpa_msg_register_cb(wpa_msg_cb_func func)
618{
619 wpa_msg_cb = func;
620}
621
622
623static wpa_msg_get_ifname_func wpa_msg_ifname_cb = NULL;
624
625void wpa_msg_register_ifname_cb(wpa_msg_get_ifname_func func)
626{
627 wpa_msg_ifname_cb = func;
628}
629
630
631void wpa_msg(void *ctx, int level, const char *fmt, ...)
632{
633 va_list ap;
634 char *buf;
Dmitry Shmidt13ca8d82014-02-20 10:18:40 -0800635 int buflen;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700636 int len;
637 char prefix[130];
638
Dmitry Shmidt13ca8d82014-02-20 10:18:40 -0800639 va_start(ap, fmt);
640 buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
641 va_end(ap);
642
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700643 buf = os_malloc(buflen);
644 if (buf == NULL) {
645 wpa_printf(MSG_ERROR, "wpa_msg: Failed to allocate message "
646 "buffer");
647 return;
648 }
649 va_start(ap, fmt);
650 prefix[0] = '\0';
651 if (wpa_msg_ifname_cb) {
652 const char *ifname = wpa_msg_ifname_cb(ctx);
653 if (ifname) {
654 int res = os_snprintf(prefix, sizeof(prefix), "%s: ",
655 ifname);
Dmitry Shmidtfb45fd52015-01-05 13:08:17 -0800656 if (os_snprintf_error(sizeof(prefix), res))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700657 prefix[0] = '\0';
658 }
659 }
660 len = vsnprintf(buf, buflen, fmt, ap);
661 va_end(ap);
662 wpa_printf(level, "%s%s", prefix, buf);
663 if (wpa_msg_cb)
Dmitry Shmidt7a53dbb2015-06-11 13:13:53 -0700664 wpa_msg_cb(ctx, level, WPA_MSG_PER_INTERFACE, buf, len);
Dmitry Shmidta3dc3092015-06-23 11:21:28 -0700665 bin_clear_free(buf, buflen);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700666}
667
668
669void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...)
670{
671 va_list ap;
672 char *buf;
Dmitry Shmidt13ca8d82014-02-20 10:18:40 -0800673 int buflen;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700674 int len;
675
676 if (!wpa_msg_cb)
677 return;
678
Dmitry Shmidt13ca8d82014-02-20 10:18:40 -0800679 va_start(ap, fmt);
680 buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
681 va_end(ap);
682
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700683 buf = os_malloc(buflen);
684 if (buf == NULL) {
685 wpa_printf(MSG_ERROR, "wpa_msg_ctrl: Failed to allocate "
686 "message buffer");
687 return;
688 }
689 va_start(ap, fmt);
690 len = vsnprintf(buf, buflen, fmt, ap);
691 va_end(ap);
Dmitry Shmidt7a53dbb2015-06-11 13:13:53 -0700692 wpa_msg_cb(ctx, level, WPA_MSG_PER_INTERFACE, buf, len);
Dmitry Shmidta3dc3092015-06-23 11:21:28 -0700693 bin_clear_free(buf, buflen);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700694}
Dmitry Shmidtb6e9aaf2013-05-20 14:49:44 -0700695
696
697void wpa_msg_global(void *ctx, int level, const char *fmt, ...)
698{
699 va_list ap;
700 char *buf;
Dmitry Shmidt13ca8d82014-02-20 10:18:40 -0800701 int buflen;
Dmitry Shmidtb6e9aaf2013-05-20 14:49:44 -0700702 int len;
703
Dmitry Shmidt13ca8d82014-02-20 10:18:40 -0800704 va_start(ap, fmt);
705 buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
706 va_end(ap);
707
Dmitry Shmidtb6e9aaf2013-05-20 14:49:44 -0700708 buf = os_malloc(buflen);
709 if (buf == NULL) {
710 wpa_printf(MSG_ERROR, "wpa_msg_global: Failed to allocate "
711 "message buffer");
712 return;
713 }
714 va_start(ap, fmt);
715 len = vsnprintf(buf, buflen, fmt, ap);
716 va_end(ap);
717 wpa_printf(level, "%s", buf);
718 if (wpa_msg_cb)
Dmitry Shmidt7a53dbb2015-06-11 13:13:53 -0700719 wpa_msg_cb(ctx, level, WPA_MSG_GLOBAL, buf, len);
Dmitry Shmidta3dc3092015-06-23 11:21:28 -0700720 bin_clear_free(buf, buflen);
Dmitry Shmidtb6e9aaf2013-05-20 14:49:44 -0700721}
722
723
Dmitry Shmidt7f0b69e2014-07-28 10:35:20 -0700724void wpa_msg_global_ctrl(void *ctx, int level, const char *fmt, ...)
725{
726 va_list ap;
727 char *buf;
728 int buflen;
729 int len;
730
731 if (!wpa_msg_cb)
732 return;
733
734 va_start(ap, fmt);
735 buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
736 va_end(ap);
737
738 buf = os_malloc(buflen);
739 if (buf == NULL) {
740 wpa_printf(MSG_ERROR,
741 "wpa_msg_global_ctrl: Failed to allocate message buffer");
742 return;
743 }
744 va_start(ap, fmt);
745 len = vsnprintf(buf, buflen, fmt, ap);
746 va_end(ap);
Dmitry Shmidt7a53dbb2015-06-11 13:13:53 -0700747 wpa_msg_cb(ctx, level, WPA_MSG_GLOBAL, buf, len);
Dmitry Shmidta3dc3092015-06-23 11:21:28 -0700748 bin_clear_free(buf, buflen);
Dmitry Shmidt7f0b69e2014-07-28 10:35:20 -0700749}
750
751
Dmitry Shmidtb6e9aaf2013-05-20 14:49:44 -0700752void wpa_msg_no_global(void *ctx, int level, const char *fmt, ...)
753{
754 va_list ap;
755 char *buf;
Dmitry Shmidt13ca8d82014-02-20 10:18:40 -0800756 int buflen;
Dmitry Shmidtb6e9aaf2013-05-20 14:49:44 -0700757 int len;
758
Dmitry Shmidt13ca8d82014-02-20 10:18:40 -0800759 va_start(ap, fmt);
760 buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
761 va_end(ap);
762
Dmitry Shmidtb6e9aaf2013-05-20 14:49:44 -0700763 buf = os_malloc(buflen);
764 if (buf == NULL) {
765 wpa_printf(MSG_ERROR, "wpa_msg_no_global: Failed to allocate "
766 "message buffer");
767 return;
768 }
769 va_start(ap, fmt);
770 len = vsnprintf(buf, buflen, fmt, ap);
771 va_end(ap);
772 wpa_printf(level, "%s", buf);
773 if (wpa_msg_cb)
Dmitry Shmidt7a53dbb2015-06-11 13:13:53 -0700774 wpa_msg_cb(ctx, level, WPA_MSG_NO_GLOBAL, buf, len);
Dmitry Shmidta3dc3092015-06-23 11:21:28 -0700775 bin_clear_free(buf, buflen);
Dmitry Shmidtb6e9aaf2013-05-20 14:49:44 -0700776}
777
Anton Nayshtutf715e8d2014-11-16 16:52:49 +0200778
779void wpa_msg_global_only(void *ctx, int level, const char *fmt, ...)
780{
781 va_list ap;
782 char *buf;
783 int buflen;
784 int len;
785
786 va_start(ap, fmt);
787 buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
788 va_end(ap);
789
790 buf = os_malloc(buflen);
791 if (buf == NULL) {
792 wpa_printf(MSG_ERROR, "%s: Failed to allocate message buffer",
793 __func__);
794 return;
795 }
796 va_start(ap, fmt);
797 len = vsnprintf(buf, buflen, fmt, ap);
798 va_end(ap);
799 wpa_printf(level, "%s", buf);
800 if (wpa_msg_cb)
801 wpa_msg_cb(ctx, level, WPA_MSG_ONLY_GLOBAL, buf, len);
802 os_free(buf);
803}
804
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700805#endif /* CONFIG_NO_WPA_MSG */
806
807
808#ifndef CONFIG_NO_HOSTAPD_LOGGER
809static hostapd_logger_cb_func hostapd_logger_cb = NULL;
810
811void hostapd_logger_register_cb(hostapd_logger_cb_func func)
812{
813 hostapd_logger_cb = func;
814}
815
816
817void hostapd_logger(void *ctx, const u8 *addr, unsigned int module, int level,
818 const char *fmt, ...)
819{
820 va_list ap;
821 char *buf;
Dmitry Shmidt13ca8d82014-02-20 10:18:40 -0800822 int buflen;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700823 int len;
824
Dmitry Shmidt13ca8d82014-02-20 10:18:40 -0800825 va_start(ap, fmt);
826 buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
827 va_end(ap);
828
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700829 buf = os_malloc(buflen);
830 if (buf == NULL) {
831 wpa_printf(MSG_ERROR, "hostapd_logger: Failed to allocate "
832 "message buffer");
833 return;
834 }
835 va_start(ap, fmt);
836 len = vsnprintf(buf, buflen, fmt, ap);
837 va_end(ap);
838 if (hostapd_logger_cb)
839 hostapd_logger_cb(ctx, addr, module, level, buf, len);
840 else if (addr)
841 wpa_printf(MSG_DEBUG, "hostapd_logger: STA " MACSTR " - %s",
842 MAC2STR(addr), buf);
843 else
844 wpa_printf(MSG_DEBUG, "hostapd_logger: %s", buf);
Dmitry Shmidta3dc3092015-06-23 11:21:28 -0700845 bin_clear_free(buf, buflen);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700846}
847#endif /* CONFIG_NO_HOSTAPD_LOGGER */
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800848
849
850const char * debug_level_str(int level)
851{
852 switch (level) {
853 case MSG_EXCESSIVE:
854 return "EXCESSIVE";
855 case MSG_MSGDUMP:
856 return "MSGDUMP";
857 case MSG_DEBUG:
858 return "DEBUG";
859 case MSG_INFO:
860 return "INFO";
861 case MSG_WARNING:
862 return "WARNING";
863 case MSG_ERROR:
864 return "ERROR";
865 default:
866 return "?";
867 }
868}
869
870
871int str_to_debug_level(const char *s)
872{
873 if (os_strcasecmp(s, "EXCESSIVE") == 0)
874 return MSG_EXCESSIVE;
875 if (os_strcasecmp(s, "MSGDUMP") == 0)
876 return MSG_MSGDUMP;
877 if (os_strcasecmp(s, "DEBUG") == 0)
878 return MSG_DEBUG;
879 if (os_strcasecmp(s, "INFO") == 0)
880 return MSG_INFO;
881 if (os_strcasecmp(s, "WARNING") == 0)
882 return MSG_WARNING;
883 if (os_strcasecmp(s, "ERROR") == 0)
884 return MSG_ERROR;
885 return -1;
886}