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