summaryrefslogtreecommitdiff
path: root/src/utils/wpa_debug.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils/wpa_debug.c')
-rw-r--r--src/utils/wpa_debug.c314
1 files changed, 301 insertions, 13 deletions
diff --git a/src/utils/wpa_debug.c b/src/utils/wpa_debug.c
index 6f6fc69ccc44a..5511ef193b0c6 100644
--- a/src/utils/wpa_debug.c
+++ b/src/utils/wpa_debug.c
@@ -2,14 +2,8 @@
* wpa_supplicant/hostapd / Debug prints
* Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
*/
#include "includes.h"
@@ -22,19 +16,55 @@
static int wpa_debug_syslog = 0;
#endif /* CONFIG_DEBUG_SYSLOG */
+#ifdef CONFIG_DEBUG_LINUX_TRACING
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+
+static FILE *wpa_debug_tracing_file = NULL;
+
+#define WPAS_TRACE_PFX "wpas <%d>: "
+#endif /* CONFIG_DEBUG_LINUX_TRACING */
+
-#ifdef CONFIG_DEBUG_FILE
-static FILE *out_file = NULL;
-#endif /* CONFIG_DEBUG_FILE */
int wpa_debug_level = MSG_INFO;
int wpa_debug_show_keys = 0;
int wpa_debug_timestamp = 0;
+#ifdef CONFIG_ANDROID_LOG
+
+#include <android/log.h>
+
+#ifndef ANDROID_LOG_NAME
+#define ANDROID_LOG_NAME "wpa_supplicant"
+#endif /* ANDROID_LOG_NAME */
+
+static int wpa_to_android_level(int level)
+{
+ if (level == MSG_ERROR)
+ return ANDROID_LOG_ERROR;
+ if (level == MSG_WARNING)
+ return ANDROID_LOG_WARN;
+ if (level == MSG_INFO)
+ return ANDROID_LOG_INFO;
+ return ANDROID_LOG_DEBUG;
+}
+
+#endif /* CONFIG_ANDROID_LOG */
+
#ifndef CONFIG_NO_STDOUT_DEBUG
+#ifdef CONFIG_DEBUG_FILE
+static FILE *out_file = NULL;
+#endif /* CONFIG_DEBUG_FILE */
+
+
void wpa_debug_print_timestamp(void)
{
+#ifndef CONFIG_ANDROID_LOG
struct os_time tv;
if (!wpa_debug_timestamp)
@@ -48,13 +78,18 @@ void wpa_debug_print_timestamp(void)
} else
#endif /* CONFIG_DEBUG_FILE */
printf("%ld.%06u: ", (long) tv.sec, (unsigned int) tv.usec);
+#endif /* CONFIG_ANDROID_LOG */
}
#ifdef CONFIG_DEBUG_SYSLOG
+#ifndef LOG_HOSTAPD
+#define LOG_HOSTAPD LOG_DAEMON
+#endif /* LOG_HOSTAPD */
+
void wpa_debug_open_syslog(void)
{
- openlog("wpa_supplicant", LOG_PID | LOG_NDELAY, LOG_DAEMON);
+ openlog("wpa_supplicant", LOG_PID | LOG_NDELAY, LOG_HOSTAPD);
wpa_debug_syslog++;
}
@@ -84,6 +119,77 @@ static int syslog_priority(int level)
#endif /* CONFIG_DEBUG_SYSLOG */
+#ifdef CONFIG_DEBUG_LINUX_TRACING
+
+int wpa_debug_open_linux_tracing(void)
+{
+ int mounts, trace_fd;
+ char buf[4096] = {};
+ ssize_t buflen;
+ char *line, *tmp1, *path = NULL;
+
+ mounts = open("/proc/mounts", O_RDONLY);
+ if (mounts < 0) {
+ printf("no /proc/mounts\n");
+ return -1;
+ }
+
+ buflen = read(mounts, buf, sizeof(buf) - 1);
+ close(mounts);
+ if (buflen < 0) {
+ printf("failed to read /proc/mounts\n");
+ return -1;
+ }
+
+ line = strtok_r(buf, "\n", &tmp1);
+ while (line) {
+ char *tmp2, *tmp_path, *fstype;
+ /* "<dev> <mountpoint> <fs type> ..." */
+ strtok_r(line, " ", &tmp2);
+ tmp_path = strtok_r(NULL, " ", &tmp2);
+ fstype = strtok_r(NULL, " ", &tmp2);
+ if (strcmp(fstype, "debugfs") == 0) {
+ path = tmp_path;
+ break;
+ }
+
+ line = strtok_r(NULL, "\n", &tmp1);
+ }
+
+ if (path == NULL) {
+ printf("debugfs mountpoint not found\n");
+ return -1;
+ }
+
+ snprintf(buf, sizeof(buf) - 1, "%s/tracing/trace_marker", path);
+
+ trace_fd = open(buf, O_WRONLY);
+ if (trace_fd < 0) {
+ printf("failed to open trace_marker file\n");
+ return -1;
+ }
+ wpa_debug_tracing_file = fdopen(trace_fd, "w");
+ if (wpa_debug_tracing_file == NULL) {
+ close(trace_fd);
+ printf("failed to fdopen()\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+
+void wpa_debug_close_linux_tracing(void)
+{
+ if (wpa_debug_tracing_file == NULL)
+ return;
+ fclose(wpa_debug_tracing_file);
+ wpa_debug_tracing_file = NULL;
+}
+
+#endif /* CONFIG_DEBUG_LINUX_TRACING */
+
+
/**
* wpa_printf - conditional printf
* @level: priority level (MSG_*) of the message
@@ -101,6 +207,10 @@ void wpa_printf(int level, const char *fmt, ...)
va_start(ap, fmt);
if (level >= wpa_debug_level) {
+#ifdef CONFIG_ANDROID_LOG
+ __android_log_vprint(wpa_to_android_level(level),
+ ANDROID_LOG_NAME, fmt, ap);
+#else /* CONFIG_ANDROID_LOG */
#ifdef CONFIG_DEBUG_SYSLOG
if (wpa_debug_syslog) {
vsyslog(syslog_priority(level), fmt, ap);
@@ -121,8 +231,20 @@ void wpa_printf(int level, const char *fmt, ...)
#ifdef CONFIG_DEBUG_SYSLOG
}
#endif /* CONFIG_DEBUG_SYSLOG */
+#endif /* CONFIG_ANDROID_LOG */
}
va_end(ap);
+
+#ifdef CONFIG_DEBUG_LINUX_TRACING
+ if (wpa_debug_tracing_file != NULL) {
+ va_start(ap, fmt);
+ fprintf(wpa_debug_tracing_file, WPAS_TRACE_PFX, level);
+ vfprintf(wpa_debug_tracing_file, fmt, ap);
+ fprintf(wpa_debug_tracing_file, "\n");
+ fflush(wpa_debug_tracing_file);
+ va_end(ap);
+ }
+#endif /* CONFIG_DEBUG_LINUX_TRACING */
}
@@ -130,8 +252,97 @@ static void _wpa_hexdump(int level, const char *title, const u8 *buf,
size_t len, int show)
{
size_t i;
+
+#ifdef CONFIG_DEBUG_LINUX_TRACING
+ if (wpa_debug_tracing_file != NULL) {
+ fprintf(wpa_debug_tracing_file,
+ WPAS_TRACE_PFX "%s - hexdump(len=%lu):",
+ level, title, (unsigned long) len);
+ if (buf == NULL) {
+ fprintf(wpa_debug_tracing_file, " [NULL]\n");
+ } else if (!show) {
+ fprintf(wpa_debug_tracing_file, " [REMOVED]\n");
+ } else {
+ for (i = 0; i < len; i++)
+ fprintf(wpa_debug_tracing_file,
+ " %02x", buf[i]);
+ }
+ fflush(wpa_debug_tracing_file);
+ }
+#endif /* CONFIG_DEBUG_LINUX_TRACING */
+
if (level < wpa_debug_level)
return;
+#ifdef CONFIG_ANDROID_LOG
+ {
+ const char *display;
+ char *strbuf = NULL;
+ size_t slen = len;
+ if (buf == NULL) {
+ display = " [NULL]";
+ } else if (len == 0) {
+ display = "";
+ } else if (show && len) {
+ /* Limit debug message length for Android log */
+ if (slen > 32)
+ slen = 32;
+ strbuf = os_malloc(1 + 3 * slen);
+ if (strbuf == NULL) {
+ wpa_printf(MSG_ERROR, "wpa_hexdump: Failed to "
+ "allocate message buffer");
+ return;
+ }
+
+ for (i = 0; i < slen; i++)
+ os_snprintf(&strbuf[i * 3], 4, " %02x",
+ buf[i]);
+
+ display = strbuf;
+ } else {
+ display = " [REMOVED]";
+ }
+
+ __android_log_print(wpa_to_android_level(level),
+ ANDROID_LOG_NAME,
+ "%s - hexdump(len=%lu):%s%s",
+ title, (long unsigned int) len, display,
+ len > slen ? " ..." : "");
+ os_free(strbuf);
+ return;
+ }
+#else /* CONFIG_ANDROID_LOG */
+#ifdef CONFIG_DEBUG_SYSLOG
+ if (wpa_debug_syslog) {
+ const char *display;
+ char *strbuf = NULL;
+
+ if (buf == NULL) {
+ display = " [NULL]";
+ } else if (len == 0) {
+ display = "";
+ } else if (show && len) {
+ strbuf = os_malloc(1 + 3 * len);
+ if (strbuf == NULL) {
+ wpa_printf(MSG_ERROR, "wpa_hexdump: Failed to "
+ "allocate message buffer");
+ return;
+ }
+
+ for (i = 0; i < len; i++)
+ os_snprintf(&strbuf[i * 3], 4, " %02x",
+ buf[i]);
+
+ display = strbuf;
+ } else {
+ display = " [REMOVED]";
+ }
+
+ syslog(syslog_priority(level), "%s - hexdump(len=%lu):%s",
+ title, (unsigned long) len, display);
+ os_free(strbuf);
+ return;
+ }
+#endif /* CONFIG_DEBUG_SYSLOG */
wpa_debug_print_timestamp();
#ifdef CONFIG_DEBUG_FILE
if (out_file) {
@@ -161,6 +372,7 @@ static void _wpa_hexdump(int level, const char *title, const u8 *buf,
#ifdef CONFIG_DEBUG_FILE
}
#endif /* CONFIG_DEBUG_FILE */
+#endif /* CONFIG_ANDROID_LOG */
}
void wpa_hexdump(int level, const char *title, const u8 *buf, size_t len)
@@ -182,8 +394,30 @@ static void _wpa_hexdump_ascii(int level, const char *title, const u8 *buf,
const u8 *pos = buf;
const size_t line_len = 16;
+#ifdef CONFIG_DEBUG_LINUX_TRACING
+ if (wpa_debug_tracing_file != NULL) {
+ fprintf(wpa_debug_tracing_file,
+ WPAS_TRACE_PFX "%s - hexdump_ascii(len=%lu):",
+ level, title, (unsigned long) len);
+ if (buf == NULL) {
+ fprintf(wpa_debug_tracing_file, " [NULL]\n");
+ } else if (!show) {
+ fprintf(wpa_debug_tracing_file, " [REMOVED]\n");
+ } else {
+ /* can do ascii processing in userspace */
+ for (i = 0; i < len; i++)
+ fprintf(wpa_debug_tracing_file,
+ " %02x", buf[i]);
+ }
+ fflush(wpa_debug_tracing_file);
+ }
+#endif /* CONFIG_DEBUG_LINUX_TRACING */
+
if (level < wpa_debug_level)
return;
+#ifdef CONFIG_ANDROID_LOG
+ _wpa_hexdump(level, title, buf, len, show);
+#else /* CONFIG_ANDROID_LOG */
wpa_debug_print_timestamp();
#ifdef CONFIG_DEBUG_FILE
if (out_file) {
@@ -257,6 +491,7 @@ static void _wpa_hexdump_ascii(int level, const char *title, const u8 *buf,
#ifdef CONFIG_DEBUG_FILE
}
#endif /* CONFIG_DEBUG_FILE */
+#endif /* CONFIG_ANDROID_LOG */
}
@@ -273,11 +508,43 @@ void wpa_hexdump_ascii_key(int level, const char *title, const u8 *buf,
}
+#ifdef CONFIG_DEBUG_FILE
+static char *last_path = NULL;
+#endif /* CONFIG_DEBUG_FILE */
+
+int wpa_debug_reopen_file(void)
+{
+#ifdef CONFIG_DEBUG_FILE
+ int rv;
+ if (last_path) {
+ char *tmp = os_strdup(last_path);
+ wpa_debug_close_file();
+ rv = wpa_debug_open_file(tmp);
+ os_free(tmp);
+ } else {
+ wpa_printf(MSG_ERROR, "Last-path was not set, cannot "
+ "re-open log file.");
+ rv = -1;
+ }
+ return rv;
+#else /* CONFIG_DEBUG_FILE */
+ return 0;
+#endif /* CONFIG_DEBUG_FILE */
+}
+
+
int wpa_debug_open_file(const char *path)
{
#ifdef CONFIG_DEBUG_FILE
if (!path)
return 0;
+
+ if (last_path == NULL || os_strcmp(last_path, path) != 0) {
+ /* Save our path to enable re-open */
+ os_free(last_path);
+ last_path = os_strdup(path);
+ }
+
out_file = fopen(path, "a");
if (out_file == NULL) {
wpa_printf(MSG_ERROR, "wpa_debug_open_file: Failed to open "
@@ -299,6 +566,8 @@ void wpa_debug_close_file(void)
return;
fclose(out_file);
out_file = NULL;
+ os_free(last_path);
+ last_path = NULL;
#endif /* CONFIG_DEBUG_FILE */
}
@@ -314,12 +583,21 @@ void wpa_msg_register_cb(wpa_msg_cb_func func)
}
+static wpa_msg_get_ifname_func wpa_msg_ifname_cb = NULL;
+
+void wpa_msg_register_ifname_cb(wpa_msg_get_ifname_func func)
+{
+ wpa_msg_ifname_cb = func;
+}
+
+
void wpa_msg(void *ctx, int level, const char *fmt, ...)
{
va_list ap;
char *buf;
const int buflen = 2048;
int len;
+ char prefix[130];
buf = os_malloc(buflen);
if (buf == NULL) {
@@ -328,9 +606,19 @@ void wpa_msg(void *ctx, int level, const char *fmt, ...)
return;
}
va_start(ap, fmt);
+ prefix[0] = '\0';
+ if (wpa_msg_ifname_cb) {
+ const char *ifname = wpa_msg_ifname_cb(ctx);
+ if (ifname) {
+ int res = os_snprintf(prefix, sizeof(prefix), "%s: ",
+ ifname);
+ if (res < 0 || res >= (int) sizeof(prefix))
+ prefix[0] = '\0';
+ }
+ }
len = vsnprintf(buf, buflen, fmt, ap);
va_end(ap);
- wpa_printf(level, "%s", buf);
+ wpa_printf(level, "%s%s", prefix, buf);
if (wpa_msg_cb)
wpa_msg_cb(ctx, level, buf, len);
os_free(buf);