common.c revision af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5
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 39static const char * hwaddr_parse(const char *txt, u8 *addr) 40{ 41 size_t i; 42 43 for (i = 0; i < ETH_ALEN; i++) { 44 int a; 45 46 a = hex2byte(txt); 47 if (a < 0) 48 return NULL; 49 txt += 2; 50 addr[i] = a; 51 if (i < ETH_ALEN - 1 && *txt++ != ':') 52 return NULL; 53 } 54 return txt; 55} 56 57 58/** 59 * hwaddr_aton - Convert ASCII string to MAC address (colon-delimited format) 60 * @txt: MAC address as a string (e.g., "00:11:22:33:44:55") 61 * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes) 62 * Returns: 0 on success, -1 on failure (e.g., string not a MAC address) 63 */ 64int hwaddr_aton(const char *txt, u8 *addr) 65{ 66 return hwaddr_parse(txt, addr) ? 0 : -1; 67} 68 69 70/** 71 * hwaddr_masked_aton - Convert ASCII string with optional mask to MAC address (colon-delimited format) 72 * @txt: MAC address with optional mask as a string (e.g., "00:11:22:33:44:55/ff:ff:ff:ff:00:00") 73 * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes) 74 * @mask: Buffer for the MAC address mask (ETH_ALEN = 6 bytes) 75 * @maskable: Flag to indicate whether a mask is allowed 76 * Returns: 0 on success, -1 on failure (e.g., string not a MAC address) 77 */ 78int hwaddr_masked_aton(const char *txt, u8 *addr, u8 *mask, u8 maskable) 79{ 80 const char *r; 81 82 /* parse address part */ 83 r = hwaddr_parse(txt, addr); 84 if (!r) 85 return -1; 86 87 /* check for optional mask */ 88 if (*r == '\0' || isspace(*r)) { 89 /* no mask specified, assume default */ 90 os_memset(mask, 0xff, ETH_ALEN); 91 } else if (maskable && *r == '/') { 92 /* mask specified and allowed */ 93 r = hwaddr_parse(r + 1, mask); 94 /* parser error? */ 95 if (!r) 96 return -1; 97 } else { 98 /* mask specified but not allowed or trailing garbage */ 99 return -1; 100 } 101 102 return 0; 103} 104 105 106/** 107 * hwaddr_compact_aton - Convert ASCII string to MAC address (no colon delimitors format) 108 * @txt: MAC address as a string (e.g., "001122334455") 109 * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes) 110 * Returns: 0 on success, -1 on failure (e.g., string not a MAC address) 111 */ 112int hwaddr_compact_aton(const char *txt, u8 *addr) 113{ 114 int i; 115 116 for (i = 0; i < 6; i++) { 117 int a, b; 118 119 a = hex2num(*txt++); 120 if (a < 0) 121 return -1; 122 b = hex2num(*txt++); 123 if (b < 0) 124 return -1; 125 *addr++ = (a << 4) | b; 126 } 127 128 return 0; 129} 130 131/** 132 * hwaddr_aton2 - Convert ASCII string to MAC address (in any known format) 133 * @txt: MAC address as a string (e.g., 00:11:22:33:44:55 or 0011.2233.4455) 134 * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes) 135 * Returns: Characters used (> 0) on success, -1 on failure 136 */ 137int hwaddr_aton2(const char *txt, u8 *addr) 138{ 139 int i; 140 const char *pos = txt; 141 142 for (i = 0; i < 6; i++) { 143 int a, b; 144 145 while (*pos == ':' || *pos == '.' || *pos == '-') 146 pos++; 147 148 a = hex2num(*pos++); 149 if (a < 0) 150 return -1; 151 b = hex2num(*pos++); 152 if (b < 0) 153 return -1; 154 *addr++ = (a << 4) | b; 155 } 156 157 return pos - txt; 158} 159 160 161/** 162 * hexstr2bin - Convert ASCII hex string into binary data 163 * @hex: ASCII hex string (e.g., "01ab") 164 * @buf: Buffer for the binary data 165 * @len: Length of the text to convert in bytes (of buf); hex will be double 166 * this size 167 * Returns: 0 on success, -1 on failure (invalid hex string) 168 */ 169int hexstr2bin(const char *hex, u8 *buf, size_t len) 170{ 171 size_t i; 172 int a; 173 const char *ipos = hex; 174 u8 *opos = buf; 175 176 for (i = 0; i < len; i++) { 177 a = hex2byte(ipos); 178 if (a < 0) 179 return -1; 180 *opos++ = a; 181 ipos += 2; 182 } 183 return 0; 184} 185 186 187int hwaddr_mask_txt(char *buf, size_t len, const u8 *addr, const u8 *mask) 188{ 189 size_t i; 190 int print_mask = 0; 191 int res; 192 193 for (i = 0; i < ETH_ALEN; i++) { 194 if (mask[i] != 0xff) { 195 print_mask = 1; 196 break; 197 } 198 } 199 200 if (print_mask) 201 res = os_snprintf(buf, len, MACSTR "/" MACSTR, 202 MAC2STR(addr), MAC2STR(mask)); 203 else 204 res = os_snprintf(buf, len, MACSTR, MAC2STR(addr)); 205 if (os_snprintf_error(len, res)) 206 return -1; 207 return res; 208} 209 210 211/** 212 * inc_byte_array - Increment arbitrary length byte array by one 213 * @counter: Pointer to byte array 214 * @len: Length of the counter in bytes 215 * 216 * This function increments the last byte of the counter by one and continues 217 * rolling over to more significant bytes if the byte was incremented from 218 * 0xff to 0x00. 219 */ 220void inc_byte_array(u8 *counter, size_t len) 221{ 222 int pos = len - 1; 223 while (pos >= 0) { 224 counter[pos]++; 225 if (counter[pos] != 0) 226 break; 227 pos--; 228 } 229} 230 231 232void wpa_get_ntp_timestamp(u8 *buf) 233{ 234 struct os_time now; 235 u32 sec, usec; 236 be32 tmp; 237 238 /* 64-bit NTP timestamp (time from 1900-01-01 00:00:00) */ 239 os_get_time(&now); 240 sec = now.sec + 2208988800U; /* Epoch to 1900 */ 241 /* Estimate 2^32/10^6 = 4295 - 1/32 - 1/512 */ 242 usec = now.usec; 243 usec = 4295 * usec - (usec >> 5) - (usec >> 9); 244 tmp = host_to_be32(sec); 245 os_memcpy(buf, (u8 *) &tmp, 4); 246 tmp = host_to_be32(usec); 247 os_memcpy(buf + 4, (u8 *) &tmp, 4); 248} 249 250/** 251 * wpa_scnprintf - Simpler-to-use snprintf function 252 * @buf: Output buffer 253 * @size: Buffer size 254 * @fmt: format 255 * 256 * Simpler snprintf version that doesn't require further error checks - the 257 * return value only indicates how many bytes were actually written, excluding 258 * the NULL byte (i.e., 0 on error, size-1 if buffer is not big enough). 259 */ 260int wpa_scnprintf(char *buf, size_t size, const char *fmt, ...) 261{ 262 va_list ap; 263 int ret; 264 265 if (!size) 266 return 0; 267 268 va_start(ap, fmt); 269 ret = vsnprintf(buf, size, fmt, ap); 270 va_end(ap); 271 272 if (ret < 0) 273 return 0; 274 if ((size_t) ret >= size) 275 return size - 1; 276 277 return ret; 278} 279 280 281int wpa_snprintf_hex_sep(char *buf, size_t buf_size, const u8 *data, size_t len, 282 char sep) 283{ 284 size_t i; 285 char *pos = buf, *end = buf + buf_size; 286 int ret; 287 288 if (buf_size == 0) 289 return 0; 290 291 for (i = 0; i < len; i++) { 292 ret = os_snprintf(pos, end - pos, "%02x%c", 293 data[i], sep); 294 if (os_snprintf_error(end - pos, ret)) { 295 end[-1] = '\0'; 296 return pos - buf; 297 } 298 pos += ret; 299 } 300 pos[-1] = '\0'; 301 return pos - buf; 302} 303 304 305static inline int _wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, 306 size_t len, int uppercase) 307{ 308 size_t i; 309 char *pos = buf, *end = buf + buf_size; 310 int ret; 311 if (buf_size == 0) 312 return 0; 313 for (i = 0; i < len; i++) { 314 ret = os_snprintf(pos, end - pos, uppercase ? "%02X" : "%02x", 315 data[i]); 316 if (os_snprintf_error(end - pos, ret)) { 317 end[-1] = '\0'; 318 return pos - buf; 319 } 320 pos += ret; 321 } 322 end[-1] = '\0'; 323 return pos - buf; 324} 325 326/** 327 * wpa_snprintf_hex - Print data as a hex string into a buffer 328 * @buf: Memory area to use as the output buffer 329 * @buf_size: Maximum buffer size in bytes (should be at least 2 * len + 1) 330 * @data: Data to be printed 331 * @len: Length of data in bytes 332 * Returns: Number of bytes written 333 */ 334int wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len) 335{ 336 return _wpa_snprintf_hex(buf, buf_size, data, len, 0); 337} 338 339 340/** 341 * wpa_snprintf_hex_uppercase - Print data as a upper case hex string into buf 342 * @buf: Memory area to use as the output buffer 343 * @buf_size: Maximum buffer size in bytes (should be at least 2 * len + 1) 344 * @data: Data to be printed 345 * @len: Length of data in bytes 346 * Returns: Number of bytes written 347 */ 348int wpa_snprintf_hex_uppercase(char *buf, size_t buf_size, const u8 *data, 349 size_t len) 350{ 351 return _wpa_snprintf_hex(buf, buf_size, data, len, 1); 352} 353 354 355#ifdef CONFIG_ANSI_C_EXTRA 356 357#ifdef _WIN32_WCE 358void perror(const char *s) 359{ 360 wpa_printf(MSG_ERROR, "%s: GetLastError: %d", 361 s, (int) GetLastError()); 362} 363#endif /* _WIN32_WCE */ 364 365 366int optind = 1; 367int optopt; 368char *optarg; 369 370int getopt(int argc, char *const argv[], const char *optstring) 371{ 372 static int optchr = 1; 373 char *cp; 374 375 if (optchr == 1) { 376 if (optind >= argc) { 377 /* all arguments processed */ 378 return EOF; 379 } 380 381 if (argv[optind][0] != '-' || argv[optind][1] == '\0') { 382 /* no option characters */ 383 return EOF; 384 } 385 } 386 387 if (os_strcmp(argv[optind], "--") == 0) { 388 /* no more options */ 389 optind++; 390 return EOF; 391 } 392 393 optopt = argv[optind][optchr]; 394 cp = os_strchr(optstring, optopt); 395 if (cp == NULL || optopt == ':') { 396 if (argv[optind][++optchr] == '\0') { 397 optchr = 1; 398 optind++; 399 } 400 return '?'; 401 } 402 403 if (cp[1] == ':') { 404 /* Argument required */ 405 optchr = 1; 406 if (argv[optind][optchr + 1]) { 407 /* No space between option and argument */ 408 optarg = &argv[optind++][optchr + 1]; 409 } else if (++optind >= argc) { 410 /* option requires an argument */ 411 return '?'; 412 } else { 413 /* Argument in the next argv */ 414 optarg = argv[optind++]; 415 } 416 } else { 417 /* No argument */ 418 if (argv[optind][++optchr] == '\0') { 419 optchr = 1; 420 optind++; 421 } 422 optarg = NULL; 423 } 424 return *cp; 425} 426#endif /* CONFIG_ANSI_C_EXTRA */ 427 428 429#ifdef CONFIG_NATIVE_WINDOWS 430/** 431 * wpa_unicode2ascii_inplace - Convert unicode string into ASCII 432 * @str: Pointer to string to convert 433 * 434 * This function converts a unicode string to ASCII using the same 435 * buffer for output. If UNICODE is not set, the buffer is not 436 * modified. 437 */ 438void wpa_unicode2ascii_inplace(TCHAR *str) 439{ 440#ifdef UNICODE 441 char *dst = (char *) str; 442 while (*str) 443 *dst++ = (char) *str++; 444 *dst = '\0'; 445#endif /* UNICODE */ 446} 447 448 449TCHAR * wpa_strdup_tchar(const char *str) 450{ 451#ifdef UNICODE 452 TCHAR *buf; 453 buf = os_malloc((strlen(str) + 1) * sizeof(TCHAR)); 454 if (buf == NULL) 455 return NULL; 456 wsprintf(buf, L"%S", str); 457 return buf; 458#else /* UNICODE */ 459 return os_strdup(str); 460#endif /* UNICODE */ 461} 462#endif /* CONFIG_NATIVE_WINDOWS */ 463 464 465void printf_encode(char *txt, size_t maxlen, const u8 *data, size_t len) 466{ 467 char *end = txt + maxlen; 468 size_t i; 469 470 for (i = 0; i < len; i++) { 471 if (txt + 4 >= end) 472 break; 473 474 switch (data[i]) { 475 case '\"': 476 *txt++ = '\\'; 477 *txt++ = '\"'; 478 break; 479 case '\\': 480 *txt++ = '\\'; 481 *txt++ = '\\'; 482 break; 483 case '\033': 484 *txt++ = '\\'; 485 *txt++ = 'e'; 486 break; 487 case '\n': 488 *txt++ = '\\'; 489 *txt++ = 'n'; 490 break; 491 case '\r': 492 *txt++ = '\\'; 493 *txt++ = 'r'; 494 break; 495 case '\t': 496 *txt++ = '\\'; 497 *txt++ = 't'; 498 break; 499 default: 500 if (data[i] >= 32 && data[i] <= 127) { 501 *txt++ = data[i]; 502 } else { 503 txt += os_snprintf(txt, end - txt, "\\x%02x", 504 data[i]); 505 } 506 break; 507 } 508 } 509 510 *txt = '\0'; 511} 512 513 514size_t printf_decode(u8 *buf, size_t maxlen, const char *str) 515{ 516 const char *pos = str; 517 size_t len = 0; 518 int val; 519 520 while (*pos) { 521 if (len + 1 >= maxlen) 522 break; 523 switch (*pos) { 524 case '\\': 525 pos++; 526 switch (*pos) { 527 case '\\': 528 buf[len++] = '\\'; 529 pos++; 530 break; 531 case '"': 532 buf[len++] = '"'; 533 pos++; 534 break; 535 case 'n': 536 buf[len++] = '\n'; 537 pos++; 538 break; 539 case 'r': 540 buf[len++] = '\r'; 541 pos++; 542 break; 543 case 't': 544 buf[len++] = '\t'; 545 pos++; 546 break; 547 case 'e': 548 buf[len++] = '\033'; 549 pos++; 550 break; 551 case 'x': 552 pos++; 553 val = hex2byte(pos); 554 if (val < 0) { 555 val = hex2num(*pos); 556 if (val < 0) 557 break; 558 buf[len++] = val; 559 pos++; 560 } else { 561 buf[len++] = val; 562 pos += 2; 563 } 564 break; 565 case '0': 566 case '1': 567 case '2': 568 case '3': 569 case '4': 570 case '5': 571 case '6': 572 case '7': 573 val = *pos++ - '0'; 574 if (*pos >= '0' && *pos <= '7') 575 val = val * 8 + (*pos++ - '0'); 576 if (*pos >= '0' && *pos <= '7') 577 val = val * 8 + (*pos++ - '0'); 578 buf[len++] = val; 579 break; 580 default: 581 break; 582 } 583 break; 584 default: 585 buf[len++] = *pos++; 586 break; 587 } 588 } 589 if (maxlen > len) 590 buf[len] = '\0'; 591 592 return len; 593} 594 595 596/** 597 * wpa_ssid_txt - Convert SSID to a printable string 598 * @ssid: SSID (32-octet string) 599 * @ssid_len: Length of ssid in octets 600 * Returns: Pointer to a printable string 601 * 602 * This function can be used to convert SSIDs into printable form. In most 603 * cases, SSIDs do not use unprintable characters, but IEEE 802.11 standard 604 * does not limit the used character set, so anything could be used in an SSID. 605 * 606 * This function uses a static buffer, so only one call can be used at the 607 * time, i.e., this is not re-entrant and the returned buffer must be used 608 * before calling this again. 609 */ 610const char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len) 611{ 612 static char ssid_txt[32 * 4 + 1]; 613 614 if (ssid == NULL) { 615 ssid_txt[0] = '\0'; 616 return ssid_txt; 617 } 618 619 printf_encode(ssid_txt, sizeof(ssid_txt), ssid, ssid_len); 620 return ssid_txt; 621} 622 623 624void * __hide_aliasing_typecast(void *foo) 625{ 626 return foo; 627} 628 629 630char * wpa_config_parse_string(const char *value, size_t *len) 631{ 632 if (*value == '"') { 633 const char *pos; 634 char *str; 635 value++; 636 pos = os_strrchr(value, '"'); 637 if (pos == NULL || pos[1] != '\0') 638 return NULL; 639 *len = pos - value; 640 str = dup_binstr(value, *len); 641 if (str == NULL) 642 return NULL; 643 return str; 644 } else if (*value == 'P' && value[1] == '"') { 645 const char *pos; 646 char *tstr, *str; 647 size_t tlen; 648 value += 2; 649 pos = os_strrchr(value, '"'); 650 if (pos == NULL || pos[1] != '\0') 651 return NULL; 652 tlen = pos - value; 653 tstr = dup_binstr(value, tlen); 654 if (tstr == NULL) 655 return NULL; 656 657 str = os_malloc(tlen + 1); 658 if (str == NULL) { 659 os_free(tstr); 660 return NULL; 661 } 662 663 *len = printf_decode((u8 *) str, tlen + 1, tstr); 664 os_free(tstr); 665 666 return str; 667 } else { 668 u8 *str; 669 size_t tlen, hlen = os_strlen(value); 670 if (hlen & 1) 671 return NULL; 672 tlen = hlen / 2; 673 str = os_malloc(tlen + 1); 674 if (str == NULL) 675 return NULL; 676 if (hexstr2bin(value, str, tlen)) { 677 os_free(str); 678 return NULL; 679 } 680 str[tlen] = '\0'; 681 *len = tlen; 682 return (char *) str; 683 } 684} 685 686 687int is_hex(const u8 *data, size_t len) 688{ 689 size_t i; 690 691 for (i = 0; i < len; i++) { 692 if (data[i] < 32 || data[i] >= 127) 693 return 1; 694 } 695 return 0; 696} 697 698 699size_t merge_byte_arrays(u8 *res, size_t res_len, 700 const u8 *src1, size_t src1_len, 701 const u8 *src2, size_t src2_len) 702{ 703 size_t len = 0; 704 705 os_memset(res, 0, res_len); 706 707 if (src1) { 708 if (src1_len >= res_len) { 709 os_memcpy(res, src1, res_len); 710 return res_len; 711 } 712 713 os_memcpy(res, src1, src1_len); 714 len += src1_len; 715 } 716 717 if (src2) { 718 if (len + src2_len >= res_len) { 719 os_memcpy(res + len, src2, res_len - len); 720 return res_len; 721 } 722 723 os_memcpy(res + len, src2, src2_len); 724 len += src2_len; 725 } 726 727 return len; 728} 729 730 731char * dup_binstr(const void *src, size_t len) 732{ 733 char *res; 734 735 if (src == NULL) 736 return NULL; 737 res = os_malloc(len + 1); 738 if (res == NULL) 739 return NULL; 740 os_memcpy(res, src, len); 741 res[len] = '\0'; 742 743 return res; 744} 745 746 747int freq_range_list_parse(struct wpa_freq_range_list *res, const char *value) 748{ 749 struct wpa_freq_range *freq = NULL, *n; 750 unsigned int count = 0; 751 const char *pos, *pos2, *pos3; 752 753 /* 754 * Comma separated list of frequency ranges. 755 * For example: 2412-2432,2462,5000-6000 756 */ 757 pos = value; 758 while (pos && pos[0]) { 759 n = os_realloc_array(freq, count + 1, 760 sizeof(struct wpa_freq_range)); 761 if (n == NULL) { 762 os_free(freq); 763 return -1; 764 } 765 freq = n; 766 freq[count].min = atoi(pos); 767 pos2 = os_strchr(pos, '-'); 768 pos3 = os_strchr(pos, ','); 769 if (pos2 && (!pos3 || pos2 < pos3)) { 770 pos2++; 771 freq[count].max = atoi(pos2); 772 } else 773 freq[count].max = freq[count].min; 774 pos = pos3; 775 if (pos) 776 pos++; 777 count++; 778 } 779 780 os_free(res->range); 781 res->range = freq; 782 res->num = count; 783 784 return 0; 785} 786 787 788int freq_range_list_includes(const struct wpa_freq_range_list *list, 789 unsigned int freq) 790{ 791 unsigned int i; 792 793 if (list == NULL) 794 return 0; 795 796 for (i = 0; i < list->num; i++) { 797 if (freq >= list->range[i].min && freq <= list->range[i].max) 798 return 1; 799 } 800 801 return 0; 802} 803 804 805char * freq_range_list_str(const struct wpa_freq_range_list *list) 806{ 807 char *buf, *pos, *end; 808 size_t maxlen; 809 unsigned int i; 810 int res; 811 812 if (list->num == 0) 813 return NULL; 814 815 maxlen = list->num * 30; 816 buf = os_malloc(maxlen); 817 if (buf == NULL) 818 return NULL; 819 pos = buf; 820 end = buf + maxlen; 821 822 for (i = 0; i < list->num; i++) { 823 struct wpa_freq_range *range = &list->range[i]; 824 825 if (range->min == range->max) 826 res = os_snprintf(pos, end - pos, "%s%u", 827 i == 0 ? "" : ",", range->min); 828 else 829 res = os_snprintf(pos, end - pos, "%s%u-%u", 830 i == 0 ? "" : ",", 831 range->min, range->max); 832 if (os_snprintf_error(end - pos, res)) { 833 os_free(buf); 834 return NULL; 835 } 836 pos += res; 837 } 838 839 return buf; 840} 841 842 843int int_array_len(const int *a) 844{ 845 int i; 846 for (i = 0; a && a[i]; i++) 847 ; 848 return i; 849} 850 851 852void int_array_concat(int **res, const int *a) 853{ 854 int reslen, alen, i; 855 int *n; 856 857 reslen = int_array_len(*res); 858 alen = int_array_len(a); 859 860 n = os_realloc_array(*res, reslen + alen + 1, sizeof(int)); 861 if (n == NULL) { 862 os_free(*res); 863 *res = NULL; 864 return; 865 } 866 for (i = 0; i <= alen; i++) 867 n[reslen + i] = a[i]; 868 *res = n; 869} 870 871 872static int freq_cmp(const void *a, const void *b) 873{ 874 int _a = *(int *) a; 875 int _b = *(int *) b; 876 877 if (_a == 0) 878 return 1; 879 if (_b == 0) 880 return -1; 881 return _a - _b; 882} 883 884 885void int_array_sort_unique(int *a) 886{ 887 int alen; 888 int i, j; 889 890 if (a == NULL) 891 return; 892 893 alen = int_array_len(a); 894 qsort(a, alen, sizeof(int), freq_cmp); 895 896 i = 0; 897 j = 1; 898 while (a[i] && a[j]) { 899 if (a[i] == a[j]) { 900 j++; 901 continue; 902 } 903 a[++i] = a[j++]; 904 } 905 if (a[i]) 906 i++; 907 a[i] = 0; 908} 909 910 911void int_array_add_unique(int **res, int a) 912{ 913 int reslen; 914 int *n; 915 916 for (reslen = 0; *res && (*res)[reslen]; reslen++) { 917 if ((*res)[reslen] == a) 918 return; /* already in the list */ 919 } 920 921 n = os_realloc_array(*res, reslen + 2, sizeof(int)); 922 if (n == NULL) { 923 os_free(*res); 924 *res = NULL; 925 return; 926 } 927 928 n[reslen] = a; 929 n[reslen + 1] = 0; 930 931 *res = n; 932} 933 934 935void str_clear_free(char *str) 936{ 937 if (str) { 938 size_t len = os_strlen(str); 939 os_memset(str, 0, len); 940 os_free(str); 941 } 942} 943 944 945void bin_clear_free(void *bin, size_t len) 946{ 947 if (bin) { 948 os_memset(bin, 0, len); 949 os_free(bin); 950 } 951} 952 953 954int random_mac_addr(u8 *addr) 955{ 956 if (os_get_random(addr, ETH_ALEN) < 0) 957 return -1; 958 addr[0] &= 0xfe; /* unicast */ 959 addr[0] |= 0x02; /* locally administered */ 960 return 0; 961} 962 963 964int random_mac_addr_keep_oui(u8 *addr) 965{ 966 if (os_get_random(addr + 3, 3) < 0) 967 return -1; 968 addr[0] &= 0xfe; /* unicast */ 969 addr[0] |= 0x02; /* locally administered */ 970 return 0; 971} 972 973 974/** 975 * str_token - Get next token from a string 976 * @buf: String to tokenize. Note that the string might be modified. 977 * @delim: String of delimiters 978 * @context: Pointer to save our context. Should be initialized with 979 * NULL on the first call, and passed for any further call. 980 * Returns: The next token, NULL if there are no more valid tokens. 981 */ 982char * str_token(char *str, const char *delim, char **context) 983{ 984 char *end, *pos = str; 985 986 if (*context) 987 pos = *context; 988 989 while (*pos && os_strchr(delim, *pos)) 990 pos++; 991 if (!*pos) 992 return NULL; 993 994 end = pos + 1; 995 while (*end && !os_strchr(delim, *end)) 996 end++; 997 998 if (*end) 999 *end++ = '\0'; 1000 1001 *context = end; 1002 return pos; 1003} 1004 1005 1006size_t utf8_unescape(const char *inp, size_t in_size, 1007 char *outp, size_t out_size) 1008{ 1009 size_t res_size = 0; 1010 1011 if (!inp || !outp) 1012 return 0; 1013 1014 if (!in_size) 1015 in_size = os_strlen(inp); 1016 1017 /* Advance past leading single quote */ 1018 if (*inp == '\'' && in_size) { 1019 inp++; 1020 in_size--; 1021 } 1022 1023 while (in_size--) { 1024 if (res_size >= out_size) 1025 return 0; 1026 1027 switch (*inp) { 1028 case '\'': 1029 /* Terminate on bare single quote */ 1030 *outp = '\0'; 1031 return res_size; 1032 1033 case '\\': 1034 if (!in_size--) 1035 return 0; 1036 inp++; 1037 /* fall through */ 1038 1039 default: 1040 *outp++ = *inp++; 1041 res_size++; 1042 } 1043 } 1044 1045 /* NUL terminate if space allows */ 1046 if (res_size < out_size) 1047 *outp = '\0'; 1048 1049 return res_size; 1050} 1051 1052 1053size_t utf8_escape(const char *inp, size_t in_size, 1054 char *outp, size_t out_size) 1055{ 1056 size_t res_size = 0; 1057 1058 if (!inp || !outp) 1059 return 0; 1060 1061 /* inp may or may not be NUL terminated, but must be if 0 size 1062 * is specified */ 1063 if (!in_size) 1064 in_size = os_strlen(inp); 1065 1066 while (in_size--) { 1067 if (res_size++ >= out_size) 1068 return 0; 1069 1070 switch (*inp) { 1071 case '\\': 1072 case '\'': 1073 if (res_size++ >= out_size) 1074 return 0; 1075 *outp++ = '\\'; 1076 /* fall through */ 1077 1078 default: 1079 *outp++ = *inp++; 1080 break; 1081 } 1082 } 1083 1084 /* NUL terminate if space allows */ 1085 if (res_size < out_size) 1086 *outp = '\0'; 1087 1088 return res_size; 1089} 1090