tizen beta release
[framework/connectivity/wpasupplicant.git] / src / utils / wpa_debug.c
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 #ifdef CONFIG_DEBUG_SYSLOG
20 #include <syslog.h>
21
22 static int wpa_debug_syslog = 0;
23 #endif /* CONFIG_DEBUG_SYSLOG */
24
25
26 #ifdef CONFIG_DEBUG_FILE
27 static FILE *out_file = NULL;
28 #endif /* CONFIG_DEBUG_FILE */
29 int wpa_debug_level = MSG_INFO;
30 int wpa_debug_show_keys = 0;
31 int wpa_debug_timestamp = 0;
32
33
34 #ifndef CONFIG_NO_STDOUT_DEBUG
35
36 void wpa_debug_print_timestamp(void)
37 {
38         struct os_time tv;
39
40         /*
41          * Oct, 26th. 2011. TIZEN
42          * Change time log's display expression like year-month-day hour:min:sec.milisec 
43          */
44
45         struct tm *ptm;
46         char time_string[40];
47         
48         if (!wpa_debug_timestamp)
49                 return;
50
51         os_get_time(&tv);
52
53         ptm = localtime ( &tv.sec);
54         strftime(time_string,sizeof(time_string), "%Y-%m-%d %H:%M:%S",ptm);
55 #ifdef CONFIG_DEBUG_FILE
56         if (out_file) {
57                 fprintf(out_file, "%s.%06u: ", time_string,
58                         (unsigned int) tv.usec);
59         } else
60 #endif /* CONFIG_DEBUG_FILE */
61         printf("%s.%06u: ", time_string, (unsigned int) tv.usec);
62 }
63
64
65 #ifdef CONFIG_DEBUG_SYSLOG
66 void wpa_debug_open_syslog(void)
67 {
68         openlog("wpa_supplicant", LOG_PID | LOG_NDELAY, LOG_DAEMON);
69         wpa_debug_syslog++;
70 }
71
72
73 void wpa_debug_close_syslog(void)
74 {
75         if (wpa_debug_syslog)
76                 closelog();
77 }
78
79
80 static int syslog_priority(int level)
81 {
82         switch (level) {
83         case MSG_MSGDUMP:
84         case MSG_DEBUG:
85                 return LOG_DEBUG;
86         case MSG_INFO:
87                 return LOG_NOTICE;
88         case MSG_WARNING:
89                 return LOG_WARNING;
90         case MSG_ERROR:
91                 return LOG_ERR;
92         }
93         return LOG_INFO;
94 }
95 #endif /* CONFIG_DEBUG_SYSLOG */
96
97
98 /**
99  * wpa_printf - conditional printf
100  * @level: priority level (MSG_*) of the message
101  * @fmt: printf format string, followed by optional arguments
102  *
103  * This function is used to print conditional debugging and error messages. The
104  * output may be directed to stdout, stderr, and/or syslog based on
105  * configuration.
106  *
107  * Note: New line '\n' is added to the end of the text when printing to stdout.
108  */
109 void wpa_printf(int level, const char *fmt, ...)
110 {
111         va_list ap;
112
113         va_start(ap, fmt);
114         if (level >= wpa_debug_level) {
115 #ifdef CONFIG_DEBUG_SYSLOG
116                 if (wpa_debug_syslog) {
117                         vsyslog(syslog_priority(level), fmt, ap);
118                 } else {
119 #endif /* CONFIG_DEBUG_SYSLOG */
120                 wpa_debug_print_timestamp();
121 #ifdef CONFIG_DEBUG_FILE
122                 if (out_file) {
123                         vfprintf(out_file, fmt, ap);
124                         fprintf(out_file, "\n");
125                 } else {
126 #endif /* CONFIG_DEBUG_FILE */
127                 vprintf(fmt, ap);
128                 printf("\n");
129 #ifdef CONFIG_DEBUG_FILE
130                 }
131 #endif /* CONFIG_DEBUG_FILE */
132 #ifdef CONFIG_DEBUG_SYSLOG
133                 }
134 #endif /* CONFIG_DEBUG_SYSLOG */
135         }
136         va_end(ap);
137 }
138
139
140 static void _wpa_hexdump(int level, const char *title, const u8 *buf,
141                          size_t len, int show)
142 {
143         size_t i;
144         if (level < wpa_debug_level)
145                 return;
146         wpa_debug_print_timestamp();
147 #ifdef CONFIG_DEBUG_FILE
148         if (out_file) {
149                 fprintf(out_file, "%s - hexdump(len=%lu):",
150                         title, (unsigned long) len);
151                 if (buf == NULL) {
152                         fprintf(out_file, " [NULL]");
153                 } else if (show) {
154                         for (i = 0; i < len; i++)
155                                 fprintf(out_file, " %02x", buf[i]);
156                 } else {
157                         fprintf(out_file, " [REMOVED]");
158                 }
159                 fprintf(out_file, "\n");
160         } else {
161 #endif /* CONFIG_DEBUG_FILE */
162         printf("%s - hexdump(len=%lu):", title, (unsigned long) len);
163         if (buf == NULL) {
164                 printf(" [NULL]");
165         } else if (show) {
166                 for (i = 0; i < len; i++)
167                         printf(" %02x", buf[i]);
168         } else {
169                 printf(" [REMOVED]");
170         }
171         printf("\n");
172 #ifdef CONFIG_DEBUG_FILE
173         }
174 #endif /* CONFIG_DEBUG_FILE */
175 }
176
177 void wpa_hexdump(int level, const char *title, const u8 *buf, size_t len)
178 {
179         _wpa_hexdump(level, title, buf, len, 1);
180 }
181
182
183 void wpa_hexdump_key(int level, const char *title, const u8 *buf, size_t len)
184 {
185         _wpa_hexdump(level, title, buf, len, wpa_debug_show_keys);
186 }
187
188
189 static void _wpa_hexdump_ascii(int level, const char *title, const u8 *buf,
190                                size_t len, int show)
191 {
192         size_t i, llen;
193         const u8 *pos = buf;
194         const size_t line_len = 16;
195
196         if (level < wpa_debug_level)
197                 return;
198         wpa_debug_print_timestamp();
199 #ifdef CONFIG_DEBUG_FILE
200         if (out_file) {
201                 if (!show) {
202                         fprintf(out_file,
203                                 "%s - hexdump_ascii(len=%lu): [REMOVED]\n",
204                                 title, (unsigned long) len);
205                         return;
206                 }
207                 if (buf == NULL) {
208                         fprintf(out_file,
209                                 "%s - hexdump_ascii(len=%lu): [NULL]\n",
210                                 title, (unsigned long) len);
211                         return;
212                 }
213                 fprintf(out_file, "%s - hexdump_ascii(len=%lu):\n",
214                         title, (unsigned long) len);
215                 while (len) {
216                         llen = len > line_len ? line_len : len;
217                         fprintf(out_file, "    ");
218                         for (i = 0; i < llen; i++)
219                                 fprintf(out_file, " %02x", pos[i]);
220                         for (i = llen; i < line_len; i++)
221                                 fprintf(out_file, "   ");
222                         fprintf(out_file, "   ");
223                         for (i = 0; i < llen; i++) {
224                                 if (isprint(pos[i]))
225                                         fprintf(out_file, "%c", pos[i]);
226                                 else
227                                         fprintf(out_file, "_");
228                         }
229                         for (i = llen; i < line_len; i++)
230                                 fprintf(out_file, " ");
231                         fprintf(out_file, "\n");
232                         pos += llen;
233                         len -= llen;
234                 }
235         } else {
236 #endif /* CONFIG_DEBUG_FILE */
237         if (!show) {
238                 printf("%s - hexdump_ascii(len=%lu): [REMOVED]\n",
239                        title, (unsigned long) len);
240                 return;
241         }
242         if (buf == NULL) {
243                 printf("%s - hexdump_ascii(len=%lu): [NULL]\n",
244                        title, (unsigned long) len);
245                 return;
246         }
247         printf("%s - hexdump_ascii(len=%lu):\n", title, (unsigned long) len);
248         while (len) {
249                 llen = len > line_len ? line_len : len;
250                 printf("    ");
251                 for (i = 0; i < llen; i++)
252                         printf(" %02x", pos[i]);
253                 for (i = llen; i < line_len; i++)
254                         printf("   ");
255                 printf("   ");
256                 for (i = 0; i < llen; i++) {
257                         if (isprint(pos[i]))
258                                 printf("%c", pos[i]);
259                         else
260                                 printf("_");
261                 }
262                 for (i = llen; i < line_len; i++)
263                         printf(" ");
264                 printf("\n");
265                 pos += llen;
266                 len -= llen;
267         }
268 #ifdef CONFIG_DEBUG_FILE
269         }
270 #endif /* CONFIG_DEBUG_FILE */
271 }
272
273
274 void wpa_hexdump_ascii(int level, const char *title, const u8 *buf, size_t len)
275 {
276         _wpa_hexdump_ascii(level, title, buf, len, 1);
277 }
278
279
280 void wpa_hexdump_ascii_key(int level, const char *title, const u8 *buf,
281                            size_t len)
282 {
283         _wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys);
284 }
285
286
287 int wpa_debug_open_file(const char *path)
288 {
289 #ifdef CONFIG_DEBUG_FILE
290         if (!path)
291                 return 0;
292         out_file = fopen(path, "a");
293         if (out_file == NULL) {
294                 wpa_printf(MSG_ERROR, "wpa_debug_open_file: Failed to open "
295                            "output file, using standard output");
296                 return -1;
297         }
298 #ifndef _WIN32
299         setvbuf(out_file, NULL, _IOLBF, 0);
300 #endif /* _WIN32 */
301 #endif /* CONFIG_DEBUG_FILE */
302         return 0;
303 }
304
305
306 void wpa_debug_close_file(void)
307 {
308 #ifdef CONFIG_DEBUG_FILE
309         if (!out_file)
310                 return;
311         fclose(out_file);
312         out_file = NULL;
313 #endif /* CONFIG_DEBUG_FILE */
314 }
315
316 #endif /* CONFIG_NO_STDOUT_DEBUG */
317
318
319 #ifndef CONFIG_NO_WPA_MSG
320 static wpa_msg_cb_func wpa_msg_cb = NULL;
321
322 void wpa_msg_register_cb(wpa_msg_cb_func func)
323 {
324         wpa_msg_cb = func;
325 }
326
327
328 void wpa_msg(void *ctx, int level, const char *fmt, ...)
329 {
330         va_list ap;
331         char *buf;
332         const int buflen = 2048;
333         int len;
334
335         buf = os_malloc(buflen);
336         if (buf == NULL) {
337                 wpa_printf(MSG_ERROR, "wpa_msg: Failed to allocate message "
338                            "buffer");
339                 return;
340         }
341         va_start(ap, fmt);
342         len = vsnprintf(buf, buflen, fmt, ap);
343         va_end(ap);
344         wpa_printf(level, "%s", buf);
345         if (wpa_msg_cb)
346                 wpa_msg_cb(ctx, level, buf, len);
347         os_free(buf);
348 }
349
350
351 void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...)
352 {
353         va_list ap;
354         char *buf;
355         const int buflen = 2048;
356         int len;
357
358         if (!wpa_msg_cb)
359                 return;
360
361         buf = os_malloc(buflen);
362         if (buf == NULL) {
363                 wpa_printf(MSG_ERROR, "wpa_msg_ctrl: Failed to allocate "
364                            "message buffer");
365                 return;
366         }
367         va_start(ap, fmt);
368         len = vsnprintf(buf, buflen, fmt, ap);
369         va_end(ap);
370         wpa_msg_cb(ctx, level, buf, len);
371         os_free(buf);
372 }
373 #endif /* CONFIG_NO_WPA_MSG */
374
375
376 #ifndef CONFIG_NO_HOSTAPD_LOGGER
377 static hostapd_logger_cb_func hostapd_logger_cb = NULL;
378
379 void hostapd_logger_register_cb(hostapd_logger_cb_func func)
380 {
381         hostapd_logger_cb = func;
382 }
383
384
385 void hostapd_logger(void *ctx, const u8 *addr, unsigned int module, int level,
386                     const char *fmt, ...)
387 {
388         va_list ap;
389         char *buf;
390         const int buflen = 2048;
391         int len;
392
393         buf = os_malloc(buflen);
394         if (buf == NULL) {
395                 wpa_printf(MSG_ERROR, "hostapd_logger: Failed to allocate "
396                            "message buffer");
397                 return;
398         }
399         va_start(ap, fmt);
400         len = vsnprintf(buf, buflen, fmt, ap);
401         va_end(ap);
402         if (hostapd_logger_cb)
403                 hostapd_logger_cb(ctx, addr, module, level, buf, len);
404         else if (addr)
405                 wpa_printf(MSG_DEBUG, "hostapd_logger: STA " MACSTR " - %s",
406                            MAC2STR(addr), buf);
407         else
408                 wpa_printf(MSG_DEBUG, "hostapd_logger: %s", buf);
409         os_free(buf);
410 }
411 #endif /* CONFIG_NO_HOSTAPD_LOGGER */