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 <utils/includes.h>
10 #include <utils/common.h>
11 
12 #include "wpa_debug.h"
13 
14 #include <zephyr/logging/log.h>
15 
16 #define WPA_DEBUG_MAX_LINE_LENGTH 256
17 
18 LOG_MODULE_REGISTER(wpa_supp, CONFIG_WIFI_NM_WPA_SUPPLICANT_LOG_LEVEL);
19 
20 int wpa_debug_level = MSG_INFO;
21 int wpa_debug_show_keys;
22 int wpa_debug_timestamp;
23 
24 #ifndef CONFIG_NO_STDOUT_DEBUG
25 
wpa_printf_impl(int level,const char * fmt,...)26 void wpa_printf_impl(int level, const char *fmt, ...)
27 {
28 	int len;
29 	va_list ap;
30 	char buffer[WPA_DEBUG_MAX_LINE_LENGTH];
31 
32 	if (level < wpa_debug_level)
33 		return;
34 
35 	va_start(ap, fmt);
36 	vsnprintf(buffer, sizeof(buffer), fmt, ap);
37 	va_end(ap);
38 
39 	/* Remove all newlines as the logger macros will add one */
40 	len = strlen(buffer);
41 	if (len > 0 && buffer[len - 1] == '\n') {
42 		buffer[len - 1] = '\0';
43 	}
44 
45 	switch (level) {
46 	case MSG_ERROR:
47 		LOG_ERR("%s", buffer);
48 		break;
49 	case MSG_WARNING:
50 		LOG_WRN("%s", buffer);
51 		break;
52 	case MSG_INFO:
53 		LOG_INF("%s", buffer);
54 		break;
55 	case MSG_DEBUG:
56 	case MSG_MSGDUMP:
57 	case MSG_EXCESSIVE:
58 		LOG_DBG("%s", buffer);
59 		break;
60 	default:
61 		break;
62 	}
63 
64 	forced_memzero(buffer, sizeof(buffer));
65 }
66 
_wpa_hexdump(int level,const char * title,const u8 * buf,size_t len,int show)67 static void _wpa_hexdump(int level, const char *title, const u8 *buf, size_t len, int show)
68 {
69 	size_t i;
70 	const char *content;
71 	char *content_buf = NULL;
72 
73 	if (level < wpa_debug_level)
74 		return;
75 
76 	if (buf == NULL) {
77 		content = " [NULL]";
78 	} else if (show) {
79 		content = content_buf = os_malloc(3 * len + 1);
80 
81 		if (content == NULL) {
82 			wpa_printf(MSG_ERROR, "wpa_hexdump: Failed to allocate message buffer");
83 			return;
84 		}
85 
86 		for (i = 0; i < len; i++) {
87 			os_snprintf(&content_buf[i * 3], 4, " %02x", buf[i]);
88 		}
89 	} else {
90 		content = " [REMOVED]";
91 	}
92 
93 	wpa_printf(level, "%s - hexdump(len=%lu):%s", title, (unsigned long)len, content);
94 	bin_clear_free(content_buf, 3 * len + 1);
95 }
96 
wpa_hexdump_impl(int level,const char * title,const void * buf,size_t len)97 void wpa_hexdump_impl(int level, const char *title, const void *buf, size_t len)
98 {
99 	_wpa_hexdump(level, title, buf, len, 1);
100 }
101 
wpa_hexdump_key_impl(int level,const char * title,const void * buf,size_t len)102 void wpa_hexdump_key_impl(int level, const char *title, const void *buf, size_t len)
103 {
104 	_wpa_hexdump(level, title, buf, len, wpa_debug_show_keys);
105 }
106 
_wpa_hexdump_ascii(int level,const char * title,const void * buf,size_t len,int show)107 static void _wpa_hexdump_ascii(int level, const char *title, const void *buf, size_t len, int show)
108 {
109 	const char *content;
110 
111 	if (level < wpa_debug_level) {
112 		return;
113 	}
114 
115 	if (buf == NULL) {
116 		content = " [NULL]";
117 	} else if (show) {
118 		content = "";
119 	} else {
120 		content = " [REMOVED]";
121 	}
122 
123 	wpa_printf(level, "%s - hexdump_ascii(len=%lu):%s", title, (unsigned long)len, content);
124 
125 	if (buf == NULL || !show) {
126 		return;
127 	}
128 
129 	switch (level) {
130 	case MSG_ERROR:
131 		LOG_HEXDUMP_ERR(buf, len, "");
132 		break;
133 	case MSG_WARNING:
134 		LOG_HEXDUMP_WRN(buf, len, "");
135 		break;
136 	case MSG_INFO:
137 		LOG_HEXDUMP_INF(buf, len, "");
138 		break;
139 	case MSG_DEBUG:
140 	case MSG_MSGDUMP:
141 	case MSG_EXCESSIVE:
142 		LOG_HEXDUMP_DBG(buf, len, "");
143 		break;
144 	default:
145 		break;
146 	}
147 }
148 
wpa_hexdump_ascii_impl(int level,const char * title,const void * buf,size_t len)149 void wpa_hexdump_ascii_impl(int level, const char *title, const void *buf, size_t len)
150 {
151 	_wpa_hexdump_ascii(level, title, buf, len, 1);
152 }
153 
wpa_hexdump_ascii_key_impl(int level,const char * title,const void * buf,size_t len)154 void wpa_hexdump_ascii_key_impl(int level, const char *title, const void *buf, size_t len)
155 {
156 	_wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys);
157 }
158 
159 #endif /* CONFIG_NO_STDOUT_DEBUG */
160 
161 #ifndef CONFIG_NO_WPA_MSG
162 
163 static wpa_msg_cb_func wpa_msg_cb;
164 
wpa_msg_register_cb(wpa_msg_cb_func func)165 void wpa_msg_register_cb(wpa_msg_cb_func func)
166 {
167 	wpa_msg_cb = func;
168 }
169 
170 static wpa_msg_get_ifname_func wpa_msg_ifname_cb;
171 
wpa_msg_register_ifname_cb(wpa_msg_get_ifname_func func)172 void wpa_msg_register_ifname_cb(wpa_msg_get_ifname_func func)
173 {
174 	wpa_msg_ifname_cb = func;
175 }
176 
wpa_msg_impl(void * ctx,int level,const char * fmt,...)177 void wpa_msg_impl(void *ctx, int level, const char *fmt, ...)
178 {
179 	va_list ap;
180 	char *buf;
181 	int buflen;
182 	int len;
183 	char prefix[130];
184 
185 	va_start(ap, fmt);
186 	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
187 	va_end(ap);
188 
189 	buf = os_malloc(buflen);
190 	if (buf == NULL) {
191 		wpa_printf(MSG_ERROR, "wpa_msg: Failed to allocate message buffer");
192 		return;
193 	}
194 	va_start(ap, fmt);
195 	prefix[0] = '\0';
196 	if (wpa_msg_ifname_cb) {
197 		const char *ifname = wpa_msg_ifname_cb(ctx);
198 
199 		if (ifname) {
200 			int res = os_snprintf(prefix, sizeof(prefix), "%s: ", ifname);
201 
202 			if (os_snprintf_error(sizeof(prefix), res))
203 				prefix[0] = '\0';
204 		}
205 	}
206 	len = vsnprintf(buf, buflen, fmt, ap);
207 	va_end(ap);
208 	wpa_printf(level, "%s%s", prefix, buf);
209 	if (wpa_msg_cb)
210 		wpa_msg_cb(ctx, level, WPA_MSG_PER_INTERFACE, buf, len);
211 	bin_clear_free(buf, buflen);
212 }
213 
wpa_msg_ctrl_impl(void * ctx,int level,const char * fmt,...)214 void wpa_msg_ctrl_impl(void *ctx, int level, const char *fmt, ...)
215 {
216 	va_list ap;
217 	char *buf;
218 	int buflen;
219 	int len;
220 
221 	if (!wpa_msg_cb)
222 		return;
223 
224 	va_start(ap, fmt);
225 	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
226 	va_end(ap);
227 
228 	buf = os_malloc(buflen);
229 	if (buf == NULL) {
230 		wpa_printf(MSG_ERROR, "wpa_msg_ctrl: Failed to allocate message buffer");
231 		return;
232 	}
233 	va_start(ap, fmt);
234 	len = vsnprintf(buf, buflen, fmt, ap);
235 	va_end(ap);
236 	wpa_msg_cb(ctx, level, WPA_MSG_PER_INTERFACE, buf, len);
237 	bin_clear_free(buf, buflen);
238 }
239 
wpa_msg_global_impl(void * ctx,int level,const char * fmt,...)240 void wpa_msg_global_impl(void *ctx, int level, const char *fmt, ...)
241 {
242 	va_list ap;
243 	char *buf;
244 	int buflen;
245 	int len;
246 
247 	va_start(ap, fmt);
248 	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
249 	va_end(ap);
250 
251 	buf = os_malloc(buflen);
252 	if (buf == NULL) {
253 		wpa_printf(MSG_ERROR, "wpa_msg_global: Failed to allocate message buffer");
254 		return;
255 	}
256 	va_start(ap, fmt);
257 	len = vsnprintf(buf, buflen, fmt, ap);
258 	va_end(ap);
259 	wpa_printf(level, "%s", buf);
260 	if (wpa_msg_cb)
261 		wpa_msg_cb(ctx, level, WPA_MSG_GLOBAL, buf, len);
262 	bin_clear_free(buf, buflen);
263 }
264 
wpa_msg_global_ctrl_impl(void * ctx,int level,const char * fmt,...)265 void wpa_msg_global_ctrl_impl(void *ctx, int level, const char *fmt, ...)
266 {
267 	va_list ap;
268 	char *buf;
269 	int buflen;
270 	int len;
271 
272 	if (!wpa_msg_cb)
273 		return;
274 
275 	va_start(ap, fmt);
276 	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
277 	va_end(ap);
278 
279 	buf = os_malloc(buflen);
280 	if (buf == NULL) {
281 		wpa_printf(MSG_ERROR, "wpa_msg_global_ctrl: Failed to allocate message buffer");
282 		return;
283 	}
284 	va_start(ap, fmt);
285 	len = vsnprintf(buf, buflen, fmt, ap);
286 	va_end(ap);
287 	wpa_msg_cb(ctx, level, WPA_MSG_GLOBAL, buf, len);
288 	bin_clear_free(buf, buflen);
289 }
290 
wpa_msg_no_global_impl(void * ctx,int level,const char * fmt,...)291 void wpa_msg_no_global_impl(void *ctx, int level, const char *fmt, ...)
292 {
293 	va_list ap;
294 	char *buf;
295 	int buflen;
296 	int len;
297 
298 	va_start(ap, fmt);
299 	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
300 	va_end(ap);
301 
302 	buf = os_malloc(buflen);
303 	if (buf == NULL) {
304 		wpa_printf(MSG_ERROR, "wpa_msg_no_global: Failed to allocate message buffer");
305 		return;
306 	}
307 	va_start(ap, fmt);
308 	len = vsnprintf(buf, buflen, fmt, ap);
309 	va_end(ap);
310 	wpa_printf(level, "%s", buf);
311 	if (wpa_msg_cb)
312 		wpa_msg_cb(ctx, level, WPA_MSG_NO_GLOBAL, buf, len);
313 	bin_clear_free(buf, buflen);
314 }
315 
wpa_msg_global_only_impl(void * ctx,int level,const char * fmt,...)316 void wpa_msg_global_only_impl(void *ctx, int level, const char *fmt, ...)
317 {
318 	va_list ap;
319 	char *buf;
320 	int buflen;
321 	int len;
322 
323 	va_start(ap, fmt);
324 	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
325 	va_end(ap);
326 
327 	buf = os_malloc(buflen);
328 	if (buf == NULL) {
329 		wpa_printf(MSG_ERROR, "%s: Failed to allocate message buffer", __func__);
330 		return;
331 	}
332 	va_start(ap, fmt);
333 	len = vsnprintf(buf, buflen, fmt, ap);
334 	va_end(ap);
335 	wpa_printf(level, "%s", buf);
336 	if (wpa_msg_cb)
337 		wpa_msg_cb(ctx, level, WPA_MSG_ONLY_GLOBAL, buf, len);
338 	os_free(buf);
339 }
340 
341 #endif /* CONFIG_NO_WPA_MSG */
342 
343 #ifndef CONFIG_NO_HOSTAPD_LOGGER
344 
345 static hostapd_logger_cb_func hostapd_logger_cb;
346 
hostapd_logger_register_cb(hostapd_logger_cb_func func)347 void hostapd_logger_register_cb(hostapd_logger_cb_func func)
348 {
349 	hostapd_logger_cb = func;
350 }
351 
hostapd_logger(void * ctx,const u8 * addr,unsigned int module,int level,const char * fmt,...)352 void hostapd_logger(void *ctx, const u8 *addr, unsigned int module, int level, const char *fmt, ...)
353 {
354 	va_list ap;
355 	char *buf;
356 	int buflen;
357 	int len;
358 
359 	va_start(ap, fmt);
360 	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
361 	va_end(ap);
362 
363 	buf = os_malloc(buflen);
364 	if (buf == NULL) {
365 		wpa_printf(MSG_ERROR, "%s: Failed to allocate message buffer", __func__);
366 		return;
367 	}
368 	va_start(ap, fmt);
369 	len = vsnprintf(buf, buflen, fmt, ap);
370 	va_end(ap);
371 	if (hostapd_logger_cb)
372 		hostapd_logger_cb(ctx, addr, module, level, buf, len);
373 	else if (addr)
374 		wpa_printf(MSG_DEBUG, "%s: STA " MACSTR " - %s", __func__, MAC2STR(addr), buf);
375 	else
376 		wpa_printf(MSG_DEBUG, "%s: %s", __func__, buf);
377 	bin_clear_free(buf, buflen);
378 }
379 
380 #endif /* CONFIG_NO_HOSTAPD_LOGGER */
381 
debug_level_str(int level)382 const char *debug_level_str(int level)
383 {
384 	switch (level) {
385 	case MSG_EXCESSIVE:
386 		return "EXCESSIVE";
387 	case MSG_MSGDUMP:
388 		return "MSGDUMP";
389 	case MSG_DEBUG:
390 		return "DEBUG";
391 	case MSG_INFO:
392 		return "INFO";
393 	case MSG_WARNING:
394 		return "WARNING";
395 	case MSG_ERROR:
396 		return "ERROR";
397 	default:
398 		return "?";
399 	}
400 }
401 
str_to_debug_level(const char * s)402 int str_to_debug_level(const char *s)
403 {
404 	if (os_strcasecmp(s, "EXCESSIVE") == 0)
405 		return MSG_EXCESSIVE;
406 	if (os_strcasecmp(s, "MSGDUMP") == 0)
407 		return MSG_MSGDUMP;
408 	if (os_strcasecmp(s, "DEBUG") == 0)
409 		return MSG_DEBUG;
410 	if (os_strcasecmp(s, "INFO") == 0)
411 		return MSG_INFO;
412 	if (os_strcasecmp(s, "WARNING") == 0)
413 		return MSG_WARNING;
414 	if (os_strcasecmp(s, "ERROR") == 0)
415 		return MSG_ERROR;
416 	return -1;
417 }
418 
wpa_debug_stop_log(void)419 void wpa_debug_stop_log(void)
420 {
421 #ifdef CONFIG_DEBUG_FILE
422 	if (!out_file)
423 		return;
424 	fclose(out_file);
425 	out_file = NULL;
426 #endif /* CONFIG_DEBUG_FILE */
427 }
428