1189251Ssam/* 2189251Ssam * wpa_supplicant/hostapd / Debug prints 3189251Ssam * Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi> 4189251Ssam * 5252726Srpaulo * This software may be distributed under the terms of the BSD license. 6252726Srpaulo * See README for more details. 7189251Ssam */ 8189251Ssam 9189251Ssam#include "includes.h" 10189251Ssam 11189251Ssam#include "common.h" 12189251Ssam 13189262Ssam#ifdef CONFIG_DEBUG_SYSLOG 14189262Ssam#include <syslog.h> 15214734Srpaulo 16214734Srpaulostatic int wpa_debug_syslog = 0; 17189262Ssam#endif /* CONFIG_DEBUG_SYSLOG */ 18189251Ssam 19252726Srpaulo#ifdef CONFIG_DEBUG_LINUX_TRACING 20252726Srpaulo#include <sys/types.h> 21252726Srpaulo#include <sys/stat.h> 22252726Srpaulo#include <fcntl.h> 23252726Srpaulo#include <string.h> 24252726Srpaulo#include <stdio.h> 25189262Ssam 26252726Srpaulostatic FILE *wpa_debug_tracing_file = NULL; 27252726Srpaulo 28252726Srpaulo#define WPAS_TRACE_PFX "wpas <%d>: " 29252726Srpaulo#endif /* CONFIG_DEBUG_LINUX_TRACING */ 30252726Srpaulo 31252726Srpaulo 32189251Ssamint wpa_debug_level = MSG_INFO; 33189251Ssamint wpa_debug_show_keys = 0; 34189251Ssamint wpa_debug_timestamp = 0; 35189251Ssam 36189251Ssam 37252726Srpaulo#ifdef CONFIG_ANDROID_LOG 38252726Srpaulo 39252726Srpaulo#include <android/log.h> 40252726Srpaulo 41252726Srpaulo#ifndef ANDROID_LOG_NAME 42252726Srpaulo#define ANDROID_LOG_NAME "wpa_supplicant" 43252726Srpaulo#endif /* ANDROID_LOG_NAME */ 44252726Srpaulo 45252726Srpaulostatic int wpa_to_android_level(int level) 46252726Srpaulo{ 47252726Srpaulo if (level == MSG_ERROR) 48252726Srpaulo return ANDROID_LOG_ERROR; 49252726Srpaulo if (level == MSG_WARNING) 50252726Srpaulo return ANDROID_LOG_WARN; 51252726Srpaulo if (level == MSG_INFO) 52252726Srpaulo return ANDROID_LOG_INFO; 53252726Srpaulo return ANDROID_LOG_DEBUG; 54252726Srpaulo} 55252726Srpaulo 56252726Srpaulo#endif /* CONFIG_ANDROID_LOG */ 57252726Srpaulo 58189251Ssam#ifndef CONFIG_NO_STDOUT_DEBUG 59189251Ssam 60252726Srpaulo#ifdef CONFIG_DEBUG_FILE 61252726Srpaulostatic FILE *out_file = NULL; 62252726Srpaulo#endif /* CONFIG_DEBUG_FILE */ 63252726Srpaulo 64252726Srpaulo 65189251Ssamvoid wpa_debug_print_timestamp(void) 66189251Ssam{ 67252726Srpaulo#ifndef CONFIG_ANDROID_LOG 68189251Ssam struct os_time tv; 69189251Ssam 70189251Ssam if (!wpa_debug_timestamp) 71189251Ssam return; 72189251Ssam 73189251Ssam os_get_time(&tv); 74189251Ssam#ifdef CONFIG_DEBUG_FILE 75189251Ssam if (out_file) { 76189251Ssam fprintf(out_file, "%ld.%06u: ", (long) tv.sec, 77189251Ssam (unsigned int) tv.usec); 78189251Ssam } else 79189251Ssam#endif /* CONFIG_DEBUG_FILE */ 80189251Ssam printf("%ld.%06u: ", (long) tv.sec, (unsigned int) tv.usec); 81252726Srpaulo#endif /* CONFIG_ANDROID_LOG */ 82189251Ssam} 83189251Ssam 84214734Srpaulo 85214734Srpaulo#ifdef CONFIG_DEBUG_SYSLOG 86252726Srpaulo#ifndef LOG_HOSTAPD 87252726Srpaulo#define LOG_HOSTAPD LOG_DAEMON 88252726Srpaulo#endif /* LOG_HOSTAPD */ 89252726Srpaulo 90189262Ssamvoid wpa_debug_open_syslog(void) 91189262Ssam{ 92252726Srpaulo openlog("wpa_supplicant", LOG_PID | LOG_NDELAY, LOG_HOSTAPD); 93189262Ssam wpa_debug_syslog++; 94189262Ssam} 95189251Ssam 96214734Srpaulo 97189262Ssamvoid wpa_debug_close_syslog(void) 98189262Ssam{ 99189262Ssam if (wpa_debug_syslog) 100189262Ssam closelog(); 101189262Ssam} 102189262Ssam 103214734Srpaulo 104189262Ssamstatic int syslog_priority(int level) 105189262Ssam{ 106189262Ssam switch (level) { 107189262Ssam case MSG_MSGDUMP: 108189262Ssam case MSG_DEBUG: 109189262Ssam return LOG_DEBUG; 110189262Ssam case MSG_INFO: 111189262Ssam return LOG_NOTICE; 112189262Ssam case MSG_WARNING: 113189262Ssam return LOG_WARNING; 114189262Ssam case MSG_ERROR: 115189262Ssam return LOG_ERR; 116189262Ssam } 117189262Ssam return LOG_INFO; 118189262Ssam} 119189262Ssam#endif /* CONFIG_DEBUG_SYSLOG */ 120189262Ssam 121189262Ssam 122252726Srpaulo#ifdef CONFIG_DEBUG_LINUX_TRACING 123252726Srpaulo 124252726Srpauloint wpa_debug_open_linux_tracing(void) 125252726Srpaulo{ 126252726Srpaulo int mounts, trace_fd; 127252726Srpaulo char buf[4096] = {}; 128252726Srpaulo ssize_t buflen; 129252726Srpaulo char *line, *tmp1, *path = NULL; 130252726Srpaulo 131252726Srpaulo mounts = open("/proc/mounts", O_RDONLY); 132252726Srpaulo if (mounts < 0) { 133252726Srpaulo printf("no /proc/mounts\n"); 134252726Srpaulo return -1; 135252726Srpaulo } 136252726Srpaulo 137252726Srpaulo buflen = read(mounts, buf, sizeof(buf) - 1); 138252726Srpaulo close(mounts); 139252726Srpaulo if (buflen < 0) { 140252726Srpaulo printf("failed to read /proc/mounts\n"); 141252726Srpaulo return -1; 142252726Srpaulo } 143252726Srpaulo 144252726Srpaulo line = strtok_r(buf, "\n", &tmp1); 145252726Srpaulo while (line) { 146252726Srpaulo char *tmp2, *tmp_path, *fstype; 147252726Srpaulo /* "<dev> <mountpoint> <fs type> ..." */ 148252726Srpaulo strtok_r(line, " ", &tmp2); 149252726Srpaulo tmp_path = strtok_r(NULL, " ", &tmp2); 150252726Srpaulo fstype = strtok_r(NULL, " ", &tmp2); 151252726Srpaulo if (strcmp(fstype, "debugfs") == 0) { 152252726Srpaulo path = tmp_path; 153252726Srpaulo break; 154252726Srpaulo } 155252726Srpaulo 156252726Srpaulo line = strtok_r(NULL, "\n", &tmp1); 157252726Srpaulo } 158252726Srpaulo 159252726Srpaulo if (path == NULL) { 160252726Srpaulo printf("debugfs mountpoint not found\n"); 161252726Srpaulo return -1; 162252726Srpaulo } 163252726Srpaulo 164252726Srpaulo snprintf(buf, sizeof(buf) - 1, "%s/tracing/trace_marker", path); 165252726Srpaulo 166252726Srpaulo trace_fd = open(buf, O_WRONLY); 167252726Srpaulo if (trace_fd < 0) { 168252726Srpaulo printf("failed to open trace_marker file\n"); 169252726Srpaulo return -1; 170252726Srpaulo } 171252726Srpaulo wpa_debug_tracing_file = fdopen(trace_fd, "w"); 172252726Srpaulo if (wpa_debug_tracing_file == NULL) { 173252726Srpaulo close(trace_fd); 174252726Srpaulo printf("failed to fdopen()\n"); 175252726Srpaulo return -1; 176252726Srpaulo } 177252726Srpaulo 178252726Srpaulo return 0; 179252726Srpaulo} 180252726Srpaulo 181252726Srpaulo 182252726Srpaulovoid wpa_debug_close_linux_tracing(void) 183252726Srpaulo{ 184252726Srpaulo if (wpa_debug_tracing_file == NULL) 185252726Srpaulo return; 186252726Srpaulo fclose(wpa_debug_tracing_file); 187252726Srpaulo wpa_debug_tracing_file = NULL; 188252726Srpaulo} 189252726Srpaulo 190252726Srpaulo#endif /* CONFIG_DEBUG_LINUX_TRACING */ 191252726Srpaulo 192252726Srpaulo 193189251Ssam/** 194189251Ssam * wpa_printf - conditional printf 195189251Ssam * @level: priority level (MSG_*) of the message 196189251Ssam * @fmt: printf format string, followed by optional arguments 197189251Ssam * 198189251Ssam * This function is used to print conditional debugging and error messages. The 199189251Ssam * output may be directed to stdout, stderr, and/or syslog based on 200189251Ssam * configuration. 201189251Ssam * 202189251Ssam * Note: New line '\n' is added to the end of the text when printing to stdout. 203189251Ssam */ 204209158Srpaulovoid wpa_printf(int level, const char *fmt, ...) 205189251Ssam{ 206189251Ssam va_list ap; 207189251Ssam 208189251Ssam va_start(ap, fmt); 209189251Ssam if (level >= wpa_debug_level) { 210252726Srpaulo#ifdef CONFIG_ANDROID_LOG 211252726Srpaulo __android_log_vprint(wpa_to_android_level(level), 212252726Srpaulo ANDROID_LOG_NAME, fmt, ap); 213252726Srpaulo#else /* CONFIG_ANDROID_LOG */ 214189262Ssam#ifdef CONFIG_DEBUG_SYSLOG 215189262Ssam if (wpa_debug_syslog) { 216189262Ssam vsyslog(syslog_priority(level), fmt, ap); 217189262Ssam } else { 218189262Ssam#endif /* CONFIG_DEBUG_SYSLOG */ 219189251Ssam wpa_debug_print_timestamp(); 220189251Ssam#ifdef CONFIG_DEBUG_FILE 221189251Ssam if (out_file) { 222189251Ssam vfprintf(out_file, fmt, ap); 223189251Ssam fprintf(out_file, "\n"); 224189251Ssam } else { 225189251Ssam#endif /* CONFIG_DEBUG_FILE */ 226189251Ssam vprintf(fmt, ap); 227189251Ssam printf("\n"); 228189251Ssam#ifdef CONFIG_DEBUG_FILE 229189251Ssam } 230189251Ssam#endif /* CONFIG_DEBUG_FILE */ 231189262Ssam#ifdef CONFIG_DEBUG_SYSLOG 232189262Ssam } 233189262Ssam#endif /* CONFIG_DEBUG_SYSLOG */ 234252726Srpaulo#endif /* CONFIG_ANDROID_LOG */ 235189251Ssam } 236189251Ssam va_end(ap); 237252726Srpaulo 238252726Srpaulo#ifdef CONFIG_DEBUG_LINUX_TRACING 239252726Srpaulo if (wpa_debug_tracing_file != NULL) { 240252726Srpaulo va_start(ap, fmt); 241252726Srpaulo fprintf(wpa_debug_tracing_file, WPAS_TRACE_PFX, level); 242252726Srpaulo vfprintf(wpa_debug_tracing_file, fmt, ap); 243252726Srpaulo fprintf(wpa_debug_tracing_file, "\n"); 244252726Srpaulo fflush(wpa_debug_tracing_file); 245252726Srpaulo va_end(ap); 246252726Srpaulo } 247252726Srpaulo#endif /* CONFIG_DEBUG_LINUX_TRACING */ 248189251Ssam} 249189251Ssam 250189251Ssam 251189251Ssamstatic void _wpa_hexdump(int level, const char *title, const u8 *buf, 252189251Ssam size_t len, int show) 253189251Ssam{ 254189251Ssam size_t i; 255252726Srpaulo 256252726Srpaulo#ifdef CONFIG_DEBUG_LINUX_TRACING 257252726Srpaulo if (wpa_debug_tracing_file != NULL) { 258252726Srpaulo fprintf(wpa_debug_tracing_file, 259252726Srpaulo WPAS_TRACE_PFX "%s - hexdump(len=%lu):", 260252726Srpaulo level, title, (unsigned long) len); 261252726Srpaulo if (buf == NULL) { 262252726Srpaulo fprintf(wpa_debug_tracing_file, " [NULL]\n"); 263252726Srpaulo } else if (!show) { 264252726Srpaulo fprintf(wpa_debug_tracing_file, " [REMOVED]\n"); 265252726Srpaulo } else { 266252726Srpaulo for (i = 0; i < len; i++) 267252726Srpaulo fprintf(wpa_debug_tracing_file, 268252726Srpaulo " %02x", buf[i]); 269252726Srpaulo } 270252726Srpaulo fflush(wpa_debug_tracing_file); 271252726Srpaulo } 272252726Srpaulo#endif /* CONFIG_DEBUG_LINUX_TRACING */ 273252726Srpaulo 274189251Ssam if (level < wpa_debug_level) 275189251Ssam return; 276252726Srpaulo#ifdef CONFIG_ANDROID_LOG 277252726Srpaulo { 278252726Srpaulo const char *display; 279252726Srpaulo char *strbuf = NULL; 280252726Srpaulo size_t slen = len; 281252726Srpaulo if (buf == NULL) { 282252726Srpaulo display = " [NULL]"; 283252726Srpaulo } else if (len == 0) { 284252726Srpaulo display = ""; 285252726Srpaulo } else if (show && len) { 286252726Srpaulo /* Limit debug message length for Android log */ 287252726Srpaulo if (slen > 32) 288252726Srpaulo slen = 32; 289252726Srpaulo strbuf = os_malloc(1 + 3 * slen); 290252726Srpaulo if (strbuf == NULL) { 291252726Srpaulo wpa_printf(MSG_ERROR, "wpa_hexdump: Failed to " 292252726Srpaulo "allocate message buffer"); 293252726Srpaulo return; 294252726Srpaulo } 295252726Srpaulo 296252726Srpaulo for (i = 0; i < slen; i++) 297252726Srpaulo os_snprintf(&strbuf[i * 3], 4, " %02x", 298252726Srpaulo buf[i]); 299252726Srpaulo 300252726Srpaulo display = strbuf; 301252726Srpaulo } else { 302252726Srpaulo display = " [REMOVED]"; 303252726Srpaulo } 304252726Srpaulo 305252726Srpaulo __android_log_print(wpa_to_android_level(level), 306252726Srpaulo ANDROID_LOG_NAME, 307252726Srpaulo "%s - hexdump(len=%lu):%s%s", 308252726Srpaulo title, (long unsigned int) len, display, 309252726Srpaulo len > slen ? " ..." : ""); 310252726Srpaulo os_free(strbuf); 311252726Srpaulo return; 312252726Srpaulo } 313252726Srpaulo#else /* CONFIG_ANDROID_LOG */ 314252726Srpaulo#ifdef CONFIG_DEBUG_SYSLOG 315252726Srpaulo if (wpa_debug_syslog) { 316252726Srpaulo const char *display; 317252726Srpaulo char *strbuf = NULL; 318252726Srpaulo 319252726Srpaulo if (buf == NULL) { 320252726Srpaulo display = " [NULL]"; 321252726Srpaulo } else if (len == 0) { 322252726Srpaulo display = ""; 323252726Srpaulo } else if (show && len) { 324252726Srpaulo strbuf = os_malloc(1 + 3 * len); 325252726Srpaulo if (strbuf == NULL) { 326252726Srpaulo wpa_printf(MSG_ERROR, "wpa_hexdump: Failed to " 327252726Srpaulo "allocate message buffer"); 328252726Srpaulo return; 329252726Srpaulo } 330252726Srpaulo 331252726Srpaulo for (i = 0; i < len; i++) 332252726Srpaulo os_snprintf(&strbuf[i * 3], 4, " %02x", 333252726Srpaulo buf[i]); 334252726Srpaulo 335252726Srpaulo display = strbuf; 336252726Srpaulo } else { 337252726Srpaulo display = " [REMOVED]"; 338252726Srpaulo } 339252726Srpaulo 340252726Srpaulo syslog(syslog_priority(level), "%s - hexdump(len=%lu):%s", 341252726Srpaulo title, (unsigned long) len, display); 342252726Srpaulo os_free(strbuf); 343252726Srpaulo return; 344252726Srpaulo } 345252726Srpaulo#endif /* CONFIG_DEBUG_SYSLOG */ 346189251Ssam wpa_debug_print_timestamp(); 347189251Ssam#ifdef CONFIG_DEBUG_FILE 348189251Ssam if (out_file) { 349189251Ssam fprintf(out_file, "%s - hexdump(len=%lu):", 350189251Ssam title, (unsigned long) len); 351189251Ssam if (buf == NULL) { 352189251Ssam fprintf(out_file, " [NULL]"); 353189251Ssam } else if (show) { 354189251Ssam for (i = 0; i < len; i++) 355189251Ssam fprintf(out_file, " %02x", buf[i]); 356189251Ssam } else { 357189251Ssam fprintf(out_file, " [REMOVED]"); 358189251Ssam } 359189251Ssam fprintf(out_file, "\n"); 360189251Ssam } else { 361189251Ssam#endif /* CONFIG_DEBUG_FILE */ 362189251Ssam printf("%s - hexdump(len=%lu):", title, (unsigned long) len); 363189251Ssam if (buf == NULL) { 364189251Ssam printf(" [NULL]"); 365189251Ssam } else if (show) { 366189251Ssam for (i = 0; i < len; i++) 367189251Ssam printf(" %02x", buf[i]); 368189251Ssam } else { 369189251Ssam printf(" [REMOVED]"); 370189251Ssam } 371189251Ssam printf("\n"); 372189251Ssam#ifdef CONFIG_DEBUG_FILE 373189251Ssam } 374189251Ssam#endif /* CONFIG_DEBUG_FILE */ 375252726Srpaulo#endif /* CONFIG_ANDROID_LOG */ 376189251Ssam} 377189251Ssam 378189251Ssamvoid wpa_hexdump(int level, const char *title, const u8 *buf, size_t len) 379189251Ssam{ 380189251Ssam _wpa_hexdump(level, title, buf, len, 1); 381189251Ssam} 382189251Ssam 383189251Ssam 384189251Ssamvoid wpa_hexdump_key(int level, const char *title, const u8 *buf, size_t len) 385189251Ssam{ 386189251Ssam _wpa_hexdump(level, title, buf, len, wpa_debug_show_keys); 387189251Ssam} 388189251Ssam 389189251Ssam 390189251Ssamstatic void _wpa_hexdump_ascii(int level, const char *title, const u8 *buf, 391189251Ssam size_t len, int show) 392189251Ssam{ 393189251Ssam size_t i, llen; 394189251Ssam const u8 *pos = buf; 395189251Ssam const size_t line_len = 16; 396189251Ssam 397252726Srpaulo#ifdef CONFIG_DEBUG_LINUX_TRACING 398252726Srpaulo if (wpa_debug_tracing_file != NULL) { 399252726Srpaulo fprintf(wpa_debug_tracing_file, 400252726Srpaulo WPAS_TRACE_PFX "%s - hexdump_ascii(len=%lu):", 401252726Srpaulo level, title, (unsigned long) len); 402252726Srpaulo if (buf == NULL) { 403252726Srpaulo fprintf(wpa_debug_tracing_file, " [NULL]\n"); 404252726Srpaulo } else if (!show) { 405252726Srpaulo fprintf(wpa_debug_tracing_file, " [REMOVED]\n"); 406252726Srpaulo } else { 407252726Srpaulo /* can do ascii processing in userspace */ 408252726Srpaulo for (i = 0; i < len; i++) 409252726Srpaulo fprintf(wpa_debug_tracing_file, 410252726Srpaulo " %02x", buf[i]); 411252726Srpaulo } 412252726Srpaulo fflush(wpa_debug_tracing_file); 413252726Srpaulo } 414252726Srpaulo#endif /* CONFIG_DEBUG_LINUX_TRACING */ 415252726Srpaulo 416189251Ssam if (level < wpa_debug_level) 417189251Ssam return; 418252726Srpaulo#ifdef CONFIG_ANDROID_LOG 419252726Srpaulo _wpa_hexdump(level, title, buf, len, show); 420252726Srpaulo#else /* CONFIG_ANDROID_LOG */ 421189251Ssam wpa_debug_print_timestamp(); 422189251Ssam#ifdef CONFIG_DEBUG_FILE 423189251Ssam if (out_file) { 424189251Ssam if (!show) { 425189251Ssam fprintf(out_file, 426189251Ssam "%s - hexdump_ascii(len=%lu): [REMOVED]\n", 427189251Ssam title, (unsigned long) len); 428189251Ssam return; 429189251Ssam } 430189251Ssam if (buf == NULL) { 431189251Ssam fprintf(out_file, 432189251Ssam "%s - hexdump_ascii(len=%lu): [NULL]\n", 433189251Ssam title, (unsigned long) len); 434189251Ssam return; 435189251Ssam } 436189251Ssam fprintf(out_file, "%s - hexdump_ascii(len=%lu):\n", 437189251Ssam title, (unsigned long) len); 438189251Ssam while (len) { 439189251Ssam llen = len > line_len ? line_len : len; 440189251Ssam fprintf(out_file, " "); 441189251Ssam for (i = 0; i < llen; i++) 442189251Ssam fprintf(out_file, " %02x", pos[i]); 443189251Ssam for (i = llen; i < line_len; i++) 444189251Ssam fprintf(out_file, " "); 445189251Ssam fprintf(out_file, " "); 446189251Ssam for (i = 0; i < llen; i++) { 447189251Ssam if (isprint(pos[i])) 448189251Ssam fprintf(out_file, "%c", pos[i]); 449189251Ssam else 450189251Ssam fprintf(out_file, "_"); 451189251Ssam } 452189251Ssam for (i = llen; i < line_len; i++) 453189251Ssam fprintf(out_file, " "); 454189251Ssam fprintf(out_file, "\n"); 455189251Ssam pos += llen; 456189251Ssam len -= llen; 457189251Ssam } 458189251Ssam } else { 459189251Ssam#endif /* CONFIG_DEBUG_FILE */ 460189251Ssam if (!show) { 461189251Ssam printf("%s - hexdump_ascii(len=%lu): [REMOVED]\n", 462189251Ssam title, (unsigned long) len); 463189251Ssam return; 464189251Ssam } 465189251Ssam if (buf == NULL) { 466189251Ssam printf("%s - hexdump_ascii(len=%lu): [NULL]\n", 467189251Ssam title, (unsigned long) len); 468189251Ssam return; 469189251Ssam } 470189251Ssam printf("%s - hexdump_ascii(len=%lu):\n", title, (unsigned long) len); 471189251Ssam while (len) { 472189251Ssam llen = len > line_len ? line_len : len; 473189251Ssam printf(" "); 474189251Ssam for (i = 0; i < llen; i++) 475189251Ssam printf(" %02x", pos[i]); 476189251Ssam for (i = llen; i < line_len; i++) 477189251Ssam printf(" "); 478189251Ssam printf(" "); 479189251Ssam for (i = 0; i < llen; i++) { 480189251Ssam if (isprint(pos[i])) 481189251Ssam printf("%c", pos[i]); 482189251Ssam else 483189251Ssam printf("_"); 484189251Ssam } 485189251Ssam for (i = llen; i < line_len; i++) 486189251Ssam printf(" "); 487189251Ssam printf("\n"); 488189251Ssam pos += llen; 489189251Ssam len -= llen; 490189251Ssam } 491189251Ssam#ifdef CONFIG_DEBUG_FILE 492189251Ssam } 493189251Ssam#endif /* CONFIG_DEBUG_FILE */ 494252726Srpaulo#endif /* CONFIG_ANDROID_LOG */ 495189251Ssam} 496189251Ssam 497189251Ssam 498189251Ssamvoid wpa_hexdump_ascii(int level, const char *title, const u8 *buf, size_t len) 499189251Ssam{ 500189251Ssam _wpa_hexdump_ascii(level, title, buf, len, 1); 501189251Ssam} 502189251Ssam 503189251Ssam 504189251Ssamvoid wpa_hexdump_ascii_key(int level, const char *title, const u8 *buf, 505189251Ssam size_t len) 506189251Ssam{ 507189251Ssam _wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys); 508189251Ssam} 509189251Ssam 510189251Ssam 511252726Srpaulo#ifdef CONFIG_DEBUG_FILE 512252726Srpaulostatic char *last_path = NULL; 513252726Srpaulo#endif /* CONFIG_DEBUG_FILE */ 514252726Srpaulo 515252726Srpauloint wpa_debug_reopen_file(void) 516252726Srpaulo{ 517252726Srpaulo#ifdef CONFIG_DEBUG_FILE 518252726Srpaulo int rv; 519252726Srpaulo if (last_path) { 520252726Srpaulo char *tmp = os_strdup(last_path); 521252726Srpaulo wpa_debug_close_file(); 522252726Srpaulo rv = wpa_debug_open_file(tmp); 523252726Srpaulo os_free(tmp); 524252726Srpaulo } else { 525252726Srpaulo wpa_printf(MSG_ERROR, "Last-path was not set, cannot " 526252726Srpaulo "re-open log file."); 527252726Srpaulo rv = -1; 528252726Srpaulo } 529252726Srpaulo return rv; 530252726Srpaulo#else /* CONFIG_DEBUG_FILE */ 531252726Srpaulo return 0; 532252726Srpaulo#endif /* CONFIG_DEBUG_FILE */ 533252726Srpaulo} 534252726Srpaulo 535252726Srpaulo 536189251Ssamint wpa_debug_open_file(const char *path) 537189251Ssam{ 538189251Ssam#ifdef CONFIG_DEBUG_FILE 539189251Ssam if (!path) 540189251Ssam return 0; 541252726Srpaulo 542252726Srpaulo if (last_path == NULL || os_strcmp(last_path, path) != 0) { 543252726Srpaulo /* Save our path to enable re-open */ 544252726Srpaulo os_free(last_path); 545252726Srpaulo last_path = os_strdup(path); 546252726Srpaulo } 547252726Srpaulo 548189251Ssam out_file = fopen(path, "a"); 549189251Ssam if (out_file == NULL) { 550189251Ssam wpa_printf(MSG_ERROR, "wpa_debug_open_file: Failed to open " 551189251Ssam "output file, using standard output"); 552189251Ssam return -1; 553189251Ssam } 554189251Ssam#ifndef _WIN32 555189251Ssam setvbuf(out_file, NULL, _IOLBF, 0); 556189251Ssam#endif /* _WIN32 */ 557189251Ssam#endif /* CONFIG_DEBUG_FILE */ 558189251Ssam return 0; 559189251Ssam} 560189251Ssam 561189251Ssam 562189251Ssamvoid wpa_debug_close_file(void) 563189251Ssam{ 564189251Ssam#ifdef CONFIG_DEBUG_FILE 565189251Ssam if (!out_file) 566189251Ssam return; 567189251Ssam fclose(out_file); 568189251Ssam out_file = NULL; 569252726Srpaulo os_free(last_path); 570252726Srpaulo last_path = NULL; 571189251Ssam#endif /* CONFIG_DEBUG_FILE */ 572189251Ssam} 573189251Ssam 574189251Ssam#endif /* CONFIG_NO_STDOUT_DEBUG */ 575189251Ssam 576189251Ssam 577189251Ssam#ifndef CONFIG_NO_WPA_MSG 578189251Ssamstatic wpa_msg_cb_func wpa_msg_cb = NULL; 579189251Ssam 580189251Ssamvoid wpa_msg_register_cb(wpa_msg_cb_func func) 581189251Ssam{ 582189251Ssam wpa_msg_cb = func; 583189251Ssam} 584189251Ssam 585189251Ssam 586252726Srpaulostatic wpa_msg_get_ifname_func wpa_msg_ifname_cb = NULL; 587252726Srpaulo 588252726Srpaulovoid wpa_msg_register_ifname_cb(wpa_msg_get_ifname_func func) 589252726Srpaulo{ 590252726Srpaulo wpa_msg_ifname_cb = func; 591252726Srpaulo} 592252726Srpaulo 593252726Srpaulo 594209158Srpaulovoid wpa_msg(void *ctx, int level, const char *fmt, ...) 595189251Ssam{ 596189251Ssam va_list ap; 597189251Ssam char *buf; 598189251Ssam const int buflen = 2048; 599189251Ssam int len; 600252726Srpaulo char prefix[130]; 601189251Ssam 602189251Ssam buf = os_malloc(buflen); 603189251Ssam if (buf == NULL) { 604189251Ssam wpa_printf(MSG_ERROR, "wpa_msg: Failed to allocate message " 605189251Ssam "buffer"); 606189251Ssam return; 607189251Ssam } 608189251Ssam va_start(ap, fmt); 609252726Srpaulo prefix[0] = '\0'; 610252726Srpaulo if (wpa_msg_ifname_cb) { 611252726Srpaulo const char *ifname = wpa_msg_ifname_cb(ctx); 612252726Srpaulo if (ifname) { 613252726Srpaulo int res = os_snprintf(prefix, sizeof(prefix), "%s: ", 614252726Srpaulo ifname); 615252726Srpaulo if (res < 0 || res >= (int) sizeof(prefix)) 616252726Srpaulo prefix[0] = '\0'; 617252726Srpaulo } 618252726Srpaulo } 619189251Ssam len = vsnprintf(buf, buflen, fmt, ap); 620189251Ssam va_end(ap); 621252726Srpaulo wpa_printf(level, "%s%s", prefix, buf); 622189251Ssam if (wpa_msg_cb) 623189251Ssam wpa_msg_cb(ctx, level, buf, len); 624189251Ssam os_free(buf); 625189251Ssam} 626209158Srpaulo 627209158Srpaulo 628209158Srpaulovoid wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) 629209158Srpaulo{ 630209158Srpaulo va_list ap; 631209158Srpaulo char *buf; 632209158Srpaulo const int buflen = 2048; 633209158Srpaulo int len; 634209158Srpaulo 635209158Srpaulo if (!wpa_msg_cb) 636209158Srpaulo return; 637209158Srpaulo 638209158Srpaulo buf = os_malloc(buflen); 639209158Srpaulo if (buf == NULL) { 640209158Srpaulo wpa_printf(MSG_ERROR, "wpa_msg_ctrl: Failed to allocate " 641209158Srpaulo "message buffer"); 642209158Srpaulo return; 643209158Srpaulo } 644209158Srpaulo va_start(ap, fmt); 645209158Srpaulo len = vsnprintf(buf, buflen, fmt, ap); 646209158Srpaulo va_end(ap); 647209158Srpaulo wpa_msg_cb(ctx, level, buf, len); 648209158Srpaulo os_free(buf); 649209158Srpaulo} 650189251Ssam#endif /* CONFIG_NO_WPA_MSG */ 651189251Ssam 652189251Ssam 653189251Ssam#ifndef CONFIG_NO_HOSTAPD_LOGGER 654189251Ssamstatic hostapd_logger_cb_func hostapd_logger_cb = NULL; 655189251Ssam 656189251Ssamvoid hostapd_logger_register_cb(hostapd_logger_cb_func func) 657189251Ssam{ 658189251Ssam hostapd_logger_cb = func; 659189251Ssam} 660189251Ssam 661189251Ssam 662189251Ssamvoid hostapd_logger(void *ctx, const u8 *addr, unsigned int module, int level, 663189251Ssam const char *fmt, ...) 664189251Ssam{ 665189251Ssam va_list ap; 666189251Ssam char *buf; 667189251Ssam const int buflen = 2048; 668189251Ssam int len; 669189251Ssam 670189251Ssam buf = os_malloc(buflen); 671189251Ssam if (buf == NULL) { 672189251Ssam wpa_printf(MSG_ERROR, "hostapd_logger: Failed to allocate " 673189251Ssam "message buffer"); 674189251Ssam return; 675189251Ssam } 676189251Ssam va_start(ap, fmt); 677189251Ssam len = vsnprintf(buf, buflen, fmt, ap); 678189251Ssam va_end(ap); 679189251Ssam if (hostapd_logger_cb) 680189251Ssam hostapd_logger_cb(ctx, addr, module, level, buf, len); 681214734Srpaulo else if (addr) 682214734Srpaulo wpa_printf(MSG_DEBUG, "hostapd_logger: STA " MACSTR " - %s", 683214734Srpaulo MAC2STR(addr), buf); 684189251Ssam else 685189251Ssam wpa_printf(MSG_DEBUG, "hostapd_logger: %s", buf); 686189251Ssam os_free(buf); 687189251Ssam} 688189251Ssam#endif /* CONFIG_NO_HOSTAPD_LOGGER */ 689