• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * wpa_supplicant/hostapd / Debug prints
3  * Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * Alternatively, this software may be distributed under the terms of BSD
10  * license.
11  *
12  * See README and COPYING for more details.
13  */
14 
15 #include "includes.h"
16 
17 #include "common.h"
18 
19 
20 #ifdef CONFIG_DEBUG_FILE
21 static FILE *out_file = NULL;
22 #endif /* CONFIG_DEBUG_FILE */
23 #ifdef CONFIG_ANDROID_LOG
24 int wpa_debug_level = MSG_WARNING;
25 #else
26 int wpa_debug_level = MSG_INFO;
27 #endif
28 int wpa_debug_show_keys = 0;
29 int wpa_debug_timestamp = 0;
30 
31 
32 #ifdef CONFIG_ANDROID_LOG
33 
34 #include <android/log.h>
35 
android_printf(int level,char * format,...)36 void android_printf(int level, char *format, ...)
37 {
38 	if (level >= wpa_debug_level) {
39 		va_list ap;
40 		if (level == MSG_ERROR) {
41 			level = ANDROID_LOG_ERROR;
42 		} else if (level == MSG_WARNING) {
43 			level = ANDROID_LOG_WARN;
44 		} else if (level == MSG_INFO) {
45 			level = ANDROID_LOG_INFO;
46 		} else {
47 			level = ANDROID_LOG_DEBUG;
48 		}
49 		va_start(ap, format);
50 		__android_log_vprint(level, "wpa_supplicant", format, ap);
51 		va_end(ap);
52 	}
53 }
54 
55 #else /* CONFIG_ANDROID_LOG */
56 
57 #ifndef CONFIG_NO_STDOUT_DEBUG
58 
wpa_debug_print_timestamp(void)59 void wpa_debug_print_timestamp(void)
60 {
61 	struct os_time tv;
62 
63 	if (!wpa_debug_timestamp)
64 		return;
65 
66 	os_get_time(&tv);
67 #ifdef CONFIG_DEBUG_FILE
68 	if (out_file) {
69 		fprintf(out_file, "%ld.%06u: ", (long) tv.sec,
70 			(unsigned int) tv.usec);
71 	} else
72 #endif /* CONFIG_DEBUG_FILE */
73 	printf("%ld.%06u: ", (long) tv.sec, (unsigned int) tv.usec);
74 }
75 
76 
77 /**
78  * wpa_printf - conditional printf
79  * @level: priority level (MSG_*) of the message
80  * @fmt: printf format string, followed by optional arguments
81  *
82  * This function is used to print conditional debugging and error messages. The
83  * output may be directed to stdout, stderr, and/or syslog based on
84  * configuration.
85  *
86  * Note: New line '\n' is added to the end of the text when printing to stdout.
87  */
wpa_printf(int level,const char * fmt,...)88 void wpa_printf(int level, const char *fmt, ...)
89 {
90 	va_list ap;
91 
92 	va_start(ap, fmt);
93 	if (level >= wpa_debug_level) {
94 		wpa_debug_print_timestamp();
95 #ifdef CONFIG_DEBUG_FILE
96 		if (out_file) {
97 			vfprintf(out_file, fmt, ap);
98 			fprintf(out_file, "\n");
99 		} else {
100 #endif /* CONFIG_DEBUG_FILE */
101 		vprintf(fmt, ap);
102 		printf("\n");
103 #ifdef CONFIG_DEBUG_FILE
104 		}
105 #endif /* CONFIG_DEBUG_FILE */
106 	}
107 	va_end(ap);
108 }
109 
110 
_wpa_hexdump(int level,const char * title,const u8 * buf,size_t len,int show)111 static void _wpa_hexdump(int level, const char *title, const u8 *buf,
112 			 size_t len, int show)
113 {
114 	size_t i;
115 	if (level < wpa_debug_level)
116 		return;
117 	wpa_debug_print_timestamp();
118 #ifdef CONFIG_DEBUG_FILE
119 	if (out_file) {
120 		fprintf(out_file, "%s - hexdump(len=%lu):",
121 			title, (unsigned long) len);
122 		if (buf == NULL) {
123 			fprintf(out_file, " [NULL]");
124 		} else if (show) {
125 			for (i = 0; i < len; i++)
126 				fprintf(out_file, " %02x", buf[i]);
127 		} else {
128 			fprintf(out_file, " [REMOVED]");
129 		}
130 		fprintf(out_file, "\n");
131 	} else {
132 #endif /* CONFIG_DEBUG_FILE */
133 	printf("%s - hexdump(len=%lu):", title, (unsigned long) len);
134 	if (buf == NULL) {
135 		printf(" [NULL]");
136 	} else if (show) {
137 		for (i = 0; i < len; i++)
138 			printf(" %02x", buf[i]);
139 	} else {
140 		printf(" [REMOVED]");
141 	}
142 	printf("\n");
143 #ifdef CONFIG_DEBUG_FILE
144 	}
145 #endif /* CONFIG_DEBUG_FILE */
146 }
147 
wpa_hexdump(int level,const char * title,const u8 * buf,size_t len)148 void wpa_hexdump(int level, const char *title, const u8 *buf, size_t len)
149 {
150 	_wpa_hexdump(level, title, buf, len, 1);
151 }
152 
153 
wpa_hexdump_key(int level,const char * title,const u8 * buf,size_t len)154 void wpa_hexdump_key(int level, const char *title, const u8 *buf, size_t len)
155 {
156 	_wpa_hexdump(level, title, buf, len, wpa_debug_show_keys);
157 }
158 
159 
_wpa_hexdump_ascii(int level,const char * title,const u8 * buf,size_t len,int show)160 static void _wpa_hexdump_ascii(int level, const char *title, const u8 *buf,
161 			       size_t len, int show)
162 {
163 	size_t i, llen;
164 	const u8 *pos = buf;
165 	const size_t line_len = 16;
166 
167 	if (level < wpa_debug_level)
168 		return;
169 	wpa_debug_print_timestamp();
170 #ifdef CONFIG_DEBUG_FILE
171 	if (out_file) {
172 		if (!show) {
173 			fprintf(out_file,
174 				"%s - hexdump_ascii(len=%lu): [REMOVED]\n",
175 				title, (unsigned long) len);
176 			return;
177 		}
178 		if (buf == NULL) {
179 			fprintf(out_file,
180 				"%s - hexdump_ascii(len=%lu): [NULL]\n",
181 				title, (unsigned long) len);
182 			return;
183 		}
184 		fprintf(out_file, "%s - hexdump_ascii(len=%lu):\n",
185 			title, (unsigned long) len);
186 		while (len) {
187 			llen = len > line_len ? line_len : len;
188 			fprintf(out_file, "    ");
189 			for (i = 0; i < llen; i++)
190 				fprintf(out_file, " %02x", pos[i]);
191 			for (i = llen; i < line_len; i++)
192 				fprintf(out_file, "   ");
193 			fprintf(out_file, "   ");
194 			for (i = 0; i < llen; i++) {
195 				if (isprint(pos[i]))
196 					fprintf(out_file, "%c", pos[i]);
197 				else
198 					fprintf(out_file, "_");
199 			}
200 			for (i = llen; i < line_len; i++)
201 				fprintf(out_file, " ");
202 			fprintf(out_file, "\n");
203 			pos += llen;
204 			len -= llen;
205 		}
206 	} else {
207 #endif /* CONFIG_DEBUG_FILE */
208 	if (!show) {
209 		printf("%s - hexdump_ascii(len=%lu): [REMOVED]\n",
210 		       title, (unsigned long) len);
211 		return;
212 	}
213 	if (buf == NULL) {
214 		printf("%s - hexdump_ascii(len=%lu): [NULL]\n",
215 		       title, (unsigned long) len);
216 		return;
217 	}
218 	printf("%s - hexdump_ascii(len=%lu):\n", title, (unsigned long) len);
219 	while (len) {
220 		llen = len > line_len ? line_len : len;
221 		printf("    ");
222 		for (i = 0; i < llen; i++)
223 			printf(" %02x", pos[i]);
224 		for (i = llen; i < line_len; i++)
225 			printf("   ");
226 		printf("   ");
227 		for (i = 0; i < llen; i++) {
228 			if (isprint(pos[i]))
229 				printf("%c", pos[i]);
230 			else
231 				printf("_");
232 		}
233 		for (i = llen; i < line_len; i++)
234 			printf(" ");
235 		printf("\n");
236 		pos += llen;
237 		len -= llen;
238 	}
239 #ifdef CONFIG_DEBUG_FILE
240 	}
241 #endif /* CONFIG_DEBUG_FILE */
242 }
243 
244 
wpa_hexdump_ascii(int level,const char * title,const u8 * buf,size_t len)245 void wpa_hexdump_ascii(int level, const char *title, const u8 *buf, size_t len)
246 {
247 	_wpa_hexdump_ascii(level, title, buf, len, 1);
248 }
249 
250 
wpa_hexdump_ascii_key(int level,const char * title,const u8 * buf,size_t len)251 void wpa_hexdump_ascii_key(int level, const char *title, const u8 *buf,
252 			   size_t len)
253 {
254 	_wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys);
255 }
256 
257 
wpa_debug_open_file(const char * path)258 int wpa_debug_open_file(const char *path)
259 {
260 #ifdef CONFIG_DEBUG_FILE
261 	if (!path)
262 		return 0;
263 	out_file = fopen(path, "a");
264 	if (out_file == NULL) {
265 		wpa_printf(MSG_ERROR, "wpa_debug_open_file: Failed to open "
266 			   "output file, using standard output");
267 		return -1;
268 	}
269 #ifndef _WIN32
270 	setvbuf(out_file, NULL, _IOLBF, 0);
271 #endif /* _WIN32 */
272 #endif /* CONFIG_DEBUG_FILE */
273 	return 0;
274 }
275 
276 
wpa_debug_close_file(void)277 void wpa_debug_close_file(void)
278 {
279 #ifdef CONFIG_DEBUG_FILE
280 	if (!out_file)
281 		return;
282 	fclose(out_file);
283 	out_file = NULL;
284 #endif /* CONFIG_DEBUG_FILE */
285 }
286 
287 #endif /* CONFIG_NO_STDOUT_DEBUG */
288 
289 #endif /* CONFIG_ANDROID_LOG */
290 
291 #ifndef CONFIG_NO_WPA_MSG
292 static wpa_msg_cb_func wpa_msg_cb = NULL;
293 
wpa_msg_register_cb(wpa_msg_cb_func func)294 void wpa_msg_register_cb(wpa_msg_cb_func func)
295 {
296 	wpa_msg_cb = func;
297 }
298 
299 
wpa_msg(void * ctx,int level,const char * fmt,...)300 void wpa_msg(void *ctx, int level, const char *fmt, ...)
301 {
302 	va_list ap;
303 	char *buf;
304 	const int buflen = 2048;
305 	int len;
306 
307 	buf = os_malloc(buflen);
308 	if (buf == NULL) {
309 		wpa_printf(MSG_ERROR, "wpa_msg: Failed to allocate message "
310 			   "buffer");
311 		return;
312 	}
313 	va_start(ap, fmt);
314 	len = vsnprintf(buf, buflen, fmt, ap);
315 	va_end(ap);
316 	wpa_printf(level, "%s", buf);
317 	if (wpa_msg_cb)
318 		wpa_msg_cb(ctx, level, buf, len);
319 	os_free(buf);
320 }
321 
322 
wpa_msg_ctrl(void * ctx,int level,const char * fmt,...)323 void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...)
324 {
325 	va_list ap;
326 	char *buf;
327 	const int buflen = 2048;
328 	int len;
329 
330 	if (!wpa_msg_cb)
331 		return;
332 
333 	buf = os_malloc(buflen);
334 	if (buf == NULL) {
335 		wpa_printf(MSG_ERROR, "wpa_msg_ctrl: Failed to allocate "
336 			   "message buffer");
337 		return;
338 	}
339 	va_start(ap, fmt);
340 	len = vsnprintf(buf, buflen, fmt, ap);
341 	va_end(ap);
342 	wpa_msg_cb(ctx, level, buf, len);
343 	os_free(buf);
344 }
345 #endif /* CONFIG_NO_WPA_MSG */
346 
347 
348 #ifndef CONFIG_NO_HOSTAPD_LOGGER
349 static hostapd_logger_cb_func hostapd_logger_cb = NULL;
350 
hostapd_logger_register_cb(hostapd_logger_cb_func func)351 void hostapd_logger_register_cb(hostapd_logger_cb_func func)
352 {
353 	hostapd_logger_cb = func;
354 }
355 
356 
hostapd_logger(void * ctx,const u8 * addr,unsigned int module,int level,const char * fmt,...)357 void hostapd_logger(void *ctx, const u8 *addr, unsigned int module, int level,
358 		    const char *fmt, ...)
359 {
360 	va_list ap;
361 	char *buf;
362 	const int buflen = 2048;
363 	int len;
364 
365 	buf = os_malloc(buflen);
366 	if (buf == NULL) {
367 		wpa_printf(MSG_ERROR, "hostapd_logger: Failed to allocate "
368 			   "message buffer");
369 		return;
370 	}
371 	va_start(ap, fmt);
372 	len = vsnprintf(buf, buflen, fmt, ap);
373 	va_end(ap);
374 	if (hostapd_logger_cb)
375 		hostapd_logger_cb(ctx, addr, module, level, buf, len);
376 	else
377 		wpa_printf(MSG_DEBUG, "hostapd_logger: %s", buf);
378 	os_free(buf);
379 }
380 #endif /* CONFIG_NO_HOSTAPD_LOGGER */
381