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  #endif /* CONFIG_DEBUG_SYSLOG */
16  
17  #ifdef CONFIG_DEBUG_LINUX_TRACING
18  #include <sys/types.h>
19  #include <sys/stat.h>
20  #include <fcntl.h>
21  #include <string.h>
22  #include <stdio.h>
23  
24  static FILE *wpa_debug_tracing_file = NULL;
25  
26  #define WPAS_TRACE_PFX "wpas <%d>: "
27  #endif /* CONFIG_DEBUG_LINUX_TRACING */
28  
29  
30  int wpa_debug_level = MSG_INFO;
31  int wpa_debug_show_keys = 0;
32  int wpa_debug_timestamp = 0;
33  int wpa_debug_syslog = 0;
34  #ifndef CONFIG_NO_STDOUT_DEBUG
35  static FILE *out_file = NULL;
36  #endif /* CONFIG_NO_STDOUT_DEBUG */
37  
38  
39  #ifdef CONFIG_ANDROID_LOG
40  
41  #include <android/log.h>
42  
43  #ifndef ANDROID_LOG_NAME
44  #define ANDROID_LOG_NAME	"wpa_supplicant"
45  #endif /* ANDROID_LOG_NAME */
46  
wpa_to_android_level(int level)47  static int wpa_to_android_level(int level)
48  {
49  	if (level == MSG_ERROR)
50  		return ANDROID_LOG_ERROR;
51  	if (level == MSG_WARNING)
52  		return ANDROID_LOG_WARN;
53  	if (level == MSG_INFO)
54  		return ANDROID_LOG_INFO;
55  	return ANDROID_LOG_DEBUG;
56  }
57  
58  #endif /* CONFIG_ANDROID_LOG */
59  
60  #ifndef CONFIG_NO_STDOUT_DEBUG
61  
62  #ifdef CONFIG_DEBUG_FILE
63  #include <sys/types.h>
64  #include <sys/stat.h>
65  #include <fcntl.h>
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  #endif /* CONFIG_DEBUG_FILE */
83  	if (!out_file && !wpa_debug_syslog)
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  	va_list ap;
212  
213  	if (level >= wpa_debug_level) {
214  #ifdef CONFIG_ANDROID_LOG
215  		va_start(ap, fmt);
216  		__android_log_vprint(wpa_to_android_level(level),
217  				     ANDROID_LOG_NAME, fmt, ap);
218  		va_end(ap);
219  #else /* CONFIG_ANDROID_LOG */
220  #ifdef CONFIG_DEBUG_SYSLOG
221  		if (wpa_debug_syslog) {
222  			va_start(ap, fmt);
223  			vsyslog(syslog_priority(level), fmt, ap);
224  			va_end(ap);
225  		}
226  #endif /* CONFIG_DEBUG_SYSLOG */
227  		wpa_debug_print_timestamp();
228  #ifdef CONFIG_DEBUG_FILE
229  		if (out_file) {
230  			va_start(ap, fmt);
231  			vfprintf(out_file, fmt, ap);
232  			fprintf(out_file, "\n");
233  			va_end(ap);
234  		}
235  #endif /* CONFIG_DEBUG_FILE */
236  		if (!wpa_debug_syslog && !out_file) {
237  			va_start(ap, fmt);
238  			vprintf(fmt, ap);
239  			printf("\n");
240  			va_end(ap);
241  		}
242  #endif /* CONFIG_ANDROID_LOG */
243  	}
244  
245  #ifdef CONFIG_DEBUG_LINUX_TRACING
246  	if (wpa_debug_tracing_file != NULL) {
247  		va_start(ap, fmt);
248  		fprintf(wpa_debug_tracing_file, WPAS_TRACE_PFX, level);
249  		vfprintf(wpa_debug_tracing_file, fmt, ap);
250  		fprintf(wpa_debug_tracing_file, "\n");
251  		fflush(wpa_debug_tracing_file);
252  		va_end(ap);
253  	}
254  #endif /* CONFIG_DEBUG_LINUX_TRACING */
255  }
256  
257  
_wpa_hexdump(int level,const char * title,const u8 * buf,size_t len,int show,int only_syslog)258  static void _wpa_hexdump(int level, const char *title, const u8 *buf,
259  			 size_t len, int show, int only_syslog)
260  {
261  	size_t i;
262  
263  #ifdef CONFIG_DEBUG_LINUX_TRACING
264  	if (wpa_debug_tracing_file != NULL) {
265  		fprintf(wpa_debug_tracing_file,
266  			WPAS_TRACE_PFX "%s - hexdump(len=%lu):",
267  			level, title, (unsigned long) len);
268  		if (buf == NULL) {
269  			fprintf(wpa_debug_tracing_file, " [NULL]\n");
270  		} else if (!show) {
271  			fprintf(wpa_debug_tracing_file, " [REMOVED]\n");
272  		} else {
273  			for (i = 0; i < len; i++)
274  				fprintf(wpa_debug_tracing_file,
275  					" %02x", buf[i]);
276  		}
277  		fflush(wpa_debug_tracing_file);
278  	}
279  #endif /* CONFIG_DEBUG_LINUX_TRACING */
280  
281  	if (level < wpa_debug_level)
282  		return;
283  #ifdef CONFIG_ANDROID_LOG
284  	{
285  		const char *display;
286  		char *strbuf = NULL;
287  		size_t slen = len;
288  		if (buf == NULL) {
289  			display = " [NULL]";
290  		} else if (len == 0) {
291  			display = "";
292  		} else if (show && len) {
293  			/* Limit debug message length for Android log */
294  			if (slen > 32)
295  				slen = 32;
296  			strbuf = os_malloc(1 + 3 * slen);
297  			if (strbuf == NULL) {
298  				wpa_printf(MSG_ERROR, "wpa_hexdump: Failed to "
299  					   "allocate message buffer");
300  				return;
301  			}
302  
303  			for (i = 0; i < slen; i++)
304  				os_snprintf(&strbuf[i * 3], 4, " %02x",
305  					    buf[i]);
306  
307  			display = strbuf;
308  		} else {
309  			display = " [REMOVED]";
310  		}
311  
312  		__android_log_print(wpa_to_android_level(level),
313  				    ANDROID_LOG_NAME,
314  				    "%s - hexdump(len=%lu):%s%s",
315  				    title, (long unsigned int) len, display,
316  				    len > slen ? " ..." : "");
317  		bin_clear_free(strbuf, 1 + 3 * slen);
318  		return;
319  	}
320  #else /* CONFIG_ANDROID_LOG */
321  #ifdef CONFIG_DEBUG_SYSLOG
322  	if (wpa_debug_syslog) {
323  		const char *display;
324  		char *strbuf = NULL;
325  
326  		if (buf == NULL) {
327  			display = " [NULL]";
328  		} else if (len == 0) {
329  			display = "";
330  		} else if (show && len) {
331  			strbuf = os_malloc(1 + 3 * len);
332  			if (strbuf == NULL) {
333  				wpa_printf(MSG_ERROR, "wpa_hexdump: Failed to "
334  					   "allocate message buffer");
335  				return;
336  			}
337  
338  			for (i = 0; i < len; i++)
339  				os_snprintf(&strbuf[i * 3], 4, " %02x",
340  					    buf[i]);
341  
342  			display = strbuf;
343  		} else {
344  			display = " [REMOVED]";
345  		}
346  
347  		syslog(syslog_priority(level), "%s - hexdump(len=%lu):%s",
348  		       title, (unsigned long) len, display);
349  		bin_clear_free(strbuf, 1 + 3 * len);
350  		if (only_syslog)
351  			return;
352  	}
353  #endif /* CONFIG_DEBUG_SYSLOG */
354  	wpa_debug_print_timestamp();
355  #ifdef CONFIG_DEBUG_FILE
356  	if (out_file) {
357  		fprintf(out_file, "%s - hexdump(len=%lu):",
358  			title, (unsigned long) len);
359  		if (buf == NULL) {
360  			fprintf(out_file, " [NULL]");
361  		} else if (show) {
362  			for (i = 0; i < len; i++)
363  				fprintf(out_file, " %02x", buf[i]);
364  		} else {
365  			fprintf(out_file, " [REMOVED]");
366  		}
367  		fprintf(out_file, "\n");
368  	}
369  #endif /* CONFIG_DEBUG_FILE */
370  	if (!wpa_debug_syslog && !out_file) {
371  		printf("%s - hexdump(len=%lu):", title, (unsigned long) len);
372  		if (buf == NULL) {
373  			printf(" [NULL]");
374  		} else if (show) {
375  			for (i = 0; i < len; i++)
376  				printf(" %02x", buf[i]);
377  		} else {
378  			printf(" [REMOVED]");
379  		}
380  		printf("\n");
381  	}
382  #endif /* CONFIG_ANDROID_LOG */
383  }
384  
wpa_hexdump(int level,const char * title,const void * buf,size_t len)385  void wpa_hexdump(int level, const char *title, const void *buf, size_t len)
386  {
387  	_wpa_hexdump(level, title, buf, len, 1, 0);
388  }
389  
390  
wpa_hexdump_key(int level,const char * title,const void * buf,size_t len)391  void wpa_hexdump_key(int level, const char *title, const void *buf, size_t len)
392  {
393  	_wpa_hexdump(level, title, buf, len, wpa_debug_show_keys, 0);
394  }
395  
396  
_wpa_hexdump_ascii(int level,const char * title,const void * buf,size_t len,int show)397  static void _wpa_hexdump_ascii(int level, const char *title, const void *buf,
398  			       size_t len, int show)
399  {
400  	size_t i, llen;
401  	const u8 *pos = buf;
402  	const size_t line_len = 16;
403  
404  #ifdef CONFIG_DEBUG_LINUX_TRACING
405  	if (wpa_debug_tracing_file != NULL) {
406  		fprintf(wpa_debug_tracing_file,
407  			WPAS_TRACE_PFX "%s - hexdump_ascii(len=%lu):",
408  			level, title, (unsigned long) len);
409  		if (buf == NULL) {
410  			fprintf(wpa_debug_tracing_file, " [NULL]\n");
411  		} else if (!show) {
412  			fprintf(wpa_debug_tracing_file, " [REMOVED]\n");
413  		} else {
414  			/* can do ascii processing in userspace */
415  			for (i = 0; i < len; i++)
416  				fprintf(wpa_debug_tracing_file,
417  					" %02x", pos[i]);
418  		}
419  		fflush(wpa_debug_tracing_file);
420  	}
421  #endif /* CONFIG_DEBUG_LINUX_TRACING */
422  
423  	if (level < wpa_debug_level)
424  		return;
425  #ifdef CONFIG_ANDROID_LOG
426  	_wpa_hexdump(level, title, buf, len, show, 0);
427  #else /* CONFIG_ANDROID_LOG */
428  #ifdef CONFIG_DEBUG_SYSLOG
429  	if (wpa_debug_syslog)
430  		_wpa_hexdump(level, title, buf, len, show, 1);
431  #endif /* CONFIG_DEBUG_SYSLOG */
432  	wpa_debug_print_timestamp();
433  #ifdef CONFIG_DEBUG_FILE
434  	if (out_file) {
435  		if (!show) {
436  			fprintf(out_file,
437  				"%s - hexdump_ascii(len=%lu): [REMOVED]\n",
438  				title, (unsigned long) len);
439  			goto file_done;
440  		}
441  		if (buf == NULL) {
442  			fprintf(out_file,
443  				"%s - hexdump_ascii(len=%lu): [NULL]\n",
444  				title, (unsigned long) len);
445  			goto file_done;
446  		}
447  		fprintf(out_file, "%s - hexdump_ascii(len=%lu):\n",
448  			title, (unsigned long) len);
449  		while (len) {
450  			llen = len > line_len ? line_len : len;
451  			fprintf(out_file, "    ");
452  			for (i = 0; i < llen; i++)
453  				fprintf(out_file, " %02x", pos[i]);
454  			for (i = llen; i < line_len; i++)
455  				fprintf(out_file, "   ");
456  			fprintf(out_file, "   ");
457  			for (i = 0; i < llen; i++) {
458  				if (isprint(pos[i]))
459  					fprintf(out_file, "%c", pos[i]);
460  				else
461  					fprintf(out_file, "_");
462  			}
463  			for (i = llen; i < line_len; i++)
464  				fprintf(out_file, " ");
465  			fprintf(out_file, "\n");
466  			pos += llen;
467  			len -= llen;
468  		}
469  	}
470  file_done:
471  #endif /* CONFIG_DEBUG_FILE */
472  	if (!wpa_debug_syslog && !out_file) {
473  		if (!show) {
474  			printf("%s - hexdump_ascii(len=%lu): [REMOVED]\n",
475  			       title, (unsigned long) len);
476  			return;
477  		}
478  		if (buf == NULL) {
479  			printf("%s - hexdump_ascii(len=%lu): [NULL]\n",
480  			       title, (unsigned long) len);
481  			return;
482  		}
483  		printf("%s - hexdump_ascii(len=%lu):\n", title,
484  		       (unsigned long) len);
485  		while (len) {
486  			llen = len > line_len ? line_len : len;
487  			printf("    ");
488  			for (i = 0; i < llen; i++)
489  				printf(" %02x", pos[i]);
490  			for (i = llen; i < line_len; i++)
491  				printf("   ");
492  			printf("   ");
493  			for (i = 0; i < llen; i++) {
494  				if (isprint(pos[i]))
495  					printf("%c", pos[i]);
496  				else
497  					printf("_");
498  			}
499  			for (i = llen; i < line_len; i++)
500  				printf(" ");
501  			printf("\n");
502  			pos += llen;
503  			len -= llen;
504  		}
505  	}
506  #endif /* CONFIG_ANDROID_LOG */
507  }
508  
509  
wpa_hexdump_ascii(int level,const char * title,const void * buf,size_t len)510  void wpa_hexdump_ascii(int level, const char *title, const void *buf,
511  		       size_t len)
512  {
513  	_wpa_hexdump_ascii(level, title, buf, len, 1);
514  }
515  
516  
wpa_hexdump_ascii_key(int level,const char * title,const void * buf,size_t len)517  void wpa_hexdump_ascii_key(int level, const char *title, const void *buf,
518  			   size_t len)
519  {
520  	_wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys);
521  }
522  
523  
524  #ifdef CONFIG_DEBUG_FILE
525  static char *last_path = NULL;
526  #endif /* CONFIG_DEBUG_FILE */
527  
wpa_debug_reopen_file(void)528  int wpa_debug_reopen_file(void)
529  {
530  #ifdef CONFIG_DEBUG_FILE
531  	int rv;
532  	char *tmp;
533  
534  	if (!last_path)
535  		return 0; /* logfile not used */
536  
537  	tmp = os_strdup(last_path);
538  	if (!tmp)
539  		return -1;
540  
541  	wpa_debug_close_file();
542  	rv = wpa_debug_open_file(tmp);
543  	os_free(tmp);
544  	return rv;
545  #else /* CONFIG_DEBUG_FILE */
546  	return 0;
547  #endif /* CONFIG_DEBUG_FILE */
548  }
549  
550  
wpa_debug_open_file(const char * path)551  int wpa_debug_open_file(const char *path)
552  {
553  #ifdef CONFIG_DEBUG_FILE
554  	int out_fd;
555  
556  	if (!path)
557  		return 0;
558  
559  	if (last_path == NULL || os_strcmp(last_path, path) != 0) {
560  		/* Save our path to enable re-open */
561  		os_free(last_path);
562  		last_path = os_strdup(path);
563  	}
564  
565  	out_fd = open(path, O_CREAT | O_APPEND | O_WRONLY,
566  		      S_IRUSR | S_IWUSR | S_IRGRP);
567  	if (out_fd < 0) {
568  		wpa_printf(MSG_ERROR,
569  			   "%s: Failed to open output file descriptor, using standard output",
570  			   __func__);
571  		return -1;
572  	}
573  
574  #ifdef __linux__
575  	if (fcntl(out_fd, F_SETFD, FD_CLOEXEC) < 0) {
576  		wpa_printf(MSG_DEBUG,
577  			   "%s: Failed to set FD_CLOEXEC - continue without: %s",
578  			   __func__, strerror(errno));
579  	}
580  #endif /* __linux__ */
581  
582  	out_file = fdopen(out_fd, "a");
583  	if (out_file == NULL) {
584  		wpa_printf(MSG_ERROR, "wpa_debug_open_file: Failed to open "
585  			   "output file, using standard output");
586  		close(out_fd);
587  		return -1;
588  	}
589  #ifndef _WIN32
590  	setvbuf(out_file, NULL, _IOLBF, 0);
591  #endif /* _WIN32 */
592  #else /* CONFIG_DEBUG_FILE */
593  	(void)path;
594  #endif /* CONFIG_DEBUG_FILE */
595  	return 0;
596  }
597  
598  
wpa_debug_stop_log(void)599  void wpa_debug_stop_log(void)
600  {
601  #ifdef CONFIG_DEBUG_FILE
602  	if (!out_file)
603  		return;
604  	fclose(out_file);
605  	out_file = NULL;
606  #endif /* CONFIG_DEBUG_FILE */
607  }
608  
609  
wpa_debug_close_file(void)610  void wpa_debug_close_file(void)
611  {
612  #ifdef CONFIG_DEBUG_FILE
613  	wpa_debug_stop_log();
614  	os_free(last_path);
615  	last_path = NULL;
616  #endif /* CONFIG_DEBUG_FILE */
617  }
618  
619  
wpa_debug_setup_stdout(void)620  void wpa_debug_setup_stdout(void)
621  {
622  #ifndef _WIN32
623  	setvbuf(stdout, NULL, _IOLBF, 0);
624  #endif /* _WIN32 */
625  }
626  
627  #endif /* CONFIG_NO_STDOUT_DEBUG */
628  
629  
630  #ifndef CONFIG_NO_WPA_MSG
631  static wpa_msg_cb_func wpa_msg_cb = NULL;
632  
wpa_msg_register_cb(wpa_msg_cb_func func)633  void wpa_msg_register_cb(wpa_msg_cb_func func)
634  {
635  	wpa_msg_cb = func;
636  }
637  
638  
639  static wpa_msg_get_ifname_func wpa_msg_ifname_cb = NULL;
640  
wpa_msg_register_ifname_cb(wpa_msg_get_ifname_func func)641  void wpa_msg_register_ifname_cb(wpa_msg_get_ifname_func func)
642  {
643  	wpa_msg_ifname_cb = func;
644  }
645  
646  
wpa_msg(void * ctx,int level,const char * fmt,...)647  void wpa_msg(void *ctx, int level, const char *fmt, ...)
648  {
649  	va_list ap;
650  	char *buf;
651  	int buflen;
652  	int len;
653  	char prefix[130];
654  
655  	va_start(ap, fmt);
656  	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
657  	va_end(ap);
658  
659  	buf = os_malloc(buflen);
660  	if (buf == NULL) {
661  		wpa_printf(MSG_ERROR, "wpa_msg: Failed to allocate message "
662  			   "buffer");
663  		return;
664  	}
665  	va_start(ap, fmt);
666  	prefix[0] = '\0';
667  	if (wpa_msg_ifname_cb) {
668  		const char *ifname = wpa_msg_ifname_cb(ctx);
669  		if (ifname) {
670  			int res = os_snprintf(prefix, sizeof(prefix), "%s: ",
671  					      ifname);
672  			if (os_snprintf_error(sizeof(prefix), res))
673  				prefix[0] = '\0';
674  		}
675  	}
676  	len = vsnprintf(buf, buflen, fmt, ap);
677  	va_end(ap);
678  	wpa_printf(level, "%s%s", prefix, buf);
679  	if (wpa_msg_cb)
680  		wpa_msg_cb(ctx, level, WPA_MSG_PER_INTERFACE, buf, len);
681  	bin_clear_free(buf, buflen);
682  }
683  
684  
wpa_msg_ctrl(void * ctx,int level,const char * fmt,...)685  void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...)
686  {
687  	va_list ap;
688  	char *buf;
689  	int buflen;
690  	int len;
691  
692  	if (!wpa_msg_cb)
693  		return;
694  
695  	va_start(ap, fmt);
696  	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
697  	va_end(ap);
698  
699  	buf = os_malloc(buflen);
700  	if (buf == NULL) {
701  		wpa_printf(MSG_ERROR, "wpa_msg_ctrl: Failed to allocate "
702  			   "message buffer");
703  		return;
704  	}
705  	va_start(ap, fmt);
706  	len = vsnprintf(buf, buflen, fmt, ap);
707  	va_end(ap);
708  	wpa_msg_cb(ctx, level, WPA_MSG_PER_INTERFACE, buf, len);
709  	bin_clear_free(buf, buflen);
710  }
711  
712  
wpa_msg_global(void * ctx,int level,const char * fmt,...)713  void wpa_msg_global(void *ctx, int level, const char *fmt, ...)
714  {
715  	va_list ap;
716  	char *buf;
717  	int buflen;
718  	int len;
719  
720  	va_start(ap, fmt);
721  	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
722  	va_end(ap);
723  
724  	buf = os_malloc(buflen);
725  	if (buf == NULL) {
726  		wpa_printf(MSG_ERROR, "wpa_msg_global: Failed to allocate "
727  			   "message buffer");
728  		return;
729  	}
730  	va_start(ap, fmt);
731  	len = vsnprintf(buf, buflen, fmt, ap);
732  	va_end(ap);
733  	wpa_printf(level, "%s", buf);
734  	if (wpa_msg_cb)
735  		wpa_msg_cb(ctx, level, WPA_MSG_GLOBAL, buf, len);
736  	bin_clear_free(buf, buflen);
737  }
738  
739  
wpa_msg_global_ctrl(void * ctx,int level,const char * fmt,...)740  void wpa_msg_global_ctrl(void *ctx, int level, const char *fmt, ...)
741  {
742  	va_list ap;
743  	char *buf;
744  	int buflen;
745  	int len;
746  
747  	if (!wpa_msg_cb)
748  		return;
749  
750  	va_start(ap, fmt);
751  	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
752  	va_end(ap);
753  
754  	buf = os_malloc(buflen);
755  	if (buf == NULL) {
756  		wpa_printf(MSG_ERROR,
757  			   "wpa_msg_global_ctrl: Failed to allocate message buffer");
758  		return;
759  	}
760  	va_start(ap, fmt);
761  	len = vsnprintf(buf, buflen, fmt, ap);
762  	va_end(ap);
763  	wpa_msg_cb(ctx, level, WPA_MSG_GLOBAL, buf, len);
764  	bin_clear_free(buf, buflen);
765  }
766  
767  
wpa_msg_no_global(void * ctx,int level,const char * fmt,...)768  void wpa_msg_no_global(void *ctx, int level, const char *fmt, ...)
769  {
770  	va_list ap;
771  	char *buf;
772  	int buflen;
773  	int len;
774  
775  	va_start(ap, fmt);
776  	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
777  	va_end(ap);
778  
779  	buf = os_malloc(buflen);
780  	if (buf == NULL) {
781  		wpa_printf(MSG_ERROR, "wpa_msg_no_global: Failed to allocate "
782  			   "message buffer");
783  		return;
784  	}
785  	va_start(ap, fmt);
786  	len = vsnprintf(buf, buflen, fmt, ap);
787  	va_end(ap);
788  	wpa_printf(level, "%s", buf);
789  	if (wpa_msg_cb)
790  		wpa_msg_cb(ctx, level, WPA_MSG_NO_GLOBAL, buf, len);
791  	bin_clear_free(buf, buflen);
792  }
793  
794  
wpa_msg_global_only(void * ctx,int level,const char * fmt,...)795  void wpa_msg_global_only(void *ctx, int level, const char *fmt, ...)
796  {
797  	va_list ap;
798  	char *buf;
799  	int buflen;
800  	int len;
801  
802  	va_start(ap, fmt);
803  	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
804  	va_end(ap);
805  
806  	buf = os_malloc(buflen);
807  	if (buf == NULL) {
808  		wpa_printf(MSG_ERROR, "%s: Failed to allocate message buffer",
809  			   __func__);
810  		return;
811  	}
812  	va_start(ap, fmt);
813  	len = vsnprintf(buf, buflen, fmt, ap);
814  	va_end(ap);
815  	wpa_printf(level, "%s", buf);
816  	if (wpa_msg_cb)
817  		wpa_msg_cb(ctx, level, WPA_MSG_ONLY_GLOBAL, buf, len);
818  	os_free(buf);
819  }
820  
821  #endif /* CONFIG_NO_WPA_MSG */
822  
823  
824  #ifndef CONFIG_NO_HOSTAPD_LOGGER
825  static hostapd_logger_cb_func hostapd_logger_cb = NULL;
826  
hostapd_logger_register_cb(hostapd_logger_cb_func func)827  void hostapd_logger_register_cb(hostapd_logger_cb_func func)
828  {
829  	hostapd_logger_cb = func;
830  }
831  
832  
hostapd_logger(void * ctx,const u8 * addr,unsigned int module,int level,const char * fmt,...)833  void hostapd_logger(void *ctx, const u8 *addr, unsigned int module, int level,
834  		    const char *fmt, ...)
835  {
836  	va_list ap;
837  	char *buf;
838  	int buflen;
839  	int len;
840  
841  	va_start(ap, fmt);
842  	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
843  	va_end(ap);
844  
845  	buf = os_malloc(buflen);
846  	if (buf == NULL) {
847  		wpa_printf(MSG_ERROR, "hostapd_logger: Failed to allocate "
848  			   "message buffer");
849  		return;
850  	}
851  	va_start(ap, fmt);
852  	len = vsnprintf(buf, buflen, fmt, ap);
853  	va_end(ap);
854  	if (hostapd_logger_cb)
855  		hostapd_logger_cb(ctx, addr, module, level, buf, len);
856  	else if (addr)
857  		wpa_printf(MSG_DEBUG, "hostapd_logger: STA " MACSTR " - %s",
858  			   MAC2STR(addr), buf);
859  	else
860  		wpa_printf(MSG_DEBUG, "hostapd_logger: %s", buf);
861  	bin_clear_free(buf, buflen);
862  }
863  #endif /* CONFIG_NO_HOSTAPD_LOGGER */
864  
865  
debug_level_str(int level)866  const char * debug_level_str(int level)
867  {
868  	switch (level) {
869  	case MSG_EXCESSIVE:
870  		return "EXCESSIVE";
871  	case MSG_MSGDUMP:
872  		return "MSGDUMP";
873  	case MSG_DEBUG:
874  		return "DEBUG";
875  	case MSG_INFO:
876  		return "INFO";
877  	case MSG_WARNING:
878  		return "WARNING";
879  	case MSG_ERROR:
880  		return "ERROR";
881  	default:
882  		return "?";
883  	}
884  }
885  
886  
str_to_debug_level(const char * s)887  int str_to_debug_level(const char *s)
888  {
889  	if (os_strcasecmp(s, "EXCESSIVE") == 0)
890  		return MSG_EXCESSIVE;
891  	if (os_strcasecmp(s, "MSGDUMP") == 0)
892  		return MSG_MSGDUMP;
893  	if (os_strcasecmp(s, "DEBUG") == 0)
894  		return MSG_DEBUG;
895  	if (os_strcasecmp(s, "INFO") == 0)
896  		return MSG_INFO;
897  	if (os_strcasecmp(s, "WARNING") == 0)
898  		return MSG_WARNING;
899  	if (os_strcasecmp(s, "ERROR") == 0)
900  		return MSG_ERROR;
901  	return -1;
902  }
903