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 #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 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 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 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 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 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 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 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 631 void wpa_msg_register_ifname_cb(wpa_msg_get_ifname_func func) 632 { 633 wpa_msg_ifname_cb = func; 634 } 635 636 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 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 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 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 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 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 817 void hostapd_logger_register_cb(hostapd_logger_cb_func func) 818 { 819 hostapd_logger_cb = func; 820 } 821 822 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 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 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