00001
00016 #include "includes.h"
00017
00018 #include "common.h"
00019
00020
00021 #ifdef CONFIG_DEBUG_FILE
00022 static FILE *out_file = NULL;
00023 #endif
00024 int wpa_debug_use_file = 0;
00025 int wpa_debug_level = MSG_INFO;
00026 int wpa_debug_show_keys = 0;
00027 int wpa_debug_timestamp = 0;
00028
00029
00030 static int hex2num(char c)
00031 {
00032 if (c >= '0' && c <= '9')
00033 return c - '0';
00034 if (c >= 'a' && c <= 'f')
00035 return c - 'a' + 10;
00036 if (c >= 'A' && c <= 'F')
00037 return c - 'A' + 10;
00038 return -1;
00039 }
00040
00041
00042 static int hex2byte(const char *hex)
00043 {
00044 int a, b;
00045 a = hex2num(*hex++);
00046 if (a < 0)
00047 return -1;
00048 b = hex2num(*hex++);
00049 if (b < 0)
00050 return -1;
00051 return (a << 4) | b;
00052 }
00053
00054
00062 int hwaddr_aton(const char *txt, u8 *addr)
00063 {
00064 int i;
00065
00066 for (i = 0; i < 6; i++) {
00067 int a, b;
00068
00069 a = hex2num(*txt++);
00070 if (a < 0)
00071 return -1;
00072 b = hex2num(*txt++);
00073 if (b < 0)
00074 return -1;
00075 *addr++ = (a << 4) | b;
00076 if (i < 5 && *txt++ != ':')
00077 return -1;
00078 }
00079
00080 return 0;
00081 }
00082
00083
00093 int hexstr2bin(const char *hex, u8 *buf, size_t len)
00094 {
00095 size_t i;
00096 int a;
00097 const char *ipos = hex;
00098 u8 *opos = buf;
00099
00100 for (i = 0; i < len; i++) {
00101 a = hex2byte(ipos);
00102 if (a < 0)
00103 return -1;
00104 *opos++ = a;
00105 ipos += 2;
00106 }
00107 return 0;
00108 }
00109
00110
00121 void inc_byte_array(u8 *counter, size_t len)
00122 {
00123 int pos = len - 1;
00124 while (pos >= 0) {
00125 counter[pos]++;
00126 if (counter[pos] != 0)
00127 break;
00128 pos--;
00129 }
00130 }
00131
00132
00133 void wpa_get_ntp_timestamp(u8 *buf)
00134 {
00135 struct os_time now;
00136 u32 sec, usec;
00137
00138
00139 os_get_time(&now);
00140 sec = host_to_be32(now.sec + 2208988800U);
00141
00142 usec = now.usec;
00143 usec = host_to_be32(4295 * usec - (usec >> 5) - (usec >> 9));
00144 os_memcpy(buf, (u8 *) &sec, 4);
00145 os_memcpy(buf + 4, (u8 *) &usec, 4);
00146 }
00147
00148
00149
00150 #ifndef CONFIG_NO_STDOUT_DEBUG
00151
00152 void wpa_debug_print_timestamp(void)
00153 {
00154 struct os_time tv;
00155
00156 if (!wpa_debug_timestamp)
00157 return;
00158
00159 os_get_time(&tv);
00160 #ifdef CONFIG_DEBUG_FILE
00161 if (out_file) {
00162 fprintf(out_file, "%ld.%06u: ", (long) tv.sec,
00163 (unsigned int) tv.usec);
00164 } else
00165 #endif
00166 printf("%ld.%06u: ", (long) tv.sec, (unsigned int) tv.usec);
00167 }
00168
00169
00182 void wpa_printf(int level, char *fmt, ...)
00183 {
00184 va_list ap;
00185
00186 va_start(ap, fmt);
00187 if (level >= wpa_debug_level) {
00188 wpa_debug_print_timestamp();
00189 #ifdef CONFIG_DEBUG_FILE
00190 if (out_file) {
00191 vfprintf(out_file, fmt, ap);
00192 fprintf(out_file, "\n");
00193 } else {
00194 #endif
00195 vprintf(fmt, ap);
00196 printf("\n");
00197 #ifdef CONFIG_DEBUG_FILE
00198 }
00199 #endif
00200 }
00201 va_end(ap);
00202 }
00203
00204
00205 static void _wpa_hexdump(int level, const char *title, const u8 *buf,
00206 size_t len, int show)
00207 {
00208 size_t i;
00209 if (level < wpa_debug_level)
00210 return;
00211 wpa_debug_print_timestamp();
00212 #ifdef CONFIG_DEBUG_FILE
00213 if (out_file) {
00214 fprintf(out_file, "%s - hexdump(len=%lu):",
00215 title, (unsigned long) len);
00216 if (buf == NULL) {
00217 fprintf(out_file, " [NULL]");
00218 } else if (show) {
00219 for (i = 0; i < len; i++)
00220 fprintf(out_file, " %02x", buf[i]);
00221 } else {
00222 fprintf(out_file, " [REMOVED]");
00223 }
00224 fprintf(out_file, "\n");
00225 } else {
00226 #endif
00227 printf("%s - hexdump(len=%lu):", title, (unsigned long) len);
00228 if (buf == NULL) {
00229 printf(" [NULL]");
00230 } else if (show) {
00231 for (i = 0; i < len; i++)
00232 printf(" %02x", buf[i]);
00233 } else {
00234 printf(" [REMOVED]");
00235 }
00236 printf("\n");
00237 #ifdef CONFIG_DEBUG_FILE
00238 }
00239 #endif
00240 }
00241
00242 void wpa_hexdump(int level, const char *title, const u8 *buf, size_t len)
00243 {
00244 _wpa_hexdump(level, title, buf, len, 1);
00245 }
00246
00247
00248 void wpa_hexdump_key(int level, const char *title, const u8 *buf, size_t len)
00249 {
00250 _wpa_hexdump(level, title, buf, len, wpa_debug_show_keys);
00251 }
00252
00253
00254 static void _wpa_hexdump_ascii(int level, const char *title, const u8 *buf,
00255 size_t len, int show)
00256 {
00257 size_t i, llen;
00258 const u8 *pos = buf;
00259 const size_t line_len = 16;
00260
00261 if (level < wpa_debug_level)
00262 return;
00263 wpa_debug_print_timestamp();
00264 #ifdef CONFIG_DEBUG_FILE
00265 if (out_file) {
00266 if (!show) {
00267 fprintf(out_file,
00268 "%s - hexdump_ascii(len=%lu): [REMOVED]\n",
00269 title, (unsigned long) len);
00270 return;
00271 }
00272 if (buf == NULL) {
00273 fprintf(out_file,
00274 "%s - hexdump_ascii(len=%lu): [NULL]\n",
00275 title, (unsigned long) len);
00276 return;
00277 }
00278 fprintf(out_file, "%s - hexdump_ascii(len=%lu):\n",
00279 title, (unsigned long) len);
00280 while (len) {
00281 llen = len > line_len ? line_len : len;
00282 fprintf(out_file, " ");
00283 for (i = 0; i < llen; i++)
00284 fprintf(out_file, " %02x", pos[i]);
00285 for (i = llen; i < line_len; i++)
00286 fprintf(out_file, " ");
00287 fprintf(out_file, " ");
00288 for (i = 0; i < llen; i++) {
00289 if (isprint(pos[i]))
00290 fprintf(out_file, "%c", pos[i]);
00291 else
00292 fprintf(out_file, "_");
00293 }
00294 for (i = llen; i < line_len; i++)
00295 fprintf(out_file, " ");
00296 fprintf(out_file, "\n");
00297 pos += llen;
00298 len -= llen;
00299 }
00300 } else {
00301 #endif
00302 if (!show) {
00303 printf("%s - hexdump_ascii(len=%lu): [REMOVED]\n",
00304 title, (unsigned long) len);
00305 return;
00306 }
00307 if (buf == NULL) {
00308 printf("%s - hexdump_ascii(len=%lu): [NULL]\n",
00309 title, (unsigned long) len);
00310 return;
00311 }
00312 printf("%s - hexdump_ascii(len=%lu):\n", title, (unsigned long) len);
00313 while (len) {
00314 llen = len > line_len ? line_len : len;
00315 printf(" ");
00316 for (i = 0; i < llen; i++)
00317 printf(" %02x", pos[i]);
00318 for (i = llen; i < line_len; i++)
00319 printf(" ");
00320 printf(" ");
00321 for (i = 0; i < llen; i++) {
00322 if (isprint(pos[i]))
00323 printf("%c", pos[i]);
00324 else
00325 printf("_");
00326 }
00327 for (i = llen; i < line_len; i++)
00328 printf(" ");
00329 printf("\n");
00330 pos += llen;
00331 len -= llen;
00332 }
00333 #ifdef CONFIG_DEBUG_FILE
00334 }
00335 #endif
00336 }
00337
00338
00339 void wpa_hexdump_ascii(int level, const char *title, const u8 *buf, size_t len)
00340 {
00341 _wpa_hexdump_ascii(level, title, buf, len, 1);
00342 }
00343
00344
00345 void wpa_hexdump_ascii_key(int level, const char *title, const u8 *buf,
00346 size_t len)
00347 {
00348 _wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys);
00349 }
00350
00351
00352 int wpa_debug_open_file(void)
00353 {
00354 #ifdef CONFIG_DEBUG_FILE
00355 static int count = 0;
00356 char fname[64];
00357 if (!wpa_debug_use_file)
00358 return 0;
00359 #ifdef _WIN32
00360 os_snprintf(fname, sizeof(fname), "\\Temp\\wpa_supplicant-log-%d.txt",
00361 count++);
00362 #else
00363 os_snprintf(fname, sizeof(fname), "/tmp/wpa_supplicant-log-%d.txt",
00364 count++);
00365 #endif
00366 out_file = fopen(fname, "w");
00367 return out_file == NULL ? -1 : 0;
00368 #else
00369 return 0;
00370 #endif
00371 }
00372
00373
00374 void wpa_debug_close_file(void)
00375 {
00376 #ifdef CONFIG_DEBUG_FILE
00377 if (!wpa_debug_use_file)
00378 return;
00379 fclose(out_file);
00380 out_file = NULL;
00381 #endif
00382 }
00383
00384 #endif
00385
00386
00387 #ifndef CONFIG_NO_WPA_MSG
00388 static wpa_msg_cb_func wpa_msg_cb = NULL;
00389
00390 void wpa_msg_register_cb(wpa_msg_cb_func func)
00391 {
00392 wpa_msg_cb = func;
00393 }
00394
00395
00396 void wpa_msg(void *ctx, int level, char *fmt, ...)
00397 {
00398 va_list ap;
00399 char *buf;
00400 const int buflen = 2048;
00401 int len;
00402
00403 buf = os_malloc(buflen);
00404 if (buf == NULL) {
00405 wpa_printf(MSG_ERROR, "wpa_msg: Failed to allocate message "
00406 "buffer");
00407 return;
00408 }
00409 va_start(ap, fmt);
00410 len = vsnprintf(buf, buflen, fmt, ap);
00411 va_end(ap);
00412 wpa_printf(level, "%s", buf);
00413 if (wpa_msg_cb)
00414 wpa_msg_cb(ctx, level, buf, len);
00415 os_free(buf);
00416 }
00417 #endif
00418
00419
00420 static inline int _wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data,
00421 size_t len, int uppercase)
00422 {
00423 size_t i;
00424 char *pos = buf, *end = buf + buf_size;
00425 int ret;
00426 if (buf_size == 0)
00427 return 0;
00428 for (i = 0; i < len; i++) {
00429 ret = os_snprintf(pos, end - pos, uppercase ? "%02X" : "%02x",
00430 data[i]);
00431 if (ret < 0 || ret >= end - pos) {
00432 end[-1] = '\0';
00433 return pos - buf;
00434 }
00435 pos += ret;
00436 }
00437 end[-1] = '\0';
00438 return pos - buf;
00439 }
00440
00450 int wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len)
00451 {
00452 return _wpa_snprintf_hex(buf, buf_size, data, len, 0);
00453 }
00454
00455
00465 int wpa_snprintf_hex_uppercase(char *buf, size_t buf_size, const u8 *data,
00466 size_t len)
00467 {
00468 return _wpa_snprintf_hex(buf, buf_size, data, len, 1);
00469 }
00470
00471
00472 #ifdef CONFIG_ANSI_C_EXTRA
00473
00474 #ifdef _WIN32_WCE
00475 void perror(const char *s)
00476 {
00477 wpa_printf(MSG_ERROR, "%s: GetLastError: %d",
00478 s, (int) GetLastError());
00479 }
00480 #endif
00481
00482
00483 int optind = 1;
00484 int optopt;
00485 char *optarg;
00486
00487 int getopt(int argc, char *const argv[], const char *optstring)
00488 {
00489 static int optchr = 1;
00490 char *cp;
00491
00492 if (optchr == 1) {
00493 if (optind >= argc) {
00494
00495 return EOF;
00496 }
00497
00498 if (argv[optind][0] != '-' || argv[optind][1] == '\0') {
00499
00500 return EOF;
00501 }
00502 }
00503
00504 if (strcmp(argv[optind], "--") == 0) {
00505
00506 optind++;
00507 return EOF;
00508 }
00509
00510 optopt = argv[optind][optchr];
00511 cp = strchr(optstring, optopt);
00512 if (cp == NULL || optopt == ':') {
00513 if (argv[optind][++optchr] == '\0') {
00514 optchr = 1;
00515 optind++;
00516 }
00517 return '?';
00518 }
00519
00520 if (cp[1] == ':') {
00521
00522 optchr = 1;
00523 if (argv[optind][optchr + 1]) {
00524
00525 optarg = &argv[optind++][optchr + 1];
00526 } else if (++optind >= argc) {
00527
00528 return '?';
00529 } else {
00530
00531 optarg = argv[optind++];
00532 }
00533 } else {
00534
00535 if (argv[optind][++optchr] == '\0') {
00536 optchr = 1;
00537 optind++;
00538 }
00539 optarg = NULL;
00540 }
00541 return *cp;
00542 }
00543 #endif
00544
00545
00546 #ifdef CONFIG_NATIVE_WINDOWS
00547
00556 void wpa_unicode2ascii_inplace(TCHAR *str)
00557 {
00558 #ifdef UNICODE
00559 char *dst = (char *) str;
00560 while (*str)
00561 *dst++ = (char) *str++;
00562 *dst = '\0';
00563 #endif
00564 }
00565
00566
00567 TCHAR * wpa_strdup_tchar(const char *str)
00568 {
00569 #ifdef UNICODE
00570 TCHAR *buf;
00571 buf = os_malloc((strlen(str) + 1) * sizeof(TCHAR));
00572 if (buf == NULL)
00573 return NULL;
00574 wsprintf(buf, L"%S", str);
00575 return buf;
00576 #else
00577 return os_strdup(str);
00578 #endif
00579 }
00580 #endif
00581
00582
00598 const char * wpa_ssid_txt(u8 *ssid, size_t ssid_len)
00599 {
00600 static char ssid_txt[33];
00601 char *pos;
00602
00603 if (ssid_len > 32)
00604 ssid_len = 32;
00605 os_memcpy(ssid_txt, ssid, ssid_len);
00606 ssid_txt[ssid_len] = '\0';
00607 for (pos = ssid_txt; *pos != '\0'; pos++) {
00608 if ((u8) *pos < 32 || (u8) *pos >= 127)
00609 *pos = '_';
00610 }
00611 return ssid_txt;
00612 }
00613