common.c revision 6c0da2bb83f6915d8260912362692d1a742e057b
1/* 2 * wpa_supplicant/hostapd / common helper functions, etc. 3 * Copyright (c) 2002-2007, 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 "includes.h" 10 11#include "common.h" 12 13 14static 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 26int 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 */ 45int 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 */ 72int 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 */ 97int 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 */ 129int 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 */ 156void 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 168void 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 * wpa_scnprintf - Simpler-to-use snprintf function 188 * @buf: Output buffer 189 * @size: Buffer size 190 * @fmt: format 191 * 192 * Simpler snprintf version that doesn't require further error checks - the 193 * return value only indicates how many bytes were actually written, excluding 194 * the NULL byte (i.e., 0 on error, size-1 if buffer is not big enough). 195 */ 196int wpa_scnprintf(char *buf, size_t size, const char *fmt, ...) 197{ 198 va_list ap; 199 int ret; 200 201 if (!size) 202 return 0; 203 204 va_start(ap, fmt); 205 ret = vsnprintf(buf, size, fmt, ap); 206 va_end(ap); 207 208 if (ret < 0) 209 return 0; 210 if ((size_t) ret >= size) 211 return size - 1; 212 213 return ret; 214} 215 216static inline int _wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, 217 size_t len, int uppercase) 218{ 219 size_t i; 220 char *pos = buf, *end = buf + buf_size; 221 int ret; 222 if (buf_size == 0) 223 return 0; 224 for (i = 0; i < len; i++) { 225 ret = os_snprintf(pos, end - pos, uppercase ? "%02X" : "%02x", 226 data[i]); 227 if (os_snprintf_error(end - pos, ret)) { 228 end[-1] = '\0'; 229 return pos - buf; 230 } 231 pos += ret; 232 } 233 end[-1] = '\0'; 234 return pos - buf; 235} 236 237/** 238 * wpa_snprintf_hex - Print data as a hex string into a buffer 239 * @buf: Memory area to use as the output buffer 240 * @buf_size: Maximum buffer size in bytes (should be at least 2 * len + 1) 241 * @data: Data to be printed 242 * @len: Length of data in bytes 243 * Returns: Number of bytes written 244 */ 245int wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len) 246{ 247 return _wpa_snprintf_hex(buf, buf_size, data, len, 0); 248} 249 250 251/** 252 * wpa_snprintf_hex_uppercase - Print data as a upper case hex string into buf 253 * @buf: Memory area to use as the output buffer 254 * @buf_size: Maximum buffer size in bytes (should be at least 2 * len + 1) 255 * @data: Data to be printed 256 * @len: Length of data in bytes 257 * Returns: Number of bytes written 258 */ 259int wpa_snprintf_hex_uppercase(char *buf, size_t buf_size, const u8 *data, 260 size_t len) 261{ 262 return _wpa_snprintf_hex(buf, buf_size, data, len, 1); 263} 264 265 266#ifdef CONFIG_ANSI_C_EXTRA 267 268#ifdef _WIN32_WCE 269void perror(const char *s) 270{ 271 wpa_printf(MSG_ERROR, "%s: GetLastError: %d", 272 s, (int) GetLastError()); 273} 274#endif /* _WIN32_WCE */ 275 276 277int optind = 1; 278int optopt; 279char *optarg; 280 281int getopt(int argc, char *const argv[], const char *optstring) 282{ 283 static int optchr = 1; 284 char *cp; 285 286 if (optchr == 1) { 287 if (optind >= argc) { 288 /* all arguments processed */ 289 return EOF; 290 } 291 292 if (argv[optind][0] != '-' || argv[optind][1] == '\0') { 293 /* no option characters */ 294 return EOF; 295 } 296 } 297 298 if (os_strcmp(argv[optind], "--") == 0) { 299 /* no more options */ 300 optind++; 301 return EOF; 302 } 303 304 optopt = argv[optind][optchr]; 305 cp = os_strchr(optstring, optopt); 306 if (cp == NULL || optopt == ':') { 307 if (argv[optind][++optchr] == '\0') { 308 optchr = 1; 309 optind++; 310 } 311 return '?'; 312 } 313 314 if (cp[1] == ':') { 315 /* Argument required */ 316 optchr = 1; 317 if (argv[optind][optchr + 1]) { 318 /* No space between option and argument */ 319 optarg = &argv[optind++][optchr + 1]; 320 } else if (++optind >= argc) { 321 /* option requires an argument */ 322 return '?'; 323 } else { 324 /* Argument in the next argv */ 325 optarg = argv[optind++]; 326 } 327 } else { 328 /* No argument */ 329 if (argv[optind][++optchr] == '\0') { 330 optchr = 1; 331 optind++; 332 } 333 optarg = NULL; 334 } 335 return *cp; 336} 337#endif /* CONFIG_ANSI_C_EXTRA */ 338 339 340#ifdef CONFIG_NATIVE_WINDOWS 341/** 342 * wpa_unicode2ascii_inplace - Convert unicode string into ASCII 343 * @str: Pointer to string to convert 344 * 345 * This function converts a unicode string to ASCII using the same 346 * buffer for output. If UNICODE is not set, the buffer is not 347 * modified. 348 */ 349void wpa_unicode2ascii_inplace(TCHAR *str) 350{ 351#ifdef UNICODE 352 char *dst = (char *) str; 353 while (*str) 354 *dst++ = (char) *str++; 355 *dst = '\0'; 356#endif /* UNICODE */ 357} 358 359 360TCHAR * wpa_strdup_tchar(const char *str) 361{ 362#ifdef UNICODE 363 TCHAR *buf; 364 buf = os_malloc((strlen(str) + 1) * sizeof(TCHAR)); 365 if (buf == NULL) 366 return NULL; 367 wsprintf(buf, L"%S", str); 368 return buf; 369#else /* UNICODE */ 370 return os_strdup(str); 371#endif /* UNICODE */ 372} 373#endif /* CONFIG_NATIVE_WINDOWS */ 374 375 376void printf_encode(char *txt, size_t maxlen, const u8 *data, size_t len) 377{ 378 char *end = txt + maxlen; 379 size_t i; 380 381 for (i = 0; i < len; i++) { 382 if (txt + 4 >= end) 383 break; 384 385 switch (data[i]) { 386 case '\"': 387 *txt++ = '\\'; 388 *txt++ = '\"'; 389 break; 390 case '\\': 391 *txt++ = '\\'; 392 *txt++ = '\\'; 393 break; 394 case '\033': 395 *txt++ = '\\'; 396 *txt++ = 'e'; 397 break; 398 case '\n': 399 *txt++ = '\\'; 400 *txt++ = 'n'; 401 break; 402 case '\r': 403 *txt++ = '\\'; 404 *txt++ = 'r'; 405 break; 406 case '\t': 407 *txt++ = '\\'; 408 *txt++ = 't'; 409 break; 410 default: 411 if (data[i] >= 32 && data[i] <= 127) { 412 *txt++ = data[i]; 413 } else { 414 txt += os_snprintf(txt, end - txt, "\\x%02x", 415 data[i]); 416 } 417 break; 418 } 419 } 420 421 *txt = '\0'; 422} 423 424 425size_t printf_decode(u8 *buf, size_t maxlen, const char *str) 426{ 427 const char *pos = str; 428 size_t len = 0; 429 int val; 430 431 while (*pos) { 432 if (len + 1 >= maxlen) 433 break; 434 switch (*pos) { 435 case '\\': 436 pos++; 437 switch (*pos) { 438 case '\\': 439 buf[len++] = '\\'; 440 pos++; 441 break; 442 case '"': 443 buf[len++] = '"'; 444 pos++; 445 break; 446 case 'n': 447 buf[len++] = '\n'; 448 pos++; 449 break; 450 case 'r': 451 buf[len++] = '\r'; 452 pos++; 453 break; 454 case 't': 455 buf[len++] = '\t'; 456 pos++; 457 break; 458 case 'e': 459 buf[len++] = '\033'; 460 pos++; 461 break; 462 case 'x': 463 pos++; 464 val = hex2byte(pos); 465 if (val < 0) { 466 val = hex2num(*pos); 467 if (val < 0) 468 break; 469 buf[len++] = val; 470 pos++; 471 } else { 472 buf[len++] = val; 473 pos += 2; 474 } 475 break; 476 case '0': 477 case '1': 478 case '2': 479 case '3': 480 case '4': 481 case '5': 482 case '6': 483 case '7': 484 val = *pos++ - '0'; 485 if (*pos >= '0' && *pos <= '7') 486 val = val * 8 + (*pos++ - '0'); 487 if (*pos >= '0' && *pos <= '7') 488 val = val * 8 + (*pos++ - '0'); 489 buf[len++] = val; 490 break; 491 default: 492 break; 493 } 494 break; 495 default: 496 buf[len++] = *pos++; 497 break; 498 } 499 } 500 if (maxlen > len) 501 buf[len] = '\0'; 502 503 return len; 504} 505 506 507/** 508 * wpa_ssid_txt - Convert SSID to a printable string 509 * @ssid: SSID (32-octet string) 510 * @ssid_len: Length of ssid in octets 511 * Returns: Pointer to a printable string 512 * 513 * This function can be used to convert SSIDs into printable form. In most 514 * cases, SSIDs do not use unprintable characters, but IEEE 802.11 standard 515 * does not limit the used character set, so anything could be used in an SSID. 516 * 517 * This function uses a static buffer, so only one call can be used at the 518 * time, i.e., this is not re-entrant and the returned buffer must be used 519 * before calling this again. 520 */ 521const char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len) 522{ 523 static char ssid_txt[32 * 4 + 1]; 524 525 if (ssid == NULL) { 526 ssid_txt[0] = '\0'; 527 return ssid_txt; 528 } 529 530 printf_encode(ssid_txt, sizeof(ssid_txt), ssid, ssid_len); 531 return ssid_txt; 532} 533 534 535void * __hide_aliasing_typecast(void *foo) 536{ 537 return foo; 538} 539 540 541char * wpa_config_parse_string(const char *value, size_t *len) 542{ 543 if (*value == '"') { 544 const char *pos; 545 char *str; 546 value++; 547 pos = os_strrchr(value, '"'); 548 if (pos == NULL || pos[1] != '\0') 549 return NULL; 550 *len = pos - value; 551 str = dup_binstr(value, *len); 552 if (str == NULL) 553 return NULL; 554 return str; 555 } else if (*value == 'P' && value[1] == '"') { 556 const char *pos; 557 char *tstr, *str; 558 size_t tlen; 559 value += 2; 560 pos = os_strrchr(value, '"'); 561 if (pos == NULL || pos[1] != '\0') 562 return NULL; 563 tlen = pos - value; 564 tstr = dup_binstr(value, tlen); 565 if (tstr == NULL) 566 return NULL; 567 568 str = os_malloc(tlen + 1); 569 if (str == NULL) { 570 os_free(tstr); 571 return NULL; 572 } 573 574 *len = printf_decode((u8 *) str, tlen + 1, tstr); 575 os_free(tstr); 576 577 return str; 578 } else { 579 u8 *str; 580 size_t tlen, hlen = os_strlen(value); 581 if (hlen & 1) 582 return NULL; 583 tlen = hlen / 2; 584 str = os_malloc(tlen + 1); 585 if (str == NULL) 586 return NULL; 587 if (hexstr2bin(value, str, tlen)) { 588 os_free(str); 589 return NULL; 590 } 591 str[tlen] = '\0'; 592 *len = tlen; 593 return (char *) str; 594 } 595} 596 597 598int is_hex(const u8 *data, size_t len) 599{ 600 size_t i; 601 602 for (i = 0; i < len; i++) { 603 if (data[i] < 32 || data[i] >= 127) 604 return 1; 605 } 606 return 0; 607} 608 609 610size_t merge_byte_arrays(u8 *res, size_t res_len, 611 const u8 *src1, size_t src1_len, 612 const u8 *src2, size_t src2_len) 613{ 614 size_t len = 0; 615 616 os_memset(res, 0, res_len); 617 618 if (src1) { 619 if (src1_len >= res_len) { 620 os_memcpy(res, src1, res_len); 621 return res_len; 622 } 623 624 os_memcpy(res, src1, src1_len); 625 len += src1_len; 626 } 627 628 if (src2) { 629 if (len + src2_len >= res_len) { 630 os_memcpy(res + len, src2, res_len - len); 631 return res_len; 632 } 633 634 os_memcpy(res + len, src2, src2_len); 635 len += src2_len; 636 } 637 638 return len; 639} 640 641 642char * dup_binstr(const void *src, size_t len) 643{ 644 char *res; 645 646 if (src == NULL) 647 return NULL; 648 res = os_malloc(len + 1); 649 if (res == NULL) 650 return NULL; 651 os_memcpy(res, src, len); 652 res[len] = '\0'; 653 654 return res; 655} 656 657 658int freq_range_list_parse(struct wpa_freq_range_list *res, const char *value) 659{ 660 struct wpa_freq_range *freq = NULL, *n; 661 unsigned int count = 0; 662 const char *pos, *pos2, *pos3; 663 664 /* 665 * Comma separated list of frequency ranges. 666 * For example: 2412-2432,2462,5000-6000 667 */ 668 pos = value; 669 while (pos && pos[0]) { 670 n = os_realloc_array(freq, count + 1, 671 sizeof(struct wpa_freq_range)); 672 if (n == NULL) { 673 os_free(freq); 674 return -1; 675 } 676 freq = n; 677 freq[count].min = atoi(pos); 678 pos2 = os_strchr(pos, '-'); 679 pos3 = os_strchr(pos, ','); 680 if (pos2 && (!pos3 || pos2 < pos3)) { 681 pos2++; 682 freq[count].max = atoi(pos2); 683 } else 684 freq[count].max = freq[count].min; 685 pos = pos3; 686 if (pos) 687 pos++; 688 count++; 689 } 690 691 os_free(res->range); 692 res->range = freq; 693 res->num = count; 694 695 return 0; 696} 697 698 699int freq_range_list_includes(const struct wpa_freq_range_list *list, 700 unsigned int freq) 701{ 702 unsigned int i; 703 704 if (list == NULL) 705 return 0; 706 707 for (i = 0; i < list->num; i++) { 708 if (freq >= list->range[i].min && freq <= list->range[i].max) 709 return 1; 710 } 711 712 return 0; 713} 714 715 716char * freq_range_list_str(const struct wpa_freq_range_list *list) 717{ 718 char *buf, *pos, *end; 719 size_t maxlen; 720 unsigned int i; 721 int res; 722 723 if (list->num == 0) 724 return NULL; 725 726 maxlen = list->num * 30; 727 buf = os_malloc(maxlen); 728 if (buf == NULL) 729 return NULL; 730 pos = buf; 731 end = buf + maxlen; 732 733 for (i = 0; i < list->num; i++) { 734 struct wpa_freq_range *range = &list->range[i]; 735 736 if (range->min == range->max) 737 res = os_snprintf(pos, end - pos, "%s%u", 738 i == 0 ? "" : ",", range->min); 739 else 740 res = os_snprintf(pos, end - pos, "%s%u-%u", 741 i == 0 ? "" : ",", 742 range->min, range->max); 743 if (os_snprintf_error(end - pos, res)) { 744 os_free(buf); 745 return NULL; 746 } 747 pos += res; 748 } 749 750 return buf; 751} 752 753 754int int_array_len(const int *a) 755{ 756 int i; 757 for (i = 0; a && a[i]; i++) 758 ; 759 return i; 760} 761 762 763void int_array_concat(int **res, const int *a) 764{ 765 int reslen, alen, i; 766 int *n; 767 768 reslen = int_array_len(*res); 769 alen = int_array_len(a); 770 771 n = os_realloc_array(*res, reslen + alen + 1, sizeof(int)); 772 if (n == NULL) { 773 os_free(*res); 774 *res = NULL; 775 return; 776 } 777 for (i = 0; i <= alen; i++) 778 n[reslen + i] = a[i]; 779 *res = n; 780} 781 782 783static int freq_cmp(const void *a, const void *b) 784{ 785 int _a = *(int *) a; 786 int _b = *(int *) b; 787 788 if (_a == 0) 789 return 1; 790 if (_b == 0) 791 return -1; 792 return _a - _b; 793} 794 795 796void int_array_sort_unique(int *a) 797{ 798 int alen; 799 int i, j; 800 801 if (a == NULL) 802 return; 803 804 alen = int_array_len(a); 805 qsort(a, alen, sizeof(int), freq_cmp); 806 807 i = 0; 808 j = 1; 809 while (a[i] && a[j]) { 810 if (a[i] == a[j]) { 811 j++; 812 continue; 813 } 814 a[++i] = a[j++]; 815 } 816 if (a[i]) 817 i++; 818 a[i] = 0; 819} 820 821 822void int_array_add_unique(int **res, int a) 823{ 824 int reslen; 825 int *n; 826 827 for (reslen = 0; *res && (*res)[reslen]; reslen++) { 828 if ((*res)[reslen] == a) 829 return; /* already in the list */ 830 } 831 832 n = os_realloc_array(*res, reslen + 2, sizeof(int)); 833 if (n == NULL) { 834 os_free(*res); 835 *res = NULL; 836 return; 837 } 838 839 n[reslen] = a; 840 n[reslen + 1] = 0; 841 842 *res = n; 843} 844 845 846void str_clear_free(char *str) 847{ 848 if (str) { 849 size_t len = os_strlen(str); 850 os_memset(str, 0, len); 851 os_free(str); 852 } 853} 854 855 856void bin_clear_free(void *bin, size_t len) 857{ 858 if (bin) { 859 os_memset(bin, 0, len); 860 os_free(bin); 861 } 862} 863 864 865int random_mac_addr(u8 *addr) 866{ 867 if (os_get_random(addr, ETH_ALEN) < 0) 868 return -1; 869 addr[0] &= 0xfe; /* unicast */ 870 addr[0] |= 0x02; /* locally administered */ 871 return 0; 872} 873 874 875int random_mac_addr_keep_oui(u8 *addr) 876{ 877 if (os_get_random(addr + 3, 3) < 0) 878 return -1; 879 addr[0] &= 0xfe; /* unicast */ 880 addr[0] |= 0x02; /* locally administered */ 881 return 0; 882} 883 884 885/** 886 * str_token - Get next token from a string 887 * @buf: String to tokenize. Note that the string might be modified. 888 * @delim: String of delimiters 889 * @context: Pointer to save our context. Should be initialized with 890 * NULL on the first call, and passed for any further call. 891 * Returns: The next token, NULL if there are no more valid tokens. 892 */ 893char * str_token(char *str, const char *delim, char **context) 894{ 895 char *end, *pos = str; 896 897 if (*context) 898 pos = *context; 899 900 while (*pos && os_strchr(delim, *pos)) 901 pos++; 902 if (!*pos) 903 return NULL; 904 905 end = pos + 1; 906 while (*end && !os_strchr(delim, *end)) 907 end++; 908 909 if (*end) 910 *end++ = '\0'; 911 912 *context = end; 913 return pos; 914} 915