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