$search
00001 /* 00002 * wpa_supplicant/hostapd / Debug prints 00003 * Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi> 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License version 2 as 00007 * published by the Free Software Foundation. 00008 * 00009 * Alternatively, this software may be distributed under the terms of BSD 00010 * license. 00011 * 00012 * See README and COPYING for more details. 00013 */ 00014 00015 #include "includes.h" 00016 00017 #include "common.h" 00018 00019 #ifdef CONFIG_DEBUG_SYSLOG 00020 #include <syslog.h> 00021 00022 static int wpa_debug_syslog = 0; 00023 #endif /* CONFIG_DEBUG_SYSLOG */ 00024 00025 00026 #ifdef CONFIG_DEBUG_FILE 00027 static FILE *out_file = NULL; 00028 #endif /* CONFIG_DEBUG_FILE */ 00029 int wpa_debug_level = MSG_INFO; 00030 int wpa_debug_show_keys = 0; 00031 int wpa_debug_timestamp = 0; 00032 00033 00034 #ifndef CONFIG_NO_STDOUT_DEBUG 00035 00036 void wpa_debug_print_timestamp(void) 00037 { 00038 struct os_time tv; 00039 00040 if (!wpa_debug_timestamp) 00041 return; 00042 00043 os_get_time(&tv); 00044 #ifdef CONFIG_DEBUG_FILE 00045 if (out_file) { 00046 fprintf(out_file, "%ld.%06u: ", (long) tv.sec, 00047 (unsigned int) tv.usec); 00048 } else 00049 #endif /* CONFIG_DEBUG_FILE */ 00050 printf("%ld.%06u: ", (long) tv.sec, (unsigned int) tv.usec); 00051 } 00052 00053 00054 #ifdef CONFIG_DEBUG_SYSLOG 00055 void wpa_debug_open_syslog(void) 00056 { 00057 openlog("wpa_supplicant", LOG_PID | LOG_NDELAY, LOG_DAEMON); 00058 wpa_debug_syslog++; 00059 } 00060 00061 00062 void wpa_debug_close_syslog(void) 00063 { 00064 if (wpa_debug_syslog) 00065 closelog(); 00066 } 00067 00068 00069 static int syslog_priority(int level) 00070 { 00071 switch (level) { 00072 case MSG_MSGDUMP: 00073 case MSG_DEBUG: 00074 return LOG_DEBUG; 00075 case MSG_INFO: 00076 return LOG_NOTICE; 00077 case MSG_WARNING: 00078 return LOG_WARNING; 00079 case MSG_ERROR: 00080 return LOG_ERR; 00081 } 00082 return LOG_INFO; 00083 } 00084 #endif /* CONFIG_DEBUG_SYSLOG */ 00085 00086 00098 void wpa_printf(int level, const char *fmt, ...) 00099 { 00100 va_list ap; 00101 00102 va_start(ap, fmt); 00103 if (level >= wpa_debug_level) { 00104 #ifdef CONFIG_DEBUG_SYSLOG 00105 if (wpa_debug_syslog) { 00106 vsyslog(syslog_priority(level), fmt, ap); 00107 } else { 00108 #endif /* CONFIG_DEBUG_SYSLOG */ 00109 wpa_debug_print_timestamp(); 00110 #ifdef CONFIG_DEBUG_FILE 00111 if (out_file) { 00112 vfprintf(out_file, fmt, ap); 00113 fprintf(out_file, "\n"); 00114 } else { 00115 #endif /* CONFIG_DEBUG_FILE */ 00116 vprintf(fmt, ap); 00117 printf("\n"); 00118 #ifdef CONFIG_DEBUG_FILE 00119 } 00120 #endif /* CONFIG_DEBUG_FILE */ 00121 #ifdef CONFIG_DEBUG_SYSLOG 00122 } 00123 #endif /* CONFIG_DEBUG_SYSLOG */ 00124 } 00125 va_end(ap); 00126 } 00127 00128 00129 static void _wpa_hexdump(int level, const char *title, const u8 *buf, 00130 size_t len, int show) 00131 { 00132 size_t i; 00133 if (level < wpa_debug_level) 00134 return; 00135 wpa_debug_print_timestamp(); 00136 #ifdef CONFIG_DEBUG_FILE 00137 if (out_file) { 00138 fprintf(out_file, "%s - hexdump(len=%lu):", 00139 title, (unsigned long) len); 00140 if (buf == NULL) { 00141 fprintf(out_file, " [NULL]"); 00142 } else if (show) { 00143 for (i = 0; i < len; i++) 00144 fprintf(out_file, " %02x", buf[i]); 00145 } else { 00146 fprintf(out_file, " [REMOVED]"); 00147 } 00148 fprintf(out_file, "\n"); 00149 } else { 00150 #endif /* CONFIG_DEBUG_FILE */ 00151 printf("%s - hexdump(len=%lu):", title, (unsigned long) len); 00152 if (buf == NULL) { 00153 printf(" [NULL]"); 00154 } else if (show) { 00155 for (i = 0; i < len; i++) 00156 printf(" %02x", buf[i]); 00157 } else { 00158 printf(" [REMOVED]"); 00159 } 00160 printf("\n"); 00161 #ifdef CONFIG_DEBUG_FILE 00162 } 00163 #endif /* CONFIG_DEBUG_FILE */ 00164 } 00165 00166 void wpa_hexdump(int level, const char *title, const u8 *buf, size_t len) 00167 { 00168 _wpa_hexdump(level, title, buf, len, 1); 00169 } 00170 00171 00172 void wpa_hexdump_key(int level, const char *title, const u8 *buf, size_t len) 00173 { 00174 _wpa_hexdump(level, title, buf, len, wpa_debug_show_keys); 00175 } 00176 00177 00178 static void _wpa_hexdump_ascii(int level, const char *title, const u8 *buf, 00179 size_t len, int show) 00180 { 00181 size_t i, llen; 00182 const u8 *pos = buf; 00183 const size_t line_len = 16; 00184 00185 if (level < wpa_debug_level) 00186 return; 00187 wpa_debug_print_timestamp(); 00188 #ifdef CONFIG_DEBUG_FILE 00189 if (out_file) { 00190 if (!show) { 00191 fprintf(out_file, 00192 "%s - hexdump_ascii(len=%lu): [REMOVED]\n", 00193 title, (unsigned long) len); 00194 return; 00195 } 00196 if (buf == NULL) { 00197 fprintf(out_file, 00198 "%s - hexdump_ascii(len=%lu): [NULL]\n", 00199 title, (unsigned long) len); 00200 return; 00201 } 00202 fprintf(out_file, "%s - hexdump_ascii(len=%lu):\n", 00203 title, (unsigned long) len); 00204 while (len) { 00205 llen = len > line_len ? line_len : len; 00206 fprintf(out_file, " "); 00207 for (i = 0; i < llen; i++) 00208 fprintf(out_file, " %02x", pos[i]); 00209 for (i = llen; i < line_len; i++) 00210 fprintf(out_file, " "); 00211 fprintf(out_file, " "); 00212 for (i = 0; i < llen; i++) { 00213 if (isprint(pos[i])) 00214 fprintf(out_file, "%c", pos[i]); 00215 else 00216 fprintf(out_file, "_"); 00217 } 00218 for (i = llen; i < line_len; i++) 00219 fprintf(out_file, " "); 00220 fprintf(out_file, "\n"); 00221 pos += llen; 00222 len -= llen; 00223 } 00224 } else { 00225 #endif /* CONFIG_DEBUG_FILE */ 00226 if (!show) { 00227 printf("%s - hexdump_ascii(len=%lu): [REMOVED]\n", 00228 title, (unsigned long) len); 00229 return; 00230 } 00231 if (buf == NULL) { 00232 printf("%s - hexdump_ascii(len=%lu): [NULL]\n", 00233 title, (unsigned long) len); 00234 return; 00235 } 00236 printf("%s - hexdump_ascii(len=%lu):\n", title, (unsigned long) len); 00237 while (len) { 00238 llen = len > line_len ? line_len : len; 00239 printf(" "); 00240 for (i = 0; i < llen; i++) 00241 printf(" %02x", pos[i]); 00242 for (i = llen; i < line_len; i++) 00243 printf(" "); 00244 printf(" "); 00245 for (i = 0; i < llen; i++) { 00246 if (isprint(pos[i])) 00247 printf("%c", pos[i]); 00248 else 00249 printf("_"); 00250 } 00251 for (i = llen; i < line_len; i++) 00252 printf(" "); 00253 printf("\n"); 00254 pos += llen; 00255 len -= llen; 00256 } 00257 #ifdef CONFIG_DEBUG_FILE 00258 } 00259 #endif /* CONFIG_DEBUG_FILE */ 00260 } 00261 00262 00263 void wpa_hexdump_ascii(int level, const char *title, const u8 *buf, size_t len) 00264 { 00265 _wpa_hexdump_ascii(level, title, buf, len, 1); 00266 } 00267 00268 00269 void wpa_hexdump_ascii_key(int level, const char *title, const u8 *buf, 00270 size_t len) 00271 { 00272 _wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys); 00273 } 00274 00275 00276 int wpa_debug_open_file(const char *path) 00277 { 00278 #ifdef CONFIG_DEBUG_FILE 00279 if (!path) 00280 return 0; 00281 out_file = fopen(path, "a"); 00282 if (out_file == NULL) { 00283 wpa_printf(MSG_ERROR, "wpa_debug_open_file: Failed to open " 00284 "output file, using standard output"); 00285 return -1; 00286 } 00287 #ifndef _WIN32 00288 setvbuf(out_file, NULL, _IOLBF, 0); 00289 #endif /* _WIN32 */ 00290 #endif /* CONFIG_DEBUG_FILE */ 00291 return 0; 00292 } 00293 00294 00295 void wpa_debug_close_file(void) 00296 { 00297 #ifdef CONFIG_DEBUG_FILE 00298 if (!out_file) 00299 return; 00300 fclose(out_file); 00301 out_file = NULL; 00302 #endif /* CONFIG_DEBUG_FILE */ 00303 } 00304 00305 #endif /* CONFIG_NO_STDOUT_DEBUG */ 00306 00307 00308 #ifndef CONFIG_NO_WPA_MSG 00309 static wpa_msg_cb_func wpa_msg_cb = NULL; 00310 00311 void wpa_msg_register_cb(wpa_msg_cb_func func) 00312 { 00313 wpa_msg_cb = func; 00314 } 00315 00316 00317 void wpa_msg(void *ctx, int level, const char *fmt, ...) 00318 { 00319 va_list ap; 00320 char *buf; 00321 const int buflen = 2048; 00322 int len; 00323 00324 buf = os_malloc(buflen); 00325 if (buf == NULL) { 00326 wpa_printf(MSG_ERROR, "wpa_msg: Failed to allocate message " 00327 "buffer"); 00328 return; 00329 } 00330 va_start(ap, fmt); 00331 len = vsnprintf(buf, buflen, fmt, ap); 00332 va_end(ap); 00333 wpa_printf(level, "%s", buf); 00334 if (wpa_msg_cb) 00335 wpa_msg_cb(ctx, level, buf, len); 00336 os_free(buf); 00337 } 00338 00339 00340 void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) 00341 { 00342 va_list ap; 00343 char *buf; 00344 const int buflen = 2048; 00345 int len; 00346 00347 if (!wpa_msg_cb) 00348 return; 00349 00350 buf = os_malloc(buflen); 00351 if (buf == NULL) { 00352 wpa_printf(MSG_ERROR, "wpa_msg_ctrl: Failed to allocate " 00353 "message buffer"); 00354 return; 00355 } 00356 va_start(ap, fmt); 00357 len = vsnprintf(buf, buflen, fmt, ap); 00358 va_end(ap); 00359 wpa_msg_cb(ctx, level, buf, len); 00360 os_free(buf); 00361 } 00362 #endif /* CONFIG_NO_WPA_MSG */ 00363 00364 00365 #ifndef CONFIG_NO_HOSTAPD_LOGGER 00366 static hostapd_logger_cb_func hostapd_logger_cb = NULL; 00367 00368 void hostapd_logger_register_cb(hostapd_logger_cb_func func) 00369 { 00370 hostapd_logger_cb = func; 00371 } 00372 00373 00374 void hostapd_logger(void *ctx, const u8 *addr, unsigned int module, int level, 00375 const char *fmt, ...) 00376 { 00377 va_list ap; 00378 char *buf; 00379 const int buflen = 2048; 00380 int len; 00381 00382 buf = os_malloc(buflen); 00383 if (buf == NULL) { 00384 wpa_printf(MSG_ERROR, "hostapd_logger: Failed to allocate " 00385 "message buffer"); 00386 return; 00387 } 00388 va_start(ap, fmt); 00389 len = vsnprintf(buf, buflen, fmt, ap); 00390 va_end(ap); 00391 if (hostapd_logger_cb) 00392 hostapd_logger_cb(ctx, addr, module, level, buf, len); 00393 else if (addr) 00394 wpa_printf(MSG_DEBUG, "hostapd_logger: STA " MACSTR " - %s", 00395 MAC2STR(addr), buf); 00396 else 00397 wpa_printf(MSG_DEBUG, "hostapd_logger: %s", buf); 00398 os_free(buf); 00399 } 00400 #endif /* CONFIG_NO_HOSTAPD_LOGGER */