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 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 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 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 101 void wpa_debug_close_syslog(void) 102 { 103 if (wpa_debug_syslog) 104 closelog(); 105 } 106 107 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 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 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 */ 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 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 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 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 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 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 */ 498 #endif /* CONFIG_ANDROID_LOG */ 499 } 500 501 502 void wpa_hexdump_ascii(int level, const char *title, const void *buf, 503 size_t len) 504 { 505 _wpa_hexdump_ascii(level, title, buf, len, 1); 506 } 507 508 509 void wpa_hexdump_ascii_key(int level, const char *title, const void *buf, 510 size_t len) 511 { 512 _wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys); 513 } 514 515 516 #ifdef CONFIG_DEBUG_FILE 517 static char *last_path = NULL; 518 #endif /* CONFIG_DEBUG_FILE */ 519 520 int wpa_debug_reopen_file(void) 521 { 522 #ifdef CONFIG_DEBUG_FILE 523 int rv; 524 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); 536 return rv; 537 #else /* CONFIG_DEBUG_FILE */ 538 return 0; 539 #endif /* CONFIG_DEBUG_FILE */ 540 } 541 542 543 int wpa_debug_open_file(const char *path) 544 { 545 #ifdef CONFIG_DEBUG_FILE 546 int out_fd; 547 548 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 557 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"); 575 if (out_file == NULL) { 576 wpa_printf(MSG_ERROR, "wpa_debug_open_file: Failed to open " 577 "output file, using standard output"); 578 close(out_fd); 579 return -1; 580 } 581 #ifndef _WIN32 582 setvbuf(out_file, NULL, _IOLBF, 0); 583 #endif /* _WIN32 */ 584 #else /* CONFIG_DEBUG_FILE */ 585 (void)path; 586 #endif /* CONFIG_DEBUG_FILE */ 587 return 0; 588 } 589 590 591 void 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 603 604 void wpa_debug_setup_stdout(void) 605 { 606 #ifndef _WIN32 607 setvbuf(stdout, NULL, _IOLBF, 0); 608 #endif /* _WIN32 */ 609 } 610 611 #endif /* CONFIG_NO_STDOUT_DEBUG */ 612 613 614 #ifndef CONFIG_NO_WPA_MSG 615 static wpa_msg_cb_func wpa_msg_cb = NULL; 616 617 void wpa_msg_register_cb(wpa_msg_cb_func func) 618 { 619 wpa_msg_cb = func; 620 } 621 622 623 static wpa_msg_get_ifname_func wpa_msg_ifname_cb = NULL; 624 625 void wpa_msg_register_ifname_cb(wpa_msg_get_ifname_func func) 626 { 627 wpa_msg_ifname_cb = func; 628 } 629 630 631 void wpa_msg(void *ctx, int level, const char *fmt, ...) 632 { 633 va_list ap; 634 char *buf; 635 int buflen; 636 int len; 637 char prefix[130]; 638 639 va_start(ap, fmt); 640 buflen = vsnprintf(NULL, 0, fmt, ap) + 1; 641 va_end(ap); 642 643 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); 656 if (os_snprintf_error(sizeof(prefix), res)) 657 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) 664 wpa_msg_cb(ctx, level, WPA_MSG_PER_INTERFACE, buf, len); 665 bin_clear_free(buf, buflen); 666 } 667 668 669 void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) 670 { 671 va_list ap; 672 char *buf; 673 int buflen; 674 int len; 675 676 if (!wpa_msg_cb) 677 return; 678 679 va_start(ap, fmt); 680 buflen = vsnprintf(NULL, 0, fmt, ap) + 1; 681 va_end(ap); 682 683 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); 692 wpa_msg_cb(ctx, level, WPA_MSG_PER_INTERFACE, buf, len); 693 bin_clear_free(buf, buflen); 694 } 695 696 697 void wpa_msg_global(void *ctx, int level, const char *fmt, ...) 698 { 699 va_list ap; 700 char *buf; 701 int buflen; 702 int len; 703 704 va_start(ap, fmt); 705 buflen = vsnprintf(NULL, 0, fmt, ap) + 1; 706 va_end(ap); 707 708 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) 719 wpa_msg_cb(ctx, level, WPA_MSG_GLOBAL, buf, len); 720 bin_clear_free(buf, buflen); 721 } 722 723 724 void 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); 747 wpa_msg_cb(ctx, level, WPA_MSG_GLOBAL, buf, len); 748 bin_clear_free(buf, buflen); 749 } 750 751 752 void wpa_msg_no_global(void *ctx, int level, const char *fmt, ...) 753 { 754 va_list ap; 755 char *buf; 756 int buflen; 757 int len; 758 759 va_start(ap, fmt); 760 buflen = vsnprintf(NULL, 0, fmt, ap) + 1; 761 va_end(ap); 762 763 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) 774 wpa_msg_cb(ctx, level, WPA_MSG_NO_GLOBAL, buf, len); 775 bin_clear_free(buf, buflen); 776 } 777 778 779 void 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 805 #endif /* CONFIG_NO_WPA_MSG */ 806 807 808 #ifndef CONFIG_NO_HOSTAPD_LOGGER 809 static hostapd_logger_cb_func hostapd_logger_cb = NULL; 810 811 void hostapd_logger_register_cb(hostapd_logger_cb_func func) 812 { 813 hostapd_logger_cb = func; 814 } 815 816 817 void hostapd_logger(void *ctx, const u8 *addr, unsigned int module, int level, 818 const char *fmt, ...) 819 { 820 va_list ap; 821 char *buf; 822 int buflen; 823 int len; 824 825 va_start(ap, fmt); 826 buflen = vsnprintf(NULL, 0, fmt, ap) + 1; 827 va_end(ap); 828 829 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); 845 bin_clear_free(buf, buflen); 846 } 847 #endif /* CONFIG_NO_HOSTAPD_LOGGER */ 848 849 850 const 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 871 int 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 } 887