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
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);
155 if (fstype && strcmp(fstype, "debugfs") == 0) {
156 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
wpa_debug_close_linux_tracing(void)186 void 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
197 /**
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 */
wpa_printf(int level,const char * fmt,...)208 void wpa_printf(int level, const char *fmt, ...)
209 {
210 va_list ap;
211
212 va_start(ap, fmt);
213 if (level >= wpa_debug_level) {
214 #ifdef CONFIG_ANDROID_LOG
215 __android_log_vprint(wpa_to_android_level(level),
216 ANDROID_LOG_NAME, fmt, ap);
217 #else /* CONFIG_ANDROID_LOG */
218 #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 */
238 #endif /* CONFIG_ANDROID_LOG */
239 }
240 va_end(ap);
241
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 */
252 }
253
254
_wpa_hexdump(int level,const char * title,const u8 * buf,size_t len,int show)255 static void _wpa_hexdump(int level, const char *title, const u8 *buf,
256 size_t len, int show)
257 {
258 size_t i;
259
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
278 if (level < wpa_debug_level)
279 return;
280 #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 ? " ..." : "");
314 bin_clear_free(strbuf, 1 + 3 * slen);
315 return;
316 }
317 #else /* CONFIG_ANDROID_LOG */
318 #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",
345 title, (unsigned long) len, display);
346 bin_clear_free(strbuf, 1 + 3 * len);
347 return;
348 }
349 #endif /* CONFIG_DEBUG_SYSLOG */
350 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 */
379 #endif /* CONFIG_ANDROID_LOG */
380 }
381
wpa_hexdump(int level,const char * title,const void * buf,size_t len)382 void wpa_hexdump(int level, const char *title, const void *buf, size_t len)
383 {
384 _wpa_hexdump(level, title, buf, len, 1);
385 }
386
387
wpa_hexdump_key(int level,const char * title,const void * buf,size_t len)388 void wpa_hexdump_key(int level, const char *title, const void *buf, size_t len)
389 {
390 _wpa_hexdump(level, title, buf, len, wpa_debug_show_keys);
391 }
392
393
_wpa_hexdump_ascii(int level,const char * title,const void * buf,size_t len,int show)394 static void _wpa_hexdump_ascii(int level, const char *title, const void *buf,
395 size_t len, int show)
396 {
397 size_t i, llen;
398 const u8 *pos = buf;
399 const size_t line_len = 16;
400
401 #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,
414 " %02x", pos[i]);
415 }
416 fflush(wpa_debug_tracing_file);
417 }
418 #endif /* CONFIG_DEBUG_LINUX_TRACING */
419
420 if (level < wpa_debug_level)
421 return;
422 #ifdef CONFIG_ANDROID_LOG
423 _wpa_hexdump(level, title, buf, len, show);
424 #else /* CONFIG_ANDROID_LOG */
425 #ifdef CONFIG_DEBUG_SYSLOG
426 if (wpa_debug_syslog) {
427 _wpa_hexdump(level, title, buf, len, show);
428 return;
429 }
430 #endif /* CONFIG_DEBUG_SYSLOG */
431 wpa_debug_print_timestamp();
432 #ifdef CONFIG_DEBUG_FILE
433 if (out_file) {
434 if (!show) {
435 fprintf(out_file,
436 "%s - hexdump_ascii(len=%lu): [REMOVED]\n",
437 title, (unsigned long) len);
438 return;
439 }
440 if (buf == NULL) {
441 fprintf(out_file,
442 "%s - hexdump_ascii(len=%lu): [NULL]\n",
443 title, (unsigned long) len);
444 return;
445 }
446 fprintf(out_file, "%s - hexdump_ascii(len=%lu):\n",
447 title, (unsigned long) len);
448 while (len) {
449 llen = len > line_len ? line_len : len;
450 fprintf(out_file, " ");
451 for (i = 0; i < llen; i++)
452 fprintf(out_file, " %02x", pos[i]);
453 for (i = llen; i < line_len; i++)
454 fprintf(out_file, " ");
455 fprintf(out_file, " ");
456 for (i = 0; i < llen; i++) {
457 if (isprint(pos[i]))
458 fprintf(out_file, "%c", pos[i]);
459 else
460 fprintf(out_file, "_");
461 }
462 for (i = llen; i < line_len; i++)
463 fprintf(out_file, " ");
464 fprintf(out_file, "\n");
465 pos += llen;
466 len -= llen;
467 }
468 } else {
469 #endif /* CONFIG_DEBUG_FILE */
470 if (!show) {
471 printf("%s - hexdump_ascii(len=%lu): [REMOVED]\n",
472 title, (unsigned long) len);
473 return;
474 }
475 if (buf == NULL) {
476 printf("%s - hexdump_ascii(len=%lu): [NULL]\n",
477 title, (unsigned long) len);
478 return;
479 }
480 printf("%s - hexdump_ascii(len=%lu):\n", title, (unsigned long) len);
481 while (len) {
482 llen = len > line_len ? line_len : len;
483 printf(" ");
484 for (i = 0; i < llen; i++)
485 printf(" %02x", pos[i]);
486 for (i = llen; i < line_len; i++)
487 printf(" ");
488 printf(" ");
489 for (i = 0; i < llen; i++) {
490 if (isprint(pos[i]))
491 printf("%c", pos[i]);
492 else
493 printf("_");
494 }
495 for (i = llen; i < line_len; i++)
496 printf(" ");
497 printf("\n");
498 pos += llen;
499 len -= llen;
500 }
501 #ifdef CONFIG_DEBUG_FILE
502 }
503 #endif /* CONFIG_DEBUG_FILE */
504 #endif /* CONFIG_ANDROID_LOG */
505 }
506
507
wpa_hexdump_ascii(int level,const char * title,const void * buf,size_t len)508 void wpa_hexdump_ascii(int level, const char *title, const void *buf,
509 size_t len)
510 {
511 _wpa_hexdump_ascii(level, title, buf, len, 1);
512 }
513
514
wpa_hexdump_ascii_key(int level,const char * title,const void * buf,size_t len)515 void wpa_hexdump_ascii_key(int level, const char *title, const void *buf,
516 size_t len)
517 {
518 _wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys);
519 }
520
521
522 #ifdef CONFIG_DEBUG_FILE
523 static char *last_path = NULL;
524 #endif /* CONFIG_DEBUG_FILE */
525
wpa_debug_reopen_file(void)526 int wpa_debug_reopen_file(void)
527 {
528 #ifdef CONFIG_DEBUG_FILE
529 int rv;
530 char *tmp;
531
532 if (!last_path)
533 return 0; /* logfile not used */
534
535 tmp = os_strdup(last_path);
536 if (!tmp)
537 return -1;
538
539 wpa_debug_close_file();
540 rv = wpa_debug_open_file(tmp);
541 os_free(tmp);
542 return rv;
543 #else /* CONFIG_DEBUG_FILE */
544 return 0;
545 #endif /* CONFIG_DEBUG_FILE */
546 }
547
548
wpa_debug_open_file(const char * path)549 int wpa_debug_open_file(const char *path)
550 {
551 #ifdef CONFIG_DEBUG_FILE
552 int out_fd;
553
554 if (!path)
555 return 0;
556
557 if (last_path == NULL || os_strcmp(last_path, path) != 0) {
558 /* Save our path to enable re-open */
559 os_free(last_path);
560 last_path = os_strdup(path);
561 }
562
563 out_fd = open(path, O_CREAT | O_APPEND | O_WRONLY,
564 S_IRUSR | S_IWUSR | S_IRGRP);
565 if (out_fd < 0) {
566 wpa_printf(MSG_ERROR,
567 "%s: Failed to open output file descriptor, using standard output",
568 __func__);
569 return -1;
570 }
571
572 #ifdef __linux__
573 if (fcntl(out_fd, F_SETFD, FD_CLOEXEC) < 0) {
574 wpa_printf(MSG_DEBUG,
575 "%s: Failed to set FD_CLOEXEC - continue without: %s",
576 __func__, strerror(errno));
577 }
578 #endif /* __linux__ */
579
580 out_file = fdopen(out_fd, "a");
581 if (out_file == NULL) {
582 wpa_printf(MSG_ERROR, "wpa_debug_open_file: Failed to open "
583 "output file, using standard output");
584 close(out_fd);
585 return -1;
586 }
587 #ifndef _WIN32
588 setvbuf(out_file, NULL, _IOLBF, 0);
589 #endif /* _WIN32 */
590 #else /* CONFIG_DEBUG_FILE */
591 (void)path;
592 #endif /* CONFIG_DEBUG_FILE */
593 return 0;
594 }
595
596
wpa_debug_close_file(void)597 void wpa_debug_close_file(void)
598 {
599 #ifdef CONFIG_DEBUG_FILE
600 if (!out_file)
601 return;
602 fclose(out_file);
603 out_file = NULL;
604 os_free(last_path);
605 last_path = NULL;
606 #endif /* CONFIG_DEBUG_FILE */
607 }
608
609
wpa_debug_setup_stdout(void)610 void wpa_debug_setup_stdout(void)
611 {
612 #ifndef _WIN32
613 setvbuf(stdout, NULL, _IOLBF, 0);
614 #endif /* _WIN32 */
615 }
616
617 #endif /* CONFIG_NO_STDOUT_DEBUG */
618
619
620 #ifndef CONFIG_NO_WPA_MSG
621 static wpa_msg_cb_func wpa_msg_cb = NULL;
622
wpa_msg_register_cb(wpa_msg_cb_func func)623 void wpa_msg_register_cb(wpa_msg_cb_func func)
624 {
625 wpa_msg_cb = func;
626 }
627
628
629 static wpa_msg_get_ifname_func wpa_msg_ifname_cb = NULL;
630
wpa_msg_register_ifname_cb(wpa_msg_get_ifname_func func)631 void wpa_msg_register_ifname_cb(wpa_msg_get_ifname_func func)
632 {
633 wpa_msg_ifname_cb = func;
634 }
635
636
wpa_msg(void * ctx,int level,const char * fmt,...)637 void wpa_msg(void *ctx, int level, const char *fmt, ...)
638 {
639 va_list ap;
640 char *buf;
641 int buflen;
642 int len;
643 char prefix[130];
644
645 va_start(ap, fmt);
646 buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
647 va_end(ap);
648
649 buf = os_malloc(buflen);
650 if (buf == NULL) {
651 wpa_printf(MSG_ERROR, "wpa_msg: Failed to allocate message "
652 "buffer");
653 return;
654 }
655 va_start(ap, fmt);
656 prefix[0] = '\0';
657 if (wpa_msg_ifname_cb) {
658 const char *ifname = wpa_msg_ifname_cb(ctx);
659 if (ifname) {
660 int res = os_snprintf(prefix, sizeof(prefix), "%s: ",
661 ifname);
662 if (os_snprintf_error(sizeof(prefix), res))
663 prefix[0] = '\0';
664 }
665 }
666 len = vsnprintf(buf, buflen, fmt, ap);
667 va_end(ap);
668 wpa_printf(level, "%s%s", prefix, buf);
669 if (wpa_msg_cb)
670 wpa_msg_cb(ctx, level, WPA_MSG_PER_INTERFACE, buf, len);
671 bin_clear_free(buf, buflen);
672 }
673
674
wpa_msg_ctrl(void * ctx,int level,const char * fmt,...)675 void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...)
676 {
677 va_list ap;
678 char *buf;
679 int buflen;
680 int len;
681
682 if (!wpa_msg_cb)
683 return;
684
685 va_start(ap, fmt);
686 buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
687 va_end(ap);
688
689 buf = os_malloc(buflen);
690 if (buf == NULL) {
691 wpa_printf(MSG_ERROR, "wpa_msg_ctrl: Failed to allocate "
692 "message buffer");
693 return;
694 }
695 va_start(ap, fmt);
696 len = vsnprintf(buf, buflen, fmt, ap);
697 va_end(ap);
698 wpa_msg_cb(ctx, level, WPA_MSG_PER_INTERFACE, buf, len);
699 bin_clear_free(buf, buflen);
700 }
701
702
wpa_msg_global(void * ctx,int level,const char * fmt,...)703 void wpa_msg_global(void *ctx, int level, const char *fmt, ...)
704 {
705 va_list ap;
706 char *buf;
707 int buflen;
708 int len;
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, "wpa_msg_global: Failed to allocate "
717 "message buffer");
718 return;
719 }
720 va_start(ap, fmt);
721 len = vsnprintf(buf, buflen, fmt, ap);
722 va_end(ap);
723 wpa_printf(level, "%s", buf);
724 if (wpa_msg_cb)
725 wpa_msg_cb(ctx, level, WPA_MSG_GLOBAL, buf, len);
726 bin_clear_free(buf, buflen);
727 }
728
729
wpa_msg_global_ctrl(void * ctx,int level,const char * fmt,...)730 void wpa_msg_global_ctrl(void *ctx, int level, const char *fmt, ...)
731 {
732 va_list ap;
733 char *buf;
734 int buflen;
735 int len;
736
737 if (!wpa_msg_cb)
738 return;
739
740 va_start(ap, fmt);
741 buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
742 va_end(ap);
743
744 buf = os_malloc(buflen);
745 if (buf == NULL) {
746 wpa_printf(MSG_ERROR,
747 "wpa_msg_global_ctrl: Failed to allocate message buffer");
748 return;
749 }
750 va_start(ap, fmt);
751 len = vsnprintf(buf, buflen, fmt, ap);
752 va_end(ap);
753 wpa_msg_cb(ctx, level, WPA_MSG_GLOBAL, buf, len);
754 bin_clear_free(buf, buflen);
755 }
756
757
wpa_msg_no_global(void * ctx,int level,const char * fmt,...)758 void wpa_msg_no_global(void *ctx, int level, const char *fmt, ...)
759 {
760 va_list ap;
761 char *buf;
762 int buflen;
763 int len;
764
765 va_start(ap, fmt);
766 buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
767 va_end(ap);
768
769 buf = os_malloc(buflen);
770 if (buf == NULL) {
771 wpa_printf(MSG_ERROR, "wpa_msg_no_global: Failed to allocate "
772 "message buffer");
773 return;
774 }
775 va_start(ap, fmt);
776 len = vsnprintf(buf, buflen, fmt, ap);
777 va_end(ap);
778 wpa_printf(level, "%s", buf);
779 if (wpa_msg_cb)
780 wpa_msg_cb(ctx, level, WPA_MSG_NO_GLOBAL, buf, len);
781 bin_clear_free(buf, buflen);
782 }
783
784
wpa_msg_global_only(void * ctx,int level,const char * fmt,...)785 void wpa_msg_global_only(void *ctx, int level, const char *fmt, ...)
786 {
787 va_list ap;
788 char *buf;
789 int buflen;
790 int len;
791
792 va_start(ap, fmt);
793 buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
794 va_end(ap);
795
796 buf = os_malloc(buflen);
797 if (buf == NULL) {
798 wpa_printf(MSG_ERROR, "%s: Failed to allocate message buffer",
799 __func__);
800 return;
801 }
802 va_start(ap, fmt);
803 len = vsnprintf(buf, buflen, fmt, ap);
804 va_end(ap);
805 wpa_printf(level, "%s", buf);
806 if (wpa_msg_cb)
807 wpa_msg_cb(ctx, level, WPA_MSG_ONLY_GLOBAL, buf, len);
808 os_free(buf);
809 }
810
811 #endif /* CONFIG_NO_WPA_MSG */
812
813
814 #ifndef CONFIG_NO_HOSTAPD_LOGGER
815 static hostapd_logger_cb_func hostapd_logger_cb = NULL;
816
hostapd_logger_register_cb(hostapd_logger_cb_func func)817 void hostapd_logger_register_cb(hostapd_logger_cb_func func)
818 {
819 hostapd_logger_cb = func;
820 }
821
822
hostapd_logger(void * ctx,const u8 * addr,unsigned int module,int level,const char * fmt,...)823 void hostapd_logger(void *ctx, const u8 *addr, unsigned int module, int level,
824 const char *fmt, ...)
825 {
826 va_list ap;
827 char *buf;
828 int buflen;
829 int len;
830
831 va_start(ap, fmt);
832 buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
833 va_end(ap);
834
835 buf = os_malloc(buflen);
836 if (buf == NULL) {
837 wpa_printf(MSG_ERROR, "hostapd_logger: Failed to allocate "
838 "message buffer");
839 return;
840 }
841 va_start(ap, fmt);
842 len = vsnprintf(buf, buflen, fmt, ap);
843 va_end(ap);
844 if (hostapd_logger_cb)
845 hostapd_logger_cb(ctx, addr, module, level, buf, len);
846 else if (addr)
847 wpa_printf(MSG_DEBUG, "hostapd_logger: STA " MACSTR " - %s",
848 MAC2STR(addr), buf);
849 else
850 wpa_printf(MSG_DEBUG, "hostapd_logger: %s", buf);
851 bin_clear_free(buf, buflen);
852 }
853 #endif /* CONFIG_NO_HOSTAPD_LOGGER */
854
855
debug_level_str(int level)856 const char * debug_level_str(int level)
857 {
858 switch (level) {
859 case MSG_EXCESSIVE:
860 return "EXCESSIVE";
861 case MSG_MSGDUMP:
862 return "MSGDUMP";
863 case MSG_DEBUG:
864 return "DEBUG";
865 case MSG_INFO:
866 return "INFO";
867 case MSG_WARNING:
868 return "WARNING";
869 case MSG_ERROR:
870 return "ERROR";
871 default:
872 return "?";
873 }
874 }
875
876
str_to_debug_level(const char * s)877 int str_to_debug_level(const char *s)
878 {
879 if (os_strcasecmp(s, "EXCESSIVE") == 0)
880 return MSG_EXCESSIVE;
881 if (os_strcasecmp(s, "MSGDUMP") == 0)
882 return MSG_MSGDUMP;
883 if (os_strcasecmp(s, "DEBUG") == 0)
884 return MSG_DEBUG;
885 if (os_strcasecmp(s, "INFO") == 0)
886 return MSG_INFO;
887 if (os_strcasecmp(s, "WARNING") == 0)
888 return MSG_WARNING;
889 if (os_strcasecmp(s, "ERROR") == 0)
890 return MSG_ERROR;
891 return -1;
892 }
893