• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * wpa_supplicant/hostapd / Debug prints
3  * Copyright (c) 2002-2013, Jouni Malinen <j@w1.fi>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8 
9 #include "includes.h"
10 
11 #include "common.h"
12 
13 #ifdef CONFIG_DEBUG_SYSLOG
14 #include <syslog.h>
15 
16 int wpa_debug_syslog = 0;
17 #endif /* CONFIG_DEBUG_SYSLOG */
18 
19 #ifdef CONFIG_DEBUG_LINUX_TRACING
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <fcntl.h>
23 #include <string.h>
24 #include <stdio.h>
25 
26 static FILE *wpa_debug_tracing_file = NULL;
27 
28 #define WPAS_TRACE_PFX "wpas <%d>: "
29 #endif /* CONFIG_DEBUG_LINUX_TRACING */
30 
31 
32 int wpa_debug_level = MSG_INFO;
33 int wpa_debug_show_keys = 0;
34 int wpa_debug_timestamp = 0;
35 
36 
37 #ifdef CONFIG_ANDROID_LOG
38 
39 #include <android/log.h>
40 
41 #ifndef ANDROID_LOG_NAME
42 #define ANDROID_LOG_NAME	"wpa_supplicant"
43 #endif /* ANDROID_LOG_NAME */
44 
wpa_to_android_level(int level)45 static int wpa_to_android_level(int level)
46 {
47 	if (level == MSG_ERROR)
48 		return ANDROID_LOG_ERROR;
49 	if (level == MSG_WARNING)
50 		return ANDROID_LOG_WARN;
51 	if (level == MSG_INFO)
52 		return ANDROID_LOG_INFO;
53 	return ANDROID_LOG_DEBUG;
54 }
55 
56 #endif /* CONFIG_ANDROID_LOG */
57 
58 #ifndef CONFIG_NO_STDOUT_DEBUG
59 
60 #ifdef CONFIG_DEBUG_FILE
61 #include <sys/types.h>
62 #include <sys/stat.h>
63 #include <fcntl.h>
64 
65 static FILE *out_file = NULL;
66 #endif /* CONFIG_DEBUG_FILE */
67 
68 
wpa_debug_print_timestamp(void)69 void wpa_debug_print_timestamp(void)
70 {
71 #ifndef CONFIG_ANDROID_LOG
72 	struct os_time tv;
73 
74 	if (!wpa_debug_timestamp)
75 		return;
76 
77 	os_get_time(&tv);
78 #ifdef CONFIG_DEBUG_FILE
79 	if (out_file) {
80 		fprintf(out_file, "%ld.%06u: ", (long) tv.sec,
81 			(unsigned int) tv.usec);
82 	} else
83 #endif /* CONFIG_DEBUG_FILE */
84 	printf("%ld.%06u: ", (long) tv.sec, (unsigned int) tv.usec);
85 #endif /* CONFIG_ANDROID_LOG */
86 }
87 
88 
89 #ifdef CONFIG_DEBUG_SYSLOG
90 #ifndef LOG_HOSTAPD
91 #define LOG_HOSTAPD LOG_DAEMON
92 #endif /* LOG_HOSTAPD */
93 
wpa_debug_open_syslog(void)94 void wpa_debug_open_syslog(void)
95 {
96 	openlog("wpa_supplicant", LOG_PID | LOG_NDELAY, LOG_HOSTAPD);
97 	wpa_debug_syslog++;
98 }
99 
100 
wpa_debug_close_syslog(void)101 void wpa_debug_close_syslog(void)
102 {
103 	if (wpa_debug_syslog)
104 		closelog();
105 }
106 
107 
syslog_priority(int level)108 static int syslog_priority(int level)
109 {
110 	switch (level) {
111 	case MSG_MSGDUMP:
112 	case MSG_DEBUG:
113 		return LOG_DEBUG;
114 	case MSG_INFO:
115 		return LOG_NOTICE;
116 	case MSG_WARNING:
117 		return LOG_WARNING;
118 	case MSG_ERROR:
119 		return LOG_ERR;
120 	}
121 	return LOG_INFO;
122 }
123 #endif /* CONFIG_DEBUG_SYSLOG */
124 
125 
126 #ifdef CONFIG_DEBUG_LINUX_TRACING
127 
wpa_debug_open_linux_tracing(void)128 int wpa_debug_open_linux_tracing(void)
129 {
130 	int mounts, trace_fd;
131 	char buf[4096] = {};
132 	ssize_t buflen;
133 	char *line, *tmp1, *path = NULL;
134 
135 	mounts = open("/proc/mounts", O_RDONLY);
136 	if (mounts < 0) {
137 		printf("no /proc/mounts\n");
138 		return -1;
139 	}
140 
141 	buflen = read(mounts, buf, sizeof(buf) - 1);
142 	close(mounts);
143 	if (buflen < 0) {
144 		printf("failed to read /proc/mounts\n");
145 		return -1;
146 	}
147 	buf[buflen] = '\0';
148 
149 	line = strtok_r(buf, "\n", &tmp1);
150 	while (line) {
151 		char *tmp2, *tmp_path, *fstype;
152 		/* "<dev> <mountpoint> <fs type> ..." */
153 		strtok_r(line, " ", &tmp2);
154 		tmp_path = strtok_r(NULL, " ", &tmp2);
155 		fstype = strtok_r(NULL, " ", &tmp2);
156 		if (fstype && strcmp(fstype, "debugfs") == 0) {
157 			path = tmp_path;
158 			break;
159 		}
160 
161 		line = strtok_r(NULL, "\n", &tmp1);
162 	}
163 
164 	if (path == NULL) {
165 		printf("debugfs mountpoint not found\n");
166 		return -1;
167 	}
168 
169 	snprintf(buf, sizeof(buf) - 1, "%s/tracing/trace_marker", path);
170 
171 	trace_fd = open(buf, O_WRONLY);
172 	if (trace_fd < 0) {
173 		printf("failed to open trace_marker file\n");
174 		return -1;
175 	}
176 	wpa_debug_tracing_file = fdopen(trace_fd, "w");
177 	if (wpa_debug_tracing_file == NULL) {
178 		close(trace_fd);
179 		printf("failed to fdopen()\n");
180 		return -1;
181 	}
182 
183 	return 0;
184 }
185 
186 
wpa_debug_close_linux_tracing(void)187 void wpa_debug_close_linux_tracing(void)
188 {
189 	if (wpa_debug_tracing_file == NULL)
190 		return;
191 	fclose(wpa_debug_tracing_file);
192 	wpa_debug_tracing_file = NULL;
193 }
194 
195 #endif /* CONFIG_DEBUG_LINUX_TRACING */
196 
197 
198 /**
199  * wpa_printf - conditional printf
200  * @level: priority level (MSG_*) of the message
201  * @fmt: printf format string, followed by optional arguments
202  *
203  * This function is used to print conditional debugging and error messages. The
204  * output may be directed to stdout, stderr, and/or syslog based on
205  * configuration.
206  *
207  * Note: New line '\n' is added to the end of the text when printing to stdout.
208  */
wpa_printf(int level,const char * fmt,...)209 void wpa_printf(int level, const char *fmt, ...)
210 {
211 #ifdef CONFIG_WPA_NO_LOG
212     return;
213 #else
214 	va_list ap;
215 
216 	va_start(ap, fmt);
217 	if (level >= wpa_debug_level) {
218 #ifdef CONFIG_ANDROID_LOG
219 		__android_log_vprint(wpa_to_android_level(level),
220 				     ANDROID_LOG_NAME, fmt, ap);
221 #else /* CONFIG_ANDROID_LOG */
222 #ifdef CONFIG_DEBUG_SYSLOG
223 		if (wpa_debug_syslog) {
224 			vsyslog(syslog_priority(level), fmt, ap);
225 		} else {
226 #endif /* CONFIG_DEBUG_SYSLOG */
227 		wpa_debug_print_timestamp();
228 #ifdef CONFIG_DEBUG_FILE
229 		if (out_file) {
230 			vfprintf(out_file, fmt, ap);
231 			fprintf(out_file, "\n");
232 		} else {
233 #endif /* CONFIG_DEBUG_FILE */
234 		vprintf(fmt, ap);
235 		printf("\n");
236 #ifdef CONFIG_DEBUG_FILE
237 		}
238 #endif /* CONFIG_DEBUG_FILE */
239 #ifdef CONFIG_DEBUG_SYSLOG
240 		}
241 #endif /* CONFIG_DEBUG_SYSLOG */
242 #endif /* CONFIG_ANDROID_LOG */
243 	}
244 	va_end(ap);
245 
246 #ifdef CONFIG_DEBUG_LINUX_TRACING
247 	if (wpa_debug_tracing_file != NULL) {
248 		va_start(ap, fmt);
249 		fprintf(wpa_debug_tracing_file, WPAS_TRACE_PFX, level);
250 		vfprintf(wpa_debug_tracing_file, fmt, ap);
251 		fprintf(wpa_debug_tracing_file, "\n");
252 		fflush(wpa_debug_tracing_file);
253 		va_end(ap);
254 	}
255 #endif /* CONFIG_DEBUG_LINUX_TRACING */
256 #endif /* CONFIG_WPA_NO_LOG */
257 }
258 
259 
_wpa_hexdump(int level,const char * title,const u8 * buf,size_t len,int show)260 static void _wpa_hexdump(int level, const char *title, const u8 *buf,
261 			 size_t len, int show)
262 {
263 #ifdef CONFIG_WPA_NO_LOG
264     return;
265 #else
266 	size_t i;
267 
268 #ifdef CONFIG_DEBUG_LINUX_TRACING
269 	if (wpa_debug_tracing_file != NULL) {
270 		fprintf(wpa_debug_tracing_file,
271 			WPAS_TRACE_PFX "%s - hexdump(len=%lu):",
272 			level, title, (unsigned long) len);
273 		if (buf == NULL) {
274 			fprintf(wpa_debug_tracing_file, " [NULL]\n");
275 		} else if (!show) {
276 			fprintf(wpa_debug_tracing_file, " [REMOVED]\n");
277 		} else {
278 			for (i = 0; i < len; i++)
279 				fprintf(wpa_debug_tracing_file,
280 					" %02x", buf[i]);
281 		}
282 		fflush(wpa_debug_tracing_file);
283 	}
284 #endif /* CONFIG_DEBUG_LINUX_TRACING */
285 
286 	if (level < wpa_debug_level)
287 		return;
288 #ifdef CONFIG_ANDROID_LOG
289 	{
290 		const char *display;
291 		char *strbuf = NULL;
292 		size_t slen = len;
293 		if (buf == NULL) {
294 			display = " [NULL]";
295 		} else if (len == 0) {
296 			display = "";
297 		} else if (show && len) {
298 			/* Limit debug message length for Android log */
299 			if (slen > 32)
300 				slen = 32;
301 			strbuf = os_malloc(1 + 3 * slen);
302 			if (strbuf == NULL) {
303 				wpa_printf(MSG_ERROR, "wpa_hexdump: Failed to "
304 					   "allocate message buffer");
305 				return;
306 			}
307 
308 			for (i = 0; i < slen; i++)
309 				os_snprintf(&strbuf[i * 3], 4, " %02x",
310 					    buf[i]);
311 
312 			display = strbuf;
313 		} else {
314 			display = " [REMOVED]";
315 		}
316 
317 		__android_log_print(wpa_to_android_level(level),
318 				    ANDROID_LOG_NAME,
319 				    "%s - hexdump(len=%lu):%s%s",
320 				    title, (long unsigned int) len, display,
321 				    len > slen ? " ..." : "");
322 		bin_clear_free(strbuf, 1 + 3 * slen);
323 		return;
324 	}
325 #else /* CONFIG_ANDROID_LOG */
326 #ifdef CONFIG_DEBUG_SYSLOG
327 	if (wpa_debug_syslog) {
328 		const char *display;
329 		char *strbuf = NULL;
330 
331 		if (buf == NULL) {
332 			display = " [NULL]";
333 		} else if (len == 0) {
334 			display = "";
335 		} else if (show && len) {
336 			strbuf = os_malloc(1 + 3 * len);
337 			if (strbuf == NULL) {
338 				wpa_printf(MSG_ERROR, "wpa_hexdump: Failed to "
339 					   "allocate message buffer");
340 				return;
341 			}
342 
343 			for (i = 0; i < len; i++)
344 				os_snprintf(&strbuf[i * 3], 4, " %02x",
345 					    buf[i]);
346 
347 			display = strbuf;
348 		} else {
349 			display = " [REMOVED]";
350 		}
351 
352 		syslog(syslog_priority(level), "%s - hexdump(len=%lu):%s",
353 		       title, (unsigned long) len, display);
354 		bin_clear_free(strbuf, 1 + 3 * len);
355 		return;
356 	}
357 #endif /* CONFIG_DEBUG_SYSLOG */
358 	wpa_debug_print_timestamp();
359 #ifdef CONFIG_DEBUG_FILE
360 	if (out_file) {
361 		fprintf(out_file, "%s - hexdump(len=%lu):",
362 			title, (unsigned long) len);
363 		if (buf == NULL) {
364 			fprintf(out_file, " [NULL]");
365 		} else if (show) {
366 			for (i = 0; i < len; i++)
367 				fprintf(out_file, " %02x", buf[i]);
368 		} else {
369 			fprintf(out_file, " [REMOVED]");
370 		}
371 		fprintf(out_file, "\n");
372 	} else {
373 #endif /* CONFIG_DEBUG_FILE */
374 	printf("%s - hexdump(len=%lu):", title, (unsigned long) len);
375 	if (buf == NULL) {
376 		printf(" [NULL]");
377 	} else if (show) {
378 		for (i = 0; i < len; i++)
379 			printf(" %02x", buf[i]);
380 	} else {
381 		printf(" [REMOVED]");
382 	}
383 	printf("\n");
384 #ifdef CONFIG_DEBUG_FILE
385 	}
386 #endif /* CONFIG_DEBUG_FILE */
387 #endif /* CONFIG_ANDROID_LOG */
388 #endif /* CONFIG_WPA_NO_LOG */
389 }
390 
wpa_hexdump(int level,const char * title,const void * buf,size_t len)391 void wpa_hexdump(int level, const char *title, const void *buf, size_t len)
392 {
393 	_wpa_hexdump(level, title, buf, len, 1);
394 }
395 
396 
wpa_hexdump_key(int level,const char * title,const void * buf,size_t len)397 void wpa_hexdump_key(int level, const char *title, const void *buf, size_t len)
398 {
399 	_wpa_hexdump(level, title, buf, len, wpa_debug_show_keys);
400 }
401 
402 
_wpa_hexdump_ascii(int level,const char * title,const void * buf,size_t len,int show)403 static void _wpa_hexdump_ascii(int level, const char *title, const void *buf,
404 			       size_t len, int show)
405 {
406 #ifdef CONFIG_WPA_NO_LOG
407     return;
408 #else
409 	size_t i, llen;
410 	const u8 *pos = buf;
411 	const size_t line_len = 16;
412 
413 #ifdef CONFIG_DEBUG_LINUX_TRACING
414 	if (wpa_debug_tracing_file != NULL) {
415 		fprintf(wpa_debug_tracing_file,
416 			WPAS_TRACE_PFX "%s - hexdump_ascii(len=%lu):",
417 			level, title, (unsigned long) len);
418 		if (buf == NULL) {
419 			fprintf(wpa_debug_tracing_file, " [NULL]\n");
420 		} else if (!show) {
421 			fprintf(wpa_debug_tracing_file, " [REMOVED]\n");
422 		} else {
423 			/* can do ascii processing in userspace */
424 			for (i = 0; i < len; i++)
425 				fprintf(wpa_debug_tracing_file,
426 					" %02x", pos[i]);
427 		}
428 		fflush(wpa_debug_tracing_file);
429 	}
430 #endif /* CONFIG_DEBUG_LINUX_TRACING */
431 
432 	if (level < wpa_debug_level)
433 		return;
434 #ifdef CONFIG_ANDROID_LOG
435 	_wpa_hexdump(level, title, buf, len, show);
436 #else /* CONFIG_ANDROID_LOG */
437 #ifdef CONFIG_DEBUG_SYSLOG
438 	if (wpa_debug_syslog) {
439 		_wpa_hexdump(level, title, buf, len, show);
440 		return;
441 	}
442 #endif /* CONFIG_DEBUG_SYSLOG */
443 	wpa_debug_print_timestamp();
444 #ifdef CONFIG_DEBUG_FILE
445 	if (out_file) {
446 		if (!show) {
447 			fprintf(out_file,
448 				"%s - hexdump_ascii(len=%lu): [REMOVED]\n",
449 				title, (unsigned long) len);
450 			return;
451 		}
452 		if (buf == NULL) {
453 			fprintf(out_file,
454 				"%s - hexdump_ascii(len=%lu): [NULL]\n",
455 				title, (unsigned long) len);
456 			return;
457 		}
458 		fprintf(out_file, "%s - hexdump_ascii(len=%lu):\n",
459 			title, (unsigned long) len);
460 		while (len) {
461 			llen = len > line_len ? line_len : len;
462 			fprintf(out_file, "    ");
463 			for (i = 0; i < llen; i++)
464 				fprintf(out_file, " %02x", pos[i]);
465 			for (i = llen; i < line_len; i++)
466 				fprintf(out_file, "   ");
467 			fprintf(out_file, "   ");
468 			for (i = 0; i < llen; i++) {
469 				if (isprint(pos[i]))
470 					fprintf(out_file, "%c", pos[i]);
471 				else
472 					fprintf(out_file, "_");
473 			}
474 			for (i = llen; i < line_len; i++)
475 				fprintf(out_file, " ");
476 			fprintf(out_file, "\n");
477 			pos += llen;
478 			len -= llen;
479 		}
480 	} else {
481 #endif /* CONFIG_DEBUG_FILE */
482 	if (!show) {
483 		printf("%s - hexdump_ascii(len=%lu): [REMOVED]\n",
484 		       title, (unsigned long) len);
485 		return;
486 	}
487 	if (buf == NULL) {
488 		printf("%s - hexdump_ascii(len=%lu): [NULL]\n",
489 		       title, (unsigned long) len);
490 		return;
491 	}
492 	printf("%s - hexdump_ascii(len=%lu):\n", title, (unsigned long) len);
493 	while (len) {
494 		llen = len > line_len ? line_len : len;
495 		printf("    ");
496 		for (i = 0; i < llen; i++)
497 			printf(" %02x", pos[i]);
498 		for (i = llen; i < line_len; i++)
499 			printf("   ");
500 		printf("   ");
501 		for (i = 0; i < llen; i++) {
502 			if (isprint(pos[i]))
503 				printf("%c", pos[i]);
504 			else
505 				printf("_");
506 		}
507 		for (i = llen; i < line_len; i++)
508 			printf(" ");
509 		printf("\n");
510 		pos += llen;
511 		len -= llen;
512 	}
513 #ifdef CONFIG_DEBUG_FILE
514 	}
515 #endif /* CONFIG_DEBUG_FILE */
516 #endif /* CONFIG_ANDROID_LOG */
517 #endif /* CONFIG_WPA_NO_LOG */
518 }
519 
520 
wpa_hexdump_ascii(int level,const char * title,const void * buf,size_t len)521 void wpa_hexdump_ascii(int level, const char *title, const void *buf,
522 		       size_t len)
523 {
524 	_wpa_hexdump_ascii(level, title, buf, len, 1);
525 }
526 
527 
wpa_hexdump_ascii_key(int level,const char * title,const void * buf,size_t len)528 void wpa_hexdump_ascii_key(int level, const char *title, const void *buf,
529 			   size_t len)
530 {
531 	_wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys);
532 }
533 
534 
535 #ifdef CONFIG_DEBUG_FILE
536 static char *last_path = NULL;
537 #endif /* CONFIG_DEBUG_FILE */
538 
wpa_debug_reopen_file(void)539 int wpa_debug_reopen_file(void)
540 {
541 #ifdef CONFIG_DEBUG_FILE
542 	int rv;
543 	char *tmp;
544 
545 	if (!last_path)
546 		return 0; /* logfile not used */
547 
548 	tmp = os_strdup(last_path);
549 	if (!tmp)
550 		return -1;
551 
552 	wpa_debug_close_file();
553 	rv = wpa_debug_open_file(tmp);
554 	os_free(tmp);
555 	return rv;
556 #else /* CONFIG_DEBUG_FILE */
557 	return 0;
558 #endif /* CONFIG_DEBUG_FILE */
559 }
560 
561 
wpa_debug_open_file(const char * path)562 int wpa_debug_open_file(const char *path)
563 {
564 #ifdef CONFIG_DEBUG_FILE
565 	int out_fd;
566 
567 	if (!path)
568 		return 0;
569 
570 	if (last_path == NULL || os_strcmp(last_path, path) != 0) {
571 		/* Save our path to enable re-open */
572 		os_free(last_path);
573 		last_path = os_strdup(path);
574 	}
575 
576 	out_fd = open(path, O_CREAT | O_APPEND | O_WRONLY,
577 		      S_IRUSR | S_IWUSR | S_IRGRP);
578 	if (out_fd < 0) {
579 		wpa_printf(MSG_ERROR,
580 			   "%s: Failed to open output file descriptor, using standard output",
581 			   __func__);
582 		return -1;
583 	}
584 
585 #ifdef __linux__
586 	if (fcntl(out_fd, F_SETFD, FD_CLOEXEC) < 0) {
587 		wpa_printf(MSG_DEBUG,
588 			   "%s: Failed to set FD_CLOEXEC - continue without: %s",
589 			   __func__, strerror(errno));
590 	}
591 #endif /* __linux__ */
592 
593 	out_file = fdopen(out_fd, "a");
594 	if (out_file == NULL) {
595 		wpa_printf(MSG_ERROR, "wpa_debug_open_file: Failed to open "
596 			   "output file, using standard output");
597 		close(out_fd);
598 		return -1;
599 	}
600 #ifndef _WIN32
601 	setvbuf(out_file, NULL, _IOLBF, 0);
602 #endif /* _WIN32 */
603 #else /* CONFIG_DEBUG_FILE */
604 	(void)path;
605 #endif /* CONFIG_DEBUG_FILE */
606 	return 0;
607 }
608 
609 
wpa_debug_close_file(void)610 void wpa_debug_close_file(void)
611 {
612 #ifdef CONFIG_DEBUG_FILE
613 	if (!out_file)
614 		return;
615 	fclose(out_file);
616 	out_file = NULL;
617 	os_free(last_path);
618 	last_path = NULL;
619 #endif /* CONFIG_DEBUG_FILE */
620 }
621 
622 
wpa_debug_setup_stdout(void)623 void wpa_debug_setup_stdout(void)
624 {
625 #ifndef _WIN32
626 	setvbuf(stdout, NULL, _IOLBF, 0);
627 #endif /* _WIN32 */
628 }
629 
630 #endif /* CONFIG_NO_STDOUT_DEBUG */
631 
632 
633 #ifndef CONFIG_NO_WPA_MSG
634 static wpa_msg_cb_func wpa_msg_cb = NULL;
635 
wpa_msg_register_cb(wpa_msg_cb_func func)636 void wpa_msg_register_cb(wpa_msg_cb_func func)
637 {
638 	wpa_msg_cb = func;
639 }
640 
641 
642 static wpa_msg_get_ifname_func wpa_msg_ifname_cb = NULL;
643 
wpa_msg_register_ifname_cb(wpa_msg_get_ifname_func func)644 void wpa_msg_register_ifname_cb(wpa_msg_get_ifname_func func)
645 {
646 	wpa_msg_ifname_cb = func;
647 }
648 
wpa_msg(void * ctx,int level,const char * fmt,...)649 void wpa_msg(void *ctx, int level, const char *fmt, ...)
650 {
651 	va_list ap;
652 	char *buf;
653 	int buflen;
654 	int len;
655 	char prefix[130];
656 
657 	va_start(ap, fmt);
658 	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
659 	va_end(ap);
660 
661 	buf = os_malloc(buflen);
662 	if (buf == NULL) {
663 		wpa_printf(MSG_ERROR, "wpa_msg: Failed to allocate message "
664 			   "buffer");
665 		return;
666 	}
667 	va_start(ap, fmt);
668 	prefix[0] = '\0';
669 	if (wpa_msg_ifname_cb) {
670 		const char *ifname = wpa_msg_ifname_cb(ctx);
671 		if (ifname) {
672 			int res = os_snprintf(prefix, sizeof(prefix), "%s: ",
673 					      ifname);
674 			if (os_snprintf_error(sizeof(prefix), res))
675 				prefix[0] = '\0';
676 		}
677 	}
678 	len = vsnprintf(buf, buflen, fmt, ap);
679 	va_end(ap);
680 	wpa_printf(level, "%s%s", prefix, buf);
681 	if (wpa_msg_cb)
682 		wpa_msg_cb(ctx, level, WPA_MSG_PER_INTERFACE, buf, len);
683 	bin_clear_free(buf, buflen);
684 }
685 
686 
wpa_msg_ctrl(void * ctx,int level,const char * fmt,...)687 void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...)
688 {
689 	va_list ap;
690 	char *buf;
691 	int buflen;
692 	int len;
693 
694 	if (!wpa_msg_cb)
695 		return;
696 
697 	va_start(ap, fmt);
698 	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
699 	va_end(ap);
700 
701 	buf = os_malloc(buflen);
702 	if (buf == NULL) {
703 		wpa_printf(MSG_ERROR, "wpa_msg_ctrl: Failed to allocate "
704 			   "message buffer");
705 		return;
706 	}
707 	va_start(ap, fmt);
708 	len = vsnprintf(buf, buflen, fmt, ap);
709 	va_end(ap);
710 	wpa_msg_cb(ctx, level, WPA_MSG_PER_INTERFACE, buf, len);
711 	bin_clear_free(buf, buflen);
712 }
713 
714 
wpa_msg_global(void * ctx,int level,const char * fmt,...)715 void wpa_msg_global(void *ctx, int level, const char *fmt, ...)
716 {
717 	va_list ap;
718 	char *buf;
719 	int buflen;
720 	int len;
721 
722 	va_start(ap, fmt);
723 	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
724 	va_end(ap);
725 
726 	buf = os_malloc(buflen);
727 	if (buf == NULL) {
728 		wpa_printf(MSG_ERROR, "wpa_msg_global: Failed to allocate "
729 			   "message buffer");
730 		return;
731 	}
732 	va_start(ap, fmt);
733 	len = vsnprintf(buf, buflen, fmt, ap);
734 	va_end(ap);
735 	wpa_printf(level, "%s", buf);
736 	if (wpa_msg_cb)
737 		wpa_msg_cb(ctx, level, WPA_MSG_GLOBAL, buf, len);
738 	bin_clear_free(buf, buflen);
739 }
740 
741 
wpa_msg_global_ctrl(void * ctx,int level,const char * fmt,...)742 void wpa_msg_global_ctrl(void *ctx, int level, const char *fmt, ...)
743 {
744 	va_list ap;
745 	char *buf;
746 	int buflen;
747 	int len;
748 
749 	if (!wpa_msg_cb)
750 		return;
751 
752 	va_start(ap, fmt);
753 	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
754 	va_end(ap);
755 
756 	buf = os_malloc(buflen);
757 	if (buf == NULL) {
758 		wpa_printf(MSG_ERROR,
759 			   "wpa_msg_global_ctrl: Failed to allocate message buffer");
760 		return;
761 	}
762 	va_start(ap, fmt);
763 	len = vsnprintf(buf, buflen, fmt, ap);
764 	va_end(ap);
765 	wpa_msg_cb(ctx, level, WPA_MSG_GLOBAL, buf, len);
766 	bin_clear_free(buf, buflen);
767 }
768 
769 
wpa_msg_no_global(void * ctx,int level,const char * fmt,...)770 void wpa_msg_no_global(void *ctx, int level, const char *fmt, ...)
771 {
772 	va_list ap;
773 	char *buf;
774 	int buflen;
775 	int len;
776 
777 	va_start(ap, fmt);
778 	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
779 	va_end(ap);
780 
781 	buf = os_malloc(buflen);
782 	if (buf == NULL) {
783 		wpa_printf(MSG_ERROR, "wpa_msg_no_global: Failed to allocate "
784 			   "message buffer");
785 		return;
786 	}
787 	va_start(ap, fmt);
788 	len = vsnprintf(buf, buflen, fmt, ap);
789 	va_end(ap);
790 	wpa_printf(level, "%s", buf);
791 	if (wpa_msg_cb)
792 		wpa_msg_cb(ctx, level, WPA_MSG_NO_GLOBAL, buf, len);
793 	bin_clear_free(buf, buflen);
794 }
795 
796 
wpa_msg_global_only(void * ctx,int level,const char * fmt,...)797 void wpa_msg_global_only(void *ctx, int level, const char *fmt, ...)
798 {
799 	va_list ap;
800 	char *buf;
801 	int buflen;
802 	int len;
803 
804 	va_start(ap, fmt);
805 	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
806 	va_end(ap);
807 
808 	buf = os_malloc(buflen);
809 	if (buf == NULL) {
810 		wpa_printf(MSG_ERROR, "%s: Failed to allocate message buffer",
811 			   __func__);
812 		return;
813 	}
814 	va_start(ap, fmt);
815 	len = vsnprintf(buf, buflen, fmt, ap);
816 	va_end(ap);
817 	wpa_printf(level, "%s", buf);
818 	if (wpa_msg_cb)
819 		wpa_msg_cb(ctx, level, WPA_MSG_ONLY_GLOBAL, buf, len);
820 	os_free(buf);
821 }
822 
823 #endif /* CONFIG_NO_WPA_MSG */
824 
825 
826 #ifndef CONFIG_NO_HOSTAPD_LOGGER
827 static hostapd_logger_cb_func hostapd_logger_cb = NULL;
828 
hostapd_logger_register_cb(hostapd_logger_cb_func func)829 void hostapd_logger_register_cb(hostapd_logger_cb_func func)
830 {
831 	hostapd_logger_cb = func;
832 }
833 
834 
hostapd_logger(void * ctx,const u8 * addr,unsigned int module,int level,const char * fmt,...)835 void hostapd_logger(void *ctx, const u8 *addr, unsigned int module, int level,
836 		    const char *fmt, ...)
837 {
838 	va_list ap;
839 	char *buf;
840 	int buflen;
841 	int len;
842 
843 	va_start(ap, fmt);
844 	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
845 	va_end(ap);
846 
847 	buf = os_malloc(buflen);
848 	if (buf == NULL) {
849 		wpa_printf(MSG_ERROR, "hostapd_logger: Failed to allocate "
850 			   "message buffer");
851 		return;
852 	}
853 	va_start(ap, fmt);
854 	len = vsnprintf(buf, buflen, fmt, ap);
855 	va_end(ap);
856 	if (hostapd_logger_cb)
857 		hostapd_logger_cb(ctx, addr, module, level, buf, len);
858 	else if (addr)
859 		wpa_printf(MSG_DEBUG, "hostapd_logger: STA " MACSTR " - %s",
860 			   MAC2STR(addr), buf);
861 	else
862 		wpa_printf(MSG_DEBUG, "hostapd_logger: %s", buf);
863 	bin_clear_free(buf, buflen);
864 }
865 #endif /* CONFIG_NO_HOSTAPD_LOGGER */
866 
867 
debug_level_str(int level)868 const char * debug_level_str(int level)
869 {
870 	switch (level) {
871 	case MSG_EXCESSIVE:
872 		return "EXCESSIVE";
873 	case MSG_MSGDUMP:
874 		return "MSGDUMP";
875 	case MSG_DEBUG:
876 		return "DEBUG";
877 	case MSG_INFO:
878 		return "INFO";
879 	case MSG_WARNING:
880 		return "WARNING";
881 	case MSG_ERROR:
882 		return "ERROR";
883 	default:
884 		return "?";
885 	}
886 }
887 
888 
str_to_debug_level(const char * s)889 int str_to_debug_level(const char *s)
890 {
891 	if (os_strcasecmp(s, "EXCESSIVE") == 0)
892 		return MSG_EXCESSIVE;
893 	if (os_strcasecmp(s, "MSGDUMP") == 0)
894 		return MSG_MSGDUMP;
895 	if (os_strcasecmp(s, "DEBUG") == 0)
896 		return MSG_DEBUG;
897 	if (os_strcasecmp(s, "INFO") == 0)
898 		return MSG_INFO;
899 	if (os_strcasecmp(s, "WARNING") == 0)
900 		return MSG_WARNING;
901 	if (os_strcasecmp(s, "ERROR") == 0)
902 		return MSG_ERROR;
903 	return -1;
904 }
905