1 /* 2 * wpa_supplicant/hostapd / common helper functions, etc. 3 * Copyright (c) 2002-2007, Jouni Malinen <j (at) 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 "includes.h" 10 11 #include "common.h" 12 13 14 static int hex2num(char c) 15 { 16 if (c >= '0' && c <= '9') 17 return c - '0'; 18 if (c >= 'a' && c <= 'f') 19 return c - 'a' + 10; 20 if (c >= 'A' && c <= 'F') 21 return c - 'A' + 10; 22 return -1; 23 } 24 25 26 int hex2byte(const char *hex) 27 { 28 int a, b; 29 a = hex2num(*hex++); 30 if (a < 0) 31 return -1; 32 b = hex2num(*hex++); 33 if (b < 0) 34 return -1; 35 return (a << 4) | b; 36 } 37 38 39 /** 40 * hwaddr_aton - Convert ASCII string to MAC address (colon-delimited format) 41 * @txt: MAC address as a string (e.g., "00:11:22:33:44:55") 42 * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes) 43 * Returns: 0 on success, -1 on failure (e.g., string not a MAC address) 44 */ 45 int hwaddr_aton(const char *txt, u8 *addr) 46 { 47 int i; 48 49 for (i = 0; i < 6; i++) { 50 int a, b; 51 52 a = hex2num(*txt++); 53 if (a < 0) 54 return -1; 55 b = hex2num(*txt++); 56 if (b < 0) 57 return -1; 58 *addr++ = (a << 4) | b; 59 if (i < 5 && *txt++ != ':') 60 return -1; 61 } 62 63 return 0; 64 } 65 66 /** 67 * hwaddr_compact_aton - Convert ASCII string to MAC address (no colon delimitors format) 68 * @txt: MAC address as a string (e.g., "001122334455") 69 * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes) 70 * Returns: 0 on success, -1 on failure (e.g., string not a MAC address) 71 */ 72 int hwaddr_compact_aton(const char *txt, u8 *addr) 73 { 74 int i; 75 76 for (i = 0; i < 6; i++) { 77 int a, b; 78 79 a = hex2num(*txt++); 80 if (a < 0) 81 return -1; 82 b = hex2num(*txt++); 83 if (b < 0) 84 return -1; 85 *addr++ = (a << 4) | b; 86 } 87 88 return 0; 89 } 90 91 /** 92 * hwaddr_aton2 - Convert ASCII string to MAC address (in any known format) 93 * @txt: MAC address as a string (e.g., 00:11:22:33:44:55 or 0011.2233.4455) 94 * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes) 95 * Returns: Characters used (> 0) on success, -1 on failure 96 */ 97 int hwaddr_aton2(const char *txt, u8 *addr) 98 { 99 int i; 100 const char *pos = txt; 101 102 for (i = 0; i < 6; i++) { 103 int a, b; 104 105 while (*pos == ':' || *pos == '.' || *pos == '-') 106 pos++; 107 108 a = hex2num(*pos++); 109 if (a < 0) 110 return -1; 111 b = hex2num(*pos++); 112 if (b < 0) 113 return -1; 114 *addr++ = (a << 4) | b; 115 } 116 117 return pos - txt; 118 } 119 120 121 /** 122 * hexstr2bin - Convert ASCII hex string into binary data 123 * @hex: ASCII hex string (e.g., "01ab") 124 * @buf: Buffer for the binary data 125 * @len: Length of the text to convert in bytes (of buf); hex will be double 126 * this size 127 * Returns: 0 on success, -1 on failure (invalid hex string) 128 */ 129 int hexstr2bin(const char *hex, u8 *buf, size_t len) 130 { 131 size_t i; 132 int a; 133 const char *ipos = hex; 134 u8 *opos = buf; 135 136 for (i = 0; i < len; i++) { 137 a = hex2byte(ipos); 138 if (a < 0) 139 return -1; 140 *opos++ = a; 141 ipos += 2; 142 } 143 return 0; 144 } 145 146 147 /** 148 * inc_byte_array - Increment arbitrary length byte array by one 149 * @counter: Pointer to byte array 150 * @len: Length of the counter in bytes 151 * 152 * This function increments the last byte of the counter by one and continues 153 * rolling over to more significant bytes if the byte was incremented from 154 * 0xff to 0x00. 155 */ 156 void inc_byte_array(u8 *counter, size_t len) 157 { 158 int pos = len - 1; 159 while (pos >= 0) { 160 counter[pos]++; 161 if (counter[pos] != 0) 162 break; 163 pos--; 164 } 165 } 166 167 168 void wpa_get_ntp_timestamp(u8 *buf) 169 { 170 struct os_time now; 171 u32 sec, usec; 172 be32 tmp; 173 174 /* 64-bit NTP timestamp (time from 1900-01-01 00:00:00) */ 175 os_get_time(&now); 176 sec = now.sec + 2208988800U; /* Epoch to 1900 */ 177 /* Estimate 2^32/10^6 = 4295 - 1/32 - 1/512 */ 178 usec = now.usec; 179 usec = 4295 * usec - (usec >> 5) - (usec >> 9); 180 tmp = host_to_be32(sec); 181 os_memcpy(buf, (u8 *) &tmp, 4); 182 tmp = host_to_be32(usec); 183 os_memcpy(buf + 4, (u8 *) &tmp, 4); 184 } 185 186 187 static inline int _wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, 188 size_t len, int uppercase) 189 { 190 size_t i; 191 char *pos = buf, *end = buf + buf_size; 192 int ret; 193 if (buf_size == 0) 194 return 0; 195 for (i = 0; i < len; i++) { 196 ret = os_snprintf(pos, end - pos, uppercase ? "%02X" : "%02x", 197 data[i]); 198 if (ret < 0 || ret >= end - pos) { 199 end[-1] = '\0'; 200 return pos - buf; 201 } 202 pos += ret; 203 } 204 end[-1] = '\0'; 205 return pos - buf; 206 } 207 208 /** 209 * wpa_snprintf_hex - Print data as a hex string into a buffer 210 * @buf: Memory area to use as the output buffer 211 * @buf_size: Maximum buffer size in bytes (should be at least 2 * len + 1) 212 * @data: Data to be printed 213 * @len: Length of data in bytes 214 * Returns: Number of bytes written 215 */ 216 int wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len) 217 { 218 return _wpa_snprintf_hex(buf, buf_size, data, len, 0); 219 } 220 221 222 /** 223 * wpa_snprintf_hex_uppercase - Print data as a upper case hex string into buf 224 * @buf: Memory area to use as the output buffer 225 * @buf_size: Maximum buffer size in bytes (should be at least 2 * len + 1) 226 * @data: Data to be printed 227 * @len: Length of data in bytes 228 * Returns: Number of bytes written 229 */ 230 int wpa_snprintf_hex_uppercase(char *buf, size_t buf_size, const u8 *data, 231 size_t len) 232 { 233 return _wpa_snprintf_hex(buf, buf_size, data, len, 1); 234 } 235 236 237 #ifdef CONFIG_ANSI_C_EXTRA 238 239 #ifdef _WIN32_WCE 240 void perror(const char *s) 241 { 242 wpa_printf(MSG_ERROR, "%s: GetLastError: %d", 243 s, (int) GetLastError()); 244 } 245 #endif /* _WIN32_WCE */ 246 247 248 int optind = 1; 249 int optopt; 250 char *optarg; 251 252 int getopt(int argc, char *const argv[], const char *optstring) 253 { 254 static int optchr = 1; 255 char *cp; 256 257 if (optchr == 1) { 258 if (optind >= argc) { 259 /* all arguments processed */ 260 return EOF; 261 } 262 263 if (argv[optind][0] != '-' || argv[optind][1] == '\0') { 264 /* no option characters */ 265 return EOF; 266 } 267 } 268 269 if (os_strcmp(argv[optind], "--") == 0) { 270 /* no more options */ 271 optind++; 272 return EOF; 273 } 274 275 optopt = argv[optind][optchr]; 276 cp = os_strchr(optstring, optopt); 277 if (cp == NULL || optopt == ':') { 278 if (argv[optind][++optchr] == '\0') { 279 optchr = 1; 280 optind++; 281 } 282 return '?'; 283 } 284 285 if (cp[1] == ':') { 286 /* Argument required */ 287 optchr = 1; 288 if (argv[optind][optchr + 1]) { 289 /* No space between option and argument */ 290 optarg = &argv[optind++][optchr + 1]; 291 } else if (++optind >= argc) { 292 /* option requires an argument */ 293 return '?'; 294 } else { 295 /* Argument in the next argv */ 296 optarg = argv[optind++]; 297 } 298 } else { 299 /* No argument */ 300 if (argv[optind][++optchr] == '\0') { 301 optchr = 1; 302 optind++; 303 } 304 optarg = NULL; 305 } 306 return *cp; 307 } 308 #endif /* CONFIG_ANSI_C_EXTRA */ 309 310 311 #ifdef CONFIG_NATIVE_WINDOWS 312 /** 313 * wpa_unicode2ascii_inplace - Convert unicode string into ASCII 314 * @str: Pointer to string to convert 315 * 316 * This function converts a unicode string to ASCII using the same 317 * buffer for output. If UNICODE is not set, the buffer is not 318 * modified. 319 */ 320 void wpa_unicode2ascii_inplace(TCHAR *str) 321 { 322 #ifdef UNICODE 323 char *dst = (char *) str; 324 while (*str) 325 *dst++ = (char) *str++; 326 *dst = '\0'; 327 #endif /* UNICODE */ 328 } 329 330 331 TCHAR * wpa_strdup_tchar(const char *str) 332 { 333 #ifdef UNICODE 334 TCHAR *buf; 335 buf = os_malloc((strlen(str) + 1) * sizeof(TCHAR)); 336 if (buf == NULL) 337 return NULL; 338 wsprintf(buf, L"%S", str); 339 return buf; 340 #else /* UNICODE */ 341 return os_strdup(str); 342 #endif /* UNICODE */ 343 } 344 #endif /* CONFIG_NATIVE_WINDOWS */ 345 346 347 void printf_encode(char *txt, size_t maxlen, const u8 *data, size_t len) 348 { 349 char *end = txt + maxlen; 350 size_t i; 351 352 for (i = 0; i < len; i++) { 353 if (txt + 4 >= end) 354 break; 355 356 switch (data[i]) { 357 case '\"': 358 *txt++ = '\\'; 359 *txt++ = '\"'; 360 break; 361 case '\\': 362 *txt++ = '\\'; 363 *txt++ = '\\'; 364 break; 365 case '\e': 366 *txt++ = '\\'; 367 *txt++ = 'e'; 368 break; 369 case '\n': 370 *txt++ = '\\'; 371 *txt++ = 'n'; 372 break; 373 case '\r': 374 *txt++ = '\\'; 375 *txt++ = 'r'; 376 break; 377 case '\t': 378 *txt++ = '\\'; 379 *txt++ = 't'; 380 break; 381 default: 382 if (data[i] >= 32 && data[i] <= 127) { 383 *txt++ = data[i]; 384 } else { 385 txt += os_snprintf(txt, end - txt, "\\x%02x", 386 data[i]); 387 } 388 break; 389 } 390 } 391 392 *txt = '\0'; 393 } 394 395 396 size_t printf_decode(u8 *buf, size_t maxlen, const char *str) 397 { 398 const char *pos = str; 399 size_t len = 0; 400 int val; 401 402 while (*pos) { 403 if (len + 1 >= maxlen) 404 break; 405 switch (*pos) { 406 case '\\': 407 pos++; 408 switch (*pos) { 409 case '\\': 410 buf[len++] = '\\'; 411 pos++; 412 break; 413 case '"': 414 buf[len++] = '"'; 415 pos++; 416 break; 417 case 'n': 418 buf[len++] = '\n'; 419 pos++; 420 break; 421 case 'r': 422 buf[len++] = '\r'; 423 pos++; 424 break; 425 case 't': 426 buf[len++] = '\t'; 427 pos++; 428 break; 429 case 'e': 430 buf[len++] = '\e'; 431 pos++; 432 break; 433 case 'x': 434 pos++; 435 val = hex2byte(pos); 436 if (val < 0) { 437 val = hex2num(*pos); 438 if (val < 0) 439 break; 440 buf[len++] = val; 441 pos++; 442 } else { 443 buf[len++] = val; 444 pos += 2; 445 } 446 break; 447 case '0': 448 case '1': 449 case '2': 450 case '3': 451 case '4': 452 case '5': 453 case '6': 454 case '7': 455 val = *pos++ - '0'; 456 if (*pos >= '0' && *pos <= '7') 457 val = val * 8 + (*pos++ - '0'); 458 if (*pos >= '0' && *pos <= '7') 459 val = val * 8 + (*pos++ - '0'); 460 buf[len++] = val; 461 break; 462 default: 463 break; 464 } 465 break; 466 default: 467 buf[len++] = *pos++; 468 break; 469 } 470 } 471 if (maxlen > len) 472 buf[len] = '\0'; 473 474 return len; 475 } 476 477 478 /** 479 * wpa_ssid_txt - Convert SSID to a printable string 480 * @ssid: SSID (32-octet string) 481 * @ssid_len: Length of ssid in octets 482 * Returns: Pointer to a printable string 483 * 484 * This function can be used to convert SSIDs into printable form. In most 485 * cases, SSIDs do not use unprintable characters, but IEEE 802.11 standard 486 * does not limit the used character set, so anything could be used in an SSID. 487 * 488 * This function uses a static buffer, so only one call can be used at the 489 * time, i.e., this is not re-entrant and the returned buffer must be used 490 * before calling this again. 491 */ 492 const char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len) 493 { 494 static char ssid_txt[32 * 4 + 1]; 495 496 if (ssid == NULL) { 497 ssid_txt[0] = '\0'; 498 return ssid_txt; 499 } 500 501 printf_encode(ssid_txt, sizeof(ssid_txt), ssid, ssid_len); 502 return ssid_txt; 503 } 504 505 506 void * __hide_aliasing_typecast(void *foo) 507 { 508 return foo; 509 } 510 511 512 char * wpa_config_parse_string(const char *value, size_t *len) 513 { 514 if (*value == '"') { 515 const char *pos; 516 char *str; 517 value++; 518 pos = os_strrchr(value, '"'); 519 if (pos == NULL || pos[1] != '\0') 520 return NULL; 521 *len = pos - value; 522 str = dup_binstr(value, *len); 523 if (str == NULL) 524 return NULL; 525 return str; 526 } else if (*value == 'P' && value[1] == '"') { 527 const char *pos; 528 char *tstr, *str; 529 size_t tlen; 530 value += 2; 531 pos = os_strrchr(value, '"'); 532 if (pos == NULL || pos[1] != '\0') 533 return NULL; 534 tlen = pos - value; 535 tstr = dup_binstr(value, tlen); 536 if (tstr == NULL) 537 return NULL; 538 539 str = os_malloc(tlen + 1); 540 if (str == NULL) { 541 os_free(tstr); 542 return NULL; 543 } 544 545 *len = printf_decode((u8 *) str, tlen + 1, tstr); 546 os_free(tstr); 547 548 return str; 549 } else { 550 u8 *str; 551 size_t tlen, hlen = os_strlen(value); 552 if (hlen & 1) 553 return NULL; 554 tlen = hlen / 2; 555 str = os_malloc(tlen + 1); 556 if (str == NULL) 557 return NULL; 558 if (hexstr2bin(value, str, tlen)) { 559 os_free(str); 560 return NULL; 561 } 562 str[tlen] = '\0'; 563 *len = tlen; 564 return (char *) str; 565 } 566 } 567 568 569 int is_hex(const u8 *data, size_t len) 570 { 571 size_t i; 572 573 for (i = 0; i < len; i++) { 574 if (data[i] < 32 || data[i] >= 127) 575 return 1; 576 } 577 return 0; 578 } 579 580 581 int find_first_bit(u32 value) 582 { 583 int pos = 0; 584 585 while (value) { 586 if (value & 0x1) 587 return pos; 588 value >>= 1; 589 pos++; 590 } 591 592 return -1; 593 } 594 595 596 size_t merge_byte_arrays(u8 *res, size_t res_len, 597 const u8 *src1, size_t src1_len, 598 const u8 *src2, size_t src2_len) 599 { 600 size_t len = 0; 601 602 os_memset(res, 0, res_len); 603 604 if (src1) { 605 if (src1_len >= res_len) { 606 os_memcpy(res, src1, res_len); 607 return res_len; 608 } 609 610 os_memcpy(res, src1, src1_len); 611 len += src1_len; 612 } 613 614 if (src2) { 615 if (len + src2_len >= res_len) { 616 os_memcpy(res + len, src2, res_len - len); 617 return res_len; 618 } 619 620 os_memcpy(res + len, src2, src2_len); 621 len += src2_len; 622 } 623 624 return len; 625 } 626 627 628 char * dup_binstr(const void *src, size_t len) 629 { 630 char *res; 631 632 if (src == NULL) 633 return NULL; 634 res = os_malloc(len + 1); 635 if (res == NULL) 636 return NULL; 637 os_memcpy(res, src, len); 638 res[len] = '\0'; 639 640 return res; 641 } 642 643 644 int freq_range_list_parse(struct wpa_freq_range_list *res, const char *value) 645 { 646 struct wpa_freq_range *freq = NULL, *n; 647 unsigned int count = 0; 648 const char *pos, *pos2, *pos3; 649 650 /* 651 * Comma separated list of frequency ranges. 652 * For example: 2412-2432,2462,5000-6000 653 */ 654 pos = value; 655 while (pos && pos[0]) { 656 n = os_realloc_array(freq, count + 1, 657 sizeof(struct wpa_freq_range)); 658 if (n == NULL) { 659 os_free(freq); 660 return -1; 661 } 662 freq = n; 663 freq[count].min = atoi(pos); 664 pos2 = os_strchr(pos, '-'); 665 pos3 = os_strchr(pos, ','); 666 if (pos2 && (!pos3 || pos2 < pos3)) { 667 pos2++; 668 freq[count].max = atoi(pos2); 669 } else 670 freq[count].max = freq[count].min; 671 pos = pos3; 672 if (pos) 673 pos++; 674 count++; 675 } 676 677 os_free(res->range); 678 res->range = freq; 679 res->num = count; 680 681 return 0; 682 } 683 684 685 int freq_range_list_includes(const struct wpa_freq_range_list *list, 686 unsigned int freq) 687 { 688 unsigned int i; 689 690 if (list == NULL) 691 return 0; 692 693 for (i = 0; i < list->num; i++) { 694 if (freq >= list->range[i].min && freq <= list->range[i].max) 695 return 1; 696 } 697 698 return 0; 699 } 700 701 702 char * freq_range_list_str(const struct wpa_freq_range_list *list) 703 { 704 char *buf, *pos, *end; 705 size_t maxlen; 706 unsigned int i; 707 int res; 708 709 if (list->num == 0) 710 return NULL; 711 712 maxlen = list->num * 30; 713 buf = os_malloc(maxlen); 714 if (buf == NULL) 715 return NULL; 716 pos = buf; 717 end = buf + maxlen; 718 719 for (i = 0; i < list->num; i++) { 720 struct wpa_freq_range *range = &list->range[i]; 721 722 if (range->min == range->max) 723 res = os_snprintf(pos, end - pos, "%s%u", 724 i == 0 ? "" : ",", range->min); 725 else 726 res = os_snprintf(pos, end - pos, "%s%u-%u", 727 i == 0 ? "" : ",", 728 range->min, range->max); 729 if (res < 0 || res > end - pos) { 730 os_free(buf); 731 return NULL; 732 } 733 pos += res; 734 } 735 736 return buf; 737 } 738 739 740 int int_array_len(const int *a) 741 { 742 int i; 743 for (i = 0; a && a[i]; i++) 744 ; 745 return i; 746 } 747 748 749 void int_array_concat(int **res, const int *a) 750 { 751 int reslen, alen, i; 752 int *n; 753 754 reslen = int_array_len(*res); 755 alen = int_array_len(a); 756 757 n = os_realloc_array(*res, reslen + alen + 1, sizeof(int)); 758 if (n == NULL) { 759 os_free(*res); 760 *res = NULL; 761 return; 762 } 763 for (i = 0; i <= alen; i++) 764 n[reslen + i] = a[i]; 765 *res = n; 766 } 767 768 769 static int freq_cmp(const void *a, const void *b) 770 { 771 int _a = *(int *) a; 772 int _b = *(int *) b; 773 774 if (_a == 0) 775 return 1; 776 if (_b == 0) 777 return -1; 778 return _a - _b; 779 } 780 781 782 void int_array_sort_unique(int *a) 783 { 784 int alen; 785 int i, j; 786 787 if (a == NULL) 788 return; 789 790 alen = int_array_len(a); 791 qsort(a, alen, sizeof(int), freq_cmp); 792 793 i = 0; 794 j = 1; 795 while (a[i] && a[j]) { 796 if (a[i] == a[j]) { 797 j++; 798 continue; 799 } 800 a[++i] = a[j++]; 801 } 802 if (a[i]) 803 i++; 804 a[i] = 0; 805 } 806 807 808 void int_array_add_unique(int **res, int a) 809 { 810 int reslen; 811 int *n; 812 813 for (reslen = 0; *res && (*res)[reslen]; reslen++) { 814 if ((*res)[reslen] == a) 815 return; /* already in the list */ 816 } 817 818 n = os_realloc_array(*res, reslen + 2, sizeof(int)); 819 if (n == NULL) { 820 os_free(*res); 821 *res = NULL; 822 return; 823 } 824 825 n[reslen] = a; 826 n[reslen + 1] = 0; 827 828 *res = n; 829 } 830 831 832 void str_clear_free(char *str) 833 { 834 if (str) { 835 size_t len = os_strlen(str); 836 os_memset(str, 0, len); 837 os_free(str); 838 } 839 } 840 841 842 void bin_clear_free(void *bin, size_t len) 843 { 844 if (bin) { 845 os_memset(bin, 0, len); 846 os_free(bin); 847 } 848 } 849