139beb93cSSam Leffler /* 239beb93cSSam Leffler * wpa_supplicant/hostapd / Debug prints 35b9c547cSRui Paulo * Copyright (c) 2002-2013, Jouni Malinen <j@w1.fi> 439beb93cSSam Leffler * 5f05cddf9SRui Paulo * This software may be distributed under the terms of the BSD license. 6f05cddf9SRui Paulo * See README for more details. 739beb93cSSam Leffler */ 839beb93cSSam Leffler 939beb93cSSam Leffler #include "includes.h" 1039beb93cSSam Leffler 1139beb93cSSam Leffler #include "common.h" 1239beb93cSSam Leffler 132aef0ff7SSam Leffler #ifdef CONFIG_DEBUG_SYSLOG 142aef0ff7SSam Leffler #include <syslog.h> 152aef0ff7SSam Leffler #endif /* CONFIG_DEBUG_SYSLOG */ 162aef0ff7SSam Leffler 17f05cddf9SRui Paulo #ifdef CONFIG_DEBUG_LINUX_TRACING 18f05cddf9SRui Paulo #include <sys/types.h> 19f05cddf9SRui Paulo #include <sys/stat.h> 20f05cddf9SRui Paulo #include <fcntl.h> 21f05cddf9SRui Paulo #include <string.h> 22f05cddf9SRui Paulo #include <stdio.h> 2339beb93cSSam Leffler 24f05cddf9SRui Paulo static FILE *wpa_debug_tracing_file = NULL; 25f05cddf9SRui Paulo 26f05cddf9SRui Paulo #define WPAS_TRACE_PFX "wpas <%d>: " 27f05cddf9SRui Paulo #endif /* CONFIG_DEBUG_LINUX_TRACING */ 28f05cddf9SRui Paulo 29f05cddf9SRui Paulo 3039beb93cSSam Leffler int wpa_debug_level = MSG_INFO; 3139beb93cSSam Leffler int wpa_debug_show_keys = 0; 3239beb93cSSam Leffler int wpa_debug_timestamp = 0; 33c1d255d3SCy Schubert int wpa_debug_syslog = 0; 34c1d255d3SCy Schubert #ifndef CONFIG_NO_STDOUT_DEBUG 35c1d255d3SCy Schubert static FILE *out_file = NULL; 36c1d255d3SCy Schubert #endif /* CONFIG_NO_STDOUT_DEBUG */ 3739beb93cSSam Leffler 3839beb93cSSam Leffler 39f05cddf9SRui Paulo #ifdef CONFIG_ANDROID_LOG 40f05cddf9SRui Paulo 41f05cddf9SRui Paulo #include <android/log.h> 42f05cddf9SRui Paulo 43f05cddf9SRui Paulo #ifndef ANDROID_LOG_NAME 44f05cddf9SRui Paulo #define ANDROID_LOG_NAME "wpa_supplicant" 45f05cddf9SRui Paulo #endif /* ANDROID_LOG_NAME */ 46f05cddf9SRui Paulo 47f05cddf9SRui Paulo static int wpa_to_android_level(int level) 48f05cddf9SRui Paulo { 49f05cddf9SRui Paulo if (level == MSG_ERROR) 50f05cddf9SRui Paulo return ANDROID_LOG_ERROR; 51f05cddf9SRui Paulo if (level == MSG_WARNING) 52f05cddf9SRui Paulo return ANDROID_LOG_WARN; 53f05cddf9SRui Paulo if (level == MSG_INFO) 54f05cddf9SRui Paulo return ANDROID_LOG_INFO; 55f05cddf9SRui Paulo return ANDROID_LOG_DEBUG; 56f05cddf9SRui Paulo } 57f05cddf9SRui Paulo 58f05cddf9SRui Paulo #endif /* CONFIG_ANDROID_LOG */ 59f05cddf9SRui Paulo 6039beb93cSSam Leffler #ifndef CONFIG_NO_STDOUT_DEBUG 6139beb93cSSam Leffler 62f05cddf9SRui Paulo #ifdef CONFIG_DEBUG_FILE 6385732ac8SCy Schubert #include <sys/types.h> 6485732ac8SCy Schubert #include <sys/stat.h> 6585732ac8SCy Schubert #include <fcntl.h> 66f05cddf9SRui Paulo #endif /* CONFIG_DEBUG_FILE */ 67f05cddf9SRui Paulo 68f05cddf9SRui Paulo 6939beb93cSSam Leffler void wpa_debug_print_timestamp(void) 7039beb93cSSam Leffler { 71f05cddf9SRui Paulo #ifndef CONFIG_ANDROID_LOG 7239beb93cSSam Leffler struct os_time tv; 7339beb93cSSam Leffler 7439beb93cSSam Leffler if (!wpa_debug_timestamp) 7539beb93cSSam Leffler return; 7639beb93cSSam Leffler 7739beb93cSSam Leffler os_get_time(&tv); 7839beb93cSSam Leffler #ifdef CONFIG_DEBUG_FILE 79c1d255d3SCy Schubert if (out_file) 8039beb93cSSam Leffler fprintf(out_file, "%ld.%06u: ", (long) tv.sec, 8139beb93cSSam Leffler (unsigned int) tv.usec); 8239beb93cSSam Leffler #endif /* CONFIG_DEBUG_FILE */ 83c1d255d3SCy Schubert if (!out_file && !wpa_debug_syslog) 8439beb93cSSam Leffler printf("%ld.%06u: ", (long) tv.sec, (unsigned int) tv.usec); 85f05cddf9SRui Paulo #endif /* CONFIG_ANDROID_LOG */ 8639beb93cSSam Leffler } 8739beb93cSSam Leffler 88e28a4053SRui Paulo 89e28a4053SRui Paulo #ifdef CONFIG_DEBUG_SYSLOG 90f05cddf9SRui Paulo #ifndef LOG_HOSTAPD 91f05cddf9SRui Paulo #define LOG_HOSTAPD LOG_DAEMON 92f05cddf9SRui Paulo #endif /* LOG_HOSTAPD */ 93f05cddf9SRui Paulo 942aef0ff7SSam Leffler void wpa_debug_open_syslog(void) 952aef0ff7SSam Leffler { 96f05cddf9SRui Paulo openlog("wpa_supplicant", LOG_PID | LOG_NDELAY, LOG_HOSTAPD); 972aef0ff7SSam Leffler wpa_debug_syslog++; 982aef0ff7SSam Leffler } 992aef0ff7SSam Leffler 100e28a4053SRui Paulo 1012aef0ff7SSam Leffler void wpa_debug_close_syslog(void) 1022aef0ff7SSam Leffler { 1032aef0ff7SSam Leffler if (wpa_debug_syslog) 1042aef0ff7SSam Leffler closelog(); 1052aef0ff7SSam Leffler } 1062aef0ff7SSam Leffler 107e28a4053SRui Paulo 1082aef0ff7SSam Leffler static int syslog_priority(int level) 1092aef0ff7SSam Leffler { 1102aef0ff7SSam Leffler switch (level) { 1112aef0ff7SSam Leffler case MSG_MSGDUMP: 1122aef0ff7SSam Leffler case MSG_DEBUG: 1132aef0ff7SSam Leffler return LOG_DEBUG; 1142aef0ff7SSam Leffler case MSG_INFO: 1152aef0ff7SSam Leffler return LOG_NOTICE; 1162aef0ff7SSam Leffler case MSG_WARNING: 1172aef0ff7SSam Leffler return LOG_WARNING; 1182aef0ff7SSam Leffler case MSG_ERROR: 1192aef0ff7SSam Leffler return LOG_ERR; 1202aef0ff7SSam Leffler } 1212aef0ff7SSam Leffler return LOG_INFO; 1222aef0ff7SSam Leffler } 1232aef0ff7SSam Leffler #endif /* CONFIG_DEBUG_SYSLOG */ 1242aef0ff7SSam Leffler 12539beb93cSSam Leffler 126f05cddf9SRui Paulo #ifdef CONFIG_DEBUG_LINUX_TRACING 127f05cddf9SRui Paulo 128f05cddf9SRui Paulo int wpa_debug_open_linux_tracing(void) 129f05cddf9SRui Paulo { 130f05cddf9SRui Paulo int mounts, trace_fd; 131f05cddf9SRui Paulo char buf[4096] = {}; 132f05cddf9SRui Paulo ssize_t buflen; 133f05cddf9SRui Paulo char *line, *tmp1, *path = NULL; 134f05cddf9SRui Paulo 135f05cddf9SRui Paulo mounts = open("/proc/mounts", O_RDONLY); 136f05cddf9SRui Paulo if (mounts < 0) { 137f05cddf9SRui Paulo printf("no /proc/mounts\n"); 138f05cddf9SRui Paulo return -1; 139f05cddf9SRui Paulo } 140f05cddf9SRui Paulo 141f05cddf9SRui Paulo buflen = read(mounts, buf, sizeof(buf) - 1); 142f05cddf9SRui Paulo close(mounts); 143f05cddf9SRui Paulo if (buflen < 0) { 144f05cddf9SRui Paulo printf("failed to read /proc/mounts\n"); 145f05cddf9SRui Paulo return -1; 146f05cddf9SRui Paulo } 147206b73d0SCy Schubert buf[buflen] = '\0'; 148f05cddf9SRui Paulo 149f05cddf9SRui Paulo line = strtok_r(buf, "\n", &tmp1); 150f05cddf9SRui Paulo while (line) { 151f05cddf9SRui Paulo char *tmp2, *tmp_path, *fstype; 152f05cddf9SRui Paulo /* "<dev> <mountpoint> <fs type> ..." */ 153f05cddf9SRui Paulo strtok_r(line, " ", &tmp2); 154f05cddf9SRui Paulo tmp_path = strtok_r(NULL, " ", &tmp2); 155f05cddf9SRui Paulo fstype = strtok_r(NULL, " ", &tmp2); 156780fb4a2SCy Schubert if (fstype && strcmp(fstype, "debugfs") == 0) { 157f05cddf9SRui Paulo path = tmp_path; 158f05cddf9SRui Paulo break; 159f05cddf9SRui Paulo } 160f05cddf9SRui Paulo 161f05cddf9SRui Paulo line = strtok_r(NULL, "\n", &tmp1); 162f05cddf9SRui Paulo } 163f05cddf9SRui Paulo 164f05cddf9SRui Paulo if (path == NULL) { 165f05cddf9SRui Paulo printf("debugfs mountpoint not found\n"); 166f05cddf9SRui Paulo return -1; 167f05cddf9SRui Paulo } 168f05cddf9SRui Paulo 169f05cddf9SRui Paulo snprintf(buf, sizeof(buf) - 1, "%s/tracing/trace_marker", path); 170f05cddf9SRui Paulo 171f05cddf9SRui Paulo trace_fd = open(buf, O_WRONLY); 172f05cddf9SRui Paulo if (trace_fd < 0) { 173f05cddf9SRui Paulo printf("failed to open trace_marker file\n"); 174f05cddf9SRui Paulo return -1; 175f05cddf9SRui Paulo } 176f05cddf9SRui Paulo wpa_debug_tracing_file = fdopen(trace_fd, "w"); 177f05cddf9SRui Paulo if (wpa_debug_tracing_file == NULL) { 178f05cddf9SRui Paulo close(trace_fd); 179f05cddf9SRui Paulo printf("failed to fdopen()\n"); 180f05cddf9SRui Paulo return -1; 181f05cddf9SRui Paulo } 182f05cddf9SRui Paulo 183f05cddf9SRui Paulo return 0; 184f05cddf9SRui Paulo } 185f05cddf9SRui Paulo 186f05cddf9SRui Paulo 187f05cddf9SRui Paulo void wpa_debug_close_linux_tracing(void) 188f05cddf9SRui Paulo { 189f05cddf9SRui Paulo if (wpa_debug_tracing_file == NULL) 190f05cddf9SRui Paulo return; 191f05cddf9SRui Paulo fclose(wpa_debug_tracing_file); 192f05cddf9SRui Paulo wpa_debug_tracing_file = NULL; 193f05cddf9SRui Paulo } 194f05cddf9SRui Paulo 195f05cddf9SRui Paulo #endif /* CONFIG_DEBUG_LINUX_TRACING */ 196f05cddf9SRui Paulo 197f05cddf9SRui Paulo 19839beb93cSSam Leffler /** 19939beb93cSSam Leffler * wpa_printf - conditional printf 20039beb93cSSam Leffler * @level: priority level (MSG_*) of the message 20139beb93cSSam Leffler * @fmt: printf format string, followed by optional arguments 20239beb93cSSam Leffler * 20339beb93cSSam Leffler * This function is used to print conditional debugging and error messages. The 20439beb93cSSam Leffler * output may be directed to stdout, stderr, and/or syslog based on 20539beb93cSSam Leffler * configuration. 20639beb93cSSam Leffler * 20739beb93cSSam Leffler * Note: New line '\n' is added to the end of the text when printing to stdout. 20839beb93cSSam Leffler */ 2093157ba21SRui Paulo void wpa_printf(int level, const char *fmt, ...) 21039beb93cSSam Leffler { 21139beb93cSSam Leffler va_list ap; 21239beb93cSSam Leffler 21339beb93cSSam Leffler if (level >= wpa_debug_level) { 214f05cddf9SRui Paulo #ifdef CONFIG_ANDROID_LOG 215c1d255d3SCy Schubert va_start(ap, fmt); 216f05cddf9SRui Paulo __android_log_vprint(wpa_to_android_level(level), 217f05cddf9SRui Paulo ANDROID_LOG_NAME, fmt, ap); 218c1d255d3SCy Schubert va_end(ap); 219f05cddf9SRui Paulo #else /* CONFIG_ANDROID_LOG */ 2202aef0ff7SSam Leffler #ifdef CONFIG_DEBUG_SYSLOG 2212aef0ff7SSam Leffler if (wpa_debug_syslog) { 222c1d255d3SCy Schubert va_start(ap, fmt); 2232aef0ff7SSam Leffler vsyslog(syslog_priority(level), fmt, ap); 224c1d255d3SCy Schubert va_end(ap); 225c1d255d3SCy Schubert } 2262aef0ff7SSam Leffler #endif /* CONFIG_DEBUG_SYSLOG */ 22739beb93cSSam Leffler wpa_debug_print_timestamp(); 22839beb93cSSam Leffler #ifdef CONFIG_DEBUG_FILE 22939beb93cSSam Leffler if (out_file) { 230c1d255d3SCy Schubert va_start(ap, fmt); 23139beb93cSSam Leffler vfprintf(out_file, fmt, ap); 23239beb93cSSam Leffler fprintf(out_file, "\n"); 233c1d255d3SCy Schubert va_end(ap); 234c1d255d3SCy Schubert } 23539beb93cSSam Leffler #endif /* CONFIG_DEBUG_FILE */ 236c1d255d3SCy Schubert if (!wpa_debug_syslog && !out_file) { 237c1d255d3SCy Schubert va_start(ap, fmt); 23839beb93cSSam Leffler vprintf(fmt, ap); 23939beb93cSSam Leffler printf("\n"); 240c1d255d3SCy Schubert va_end(ap); 24139beb93cSSam Leffler } 242f05cddf9SRui Paulo #endif /* CONFIG_ANDROID_LOG */ 24339beb93cSSam Leffler } 244f05cddf9SRui Paulo 245f05cddf9SRui Paulo #ifdef CONFIG_DEBUG_LINUX_TRACING 246f05cddf9SRui Paulo if (wpa_debug_tracing_file != NULL) { 247f05cddf9SRui Paulo va_start(ap, fmt); 248f05cddf9SRui Paulo fprintf(wpa_debug_tracing_file, WPAS_TRACE_PFX, level); 249f05cddf9SRui Paulo vfprintf(wpa_debug_tracing_file, fmt, ap); 250f05cddf9SRui Paulo fprintf(wpa_debug_tracing_file, "\n"); 251f05cddf9SRui Paulo fflush(wpa_debug_tracing_file); 252f05cddf9SRui Paulo va_end(ap); 253f05cddf9SRui Paulo } 254f05cddf9SRui Paulo #endif /* CONFIG_DEBUG_LINUX_TRACING */ 25539beb93cSSam Leffler } 25639beb93cSSam Leffler 25739beb93cSSam Leffler 25839beb93cSSam Leffler static void _wpa_hexdump(int level, const char *title, const u8 *buf, 259c1d255d3SCy Schubert size_t len, int show, int only_syslog) 26039beb93cSSam Leffler { 26139beb93cSSam Leffler size_t i; 262f05cddf9SRui Paulo 263f05cddf9SRui Paulo #ifdef CONFIG_DEBUG_LINUX_TRACING 264f05cddf9SRui Paulo if (wpa_debug_tracing_file != NULL) { 265f05cddf9SRui Paulo fprintf(wpa_debug_tracing_file, 266f05cddf9SRui Paulo WPAS_TRACE_PFX "%s - hexdump(len=%lu):", 267f05cddf9SRui Paulo level, title, (unsigned long) len); 268f05cddf9SRui Paulo if (buf == NULL) { 269f05cddf9SRui Paulo fprintf(wpa_debug_tracing_file, " [NULL]\n"); 270f05cddf9SRui Paulo } else if (!show) { 271f05cddf9SRui Paulo fprintf(wpa_debug_tracing_file, " [REMOVED]\n"); 272f05cddf9SRui Paulo } else { 273f05cddf9SRui Paulo for (i = 0; i < len; i++) 274f05cddf9SRui Paulo fprintf(wpa_debug_tracing_file, 275f05cddf9SRui Paulo " %02x", buf[i]); 276f05cddf9SRui Paulo } 277f05cddf9SRui Paulo fflush(wpa_debug_tracing_file); 278f05cddf9SRui Paulo } 279f05cddf9SRui Paulo #endif /* CONFIG_DEBUG_LINUX_TRACING */ 280f05cddf9SRui Paulo 28139beb93cSSam Leffler if (level < wpa_debug_level) 28239beb93cSSam Leffler return; 283f05cddf9SRui Paulo #ifdef CONFIG_ANDROID_LOG 284f05cddf9SRui Paulo { 285f05cddf9SRui Paulo const char *display; 286f05cddf9SRui Paulo char *strbuf = NULL; 287f05cddf9SRui Paulo size_t slen = len; 288f05cddf9SRui Paulo if (buf == NULL) { 289f05cddf9SRui Paulo display = " [NULL]"; 290f05cddf9SRui Paulo } else if (len == 0) { 291f05cddf9SRui Paulo display = ""; 292f05cddf9SRui Paulo } else if (show && len) { 293f05cddf9SRui Paulo /* Limit debug message length for Android log */ 294f05cddf9SRui Paulo if (slen > 32) 295f05cddf9SRui Paulo slen = 32; 296f05cddf9SRui Paulo strbuf = os_malloc(1 + 3 * slen); 297f05cddf9SRui Paulo if (strbuf == NULL) { 298f05cddf9SRui Paulo wpa_printf(MSG_ERROR, "wpa_hexdump: Failed to " 299f05cddf9SRui Paulo "allocate message buffer"); 300f05cddf9SRui Paulo return; 301f05cddf9SRui Paulo } 302f05cddf9SRui Paulo 303f05cddf9SRui Paulo for (i = 0; i < slen; i++) 304f05cddf9SRui Paulo os_snprintf(&strbuf[i * 3], 4, " %02x", 305f05cddf9SRui Paulo buf[i]); 306f05cddf9SRui Paulo 307f05cddf9SRui Paulo display = strbuf; 308f05cddf9SRui Paulo } else { 309f05cddf9SRui Paulo display = " [REMOVED]"; 310f05cddf9SRui Paulo } 311f05cddf9SRui Paulo 312f05cddf9SRui Paulo __android_log_print(wpa_to_android_level(level), 313f05cddf9SRui Paulo ANDROID_LOG_NAME, 314f05cddf9SRui Paulo "%s - hexdump(len=%lu):%s%s", 315f05cddf9SRui Paulo title, (long unsigned int) len, display, 316f05cddf9SRui Paulo len > slen ? " ..." : ""); 317325151a3SRui Paulo bin_clear_free(strbuf, 1 + 3 * slen); 318f05cddf9SRui Paulo return; 319f05cddf9SRui Paulo } 320f05cddf9SRui Paulo #else /* CONFIG_ANDROID_LOG */ 321f05cddf9SRui Paulo #ifdef CONFIG_DEBUG_SYSLOG 322f05cddf9SRui Paulo if (wpa_debug_syslog) { 323f05cddf9SRui Paulo const char *display; 324f05cddf9SRui Paulo char *strbuf = NULL; 325f05cddf9SRui Paulo 326f05cddf9SRui Paulo if (buf == NULL) { 327f05cddf9SRui Paulo display = " [NULL]"; 328f05cddf9SRui Paulo } else if (len == 0) { 329f05cddf9SRui Paulo display = ""; 330f05cddf9SRui Paulo } else if (show && len) { 331f05cddf9SRui Paulo strbuf = os_malloc(1 + 3 * len); 332f05cddf9SRui Paulo if (strbuf == NULL) { 333f05cddf9SRui Paulo wpa_printf(MSG_ERROR, "wpa_hexdump: Failed to " 334f05cddf9SRui Paulo "allocate message buffer"); 335f05cddf9SRui Paulo return; 336f05cddf9SRui Paulo } 337f05cddf9SRui Paulo 338f05cddf9SRui Paulo for (i = 0; i < len; i++) 339f05cddf9SRui Paulo os_snprintf(&strbuf[i * 3], 4, " %02x", 340f05cddf9SRui Paulo buf[i]); 341f05cddf9SRui Paulo 342f05cddf9SRui Paulo display = strbuf; 343f05cddf9SRui Paulo } else { 344f05cddf9SRui Paulo display = " [REMOVED]"; 345f05cddf9SRui Paulo } 346f05cddf9SRui Paulo 347f05cddf9SRui Paulo syslog(syslog_priority(level), "%s - hexdump(len=%lu):%s", 348f05cddf9SRui Paulo title, (unsigned long) len, display); 349325151a3SRui Paulo bin_clear_free(strbuf, 1 + 3 * len); 350c1d255d3SCy Schubert if (only_syslog) 351f05cddf9SRui Paulo return; 352f05cddf9SRui Paulo } 353f05cddf9SRui Paulo #endif /* CONFIG_DEBUG_SYSLOG */ 35439beb93cSSam Leffler wpa_debug_print_timestamp(); 35539beb93cSSam Leffler #ifdef CONFIG_DEBUG_FILE 35639beb93cSSam Leffler if (out_file) { 35739beb93cSSam Leffler fprintf(out_file, "%s - hexdump(len=%lu):", 35839beb93cSSam Leffler title, (unsigned long) len); 35939beb93cSSam Leffler if (buf == NULL) { 36039beb93cSSam Leffler fprintf(out_file, " [NULL]"); 36139beb93cSSam Leffler } else if (show) { 36239beb93cSSam Leffler for (i = 0; i < len; i++) 36339beb93cSSam Leffler fprintf(out_file, " %02x", buf[i]); 36439beb93cSSam Leffler } else { 36539beb93cSSam Leffler fprintf(out_file, " [REMOVED]"); 36639beb93cSSam Leffler } 36739beb93cSSam Leffler fprintf(out_file, "\n"); 368c1d255d3SCy Schubert } 36939beb93cSSam Leffler #endif /* CONFIG_DEBUG_FILE */ 370c1d255d3SCy Schubert if (!wpa_debug_syslog && !out_file) { 37139beb93cSSam Leffler printf("%s - hexdump(len=%lu):", title, (unsigned long) len); 37239beb93cSSam Leffler if (buf == NULL) { 37339beb93cSSam Leffler printf(" [NULL]"); 37439beb93cSSam Leffler } else if (show) { 37539beb93cSSam Leffler for (i = 0; i < len; i++) 37639beb93cSSam Leffler printf(" %02x", buf[i]); 37739beb93cSSam Leffler } else { 37839beb93cSSam Leffler printf(" [REMOVED]"); 37939beb93cSSam Leffler } 38039beb93cSSam Leffler printf("\n"); 38139beb93cSSam Leffler } 382f05cddf9SRui Paulo #endif /* CONFIG_ANDROID_LOG */ 38339beb93cSSam Leffler } 38439beb93cSSam Leffler 3855b9c547cSRui Paulo void wpa_hexdump(int level, const char *title, const void *buf, size_t len) 38639beb93cSSam Leffler { 387c1d255d3SCy Schubert _wpa_hexdump(level, title, buf, len, 1, 0); 38839beb93cSSam Leffler } 38939beb93cSSam Leffler 39039beb93cSSam Leffler 3915b9c547cSRui Paulo void wpa_hexdump_key(int level, const char *title, const void *buf, size_t len) 39239beb93cSSam Leffler { 393c1d255d3SCy Schubert _wpa_hexdump(level, title, buf, len, wpa_debug_show_keys, 0); 39439beb93cSSam Leffler } 39539beb93cSSam Leffler 39639beb93cSSam Leffler 3975b9c547cSRui Paulo static void _wpa_hexdump_ascii(int level, const char *title, const void *buf, 39839beb93cSSam Leffler size_t len, int show) 39939beb93cSSam Leffler { 40039beb93cSSam Leffler size_t i, llen; 40139beb93cSSam Leffler const u8 *pos = buf; 40239beb93cSSam Leffler const size_t line_len = 16; 40339beb93cSSam Leffler 404f05cddf9SRui Paulo #ifdef CONFIG_DEBUG_LINUX_TRACING 405f05cddf9SRui Paulo if (wpa_debug_tracing_file != NULL) { 406f05cddf9SRui Paulo fprintf(wpa_debug_tracing_file, 407f05cddf9SRui Paulo WPAS_TRACE_PFX "%s - hexdump_ascii(len=%lu):", 408f05cddf9SRui Paulo level, title, (unsigned long) len); 409f05cddf9SRui Paulo if (buf == NULL) { 410f05cddf9SRui Paulo fprintf(wpa_debug_tracing_file, " [NULL]\n"); 411f05cddf9SRui Paulo } else if (!show) { 412f05cddf9SRui Paulo fprintf(wpa_debug_tracing_file, " [REMOVED]\n"); 413f05cddf9SRui Paulo } else { 414f05cddf9SRui Paulo /* can do ascii processing in userspace */ 415f05cddf9SRui Paulo for (i = 0; i < len; i++) 416f05cddf9SRui Paulo fprintf(wpa_debug_tracing_file, 4175b9c547cSRui Paulo " %02x", pos[i]); 418f05cddf9SRui Paulo } 419f05cddf9SRui Paulo fflush(wpa_debug_tracing_file); 420f05cddf9SRui Paulo } 421f05cddf9SRui Paulo #endif /* CONFIG_DEBUG_LINUX_TRACING */ 422f05cddf9SRui Paulo 42339beb93cSSam Leffler if (level < wpa_debug_level) 42439beb93cSSam Leffler return; 425f05cddf9SRui Paulo #ifdef CONFIG_ANDROID_LOG 426c1d255d3SCy Schubert _wpa_hexdump(level, title, buf, len, show, 0); 427f05cddf9SRui Paulo #else /* CONFIG_ANDROID_LOG */ 4284bc52338SCy Schubert #ifdef CONFIG_DEBUG_SYSLOG 429c1d255d3SCy Schubert if (wpa_debug_syslog) 430c1d255d3SCy Schubert _wpa_hexdump(level, title, buf, len, show, 1); 4314bc52338SCy Schubert #endif /* CONFIG_DEBUG_SYSLOG */ 43239beb93cSSam Leffler wpa_debug_print_timestamp(); 43339beb93cSSam Leffler #ifdef CONFIG_DEBUG_FILE 43439beb93cSSam Leffler if (out_file) { 43539beb93cSSam Leffler if (!show) { 43639beb93cSSam Leffler fprintf(out_file, 43739beb93cSSam Leffler "%s - hexdump_ascii(len=%lu): [REMOVED]\n", 43839beb93cSSam Leffler title, (unsigned long) len); 439c1d255d3SCy Schubert goto file_done; 44039beb93cSSam Leffler } 44139beb93cSSam Leffler if (buf == NULL) { 44239beb93cSSam Leffler fprintf(out_file, 44339beb93cSSam Leffler "%s - hexdump_ascii(len=%lu): [NULL]\n", 44439beb93cSSam Leffler title, (unsigned long) len); 445c1d255d3SCy Schubert goto file_done; 44639beb93cSSam Leffler } 44739beb93cSSam Leffler fprintf(out_file, "%s - hexdump_ascii(len=%lu):\n", 44839beb93cSSam Leffler title, (unsigned long) len); 44939beb93cSSam Leffler while (len) { 45039beb93cSSam Leffler llen = len > line_len ? line_len : len; 45139beb93cSSam Leffler fprintf(out_file, " "); 45239beb93cSSam Leffler for (i = 0; i < llen; i++) 45339beb93cSSam Leffler fprintf(out_file, " %02x", pos[i]); 45439beb93cSSam Leffler for (i = llen; i < line_len; i++) 45539beb93cSSam Leffler fprintf(out_file, " "); 45639beb93cSSam Leffler fprintf(out_file, " "); 45739beb93cSSam Leffler for (i = 0; i < llen; i++) { 45839beb93cSSam Leffler if (isprint(pos[i])) 45939beb93cSSam Leffler fprintf(out_file, "%c", pos[i]); 46039beb93cSSam Leffler else 46139beb93cSSam Leffler fprintf(out_file, "_"); 46239beb93cSSam Leffler } 46339beb93cSSam Leffler for (i = llen; i < line_len; i++) 46439beb93cSSam Leffler fprintf(out_file, " "); 46539beb93cSSam Leffler fprintf(out_file, "\n"); 46639beb93cSSam Leffler pos += llen; 46739beb93cSSam Leffler len -= llen; 46839beb93cSSam Leffler } 469c1d255d3SCy Schubert } 470c1d255d3SCy Schubert file_done: 47139beb93cSSam Leffler #endif /* CONFIG_DEBUG_FILE */ 472c1d255d3SCy Schubert if (!wpa_debug_syslog && !out_file) { 47339beb93cSSam Leffler if (!show) { 47439beb93cSSam Leffler printf("%s - hexdump_ascii(len=%lu): [REMOVED]\n", 47539beb93cSSam Leffler title, (unsigned long) len); 47639beb93cSSam Leffler return; 47739beb93cSSam Leffler } 47839beb93cSSam Leffler if (buf == NULL) { 47939beb93cSSam Leffler printf("%s - hexdump_ascii(len=%lu): [NULL]\n", 48039beb93cSSam Leffler title, (unsigned long) len); 48139beb93cSSam Leffler return; 48239beb93cSSam Leffler } 483c1d255d3SCy Schubert printf("%s - hexdump_ascii(len=%lu):\n", title, 484c1d255d3SCy Schubert (unsigned long) len); 48539beb93cSSam Leffler while (len) { 48639beb93cSSam Leffler llen = len > line_len ? line_len : len; 48739beb93cSSam Leffler printf(" "); 48839beb93cSSam Leffler for (i = 0; i < llen; i++) 48939beb93cSSam Leffler printf(" %02x", pos[i]); 49039beb93cSSam Leffler for (i = llen; i < line_len; i++) 49139beb93cSSam Leffler printf(" "); 49239beb93cSSam Leffler printf(" "); 49339beb93cSSam Leffler for (i = 0; i < llen; i++) { 49439beb93cSSam Leffler if (isprint(pos[i])) 49539beb93cSSam Leffler printf("%c", pos[i]); 49639beb93cSSam Leffler else 49739beb93cSSam Leffler printf("_"); 49839beb93cSSam Leffler } 49939beb93cSSam Leffler for (i = llen; i < line_len; i++) 50039beb93cSSam Leffler printf(" "); 50139beb93cSSam Leffler printf("\n"); 50239beb93cSSam Leffler pos += llen; 50339beb93cSSam Leffler len -= llen; 50439beb93cSSam Leffler } 50539beb93cSSam Leffler } 506f05cddf9SRui Paulo #endif /* CONFIG_ANDROID_LOG */ 50739beb93cSSam Leffler } 50839beb93cSSam Leffler 50939beb93cSSam Leffler 5105b9c547cSRui Paulo void wpa_hexdump_ascii(int level, const char *title, const void *buf, 5115b9c547cSRui Paulo size_t len) 51239beb93cSSam Leffler { 51339beb93cSSam Leffler _wpa_hexdump_ascii(level, title, buf, len, 1); 51439beb93cSSam Leffler } 51539beb93cSSam Leffler 51639beb93cSSam Leffler 5175b9c547cSRui Paulo void wpa_hexdump_ascii_key(int level, const char *title, const void *buf, 51839beb93cSSam Leffler size_t len) 51939beb93cSSam Leffler { 52039beb93cSSam Leffler _wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys); 52139beb93cSSam Leffler } 52239beb93cSSam Leffler 52339beb93cSSam Leffler 524f05cddf9SRui Paulo #ifdef CONFIG_DEBUG_FILE 525f05cddf9SRui Paulo static char *last_path = NULL; 526f05cddf9SRui Paulo #endif /* CONFIG_DEBUG_FILE */ 527f05cddf9SRui Paulo 528f05cddf9SRui Paulo int wpa_debug_reopen_file(void) 529f05cddf9SRui Paulo { 530f05cddf9SRui Paulo #ifdef CONFIG_DEBUG_FILE 531f05cddf9SRui Paulo int rv; 532780fb4a2SCy Schubert char *tmp; 533780fb4a2SCy Schubert 534780fb4a2SCy Schubert if (!last_path) 535780fb4a2SCy Schubert return 0; /* logfile not used */ 536780fb4a2SCy Schubert 537780fb4a2SCy Schubert tmp = os_strdup(last_path); 538780fb4a2SCy Schubert if (!tmp) 539780fb4a2SCy Schubert return -1; 540780fb4a2SCy Schubert 541f05cddf9SRui Paulo wpa_debug_close_file(); 542f05cddf9SRui Paulo rv = wpa_debug_open_file(tmp); 543f05cddf9SRui Paulo os_free(tmp); 544f05cddf9SRui Paulo return rv; 545f05cddf9SRui Paulo #else /* CONFIG_DEBUG_FILE */ 546f05cddf9SRui Paulo return 0; 547f05cddf9SRui Paulo #endif /* CONFIG_DEBUG_FILE */ 548f05cddf9SRui Paulo } 549f05cddf9SRui Paulo 550f05cddf9SRui Paulo 55139beb93cSSam Leffler int wpa_debug_open_file(const char *path) 55239beb93cSSam Leffler { 55339beb93cSSam Leffler #ifdef CONFIG_DEBUG_FILE 55485732ac8SCy Schubert int out_fd; 55585732ac8SCy Schubert 55639beb93cSSam Leffler if (!path) 55739beb93cSSam Leffler return 0; 558f05cddf9SRui Paulo 559f05cddf9SRui Paulo if (last_path == NULL || os_strcmp(last_path, path) != 0) { 560f05cddf9SRui Paulo /* Save our path to enable re-open */ 561f05cddf9SRui Paulo os_free(last_path); 562f05cddf9SRui Paulo last_path = os_strdup(path); 563f05cddf9SRui Paulo } 564f05cddf9SRui Paulo 56585732ac8SCy Schubert out_fd = open(path, O_CREAT | O_APPEND | O_WRONLY, 56685732ac8SCy Schubert S_IRUSR | S_IWUSR | S_IRGRP); 56785732ac8SCy Schubert if (out_fd < 0) { 56885732ac8SCy Schubert wpa_printf(MSG_ERROR, 56985732ac8SCy Schubert "%s: Failed to open output file descriptor, using standard output", 57085732ac8SCy Schubert __func__); 57185732ac8SCy Schubert return -1; 57285732ac8SCy Schubert } 57385732ac8SCy Schubert 57485732ac8SCy Schubert #ifdef __linux__ 57585732ac8SCy Schubert if (fcntl(out_fd, F_SETFD, FD_CLOEXEC) < 0) { 57685732ac8SCy Schubert wpa_printf(MSG_DEBUG, 57785732ac8SCy Schubert "%s: Failed to set FD_CLOEXEC - continue without: %s", 57885732ac8SCy Schubert __func__, strerror(errno)); 57985732ac8SCy Schubert } 58085732ac8SCy Schubert #endif /* __linux__ */ 58185732ac8SCy Schubert 58285732ac8SCy Schubert out_file = fdopen(out_fd, "a"); 58339beb93cSSam Leffler if (out_file == NULL) { 58439beb93cSSam Leffler wpa_printf(MSG_ERROR, "wpa_debug_open_file: Failed to open " 58539beb93cSSam Leffler "output file, using standard output"); 58685732ac8SCy Schubert close(out_fd); 58739beb93cSSam Leffler return -1; 58839beb93cSSam Leffler } 58939beb93cSSam Leffler #ifndef _WIN32 59039beb93cSSam Leffler setvbuf(out_file, NULL, _IOLBF, 0); 59139beb93cSSam Leffler #endif /* _WIN32 */ 5925b9c547cSRui Paulo #else /* CONFIG_DEBUG_FILE */ 5935b9c547cSRui Paulo (void)path; 59439beb93cSSam Leffler #endif /* CONFIG_DEBUG_FILE */ 59539beb93cSSam Leffler return 0; 59639beb93cSSam Leffler } 59739beb93cSSam Leffler 59839beb93cSSam Leffler 599*a90b9d01SCy Schubert void wpa_debug_stop_log(void) 60039beb93cSSam Leffler { 60139beb93cSSam Leffler #ifdef CONFIG_DEBUG_FILE 60239beb93cSSam Leffler if (!out_file) 60339beb93cSSam Leffler return; 60439beb93cSSam Leffler fclose(out_file); 60539beb93cSSam Leffler out_file = NULL; 606*a90b9d01SCy Schubert #endif /* CONFIG_DEBUG_FILE */ 607*a90b9d01SCy Schubert } 608*a90b9d01SCy Schubert 609*a90b9d01SCy Schubert 610*a90b9d01SCy Schubert void wpa_debug_close_file(void) 611*a90b9d01SCy Schubert { 612*a90b9d01SCy Schubert #ifdef CONFIG_DEBUG_FILE 613*a90b9d01SCy Schubert wpa_debug_stop_log(); 614f05cddf9SRui Paulo os_free(last_path); 615f05cddf9SRui Paulo last_path = NULL; 61639beb93cSSam Leffler #endif /* CONFIG_DEBUG_FILE */ 61739beb93cSSam Leffler } 61839beb93cSSam Leffler 6195b9c547cSRui Paulo 6205b9c547cSRui Paulo void wpa_debug_setup_stdout(void) 6215b9c547cSRui Paulo { 6225b9c547cSRui Paulo #ifndef _WIN32 6235b9c547cSRui Paulo setvbuf(stdout, NULL, _IOLBF, 0); 6245b9c547cSRui Paulo #endif /* _WIN32 */ 6255b9c547cSRui Paulo } 6265b9c547cSRui Paulo 62739beb93cSSam Leffler #endif /* CONFIG_NO_STDOUT_DEBUG */ 62839beb93cSSam Leffler 62939beb93cSSam Leffler 63039beb93cSSam Leffler #ifndef CONFIG_NO_WPA_MSG 63139beb93cSSam Leffler static wpa_msg_cb_func wpa_msg_cb = NULL; 63239beb93cSSam Leffler 63339beb93cSSam Leffler void wpa_msg_register_cb(wpa_msg_cb_func func) 63439beb93cSSam Leffler { 63539beb93cSSam Leffler wpa_msg_cb = func; 63639beb93cSSam Leffler } 63739beb93cSSam Leffler 63839beb93cSSam Leffler 639f05cddf9SRui Paulo static wpa_msg_get_ifname_func wpa_msg_ifname_cb = NULL; 640f05cddf9SRui Paulo 641f05cddf9SRui Paulo void wpa_msg_register_ifname_cb(wpa_msg_get_ifname_func func) 642f05cddf9SRui Paulo { 643f05cddf9SRui Paulo wpa_msg_ifname_cb = func; 644f05cddf9SRui Paulo } 645f05cddf9SRui Paulo 646f05cddf9SRui Paulo 6473157ba21SRui Paulo void wpa_msg(void *ctx, int level, const char *fmt, ...) 64839beb93cSSam Leffler { 64939beb93cSSam Leffler va_list ap; 65039beb93cSSam Leffler char *buf; 6515b9c547cSRui Paulo int buflen; 65239beb93cSSam Leffler int len; 653f05cddf9SRui Paulo char prefix[130]; 65439beb93cSSam Leffler 6555b9c547cSRui Paulo va_start(ap, fmt); 6565b9c547cSRui Paulo buflen = vsnprintf(NULL, 0, fmt, ap) + 1; 6575b9c547cSRui Paulo va_end(ap); 6585b9c547cSRui Paulo 65939beb93cSSam Leffler buf = os_malloc(buflen); 66039beb93cSSam Leffler if (buf == NULL) { 66139beb93cSSam Leffler wpa_printf(MSG_ERROR, "wpa_msg: Failed to allocate message " 66239beb93cSSam Leffler "buffer"); 66339beb93cSSam Leffler return; 66439beb93cSSam Leffler } 66539beb93cSSam Leffler va_start(ap, fmt); 666f05cddf9SRui Paulo prefix[0] = '\0'; 667f05cddf9SRui Paulo if (wpa_msg_ifname_cb) { 668f05cddf9SRui Paulo const char *ifname = wpa_msg_ifname_cb(ctx); 669f05cddf9SRui Paulo if (ifname) { 670f05cddf9SRui Paulo int res = os_snprintf(prefix, sizeof(prefix), "%s: ", 671f05cddf9SRui Paulo ifname); 6725b9c547cSRui Paulo if (os_snprintf_error(sizeof(prefix), res)) 673f05cddf9SRui Paulo prefix[0] = '\0'; 674f05cddf9SRui Paulo } 675f05cddf9SRui Paulo } 67639beb93cSSam Leffler len = vsnprintf(buf, buflen, fmt, ap); 67739beb93cSSam Leffler va_end(ap); 678f05cddf9SRui Paulo wpa_printf(level, "%s%s", prefix, buf); 67939beb93cSSam Leffler if (wpa_msg_cb) 680325151a3SRui Paulo wpa_msg_cb(ctx, level, WPA_MSG_PER_INTERFACE, buf, len); 681325151a3SRui Paulo bin_clear_free(buf, buflen); 68239beb93cSSam Leffler } 6833157ba21SRui Paulo 6843157ba21SRui Paulo 6853157ba21SRui Paulo void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) 6863157ba21SRui Paulo { 6873157ba21SRui Paulo va_list ap; 6883157ba21SRui Paulo char *buf; 6895b9c547cSRui Paulo int buflen; 6903157ba21SRui Paulo int len; 6913157ba21SRui Paulo 6923157ba21SRui Paulo if (!wpa_msg_cb) 6933157ba21SRui Paulo return; 6943157ba21SRui Paulo 6955b9c547cSRui Paulo va_start(ap, fmt); 6965b9c547cSRui Paulo buflen = vsnprintf(NULL, 0, fmt, ap) + 1; 6975b9c547cSRui Paulo va_end(ap); 6985b9c547cSRui Paulo 6993157ba21SRui Paulo buf = os_malloc(buflen); 7003157ba21SRui Paulo if (buf == NULL) { 7013157ba21SRui Paulo wpa_printf(MSG_ERROR, "wpa_msg_ctrl: Failed to allocate " 7023157ba21SRui Paulo "message buffer"); 7033157ba21SRui Paulo return; 7043157ba21SRui Paulo } 7053157ba21SRui Paulo va_start(ap, fmt); 7063157ba21SRui Paulo len = vsnprintf(buf, buflen, fmt, ap); 7073157ba21SRui Paulo va_end(ap); 708325151a3SRui Paulo wpa_msg_cb(ctx, level, WPA_MSG_PER_INTERFACE, buf, len); 709325151a3SRui Paulo bin_clear_free(buf, buflen); 7103157ba21SRui Paulo } 7115b9c547cSRui Paulo 7125b9c547cSRui Paulo 7135b9c547cSRui Paulo void wpa_msg_global(void *ctx, int level, const char *fmt, ...) 7145b9c547cSRui Paulo { 7155b9c547cSRui Paulo va_list ap; 7165b9c547cSRui Paulo char *buf; 7175b9c547cSRui Paulo int buflen; 7185b9c547cSRui Paulo int len; 7195b9c547cSRui Paulo 7205b9c547cSRui Paulo va_start(ap, fmt); 7215b9c547cSRui Paulo buflen = vsnprintf(NULL, 0, fmt, ap) + 1; 7225b9c547cSRui Paulo va_end(ap); 7235b9c547cSRui Paulo 7245b9c547cSRui Paulo buf = os_malloc(buflen); 7255b9c547cSRui Paulo if (buf == NULL) { 7265b9c547cSRui Paulo wpa_printf(MSG_ERROR, "wpa_msg_global: Failed to allocate " 7275b9c547cSRui Paulo "message buffer"); 7285b9c547cSRui Paulo return; 7295b9c547cSRui Paulo } 7305b9c547cSRui Paulo va_start(ap, fmt); 7315b9c547cSRui Paulo len = vsnprintf(buf, buflen, fmt, ap); 7325b9c547cSRui Paulo va_end(ap); 7335b9c547cSRui Paulo wpa_printf(level, "%s", buf); 7345b9c547cSRui Paulo if (wpa_msg_cb) 735325151a3SRui Paulo wpa_msg_cb(ctx, level, WPA_MSG_GLOBAL, buf, len); 736325151a3SRui Paulo bin_clear_free(buf, buflen); 7375b9c547cSRui Paulo } 7385b9c547cSRui Paulo 7395b9c547cSRui Paulo 7405b9c547cSRui Paulo void wpa_msg_global_ctrl(void *ctx, int level, const char *fmt, ...) 7415b9c547cSRui Paulo { 7425b9c547cSRui Paulo va_list ap; 7435b9c547cSRui Paulo char *buf; 7445b9c547cSRui Paulo int buflen; 7455b9c547cSRui Paulo int len; 7465b9c547cSRui Paulo 7475b9c547cSRui Paulo if (!wpa_msg_cb) 7485b9c547cSRui Paulo return; 7495b9c547cSRui Paulo 7505b9c547cSRui Paulo va_start(ap, fmt); 7515b9c547cSRui Paulo buflen = vsnprintf(NULL, 0, fmt, ap) + 1; 7525b9c547cSRui Paulo va_end(ap); 7535b9c547cSRui Paulo 7545b9c547cSRui Paulo buf = os_malloc(buflen); 7555b9c547cSRui Paulo if (buf == NULL) { 7565b9c547cSRui Paulo wpa_printf(MSG_ERROR, 7575b9c547cSRui Paulo "wpa_msg_global_ctrl: Failed to allocate message buffer"); 7585b9c547cSRui Paulo return; 7595b9c547cSRui Paulo } 7605b9c547cSRui Paulo va_start(ap, fmt); 7615b9c547cSRui Paulo len = vsnprintf(buf, buflen, fmt, ap); 7625b9c547cSRui Paulo va_end(ap); 763325151a3SRui Paulo wpa_msg_cb(ctx, level, WPA_MSG_GLOBAL, buf, len); 764325151a3SRui Paulo bin_clear_free(buf, buflen); 7655b9c547cSRui Paulo } 7665b9c547cSRui Paulo 7675b9c547cSRui Paulo 7685b9c547cSRui Paulo void wpa_msg_no_global(void *ctx, int level, const char *fmt, ...) 7695b9c547cSRui Paulo { 7705b9c547cSRui Paulo va_list ap; 7715b9c547cSRui Paulo char *buf; 7725b9c547cSRui Paulo int buflen; 7735b9c547cSRui Paulo int len; 7745b9c547cSRui Paulo 7755b9c547cSRui Paulo va_start(ap, fmt); 7765b9c547cSRui Paulo buflen = vsnprintf(NULL, 0, fmt, ap) + 1; 7775b9c547cSRui Paulo va_end(ap); 7785b9c547cSRui Paulo 7795b9c547cSRui Paulo buf = os_malloc(buflen); 7805b9c547cSRui Paulo if (buf == NULL) { 7815b9c547cSRui Paulo wpa_printf(MSG_ERROR, "wpa_msg_no_global: Failed to allocate " 7825b9c547cSRui Paulo "message buffer"); 7835b9c547cSRui Paulo return; 7845b9c547cSRui Paulo } 7855b9c547cSRui Paulo va_start(ap, fmt); 7865b9c547cSRui Paulo len = vsnprintf(buf, buflen, fmt, ap); 7875b9c547cSRui Paulo va_end(ap); 7885b9c547cSRui Paulo wpa_printf(level, "%s", buf); 7895b9c547cSRui Paulo if (wpa_msg_cb) 790325151a3SRui Paulo wpa_msg_cb(ctx, level, WPA_MSG_NO_GLOBAL, buf, len); 791325151a3SRui Paulo bin_clear_free(buf, buflen); 792325151a3SRui Paulo } 793325151a3SRui Paulo 794325151a3SRui Paulo 795325151a3SRui Paulo void wpa_msg_global_only(void *ctx, int level, const char *fmt, ...) 796325151a3SRui Paulo { 797325151a3SRui Paulo va_list ap; 798325151a3SRui Paulo char *buf; 799325151a3SRui Paulo int buflen; 800325151a3SRui Paulo int len; 801325151a3SRui Paulo 802325151a3SRui Paulo va_start(ap, fmt); 803325151a3SRui Paulo buflen = vsnprintf(NULL, 0, fmt, ap) + 1; 804325151a3SRui Paulo va_end(ap); 805325151a3SRui Paulo 806325151a3SRui Paulo buf = os_malloc(buflen); 807325151a3SRui Paulo if (buf == NULL) { 808325151a3SRui Paulo wpa_printf(MSG_ERROR, "%s: Failed to allocate message buffer", 809325151a3SRui Paulo __func__); 810325151a3SRui Paulo return; 811325151a3SRui Paulo } 812325151a3SRui Paulo va_start(ap, fmt); 813325151a3SRui Paulo len = vsnprintf(buf, buflen, fmt, ap); 814325151a3SRui Paulo va_end(ap); 815325151a3SRui Paulo wpa_printf(level, "%s", buf); 816325151a3SRui Paulo if (wpa_msg_cb) 817325151a3SRui Paulo wpa_msg_cb(ctx, level, WPA_MSG_ONLY_GLOBAL, buf, len); 8185b9c547cSRui Paulo os_free(buf); 8195b9c547cSRui Paulo } 8205b9c547cSRui Paulo 82139beb93cSSam Leffler #endif /* CONFIG_NO_WPA_MSG */ 82239beb93cSSam Leffler 82339beb93cSSam Leffler 82439beb93cSSam Leffler #ifndef CONFIG_NO_HOSTAPD_LOGGER 82539beb93cSSam Leffler static hostapd_logger_cb_func hostapd_logger_cb = NULL; 82639beb93cSSam Leffler 82739beb93cSSam Leffler void hostapd_logger_register_cb(hostapd_logger_cb_func func) 82839beb93cSSam Leffler { 82939beb93cSSam Leffler hostapd_logger_cb = func; 83039beb93cSSam Leffler } 83139beb93cSSam Leffler 83239beb93cSSam Leffler 83339beb93cSSam Leffler void hostapd_logger(void *ctx, const u8 *addr, unsigned int module, int level, 83439beb93cSSam Leffler const char *fmt, ...) 83539beb93cSSam Leffler { 83639beb93cSSam Leffler va_list ap; 83739beb93cSSam Leffler char *buf; 8385b9c547cSRui Paulo int buflen; 83939beb93cSSam Leffler int len; 84039beb93cSSam Leffler 8415b9c547cSRui Paulo va_start(ap, fmt); 8425b9c547cSRui Paulo buflen = vsnprintf(NULL, 0, fmt, ap) + 1; 8435b9c547cSRui Paulo va_end(ap); 8445b9c547cSRui Paulo 84539beb93cSSam Leffler buf = os_malloc(buflen); 84639beb93cSSam Leffler if (buf == NULL) { 84739beb93cSSam Leffler wpa_printf(MSG_ERROR, "hostapd_logger: Failed to allocate " 84839beb93cSSam Leffler "message buffer"); 84939beb93cSSam Leffler return; 85039beb93cSSam Leffler } 85139beb93cSSam Leffler va_start(ap, fmt); 85239beb93cSSam Leffler len = vsnprintf(buf, buflen, fmt, ap); 85339beb93cSSam Leffler va_end(ap); 85439beb93cSSam Leffler if (hostapd_logger_cb) 85539beb93cSSam Leffler hostapd_logger_cb(ctx, addr, module, level, buf, len); 856e28a4053SRui Paulo else if (addr) 857e28a4053SRui Paulo wpa_printf(MSG_DEBUG, "hostapd_logger: STA " MACSTR " - %s", 858e28a4053SRui Paulo MAC2STR(addr), buf); 85939beb93cSSam Leffler else 86039beb93cSSam Leffler wpa_printf(MSG_DEBUG, "hostapd_logger: %s", buf); 861325151a3SRui Paulo bin_clear_free(buf, buflen); 86239beb93cSSam Leffler } 86339beb93cSSam Leffler #endif /* CONFIG_NO_HOSTAPD_LOGGER */ 864325151a3SRui Paulo 865325151a3SRui Paulo 866325151a3SRui Paulo const char * debug_level_str(int level) 867325151a3SRui Paulo { 868325151a3SRui Paulo switch (level) { 869325151a3SRui Paulo case MSG_EXCESSIVE: 870325151a3SRui Paulo return "EXCESSIVE"; 871325151a3SRui Paulo case MSG_MSGDUMP: 872325151a3SRui Paulo return "MSGDUMP"; 873325151a3SRui Paulo case MSG_DEBUG: 874325151a3SRui Paulo return "DEBUG"; 875325151a3SRui Paulo case MSG_INFO: 876325151a3SRui Paulo return "INFO"; 877325151a3SRui Paulo case MSG_WARNING: 878325151a3SRui Paulo return "WARNING"; 879325151a3SRui Paulo case MSG_ERROR: 880325151a3SRui Paulo return "ERROR"; 881325151a3SRui Paulo default: 882325151a3SRui Paulo return "?"; 883325151a3SRui Paulo } 884325151a3SRui Paulo } 885325151a3SRui Paulo 886325151a3SRui Paulo 887325151a3SRui Paulo int str_to_debug_level(const char *s) 888325151a3SRui Paulo { 889325151a3SRui Paulo if (os_strcasecmp(s, "EXCESSIVE") == 0) 890325151a3SRui Paulo return MSG_EXCESSIVE; 891325151a3SRui Paulo if (os_strcasecmp(s, "MSGDUMP") == 0) 892325151a3SRui Paulo return MSG_MSGDUMP; 893325151a3SRui Paulo if (os_strcasecmp(s, "DEBUG") == 0) 894325151a3SRui Paulo return MSG_DEBUG; 895325151a3SRui Paulo if (os_strcasecmp(s, "INFO") == 0) 896325151a3SRui Paulo return MSG_INFO; 897325151a3SRui Paulo if (os_strcasecmp(s, "WARNING") == 0) 898325151a3SRui Paulo return MSG_WARNING; 899325151a3SRui Paulo if (os_strcasecmp(s, "ERROR") == 0) 900325151a3SRui Paulo return MSG_ERROR; 901325151a3SRui Paulo return -1; 902325151a3SRui Paulo } 903