xref: /dflybsd-src/contrib/wpa_supplicant/src/utils/wpa_debug.c (revision 3a84a4273475ed07d0ab1c2dfeffdfedef35d9cd)
16d49e1aeSJan Lentfer /*
26d49e1aeSJan Lentfer  * wpa_supplicant/hostapd / Debug prints
33ff40c12SJohn Marino  * Copyright (c) 2002-2013, Jouni Malinen <j@w1.fi>
46d49e1aeSJan Lentfer  *
53ff40c12SJohn Marino  * This software may be distributed under the terms of the BSD license.
63ff40c12SJohn Marino  * See README for more details.
76d49e1aeSJan Lentfer  */
86d49e1aeSJan Lentfer 
96d49e1aeSJan Lentfer #include "includes.h"
106d49e1aeSJan Lentfer 
116d49e1aeSJan Lentfer #include "common.h"
126d49e1aeSJan Lentfer 
133ff40c12SJohn Marino #ifdef CONFIG_DEBUG_SYSLOG
143ff40c12SJohn Marino #include <syslog.h>
156d49e1aeSJan Lentfer 
16*a1157835SDaniel Fojt int wpa_debug_syslog = 0;
173ff40c12SJohn Marino #endif /* CONFIG_DEBUG_SYSLOG */
183ff40c12SJohn Marino 
193ff40c12SJohn Marino #ifdef CONFIG_DEBUG_LINUX_TRACING
203ff40c12SJohn Marino #include <sys/types.h>
213ff40c12SJohn Marino #include <sys/stat.h>
223ff40c12SJohn Marino #include <fcntl.h>
233ff40c12SJohn Marino #include <string.h>
243ff40c12SJohn Marino #include <stdio.h>
253ff40c12SJohn Marino 
263ff40c12SJohn Marino static FILE *wpa_debug_tracing_file = NULL;
273ff40c12SJohn Marino 
283ff40c12SJohn Marino #define WPAS_TRACE_PFX "wpas <%d>: "
293ff40c12SJohn Marino #endif /* CONFIG_DEBUG_LINUX_TRACING */
303ff40c12SJohn Marino 
313ff40c12SJohn Marino 
326d49e1aeSJan Lentfer int wpa_debug_level = MSG_INFO;
336d49e1aeSJan Lentfer int wpa_debug_show_keys = 0;
346d49e1aeSJan Lentfer int wpa_debug_timestamp = 0;
356d49e1aeSJan Lentfer 
366d49e1aeSJan Lentfer 
373ff40c12SJohn Marino #ifdef CONFIG_ANDROID_LOG
383ff40c12SJohn Marino 
393ff40c12SJohn Marino #include <android/log.h>
403ff40c12SJohn Marino 
413ff40c12SJohn Marino #ifndef ANDROID_LOG_NAME
423ff40c12SJohn Marino #define ANDROID_LOG_NAME	"wpa_supplicant"
433ff40c12SJohn Marino #endif /* ANDROID_LOG_NAME */
443ff40c12SJohn Marino 
wpa_to_android_level(int level)453ff40c12SJohn Marino static int wpa_to_android_level(int level)
463ff40c12SJohn Marino {
473ff40c12SJohn Marino 	if (level == MSG_ERROR)
483ff40c12SJohn Marino 		return ANDROID_LOG_ERROR;
493ff40c12SJohn Marino 	if (level == MSG_WARNING)
503ff40c12SJohn Marino 		return ANDROID_LOG_WARN;
513ff40c12SJohn Marino 	if (level == MSG_INFO)
523ff40c12SJohn Marino 		return ANDROID_LOG_INFO;
533ff40c12SJohn Marino 	return ANDROID_LOG_DEBUG;
543ff40c12SJohn Marino }
553ff40c12SJohn Marino 
563ff40c12SJohn Marino #endif /* CONFIG_ANDROID_LOG */
573ff40c12SJohn Marino 
586d49e1aeSJan Lentfer #ifndef CONFIG_NO_STDOUT_DEBUG
596d49e1aeSJan Lentfer 
603ff40c12SJohn Marino #ifdef CONFIG_DEBUG_FILE
61*a1157835SDaniel Fojt #include <sys/types.h>
62*a1157835SDaniel Fojt #include <sys/stat.h>
63*a1157835SDaniel Fojt #include <fcntl.h>
64*a1157835SDaniel Fojt 
653ff40c12SJohn Marino static FILE *out_file = NULL;
663ff40c12SJohn Marino #endif /* CONFIG_DEBUG_FILE */
673ff40c12SJohn Marino 
683ff40c12SJohn Marino 
wpa_debug_print_timestamp(void)696d49e1aeSJan Lentfer void wpa_debug_print_timestamp(void)
706d49e1aeSJan Lentfer {
713ff40c12SJohn Marino #ifndef CONFIG_ANDROID_LOG
726d49e1aeSJan Lentfer 	struct os_time tv;
736d49e1aeSJan Lentfer 
746d49e1aeSJan Lentfer 	if (!wpa_debug_timestamp)
756d49e1aeSJan Lentfer 		return;
766d49e1aeSJan Lentfer 
776d49e1aeSJan Lentfer 	os_get_time(&tv);
786d49e1aeSJan Lentfer #ifdef CONFIG_DEBUG_FILE
796d49e1aeSJan Lentfer 	if (out_file) {
806d49e1aeSJan Lentfer 		fprintf(out_file, "%ld.%06u: ", (long) tv.sec,
816d49e1aeSJan Lentfer 			(unsigned int) tv.usec);
826d49e1aeSJan Lentfer 	} else
836d49e1aeSJan Lentfer #endif /* CONFIG_DEBUG_FILE */
846d49e1aeSJan Lentfer 	printf("%ld.%06u: ", (long) tv.sec, (unsigned int) tv.usec);
853ff40c12SJohn Marino #endif /* CONFIG_ANDROID_LOG */
866d49e1aeSJan Lentfer }
876d49e1aeSJan Lentfer 
886d49e1aeSJan Lentfer 
893ff40c12SJohn Marino #ifdef CONFIG_DEBUG_SYSLOG
903ff40c12SJohn Marino #ifndef LOG_HOSTAPD
913ff40c12SJohn Marino #define LOG_HOSTAPD LOG_DAEMON
923ff40c12SJohn Marino #endif /* LOG_HOSTAPD */
933ff40c12SJohn Marino 
wpa_debug_open_syslog(void)943ff40c12SJohn Marino void wpa_debug_open_syslog(void)
953ff40c12SJohn Marino {
963ff40c12SJohn Marino 	openlog("wpa_supplicant", LOG_PID | LOG_NDELAY, LOG_HOSTAPD);
973ff40c12SJohn Marino 	wpa_debug_syslog++;
983ff40c12SJohn Marino }
993ff40c12SJohn Marino 
1003ff40c12SJohn Marino 
wpa_debug_close_syslog(void)1013ff40c12SJohn Marino void wpa_debug_close_syslog(void)
1023ff40c12SJohn Marino {
1033ff40c12SJohn Marino 	if (wpa_debug_syslog)
1043ff40c12SJohn Marino 		closelog();
1053ff40c12SJohn Marino }
1063ff40c12SJohn Marino 
1073ff40c12SJohn Marino 
syslog_priority(int level)1083ff40c12SJohn Marino static int syslog_priority(int level)
1093ff40c12SJohn Marino {
1103ff40c12SJohn Marino 	switch (level) {
1113ff40c12SJohn Marino 	case MSG_MSGDUMP:
1123ff40c12SJohn Marino 	case MSG_DEBUG:
1133ff40c12SJohn Marino 		return LOG_DEBUG;
1143ff40c12SJohn Marino 	case MSG_INFO:
1153ff40c12SJohn Marino 		return LOG_NOTICE;
1163ff40c12SJohn Marino 	case MSG_WARNING:
1173ff40c12SJohn Marino 		return LOG_WARNING;
1183ff40c12SJohn Marino 	case MSG_ERROR:
1193ff40c12SJohn Marino 		return LOG_ERR;
1203ff40c12SJohn Marino 	}
1213ff40c12SJohn Marino 	return LOG_INFO;
1223ff40c12SJohn Marino }
1233ff40c12SJohn Marino #endif /* CONFIG_DEBUG_SYSLOG */
1243ff40c12SJohn Marino 
1253ff40c12SJohn Marino 
1263ff40c12SJohn Marino #ifdef CONFIG_DEBUG_LINUX_TRACING
1273ff40c12SJohn Marino 
wpa_debug_open_linux_tracing(void)1283ff40c12SJohn Marino int wpa_debug_open_linux_tracing(void)
1293ff40c12SJohn Marino {
1303ff40c12SJohn Marino 	int mounts, trace_fd;
1313ff40c12SJohn Marino 	char buf[4096] = {};
1323ff40c12SJohn Marino 	ssize_t buflen;
1333ff40c12SJohn Marino 	char *line, *tmp1, *path = NULL;
1343ff40c12SJohn Marino 
1353ff40c12SJohn Marino 	mounts = open("/proc/mounts", O_RDONLY);
1363ff40c12SJohn Marino 	if (mounts < 0) {
1373ff40c12SJohn Marino 		printf("no /proc/mounts\n");
1383ff40c12SJohn Marino 		return -1;
1393ff40c12SJohn Marino 	}
1403ff40c12SJohn Marino 
1413ff40c12SJohn Marino 	buflen = read(mounts, buf, sizeof(buf) - 1);
1423ff40c12SJohn Marino 	close(mounts);
1433ff40c12SJohn Marino 	if (buflen < 0) {
1443ff40c12SJohn Marino 		printf("failed to read /proc/mounts\n");
1453ff40c12SJohn Marino 		return -1;
1463ff40c12SJohn Marino 	}
147*a1157835SDaniel Fojt 	buf[buflen] = '\0';
1483ff40c12SJohn Marino 
1493ff40c12SJohn Marino 	line = strtok_r(buf, "\n", &tmp1);
1503ff40c12SJohn Marino 	while (line) {
1513ff40c12SJohn Marino 		char *tmp2, *tmp_path, *fstype;
1523ff40c12SJohn Marino 		/* "<dev> <mountpoint> <fs type> ..." */
1533ff40c12SJohn Marino 		strtok_r(line, " ", &tmp2);
1543ff40c12SJohn Marino 		tmp_path = strtok_r(NULL, " ", &tmp2);
1553ff40c12SJohn Marino 		fstype = strtok_r(NULL, " ", &tmp2);
156*a1157835SDaniel Fojt 		if (fstype && strcmp(fstype, "debugfs") == 0) {
1573ff40c12SJohn Marino 			path = tmp_path;
1583ff40c12SJohn Marino 			break;
1593ff40c12SJohn Marino 		}
1603ff40c12SJohn Marino 
1613ff40c12SJohn Marino 		line = strtok_r(NULL, "\n", &tmp1);
1623ff40c12SJohn Marino 	}
1633ff40c12SJohn Marino 
1643ff40c12SJohn Marino 	if (path == NULL) {
1653ff40c12SJohn Marino 		printf("debugfs mountpoint not found\n");
1663ff40c12SJohn Marino 		return -1;
1673ff40c12SJohn Marino 	}
1683ff40c12SJohn Marino 
1693ff40c12SJohn Marino 	snprintf(buf, sizeof(buf) - 1, "%s/tracing/trace_marker", path);
1703ff40c12SJohn Marino 
1713ff40c12SJohn Marino 	trace_fd = open(buf, O_WRONLY);
1723ff40c12SJohn Marino 	if (trace_fd < 0) {
1733ff40c12SJohn Marino 		printf("failed to open trace_marker file\n");
1743ff40c12SJohn Marino 		return -1;
1753ff40c12SJohn Marino 	}
1763ff40c12SJohn Marino 	wpa_debug_tracing_file = fdopen(trace_fd, "w");
1773ff40c12SJohn Marino 	if (wpa_debug_tracing_file == NULL) {
1783ff40c12SJohn Marino 		close(trace_fd);
1793ff40c12SJohn Marino 		printf("failed to fdopen()\n");
1803ff40c12SJohn Marino 		return -1;
1813ff40c12SJohn Marino 	}
1823ff40c12SJohn Marino 
1833ff40c12SJohn Marino 	return 0;
1843ff40c12SJohn Marino }
1853ff40c12SJohn Marino 
1863ff40c12SJohn Marino 
wpa_debug_close_linux_tracing(void)1873ff40c12SJohn Marino void wpa_debug_close_linux_tracing(void)
1883ff40c12SJohn Marino {
1893ff40c12SJohn Marino 	if (wpa_debug_tracing_file == NULL)
1903ff40c12SJohn Marino 		return;
1913ff40c12SJohn Marino 	fclose(wpa_debug_tracing_file);
1923ff40c12SJohn Marino 	wpa_debug_tracing_file = NULL;
1933ff40c12SJohn Marino }
1943ff40c12SJohn Marino 
1953ff40c12SJohn Marino #endif /* CONFIG_DEBUG_LINUX_TRACING */
1963ff40c12SJohn Marino 
1973ff40c12SJohn Marino 
1986d49e1aeSJan Lentfer /**
1996d49e1aeSJan Lentfer  * wpa_printf - conditional printf
2006d49e1aeSJan Lentfer  * @level: priority level (MSG_*) of the message
2016d49e1aeSJan Lentfer  * @fmt: printf format string, followed by optional arguments
2026d49e1aeSJan Lentfer  *
2036d49e1aeSJan Lentfer  * This function is used to print conditional debugging and error messages. The
2046d49e1aeSJan Lentfer  * output may be directed to stdout, stderr, and/or syslog based on
2056d49e1aeSJan Lentfer  * configuration.
2066d49e1aeSJan Lentfer  *
2076d49e1aeSJan Lentfer  * Note: New line '\n' is added to the end of the text when printing to stdout.
2086d49e1aeSJan Lentfer  */
wpa_printf(int level,const char * fmt,...)2096d49e1aeSJan Lentfer void wpa_printf(int level, const char *fmt, ...)
2106d49e1aeSJan Lentfer {
2116d49e1aeSJan Lentfer 	va_list ap;
2126d49e1aeSJan Lentfer 
2136d49e1aeSJan Lentfer 	va_start(ap, fmt);
2146d49e1aeSJan Lentfer 	if (level >= wpa_debug_level) {
2153ff40c12SJohn Marino #ifdef CONFIG_ANDROID_LOG
2163ff40c12SJohn Marino 		__android_log_vprint(wpa_to_android_level(level),
2173ff40c12SJohn Marino 				     ANDROID_LOG_NAME, fmt, ap);
2183ff40c12SJohn Marino #else /* CONFIG_ANDROID_LOG */
2193ff40c12SJohn Marino #ifdef CONFIG_DEBUG_SYSLOG
2203ff40c12SJohn Marino 		if (wpa_debug_syslog) {
2213ff40c12SJohn Marino 			vsyslog(syslog_priority(level), fmt, ap);
2223ff40c12SJohn Marino 		} else {
2233ff40c12SJohn Marino #endif /* CONFIG_DEBUG_SYSLOG */
2246d49e1aeSJan Lentfer 		wpa_debug_print_timestamp();
2256d49e1aeSJan Lentfer #ifdef CONFIG_DEBUG_FILE
2266d49e1aeSJan Lentfer 		if (out_file) {
2276d49e1aeSJan Lentfer 			vfprintf(out_file, fmt, ap);
2286d49e1aeSJan Lentfer 			fprintf(out_file, "\n");
2296d49e1aeSJan Lentfer 		} else {
2306d49e1aeSJan Lentfer #endif /* CONFIG_DEBUG_FILE */
2316d49e1aeSJan Lentfer 		vprintf(fmt, ap);
2326d49e1aeSJan Lentfer 		printf("\n");
2336d49e1aeSJan Lentfer #ifdef CONFIG_DEBUG_FILE
2346d49e1aeSJan Lentfer 		}
2356d49e1aeSJan Lentfer #endif /* CONFIG_DEBUG_FILE */
2363ff40c12SJohn Marino #ifdef CONFIG_DEBUG_SYSLOG
2373ff40c12SJohn Marino 		}
2383ff40c12SJohn Marino #endif /* CONFIG_DEBUG_SYSLOG */
2393ff40c12SJohn Marino #endif /* CONFIG_ANDROID_LOG */
2406d49e1aeSJan Lentfer 	}
2416d49e1aeSJan Lentfer 	va_end(ap);
2423ff40c12SJohn Marino 
2433ff40c12SJohn Marino #ifdef CONFIG_DEBUG_LINUX_TRACING
2443ff40c12SJohn Marino 	if (wpa_debug_tracing_file != NULL) {
2453ff40c12SJohn Marino 		va_start(ap, fmt);
2463ff40c12SJohn Marino 		fprintf(wpa_debug_tracing_file, WPAS_TRACE_PFX, level);
2473ff40c12SJohn Marino 		vfprintf(wpa_debug_tracing_file, fmt, ap);
2483ff40c12SJohn Marino 		fprintf(wpa_debug_tracing_file, "\n");
2493ff40c12SJohn Marino 		fflush(wpa_debug_tracing_file);
2503ff40c12SJohn Marino 		va_end(ap);
2513ff40c12SJohn Marino 	}
2523ff40c12SJohn Marino #endif /* CONFIG_DEBUG_LINUX_TRACING */
2536d49e1aeSJan Lentfer }
2546d49e1aeSJan Lentfer 
2556d49e1aeSJan Lentfer 
_wpa_hexdump(int level,const char * title,const u8 * buf,size_t len,int show)2566d49e1aeSJan Lentfer static void _wpa_hexdump(int level, const char *title, const u8 *buf,
2576d49e1aeSJan Lentfer 			 size_t len, int show)
2586d49e1aeSJan Lentfer {
2596d49e1aeSJan Lentfer 	size_t i;
2603ff40c12SJohn Marino 
2613ff40c12SJohn Marino #ifdef CONFIG_DEBUG_LINUX_TRACING
2623ff40c12SJohn Marino 	if (wpa_debug_tracing_file != NULL) {
2633ff40c12SJohn Marino 		fprintf(wpa_debug_tracing_file,
2643ff40c12SJohn Marino 			WPAS_TRACE_PFX "%s - hexdump(len=%lu):",
2653ff40c12SJohn Marino 			level, title, (unsigned long) len);
2663ff40c12SJohn Marino 		if (buf == NULL) {
2673ff40c12SJohn Marino 			fprintf(wpa_debug_tracing_file, " [NULL]\n");
2683ff40c12SJohn Marino 		} else if (!show) {
2693ff40c12SJohn Marino 			fprintf(wpa_debug_tracing_file, " [REMOVED]\n");
2703ff40c12SJohn Marino 		} else {
2713ff40c12SJohn Marino 			for (i = 0; i < len; i++)
2723ff40c12SJohn Marino 				fprintf(wpa_debug_tracing_file,
2733ff40c12SJohn Marino 					" %02x", buf[i]);
2743ff40c12SJohn Marino 		}
2753ff40c12SJohn Marino 		fflush(wpa_debug_tracing_file);
2763ff40c12SJohn Marino 	}
2773ff40c12SJohn Marino #endif /* CONFIG_DEBUG_LINUX_TRACING */
2783ff40c12SJohn Marino 
2796d49e1aeSJan Lentfer 	if (level < wpa_debug_level)
2806d49e1aeSJan Lentfer 		return;
2813ff40c12SJohn Marino #ifdef CONFIG_ANDROID_LOG
2823ff40c12SJohn Marino 	{
2833ff40c12SJohn Marino 		const char *display;
2843ff40c12SJohn Marino 		char *strbuf = NULL;
2853ff40c12SJohn Marino 		size_t slen = len;
2863ff40c12SJohn Marino 		if (buf == NULL) {
2873ff40c12SJohn Marino 			display = " [NULL]";
2883ff40c12SJohn Marino 		} else if (len == 0) {
2893ff40c12SJohn Marino 			display = "";
2903ff40c12SJohn Marino 		} else if (show && len) {
2913ff40c12SJohn Marino 			/* Limit debug message length for Android log */
2923ff40c12SJohn Marino 			if (slen > 32)
2933ff40c12SJohn Marino 				slen = 32;
2943ff40c12SJohn Marino 			strbuf = os_malloc(1 + 3 * slen);
2953ff40c12SJohn Marino 			if (strbuf == NULL) {
2963ff40c12SJohn Marino 				wpa_printf(MSG_ERROR, "wpa_hexdump: Failed to "
2973ff40c12SJohn Marino 					   "allocate message buffer");
2983ff40c12SJohn Marino 				return;
2993ff40c12SJohn Marino 			}
3003ff40c12SJohn Marino 
3013ff40c12SJohn Marino 			for (i = 0; i < slen; i++)
3023ff40c12SJohn Marino 				os_snprintf(&strbuf[i * 3], 4, " %02x",
3033ff40c12SJohn Marino 					    buf[i]);
3043ff40c12SJohn Marino 
3053ff40c12SJohn Marino 			display = strbuf;
3063ff40c12SJohn Marino 		} else {
3073ff40c12SJohn Marino 			display = " [REMOVED]";
3083ff40c12SJohn Marino 		}
3093ff40c12SJohn Marino 
3103ff40c12SJohn Marino 		__android_log_print(wpa_to_android_level(level),
3113ff40c12SJohn Marino 				    ANDROID_LOG_NAME,
3123ff40c12SJohn Marino 				    "%s - hexdump(len=%lu):%s%s",
3133ff40c12SJohn Marino 				    title, (long unsigned int) len, display,
3143ff40c12SJohn Marino 				    len > slen ? " ..." : "");
315*a1157835SDaniel Fojt 		bin_clear_free(strbuf, 1 + 3 * slen);
3163ff40c12SJohn Marino 		return;
3173ff40c12SJohn Marino 	}
3183ff40c12SJohn Marino #else /* CONFIG_ANDROID_LOG */
3193ff40c12SJohn Marino #ifdef CONFIG_DEBUG_SYSLOG
3203ff40c12SJohn Marino 	if (wpa_debug_syslog) {
3213ff40c12SJohn Marino 		const char *display;
3223ff40c12SJohn Marino 		char *strbuf = NULL;
3233ff40c12SJohn Marino 
3243ff40c12SJohn Marino 		if (buf == NULL) {
3253ff40c12SJohn Marino 			display = " [NULL]";
3263ff40c12SJohn Marino 		} else if (len == 0) {
3273ff40c12SJohn Marino 			display = "";
3283ff40c12SJohn Marino 		} else if (show && len) {
3293ff40c12SJohn Marino 			strbuf = os_malloc(1 + 3 * len);
3303ff40c12SJohn Marino 			if (strbuf == NULL) {
3313ff40c12SJohn Marino 				wpa_printf(MSG_ERROR, "wpa_hexdump: Failed to "
3323ff40c12SJohn Marino 					   "allocate message buffer");
3333ff40c12SJohn Marino 				return;
3343ff40c12SJohn Marino 			}
3353ff40c12SJohn Marino 
3363ff40c12SJohn Marino 			for (i = 0; i < len; i++)
3373ff40c12SJohn Marino 				os_snprintf(&strbuf[i * 3], 4, " %02x",
3383ff40c12SJohn Marino 					    buf[i]);
3393ff40c12SJohn Marino 
3403ff40c12SJohn Marino 			display = strbuf;
3413ff40c12SJohn Marino 		} else {
3423ff40c12SJohn Marino 			display = " [REMOVED]";
3433ff40c12SJohn Marino 		}
3443ff40c12SJohn Marino 
3453ff40c12SJohn Marino 		syslog(syslog_priority(level), "%s - hexdump(len=%lu):%s",
3463ff40c12SJohn Marino 		       title, (unsigned long) len, display);
347*a1157835SDaniel Fojt 		bin_clear_free(strbuf, 1 + 3 * len);
3483ff40c12SJohn Marino 		return;
3493ff40c12SJohn Marino 	}
3503ff40c12SJohn Marino #endif /* CONFIG_DEBUG_SYSLOG */
3516d49e1aeSJan Lentfer 	wpa_debug_print_timestamp();
3526d49e1aeSJan Lentfer #ifdef CONFIG_DEBUG_FILE
3536d49e1aeSJan Lentfer 	if (out_file) {
3546d49e1aeSJan Lentfer 		fprintf(out_file, "%s - hexdump(len=%lu):",
3556d49e1aeSJan Lentfer 			title, (unsigned long) len);
3566d49e1aeSJan Lentfer 		if (buf == NULL) {
3576d49e1aeSJan Lentfer 			fprintf(out_file, " [NULL]");
3586d49e1aeSJan Lentfer 		} else if (show) {
3596d49e1aeSJan Lentfer 			for (i = 0; i < len; i++)
3606d49e1aeSJan Lentfer 				fprintf(out_file, " %02x", buf[i]);
3616d49e1aeSJan Lentfer 		} else {
3626d49e1aeSJan Lentfer 			fprintf(out_file, " [REMOVED]");
3636d49e1aeSJan Lentfer 		}
3646d49e1aeSJan Lentfer 		fprintf(out_file, "\n");
3656d49e1aeSJan Lentfer 	} else {
3666d49e1aeSJan Lentfer #endif /* CONFIG_DEBUG_FILE */
3676d49e1aeSJan Lentfer 	printf("%s - hexdump(len=%lu):", title, (unsigned long) len);
3686d49e1aeSJan Lentfer 	if (buf == NULL) {
3696d49e1aeSJan Lentfer 		printf(" [NULL]");
3706d49e1aeSJan Lentfer 	} else if (show) {
3716d49e1aeSJan Lentfer 		for (i = 0; i < len; i++)
3726d49e1aeSJan Lentfer 			printf(" %02x", buf[i]);
3736d49e1aeSJan Lentfer 	} else {
3746d49e1aeSJan Lentfer 		printf(" [REMOVED]");
3756d49e1aeSJan Lentfer 	}
3766d49e1aeSJan Lentfer 	printf("\n");
3776d49e1aeSJan Lentfer #ifdef CONFIG_DEBUG_FILE
3786d49e1aeSJan Lentfer 	}
3796d49e1aeSJan Lentfer #endif /* CONFIG_DEBUG_FILE */
3803ff40c12SJohn Marino #endif /* CONFIG_ANDROID_LOG */
3816d49e1aeSJan Lentfer }
3826d49e1aeSJan Lentfer 
wpa_hexdump(int level,const char * title,const void * buf,size_t len)3833ff40c12SJohn Marino void wpa_hexdump(int level, const char *title, const void *buf, size_t len)
3846d49e1aeSJan Lentfer {
3856d49e1aeSJan Lentfer 	_wpa_hexdump(level, title, buf, len, 1);
3866d49e1aeSJan Lentfer }
3876d49e1aeSJan Lentfer 
3886d49e1aeSJan Lentfer 
wpa_hexdump_key(int level,const char * title,const void * buf,size_t len)3893ff40c12SJohn Marino void wpa_hexdump_key(int level, const char *title, const void *buf, size_t len)
3906d49e1aeSJan Lentfer {
3916d49e1aeSJan Lentfer 	_wpa_hexdump(level, title, buf, len, wpa_debug_show_keys);
3926d49e1aeSJan Lentfer }
3936d49e1aeSJan Lentfer 
3946d49e1aeSJan Lentfer 
_wpa_hexdump_ascii(int level,const char * title,const void * buf,size_t len,int show)3953ff40c12SJohn Marino static void _wpa_hexdump_ascii(int level, const char *title, const void *buf,
3966d49e1aeSJan Lentfer 			       size_t len, int show)
3976d49e1aeSJan Lentfer {
3986d49e1aeSJan Lentfer 	size_t i, llen;
3996d49e1aeSJan Lentfer 	const u8 *pos = buf;
4006d49e1aeSJan Lentfer 	const size_t line_len = 16;
4016d49e1aeSJan Lentfer 
4023ff40c12SJohn Marino #ifdef CONFIG_DEBUG_LINUX_TRACING
4033ff40c12SJohn Marino 	if (wpa_debug_tracing_file != NULL) {
4043ff40c12SJohn Marino 		fprintf(wpa_debug_tracing_file,
4053ff40c12SJohn Marino 			WPAS_TRACE_PFX "%s - hexdump_ascii(len=%lu):",
4063ff40c12SJohn Marino 			level, title, (unsigned long) len);
4073ff40c12SJohn Marino 		if (buf == NULL) {
4083ff40c12SJohn Marino 			fprintf(wpa_debug_tracing_file, " [NULL]\n");
4093ff40c12SJohn Marino 		} else if (!show) {
4103ff40c12SJohn Marino 			fprintf(wpa_debug_tracing_file, " [REMOVED]\n");
4113ff40c12SJohn Marino 		} else {
4123ff40c12SJohn Marino 			/* can do ascii processing in userspace */
4133ff40c12SJohn Marino 			for (i = 0; i < len; i++)
4143ff40c12SJohn Marino 				fprintf(wpa_debug_tracing_file,
4153ff40c12SJohn Marino 					" %02x", pos[i]);
4163ff40c12SJohn Marino 		}
4173ff40c12SJohn Marino 		fflush(wpa_debug_tracing_file);
4183ff40c12SJohn Marino 	}
4193ff40c12SJohn Marino #endif /* CONFIG_DEBUG_LINUX_TRACING */
4203ff40c12SJohn Marino 
4216d49e1aeSJan Lentfer 	if (level < wpa_debug_level)
4226d49e1aeSJan Lentfer 		return;
4233ff40c12SJohn Marino #ifdef CONFIG_ANDROID_LOG
4243ff40c12SJohn Marino 	_wpa_hexdump(level, title, buf, len, show);
4253ff40c12SJohn Marino #else /* CONFIG_ANDROID_LOG */
426*a1157835SDaniel Fojt #ifdef CONFIG_DEBUG_SYSLOG
427*a1157835SDaniel Fojt 	if (wpa_debug_syslog) {
428*a1157835SDaniel Fojt 		_wpa_hexdump(level, title, buf, len, show);
429*a1157835SDaniel Fojt 		return;
430*a1157835SDaniel Fojt 	}
431*a1157835SDaniel Fojt #endif /* CONFIG_DEBUG_SYSLOG */
4326d49e1aeSJan Lentfer 	wpa_debug_print_timestamp();
4336d49e1aeSJan Lentfer #ifdef CONFIG_DEBUG_FILE
4346d49e1aeSJan Lentfer 	if (out_file) {
4356d49e1aeSJan Lentfer 		if (!show) {
4366d49e1aeSJan Lentfer 			fprintf(out_file,
4376d49e1aeSJan Lentfer 				"%s - hexdump_ascii(len=%lu): [REMOVED]\n",
4386d49e1aeSJan Lentfer 				title, (unsigned long) len);
4396d49e1aeSJan Lentfer 			return;
4406d49e1aeSJan Lentfer 		}
4416d49e1aeSJan Lentfer 		if (buf == NULL) {
4426d49e1aeSJan Lentfer 			fprintf(out_file,
4436d49e1aeSJan Lentfer 				"%s - hexdump_ascii(len=%lu): [NULL]\n",
4446d49e1aeSJan Lentfer 				title, (unsigned long) len);
4456d49e1aeSJan Lentfer 			return;
4466d49e1aeSJan Lentfer 		}
4476d49e1aeSJan Lentfer 		fprintf(out_file, "%s - hexdump_ascii(len=%lu):\n",
4486d49e1aeSJan Lentfer 			title, (unsigned long) len);
4496d49e1aeSJan Lentfer 		while (len) {
4506d49e1aeSJan Lentfer 			llen = len > line_len ? line_len : len;
4516d49e1aeSJan Lentfer 			fprintf(out_file, "    ");
4526d49e1aeSJan Lentfer 			for (i = 0; i < llen; i++)
4536d49e1aeSJan Lentfer 				fprintf(out_file, " %02x", pos[i]);
4546d49e1aeSJan Lentfer 			for (i = llen; i < line_len; i++)
4556d49e1aeSJan Lentfer 				fprintf(out_file, "   ");
4566d49e1aeSJan Lentfer 			fprintf(out_file, "   ");
4576d49e1aeSJan Lentfer 			for (i = 0; i < llen; i++) {
4586d49e1aeSJan Lentfer 				if (isprint(pos[i]))
4596d49e1aeSJan Lentfer 					fprintf(out_file, "%c", pos[i]);
4606d49e1aeSJan Lentfer 				else
4616d49e1aeSJan Lentfer 					fprintf(out_file, "_");
4626d49e1aeSJan Lentfer 			}
4636d49e1aeSJan Lentfer 			for (i = llen; i < line_len; i++)
4646d49e1aeSJan Lentfer 				fprintf(out_file, " ");
4656d49e1aeSJan Lentfer 			fprintf(out_file, "\n");
4666d49e1aeSJan Lentfer 			pos += llen;
4676d49e1aeSJan Lentfer 			len -= llen;
4686d49e1aeSJan Lentfer 		}
4696d49e1aeSJan Lentfer 	} else {
4706d49e1aeSJan Lentfer #endif /* CONFIG_DEBUG_FILE */
4716d49e1aeSJan Lentfer 	if (!show) {
4726d49e1aeSJan Lentfer 		printf("%s - hexdump_ascii(len=%lu): [REMOVED]\n",
4736d49e1aeSJan Lentfer 		       title, (unsigned long) len);
4746d49e1aeSJan Lentfer 		return;
4756d49e1aeSJan Lentfer 	}
4766d49e1aeSJan Lentfer 	if (buf == NULL) {
4776d49e1aeSJan Lentfer 		printf("%s - hexdump_ascii(len=%lu): [NULL]\n",
4786d49e1aeSJan Lentfer 		       title, (unsigned long) len);
4796d49e1aeSJan Lentfer 		return;
4806d49e1aeSJan Lentfer 	}
4816d49e1aeSJan Lentfer 	printf("%s - hexdump_ascii(len=%lu):\n", title, (unsigned long) len);
4826d49e1aeSJan Lentfer 	while (len) {
4836d49e1aeSJan Lentfer 		llen = len > line_len ? line_len : len;
4846d49e1aeSJan Lentfer 		printf("    ");
4856d49e1aeSJan Lentfer 		for (i = 0; i < llen; i++)
4866d49e1aeSJan Lentfer 			printf(" %02x", pos[i]);
4876d49e1aeSJan Lentfer 		for (i = llen; i < line_len; i++)
4886d49e1aeSJan Lentfer 			printf("   ");
4896d49e1aeSJan Lentfer 		printf("   ");
4906d49e1aeSJan Lentfer 		for (i = 0; i < llen; i++) {
4916d49e1aeSJan Lentfer 			if (isprint(pos[i]))
4926d49e1aeSJan Lentfer 				printf("%c", pos[i]);
4936d49e1aeSJan Lentfer 			else
4946d49e1aeSJan Lentfer 				printf("_");
4956d49e1aeSJan Lentfer 		}
4966d49e1aeSJan Lentfer 		for (i = llen; i < line_len; i++)
4976d49e1aeSJan Lentfer 			printf(" ");
4986d49e1aeSJan Lentfer 		printf("\n");
4996d49e1aeSJan Lentfer 		pos += llen;
5006d49e1aeSJan Lentfer 		len -= llen;
5016d49e1aeSJan Lentfer 	}
5026d49e1aeSJan Lentfer #ifdef CONFIG_DEBUG_FILE
5036d49e1aeSJan Lentfer 	}
5046d49e1aeSJan Lentfer #endif /* CONFIG_DEBUG_FILE */
5053ff40c12SJohn Marino #endif /* CONFIG_ANDROID_LOG */
5066d49e1aeSJan Lentfer }
5076d49e1aeSJan Lentfer 
5086d49e1aeSJan Lentfer 
wpa_hexdump_ascii(int level,const char * title,const void * buf,size_t len)5093ff40c12SJohn Marino void wpa_hexdump_ascii(int level, const char *title, const void *buf,
5103ff40c12SJohn Marino 		       size_t len)
5116d49e1aeSJan Lentfer {
5126d49e1aeSJan Lentfer 	_wpa_hexdump_ascii(level, title, buf, len, 1);
5136d49e1aeSJan Lentfer }
5146d49e1aeSJan Lentfer 
5156d49e1aeSJan Lentfer 
wpa_hexdump_ascii_key(int level,const char * title,const void * buf,size_t len)5163ff40c12SJohn Marino void wpa_hexdump_ascii_key(int level, const char *title, const void *buf,
5176d49e1aeSJan Lentfer 			   size_t len)
5186d49e1aeSJan Lentfer {
5196d49e1aeSJan Lentfer 	_wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys);
5206d49e1aeSJan Lentfer }
5216d49e1aeSJan Lentfer 
5226d49e1aeSJan Lentfer 
5233ff40c12SJohn Marino #ifdef CONFIG_DEBUG_FILE
5243ff40c12SJohn Marino static char *last_path = NULL;
5253ff40c12SJohn Marino #endif /* CONFIG_DEBUG_FILE */
5263ff40c12SJohn Marino 
wpa_debug_reopen_file(void)5273ff40c12SJohn Marino int wpa_debug_reopen_file(void)
5283ff40c12SJohn Marino {
5293ff40c12SJohn Marino #ifdef CONFIG_DEBUG_FILE
5303ff40c12SJohn Marino 	int rv;
531*a1157835SDaniel Fojt 	char *tmp;
532*a1157835SDaniel Fojt 
533*a1157835SDaniel Fojt 	if (!last_path)
534*a1157835SDaniel Fojt 		return 0; /* logfile not used */
535*a1157835SDaniel Fojt 
536*a1157835SDaniel Fojt 	tmp = os_strdup(last_path);
537*a1157835SDaniel Fojt 	if (!tmp)
538*a1157835SDaniel Fojt 		return -1;
539*a1157835SDaniel Fojt 
5403ff40c12SJohn Marino 	wpa_debug_close_file();
5413ff40c12SJohn Marino 	rv = wpa_debug_open_file(tmp);
5423ff40c12SJohn Marino 	os_free(tmp);
5433ff40c12SJohn Marino 	return rv;
5443ff40c12SJohn Marino #else /* CONFIG_DEBUG_FILE */
5453ff40c12SJohn Marino 	return 0;
5463ff40c12SJohn Marino #endif /* CONFIG_DEBUG_FILE */
5473ff40c12SJohn Marino }
5483ff40c12SJohn Marino 
5493ff40c12SJohn Marino 
wpa_debug_open_file(const char * path)5506d49e1aeSJan Lentfer int wpa_debug_open_file(const char *path)
5516d49e1aeSJan Lentfer {
5526d49e1aeSJan Lentfer #ifdef CONFIG_DEBUG_FILE
553*a1157835SDaniel Fojt 	int out_fd;
554*a1157835SDaniel Fojt 
5556d49e1aeSJan Lentfer 	if (!path)
5566d49e1aeSJan Lentfer 		return 0;
5573ff40c12SJohn Marino 
5583ff40c12SJohn Marino 	if (last_path == NULL || os_strcmp(last_path, path) != 0) {
5593ff40c12SJohn Marino 		/* Save our path to enable re-open */
5603ff40c12SJohn Marino 		os_free(last_path);
5613ff40c12SJohn Marino 		last_path = os_strdup(path);
5623ff40c12SJohn Marino 	}
5633ff40c12SJohn Marino 
564*a1157835SDaniel Fojt 	out_fd = open(path, O_CREAT | O_APPEND | O_WRONLY,
565*a1157835SDaniel Fojt 		      S_IRUSR | S_IWUSR | S_IRGRP);
566*a1157835SDaniel Fojt 	if (out_fd < 0) {
567*a1157835SDaniel Fojt 		wpa_printf(MSG_ERROR,
568*a1157835SDaniel Fojt 			   "%s: Failed to open output file descriptor, using standard output",
569*a1157835SDaniel Fojt 			   __func__);
570*a1157835SDaniel Fojt 		return -1;
571*a1157835SDaniel Fojt 	}
572*a1157835SDaniel Fojt 
573*a1157835SDaniel Fojt #ifdef __linux__
574*a1157835SDaniel Fojt 	if (fcntl(out_fd, F_SETFD, FD_CLOEXEC) < 0) {
575*a1157835SDaniel Fojt 		wpa_printf(MSG_DEBUG,
576*a1157835SDaniel Fojt 			   "%s: Failed to set FD_CLOEXEC - continue without: %s",
577*a1157835SDaniel Fojt 			   __func__, strerror(errno));
578*a1157835SDaniel Fojt 	}
579*a1157835SDaniel Fojt #endif /* __linux__ */
580*a1157835SDaniel Fojt 
581*a1157835SDaniel Fojt 	out_file = fdopen(out_fd, "a");
5826d49e1aeSJan Lentfer 	if (out_file == NULL) {
5836d49e1aeSJan Lentfer 		wpa_printf(MSG_ERROR, "wpa_debug_open_file: Failed to open "
5846d49e1aeSJan Lentfer 			   "output file, using standard output");
585*a1157835SDaniel Fojt 		close(out_fd);
5866d49e1aeSJan Lentfer 		return -1;
5876d49e1aeSJan Lentfer 	}
5886d49e1aeSJan Lentfer #ifndef _WIN32
5896d49e1aeSJan Lentfer 	setvbuf(out_file, NULL, _IOLBF, 0);
5906d49e1aeSJan Lentfer #endif /* _WIN32 */
591*a1157835SDaniel Fojt #else /* CONFIG_DEBUG_FILE */
592*a1157835SDaniel Fojt 	(void)path;
5936d49e1aeSJan Lentfer #endif /* CONFIG_DEBUG_FILE */
5946d49e1aeSJan Lentfer 	return 0;
5956d49e1aeSJan Lentfer }
5966d49e1aeSJan Lentfer 
5976d49e1aeSJan Lentfer 
wpa_debug_close_file(void)5986d49e1aeSJan Lentfer void wpa_debug_close_file(void)
5996d49e1aeSJan Lentfer {
6006d49e1aeSJan Lentfer #ifdef CONFIG_DEBUG_FILE
6016d49e1aeSJan Lentfer 	if (!out_file)
6026d49e1aeSJan Lentfer 		return;
6036d49e1aeSJan Lentfer 	fclose(out_file);
6046d49e1aeSJan Lentfer 	out_file = NULL;
6053ff40c12SJohn Marino 	os_free(last_path);
6063ff40c12SJohn Marino 	last_path = NULL;
6076d49e1aeSJan Lentfer #endif /* CONFIG_DEBUG_FILE */
6086d49e1aeSJan Lentfer }
6096d49e1aeSJan Lentfer 
610*a1157835SDaniel Fojt 
wpa_debug_setup_stdout(void)611*a1157835SDaniel Fojt void wpa_debug_setup_stdout(void)
612*a1157835SDaniel Fojt {
613*a1157835SDaniel Fojt #ifndef _WIN32
614*a1157835SDaniel Fojt 	setvbuf(stdout, NULL, _IOLBF, 0);
615*a1157835SDaniel Fojt #endif /* _WIN32 */
616*a1157835SDaniel Fojt }
617*a1157835SDaniel Fojt 
6186d49e1aeSJan Lentfer #endif /* CONFIG_NO_STDOUT_DEBUG */
6196d49e1aeSJan Lentfer 
6206d49e1aeSJan Lentfer 
6216d49e1aeSJan Lentfer #ifndef CONFIG_NO_WPA_MSG
6226d49e1aeSJan Lentfer static wpa_msg_cb_func wpa_msg_cb = NULL;
6236d49e1aeSJan Lentfer 
wpa_msg_register_cb(wpa_msg_cb_func func)6246d49e1aeSJan Lentfer void wpa_msg_register_cb(wpa_msg_cb_func func)
6256d49e1aeSJan Lentfer {
6266d49e1aeSJan Lentfer 	wpa_msg_cb = func;
6276d49e1aeSJan Lentfer }
6286d49e1aeSJan Lentfer 
6296d49e1aeSJan Lentfer 
6303ff40c12SJohn Marino static wpa_msg_get_ifname_func wpa_msg_ifname_cb = NULL;
6313ff40c12SJohn Marino 
wpa_msg_register_ifname_cb(wpa_msg_get_ifname_func func)6323ff40c12SJohn Marino void wpa_msg_register_ifname_cb(wpa_msg_get_ifname_func func)
6333ff40c12SJohn Marino {
6343ff40c12SJohn Marino 	wpa_msg_ifname_cb = func;
6353ff40c12SJohn Marino }
6363ff40c12SJohn Marino 
6373ff40c12SJohn Marino 
wpa_msg(void * ctx,int level,const char * fmt,...)6386d49e1aeSJan Lentfer void wpa_msg(void *ctx, int level, const char *fmt, ...)
6396d49e1aeSJan Lentfer {
6406d49e1aeSJan Lentfer 	va_list ap;
6416d49e1aeSJan Lentfer 	char *buf;
642*a1157835SDaniel Fojt 	int buflen;
6436d49e1aeSJan Lentfer 	int len;
6443ff40c12SJohn Marino 	char prefix[130];
6456d49e1aeSJan Lentfer 
646*a1157835SDaniel Fojt 	va_start(ap, fmt);
647*a1157835SDaniel Fojt 	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
648*a1157835SDaniel Fojt 	va_end(ap);
649*a1157835SDaniel Fojt 
6506d49e1aeSJan Lentfer 	buf = os_malloc(buflen);
6516d49e1aeSJan Lentfer 	if (buf == NULL) {
6526d49e1aeSJan Lentfer 		wpa_printf(MSG_ERROR, "wpa_msg: Failed to allocate message "
6536d49e1aeSJan Lentfer 			   "buffer");
6546d49e1aeSJan Lentfer 		return;
6556d49e1aeSJan Lentfer 	}
6566d49e1aeSJan Lentfer 	va_start(ap, fmt);
6573ff40c12SJohn Marino 	prefix[0] = '\0';
6583ff40c12SJohn Marino 	if (wpa_msg_ifname_cb) {
6593ff40c12SJohn Marino 		const char *ifname = wpa_msg_ifname_cb(ctx);
6603ff40c12SJohn Marino 		if (ifname) {
6613ff40c12SJohn Marino 			int res = os_snprintf(prefix, sizeof(prefix), "%s: ",
6623ff40c12SJohn Marino 					      ifname);
663*a1157835SDaniel Fojt 			if (os_snprintf_error(sizeof(prefix), res))
6643ff40c12SJohn Marino 				prefix[0] = '\0';
6653ff40c12SJohn Marino 		}
6663ff40c12SJohn Marino 	}
6676d49e1aeSJan Lentfer 	len = vsnprintf(buf, buflen, fmt, ap);
6686d49e1aeSJan Lentfer 	va_end(ap);
6693ff40c12SJohn Marino 	wpa_printf(level, "%s%s", prefix, buf);
6706d49e1aeSJan Lentfer 	if (wpa_msg_cb)
671*a1157835SDaniel Fojt 		wpa_msg_cb(ctx, level, WPA_MSG_PER_INTERFACE, buf, len);
672*a1157835SDaniel Fojt 	bin_clear_free(buf, buflen);
6736d49e1aeSJan Lentfer }
6746d49e1aeSJan Lentfer 
6756d49e1aeSJan Lentfer 
wpa_msg_ctrl(void * ctx,int level,const char * fmt,...)6766d49e1aeSJan Lentfer void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...)
6776d49e1aeSJan Lentfer {
6786d49e1aeSJan Lentfer 	va_list ap;
6796d49e1aeSJan Lentfer 	char *buf;
680*a1157835SDaniel Fojt 	int buflen;
6816d49e1aeSJan Lentfer 	int len;
6826d49e1aeSJan Lentfer 
6836d49e1aeSJan Lentfer 	if (!wpa_msg_cb)
6846d49e1aeSJan Lentfer 		return;
6856d49e1aeSJan Lentfer 
686*a1157835SDaniel Fojt 	va_start(ap, fmt);
687*a1157835SDaniel Fojt 	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
688*a1157835SDaniel Fojt 	va_end(ap);
689*a1157835SDaniel Fojt 
6906d49e1aeSJan Lentfer 	buf = os_malloc(buflen);
6916d49e1aeSJan Lentfer 	if (buf == NULL) {
6926d49e1aeSJan Lentfer 		wpa_printf(MSG_ERROR, "wpa_msg_ctrl: Failed to allocate "
6936d49e1aeSJan Lentfer 			   "message buffer");
6946d49e1aeSJan Lentfer 		return;
6956d49e1aeSJan Lentfer 	}
6966d49e1aeSJan Lentfer 	va_start(ap, fmt);
6976d49e1aeSJan Lentfer 	len = vsnprintf(buf, buflen, fmt, ap);
6986d49e1aeSJan Lentfer 	va_end(ap);
699*a1157835SDaniel Fojt 	wpa_msg_cb(ctx, level, WPA_MSG_PER_INTERFACE, buf, len);
700*a1157835SDaniel Fojt 	bin_clear_free(buf, buflen);
7016d49e1aeSJan Lentfer }
7023ff40c12SJohn Marino 
7033ff40c12SJohn Marino 
wpa_msg_global(void * ctx,int level,const char * fmt,...)7043ff40c12SJohn Marino void wpa_msg_global(void *ctx, int level, const char *fmt, ...)
7053ff40c12SJohn Marino {
7063ff40c12SJohn Marino 	va_list ap;
7073ff40c12SJohn Marino 	char *buf;
708*a1157835SDaniel Fojt 	int buflen;
7093ff40c12SJohn Marino 	int len;
7103ff40c12SJohn Marino 
711*a1157835SDaniel Fojt 	va_start(ap, fmt);
712*a1157835SDaniel Fojt 	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
713*a1157835SDaniel Fojt 	va_end(ap);
714*a1157835SDaniel Fojt 
7153ff40c12SJohn Marino 	buf = os_malloc(buflen);
7163ff40c12SJohn Marino 	if (buf == NULL) {
7173ff40c12SJohn Marino 		wpa_printf(MSG_ERROR, "wpa_msg_global: Failed to allocate "
7183ff40c12SJohn Marino 			   "message buffer");
7193ff40c12SJohn Marino 		return;
7203ff40c12SJohn Marino 	}
7213ff40c12SJohn Marino 	va_start(ap, fmt);
7223ff40c12SJohn Marino 	len = vsnprintf(buf, buflen, fmt, ap);
7233ff40c12SJohn Marino 	va_end(ap);
7243ff40c12SJohn Marino 	wpa_printf(level, "%s", buf);
7253ff40c12SJohn Marino 	if (wpa_msg_cb)
726*a1157835SDaniel Fojt 		wpa_msg_cb(ctx, level, WPA_MSG_GLOBAL, buf, len);
727*a1157835SDaniel Fojt 	bin_clear_free(buf, buflen);
728*a1157835SDaniel Fojt }
729*a1157835SDaniel Fojt 
730*a1157835SDaniel Fojt 
wpa_msg_global_ctrl(void * ctx,int level,const char * fmt,...)731*a1157835SDaniel Fojt void wpa_msg_global_ctrl(void *ctx, int level, const char *fmt, ...)
732*a1157835SDaniel Fojt {
733*a1157835SDaniel Fojt 	va_list ap;
734*a1157835SDaniel Fojt 	char *buf;
735*a1157835SDaniel Fojt 	int buflen;
736*a1157835SDaniel Fojt 	int len;
737*a1157835SDaniel Fojt 
738*a1157835SDaniel Fojt 	if (!wpa_msg_cb)
739*a1157835SDaniel Fojt 		return;
740*a1157835SDaniel Fojt 
741*a1157835SDaniel Fojt 	va_start(ap, fmt);
742*a1157835SDaniel Fojt 	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
743*a1157835SDaniel Fojt 	va_end(ap);
744*a1157835SDaniel Fojt 
745*a1157835SDaniel Fojt 	buf = os_malloc(buflen);
746*a1157835SDaniel Fojt 	if (buf == NULL) {
747*a1157835SDaniel Fojt 		wpa_printf(MSG_ERROR,
748*a1157835SDaniel Fojt 			   "wpa_msg_global_ctrl: Failed to allocate message buffer");
749*a1157835SDaniel Fojt 		return;
750*a1157835SDaniel Fojt 	}
751*a1157835SDaniel Fojt 	va_start(ap, fmt);
752*a1157835SDaniel Fojt 	len = vsnprintf(buf, buflen, fmt, ap);
753*a1157835SDaniel Fojt 	va_end(ap);
754*a1157835SDaniel Fojt 	wpa_msg_cb(ctx, level, WPA_MSG_GLOBAL, buf, len);
755*a1157835SDaniel Fojt 	bin_clear_free(buf, buflen);
7563ff40c12SJohn Marino }
7573ff40c12SJohn Marino 
7583ff40c12SJohn Marino 
wpa_msg_no_global(void * ctx,int level,const char * fmt,...)7593ff40c12SJohn Marino void wpa_msg_no_global(void *ctx, int level, const char *fmt, ...)
7603ff40c12SJohn Marino {
7613ff40c12SJohn Marino 	va_list ap;
7623ff40c12SJohn Marino 	char *buf;
763*a1157835SDaniel Fojt 	int buflen;
7643ff40c12SJohn Marino 	int len;
7653ff40c12SJohn Marino 
766*a1157835SDaniel Fojt 	va_start(ap, fmt);
767*a1157835SDaniel Fojt 	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
768*a1157835SDaniel Fojt 	va_end(ap);
769*a1157835SDaniel Fojt 
7703ff40c12SJohn Marino 	buf = os_malloc(buflen);
7713ff40c12SJohn Marino 	if (buf == NULL) {
7723ff40c12SJohn Marino 		wpa_printf(MSG_ERROR, "wpa_msg_no_global: Failed to allocate "
7733ff40c12SJohn Marino 			   "message buffer");
7743ff40c12SJohn Marino 		return;
7753ff40c12SJohn Marino 	}
7763ff40c12SJohn Marino 	va_start(ap, fmt);
7773ff40c12SJohn Marino 	len = vsnprintf(buf, buflen, fmt, ap);
7783ff40c12SJohn Marino 	va_end(ap);
7793ff40c12SJohn Marino 	wpa_printf(level, "%s", buf);
7803ff40c12SJohn Marino 	if (wpa_msg_cb)
781*a1157835SDaniel Fojt 		wpa_msg_cb(ctx, level, WPA_MSG_NO_GLOBAL, buf, len);
782*a1157835SDaniel Fojt 	bin_clear_free(buf, buflen);
783*a1157835SDaniel Fojt }
784*a1157835SDaniel Fojt 
785*a1157835SDaniel Fojt 
wpa_msg_global_only(void * ctx,int level,const char * fmt,...)786*a1157835SDaniel Fojt void wpa_msg_global_only(void *ctx, int level, const char *fmt, ...)
787*a1157835SDaniel Fojt {
788*a1157835SDaniel Fojt 	va_list ap;
789*a1157835SDaniel Fojt 	char *buf;
790*a1157835SDaniel Fojt 	int buflen;
791*a1157835SDaniel Fojt 	int len;
792*a1157835SDaniel Fojt 
793*a1157835SDaniel Fojt 	va_start(ap, fmt);
794*a1157835SDaniel Fojt 	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
795*a1157835SDaniel Fojt 	va_end(ap);
796*a1157835SDaniel Fojt 
797*a1157835SDaniel Fojt 	buf = os_malloc(buflen);
798*a1157835SDaniel Fojt 	if (buf == NULL) {
799*a1157835SDaniel Fojt 		wpa_printf(MSG_ERROR, "%s: Failed to allocate message buffer",
800*a1157835SDaniel Fojt 			   __func__);
801*a1157835SDaniel Fojt 		return;
802*a1157835SDaniel Fojt 	}
803*a1157835SDaniel Fojt 	va_start(ap, fmt);
804*a1157835SDaniel Fojt 	len = vsnprintf(buf, buflen, fmt, ap);
805*a1157835SDaniel Fojt 	va_end(ap);
806*a1157835SDaniel Fojt 	wpa_printf(level, "%s", buf);
807*a1157835SDaniel Fojt 	if (wpa_msg_cb)
808*a1157835SDaniel Fojt 		wpa_msg_cb(ctx, level, WPA_MSG_ONLY_GLOBAL, buf, len);
8093ff40c12SJohn Marino 	os_free(buf);
8103ff40c12SJohn Marino }
8113ff40c12SJohn Marino 
8126d49e1aeSJan Lentfer #endif /* CONFIG_NO_WPA_MSG */
8136d49e1aeSJan Lentfer 
8146d49e1aeSJan Lentfer 
8156d49e1aeSJan Lentfer #ifndef CONFIG_NO_HOSTAPD_LOGGER
8166d49e1aeSJan Lentfer static hostapd_logger_cb_func hostapd_logger_cb = NULL;
8176d49e1aeSJan Lentfer 
hostapd_logger_register_cb(hostapd_logger_cb_func func)8186d49e1aeSJan Lentfer void hostapd_logger_register_cb(hostapd_logger_cb_func func)
8196d49e1aeSJan Lentfer {
8206d49e1aeSJan Lentfer 	hostapd_logger_cb = func;
8216d49e1aeSJan Lentfer }
8226d49e1aeSJan Lentfer 
8236d49e1aeSJan Lentfer 
hostapd_logger(void * ctx,const u8 * addr,unsigned int module,int level,const char * fmt,...)8246d49e1aeSJan Lentfer void hostapd_logger(void *ctx, const u8 *addr, unsigned int module, int level,
8256d49e1aeSJan Lentfer 		    const char *fmt, ...)
8266d49e1aeSJan Lentfer {
8276d49e1aeSJan Lentfer 	va_list ap;
8286d49e1aeSJan Lentfer 	char *buf;
829*a1157835SDaniel Fojt 	int buflen;
8306d49e1aeSJan Lentfer 	int len;
8316d49e1aeSJan Lentfer 
832*a1157835SDaniel Fojt 	va_start(ap, fmt);
833*a1157835SDaniel Fojt 	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
834*a1157835SDaniel Fojt 	va_end(ap);
835*a1157835SDaniel Fojt 
8366d49e1aeSJan Lentfer 	buf = os_malloc(buflen);
8376d49e1aeSJan Lentfer 	if (buf == NULL) {
8386d49e1aeSJan Lentfer 		wpa_printf(MSG_ERROR, "hostapd_logger: Failed to allocate "
8396d49e1aeSJan Lentfer 			   "message buffer");
8406d49e1aeSJan Lentfer 		return;
8416d49e1aeSJan Lentfer 	}
8426d49e1aeSJan Lentfer 	va_start(ap, fmt);
8436d49e1aeSJan Lentfer 	len = vsnprintf(buf, buflen, fmt, ap);
8446d49e1aeSJan Lentfer 	va_end(ap);
8456d49e1aeSJan Lentfer 	if (hostapd_logger_cb)
8466d49e1aeSJan Lentfer 		hostapd_logger_cb(ctx, addr, module, level, buf, len);
8473ff40c12SJohn Marino 	else if (addr)
8483ff40c12SJohn Marino 		wpa_printf(MSG_DEBUG, "hostapd_logger: STA " MACSTR " - %s",
8493ff40c12SJohn Marino 			   MAC2STR(addr), buf);
8506d49e1aeSJan Lentfer 	else
8516d49e1aeSJan Lentfer 		wpa_printf(MSG_DEBUG, "hostapd_logger: %s", buf);
852*a1157835SDaniel Fojt 	bin_clear_free(buf, buflen);
8536d49e1aeSJan Lentfer }
8546d49e1aeSJan Lentfer #endif /* CONFIG_NO_HOSTAPD_LOGGER */
855*a1157835SDaniel Fojt 
856*a1157835SDaniel Fojt 
debug_level_str(int level)857*a1157835SDaniel Fojt const char * debug_level_str(int level)
858*a1157835SDaniel Fojt {
859*a1157835SDaniel Fojt 	switch (level) {
860*a1157835SDaniel Fojt 	case MSG_EXCESSIVE:
861*a1157835SDaniel Fojt 		return "EXCESSIVE";
862*a1157835SDaniel Fojt 	case MSG_MSGDUMP:
863*a1157835SDaniel Fojt 		return "MSGDUMP";
864*a1157835SDaniel Fojt 	case MSG_DEBUG:
865*a1157835SDaniel Fojt 		return "DEBUG";
866*a1157835SDaniel Fojt 	case MSG_INFO:
867*a1157835SDaniel Fojt 		return "INFO";
868*a1157835SDaniel Fojt 	case MSG_WARNING:
869*a1157835SDaniel Fojt 		return "WARNING";
870*a1157835SDaniel Fojt 	case MSG_ERROR:
871*a1157835SDaniel Fojt 		return "ERROR";
872*a1157835SDaniel Fojt 	default:
873*a1157835SDaniel Fojt 		return "?";
874*a1157835SDaniel Fojt 	}
875*a1157835SDaniel Fojt }
876*a1157835SDaniel Fojt 
877*a1157835SDaniel Fojt 
str_to_debug_level(const char * s)878*a1157835SDaniel Fojt int str_to_debug_level(const char *s)
879*a1157835SDaniel Fojt {
880*a1157835SDaniel Fojt 	if (os_strcasecmp(s, "EXCESSIVE") == 0)
881*a1157835SDaniel Fojt 		return MSG_EXCESSIVE;
882*a1157835SDaniel Fojt 	if (os_strcasecmp(s, "MSGDUMP") == 0)
883*a1157835SDaniel Fojt 		return MSG_MSGDUMP;
884*a1157835SDaniel Fojt 	if (os_strcasecmp(s, "DEBUG") == 0)
885*a1157835SDaniel Fojt 		return MSG_DEBUG;
886*a1157835SDaniel Fojt 	if (os_strcasecmp(s, "INFO") == 0)
887*a1157835SDaniel Fojt 		return MSG_INFO;
888*a1157835SDaniel Fojt 	if (os_strcasecmp(s, "WARNING") == 0)
889*a1157835SDaniel Fojt 		return MSG_WARNING;
890*a1157835SDaniel Fojt 	if (os_strcasecmp(s, "ERROR") == 0)
891*a1157835SDaniel Fojt 		return MSG_ERROR;
892*a1157835SDaniel Fojt 	return -1;
893*a1157835SDaniel Fojt }
894