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 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 static 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 */ 64 int 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 */ 78 int 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 */ 112 int 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 */ 137 int 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 */ 169 int 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 187 int 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 */ 220 void 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 232 void 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 */ 260 int 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 static inline int _wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, 281 size_t len, int uppercase) 282 { 283 size_t i; 284 char *pos = buf, *end = buf + buf_size; 285 int ret; 286 if (buf_size == 0) 287 return 0; 288 for (i = 0; i < len; i++) { 289 ret = os_snprintf(pos, end - pos, uppercase ? "%02X" : "%02x", 290 data[i]); 291 if (os_snprintf_error(end - pos, ret)) { 292 end[-1] = '\0'; 293 return pos - buf; 294 } 295 pos += ret; 296 } 297 end[-1] = '\0'; 298 return pos - buf; 299 } 300 301 /** 302 * wpa_snprintf_hex - Print data as a hex string into a buffer 303 * @buf: Memory area to use as the output buffer 304 * @buf_size: Maximum buffer size in bytes (should be at least 2 * len + 1) 305 * @data: Data to be printed 306 * @len: Length of data in bytes 307 * Returns: Number of bytes written 308 */ 309 int wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len) 310 { 311 return _wpa_snprintf_hex(buf, buf_size, data, len, 0); 312 } 313 314 315 /** 316 * wpa_snprintf_hex_uppercase - Print data as a upper case hex string into buf 317 * @buf: Memory area to use as the output buffer 318 * @buf_size: Maximum buffer size in bytes (should be at least 2 * len + 1) 319 * @data: Data to be printed 320 * @len: Length of data in bytes 321 * Returns: Number of bytes written 322 */ 323 int wpa_snprintf_hex_uppercase(char *buf, size_t buf_size, const u8 *data, 324 size_t len) 325 { 326 return _wpa_snprintf_hex(buf, buf_size, data, len, 1); 327 } 328 329 330 #ifdef CONFIG_ANSI_C_EXTRA 331 332 #ifdef _WIN32_WCE 333 void perror(const char *s) 334 { 335 wpa_printf(MSG_ERROR, "%s: GetLastError: %d", 336 s, (int) GetLastError()); 337 } 338 #endif /* _WIN32_WCE */ 339 340 341 int optind = 1; 342 int optopt; 343 char *optarg; 344 345 int getopt(int argc, char *const argv[], const char *optstring) 346 { 347 static int optchr = 1; 348 char *cp; 349 350 if (optchr == 1) { 351 if (optind >= argc) { 352 /* all arguments processed */ 353 return EOF; 354 } 355 356 if (argv[optind][0] != '-' || argv[optind][1] == '\0') { 357 /* no option characters */ 358 return EOF; 359 } 360 } 361 362 if (os_strcmp(argv[optind], "--") == 0) { 363 /* no more options */ 364 optind++; 365 return EOF; 366 } 367 368 optopt = argv[optind][optchr]; 369 cp = os_strchr(optstring, optopt); 370 if (cp == NULL || optopt == ':') { 371 if (argv[optind][++optchr] == '\0') { 372 optchr = 1; 373 optind++; 374 } 375 return '?'; 376 } 377 378 if (cp[1] == ':') { 379 /* Argument required */ 380 optchr = 1; 381 if (argv[optind][optchr + 1]) { 382 /* No space between option and argument */ 383 optarg = &argv[optind++][optchr + 1]; 384 } else if (++optind >= argc) { 385 /* option requires an argument */ 386 return '?'; 387 } else { 388 /* Argument in the next argv */ 389 optarg = argv[optind++]; 390 } 391 } else { 392 /* No argument */ 393 if (argv[optind][++optchr] == '\0') { 394 optchr = 1; 395 optind++; 396 } 397 optarg = NULL; 398 } 399 return *cp; 400 } 401 #endif /* CONFIG_ANSI_C_EXTRA */ 402 403 404 #ifdef CONFIG_NATIVE_WINDOWS 405 /** 406 * wpa_unicode2ascii_inplace - Convert unicode string into ASCII 407 * @str: Pointer to string to convert 408 * 409 * This function converts a unicode string to ASCII using the same 410 * buffer for output. If UNICODE is not set, the buffer is not 411 * modified. 412 */ 413 void wpa_unicode2ascii_inplace(TCHAR *str) 414 { 415 #ifdef UNICODE 416 char *dst = (char *) str; 417 while (*str) 418 *dst++ = (char) *str++; 419 *dst = '\0'; 420 #endif /* UNICODE */ 421 } 422 423 424 TCHAR * wpa_strdup_tchar(const char *str) 425 { 426 #ifdef UNICODE 427 TCHAR *buf; 428 buf = os_malloc((strlen(str) + 1) * sizeof(TCHAR)); 429 if (buf == NULL) 430 return NULL; 431 wsprintf(buf, L"%S", str); 432 return buf; 433 #else /* UNICODE */ 434 return os_strdup(str); 435 #endif /* UNICODE */ 436 } 437 #endif /* CONFIG_NATIVE_WINDOWS */ 438 439 440 void printf_encode(char *txt, size_t maxlen, const u8 *data, size_t len) 441 { 442 char *end = txt + maxlen; 443 size_t i; 444 445 for (i = 0; i < len; i++) { 446 if (txt + 4 >= end) 447 break; 448 449 switch (data[i]) { 450 case '\"': 451 *txt++ = '\\'; 452 *txt++ = '\"'; 453 break; 454 case '\\': 455 *txt++ = '\\'; 456 *txt++ = '\\'; 457 break; 458 case '\033': 459 *txt++ = '\\'; 460 *txt++ = 'e'; 461 break; 462 case '\n': 463 *txt++ = '\\'; 464 *txt++ = 'n'; 465 break; 466 case '\r': 467 *txt++ = '\\'; 468 *txt++ = 'r'; 469 break; 470 case '\t': 471 *txt++ = '\\'; 472 *txt++ = 't'; 473 break; 474 default: 475 if (data[i] >= 32 && data[i] <= 127) { 476 *txt++ = data[i]; 477 } else { 478 txt += os_snprintf(txt, end - txt, "\\x%02x", 479 data[i]); 480 } 481 break; 482 } 483 } 484 485 *txt = '\0'; 486 } 487 488 489 size_t printf_decode(u8 *buf, size_t maxlen, const char *str) 490 { 491 const char *pos = str; 492 size_t len = 0; 493 int val; 494 495 while (*pos) { 496 if (len + 1 >= maxlen) 497 break; 498 switch (*pos) { 499 case '\\': 500 pos++; 501 switch (*pos) { 502 case '\\': 503 buf[len++] = '\\'; 504 pos++; 505 break; 506 case '"': 507 buf[len++] = '"'; 508 pos++; 509 break; 510 case 'n': 511 buf[len++] = '\n'; 512 pos++; 513 break; 514 case 'r': 515 buf[len++] = '\r'; 516 pos++; 517 break; 518 case 't': 519 buf[len++] = '\t'; 520 pos++; 521 break; 522 case 'e': 523 buf[len++] = '\033'; 524 pos++; 525 break; 526 case 'x': 527 pos++; 528 val = hex2byte(pos); 529 if (val < 0) { 530 val = hex2num(*pos); 531 if (val < 0) 532 break; 533 buf[len++] = val; 534 pos++; 535 } else { 536 buf[len++] = val; 537 pos += 2; 538 } 539 break; 540 case '0': 541 case '1': 542 case '2': 543 case '3': 544 case '4': 545 case '5': 546 case '6': 547 case '7': 548 val = *pos++ - '0'; 549 if (*pos >= '0' && *pos <= '7') 550 val = val * 8 + (*pos++ - '0'); 551 if (*pos >= '0' && *pos <= '7') 552 val = val * 8 + (*pos++ - '0'); 553 buf[len++] = val; 554 break; 555 default: 556 break; 557 } 558 break; 559 default: 560 buf[len++] = *pos++; 561 break; 562 } 563 } 564 if (maxlen > len) 565 buf[len] = '\0'; 566 567 return len; 568 } 569 570 571 /** 572 * wpa_ssid_txt - Convert SSID to a printable string 573 * @ssid: SSID (32-octet string) 574 * @ssid_len: Length of ssid in octets 575 * Returns: Pointer to a printable string 576 * 577 * This function can be used to convert SSIDs into printable form. In most 578 * cases, SSIDs do not use unprintable characters, but IEEE 802.11 standard 579 * does not limit the used character set, so anything could be used in an SSID. 580 * 581 * This function uses a static buffer, so only one call can be used at the 582 * time, i.e., this is not re-entrant and the returned buffer must be used 583 * before calling this again. 584 */ 585 const char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len) 586 { 587 static char ssid_txt[32 * 4 + 1]; 588 589 if (ssid == NULL) { 590 ssid_txt[0] = '\0'; 591 return ssid_txt; 592 } 593 594 printf_encode(ssid_txt, sizeof(ssid_txt), ssid, ssid_len); 595 return ssid_txt; 596 } 597 598 599 void * __hide_aliasing_typecast(void *foo) 600 { 601 return foo; 602 } 603 604 605 char * wpa_config_parse_string(const char *value, size_t *len) 606 { 607 if (*value == '"') { 608 const char *pos; 609 char *str; 610 value++; 611 pos = os_strrchr(value, '"'); 612 if (pos == NULL || pos[1] != '\0') 613 return NULL; 614 *len = pos - value; 615 str = dup_binstr(value, *len); 616 if (str == NULL) 617 return NULL; 618 return str; 619 } else if (*value == 'P' && value[1] == '"') { 620 const char *pos; 621 char *tstr, *str; 622 size_t tlen; 623 value += 2; 624 pos = os_strrchr(value, '"'); 625 if (pos == NULL || pos[1] != '\0') 626 return NULL; 627 tlen = pos - value; 628 tstr = dup_binstr(value, tlen); 629 if (tstr == NULL) 630 return NULL; 631 632 str = os_malloc(tlen + 1); 633 if (str == NULL) { 634 os_free(tstr); 635 return NULL; 636 } 637 638 *len = printf_decode((u8 *) str, tlen + 1, tstr); 639 os_free(tstr); 640 641 return str; 642 } else { 643 u8 *str; 644 size_t tlen, hlen = os_strlen(value); 645 if (hlen & 1) 646 return NULL; 647 tlen = hlen / 2; 648 str = os_malloc(tlen + 1); 649 if (str == NULL) 650 return NULL; 651 if (hexstr2bin(value, str, tlen)) { 652 os_free(str); 653 return NULL; 654 } 655 str[tlen] = '\0'; 656 *len = tlen; 657 return (char *) str; 658 } 659 } 660 661 662 int is_hex(const u8 *data, size_t len) 663 { 664 size_t i; 665 666 for (i = 0; i < len; i++) { 667 if (data[i] < 32 || data[i] >= 127) 668 return 1; 669 } 670 return 0; 671 } 672 673 674 size_t merge_byte_arrays(u8 *res, size_t res_len, 675 const u8 *src1, size_t src1_len, 676 const u8 *src2, size_t src2_len) 677 { 678 size_t len = 0; 679 680 os_memset(res, 0, res_len); 681 682 if (src1) { 683 if (src1_len >= res_len) { 684 os_memcpy(res, src1, res_len); 685 return res_len; 686 } 687 688 os_memcpy(res, src1, src1_len); 689 len += src1_len; 690 } 691 692 if (src2) { 693 if (len + src2_len >= res_len) { 694 os_memcpy(res + len, src2, res_len - len); 695 return res_len; 696 } 697 698 os_memcpy(res + len, src2, src2_len); 699 len += src2_len; 700 } 701 702 return len; 703 } 704 705 706 char * dup_binstr(const void *src, size_t len) 707 { 708 char *res; 709 710 if (src == NULL) 711 return NULL; 712 res = os_malloc(len + 1); 713 if (res == NULL) 714 return NULL; 715 os_memcpy(res, src, len); 716 res[len] = '\0'; 717 718 return res; 719 } 720 721 722 int freq_range_list_parse(struct wpa_freq_range_list *res, const char *value) 723 { 724 struct wpa_freq_range *freq = NULL, *n; 725 unsigned int count = 0; 726 const char *pos, *pos2, *pos3; 727 728 /* 729 * Comma separated list of frequency ranges. 730 * For example: 2412-2432,2462,5000-6000 731 */ 732 pos = value; 733 while (pos && pos[0]) { 734 n = os_realloc_array(freq, count + 1, 735 sizeof(struct wpa_freq_range)); 736 if (n == NULL) { 737 os_free(freq); 738 return -1; 739 } 740 freq = n; 741 freq[count].min = atoi(pos); 742 pos2 = os_strchr(pos, '-'); 743 pos3 = os_strchr(pos, ','); 744 if (pos2 && (!pos3 || pos2 < pos3)) { 745 pos2++; 746 freq[count].max = atoi(pos2); 747 } else 748 freq[count].max = freq[count].min; 749 pos = pos3; 750 if (pos) 751 pos++; 752 count++; 753 } 754 755 os_free(res->range); 756 res->range = freq; 757 res->num = count; 758 759 return 0; 760 } 761 762 763 int freq_range_list_includes(const struct wpa_freq_range_list *list, 764 unsigned int freq) 765 { 766 unsigned int i; 767 768 if (list == NULL) 769 return 0; 770 771 for (i = 0; i < list->num; i++) { 772 if (freq >= list->range[i].min && freq <= list->range[i].max) 773 return 1; 774 } 775 776 return 0; 777 } 778 779 780 char * freq_range_list_str(const struct wpa_freq_range_list *list) 781 { 782 char *buf, *pos, *end; 783 size_t maxlen; 784 unsigned int i; 785 int res; 786 787 if (list->num == 0) 788 return NULL; 789 790 maxlen = list->num * 30; 791 buf = os_malloc(maxlen); 792 if (buf == NULL) 793 return NULL; 794 pos = buf; 795 end = buf + maxlen; 796 797 for (i = 0; i < list->num; i++) { 798 struct wpa_freq_range *range = &list->range[i]; 799 800 if (range->min == range->max) 801 res = os_snprintf(pos, end - pos, "%s%u", 802 i == 0 ? "" : ",", range->min); 803 else 804 res = os_snprintf(pos, end - pos, "%s%u-%u", 805 i == 0 ? "" : ",", 806 range->min, range->max); 807 if (os_snprintf_error(end - pos, res)) { 808 os_free(buf); 809 return NULL; 810 } 811 pos += res; 812 } 813 814 return buf; 815 } 816 817 818 int int_array_len(const int *a) 819 { 820 int i; 821 for (i = 0; a && a[i]; i++) 822 ; 823 return i; 824 } 825 826 827 void int_array_concat(int **res, const int *a) 828 { 829 int reslen, alen, i; 830 int *n; 831 832 reslen = int_array_len(*res); 833 alen = int_array_len(a); 834 835 n = os_realloc_array(*res, reslen + alen + 1, sizeof(int)); 836 if (n == NULL) { 837 os_free(*res); 838 *res = NULL; 839 return; 840 } 841 for (i = 0; i <= alen; i++) 842 n[reslen + i] = a[i]; 843 *res = n; 844 } 845 846 847 static int freq_cmp(const void *a, const void *b) 848 { 849 int _a = *(int *) a; 850 int _b = *(int *) b; 851 852 if (_a == 0) 853 return 1; 854 if (_b == 0) 855 return -1; 856 return _a - _b; 857 } 858 859 860 void int_array_sort_unique(int *a) 861 { 862 int alen; 863 int i, j; 864 865 if (a == NULL) 866 return; 867 868 alen = int_array_len(a); 869 qsort(a, alen, sizeof(int), freq_cmp); 870 871 i = 0; 872 j = 1; 873 while (a[i] && a[j]) { 874 if (a[i] == a[j]) { 875 j++; 876 continue; 877 } 878 a[++i] = a[j++]; 879 } 880 if (a[i]) 881 i++; 882 a[i] = 0; 883 } 884 885 886 void int_array_add_unique(int **res, int a) 887 { 888 int reslen; 889 int *n; 890 891 for (reslen = 0; *res && (*res)[reslen]; reslen++) { 892 if ((*res)[reslen] == a) 893 return; /* already in the list */ 894 } 895 896 n = os_realloc_array(*res, reslen + 2, sizeof(int)); 897 if (n == NULL) { 898 os_free(*res); 899 *res = NULL; 900 return; 901 } 902 903 n[reslen] = a; 904 n[reslen + 1] = 0; 905 906 *res = n; 907 } 908 909 910 void str_clear_free(char *str) 911 { 912 if (str) { 913 size_t len = os_strlen(str); 914 os_memset(str, 0, len); 915 os_free(str); 916 } 917 } 918 919 920 void bin_clear_free(void *bin, size_t len) 921 { 922 if (bin) { 923 os_memset(bin, 0, len); 924 os_free(bin); 925 } 926 } 927 928 929 int random_mac_addr(u8 *addr) 930 { 931 if (os_get_random(addr, ETH_ALEN) < 0) 932 return -1; 933 addr[0] &= 0xfe; /* unicast */ 934 addr[0] |= 0x02; /* locally administered */ 935 return 0; 936 } 937 938 939 int random_mac_addr_keep_oui(u8 *addr) 940 { 941 if (os_get_random(addr + 3, 3) < 0) 942 return -1; 943 addr[0] &= 0xfe; /* unicast */ 944 addr[0] |= 0x02; /* locally administered */ 945 return 0; 946 } 947 948 949 /** 950 * str_token - Get next token from a string 951 * @buf: String to tokenize. Note that the string might be modified. 952 * @delim: String of delimiters 953 * @context: Pointer to save our context. Should be initialized with 954 * NULL on the first call, and passed for any further call. 955 * Returns: The next token, NULL if there are no more valid tokens. 956 */ 957 char * str_token(char *str, const char *delim, char **context) 958 { 959 char *end, *pos = str; 960 961 if (*context) 962 pos = *context; 963 964 while (*pos && os_strchr(delim, *pos)) 965 pos++; 966 if (!*pos) 967 return NULL; 968 969 end = pos + 1; 970 while (*end && !os_strchr(delim, *end)) 971 end++; 972 973 if (*end) 974 *end++ = '\0'; 975 976 *context = end; 977 return pos; 978 } 979 980 981 size_t utf8_unescape(const char *inp, size_t in_size, 982 char *outp, size_t out_size) 983 { 984 size_t res_size = 0; 985 986 if (!inp || !outp) 987 return 0; 988 989 if (!in_size) 990 in_size = os_strlen(inp); 991 992 /* Advance past leading single quote */ 993 if (*inp == '\'' && in_size) { 994 inp++; 995 in_size--; 996 } 997 998 while (in_size--) { 999 if (res_size >= out_size) 1000 return 0; 1001 1002 switch (*inp) { 1003 case '\'': 1004 /* Terminate on bare single quote */ 1005 *outp = '\0'; 1006 return res_size; 1007 1008 case '\\': 1009 if (!in_size--) 1010 return 0; 1011 inp++; 1012 /* fall through */ 1013 1014 default: 1015 *outp++ = *inp++; 1016 res_size++; 1017 } 1018 } 1019 1020 /* NUL terminate if space allows */ 1021 if (res_size < out_size) 1022 *outp = '\0'; 1023 1024 return res_size; 1025 } 1026 1027 1028 size_t utf8_escape(const char *inp, size_t in_size, 1029 char *outp, size_t out_size) 1030 { 1031 size_t res_size = 0; 1032 1033 if (!inp || !outp) 1034 return 0; 1035 1036 /* inp may or may not be NUL terminated, but must be if 0 size 1037 * is specified */ 1038 if (!in_size) 1039 in_size = os_strlen(inp); 1040 1041 while (in_size--) { 1042 if (res_size++ >= out_size) 1043 return 0; 1044 1045 switch (*inp) { 1046 case '\\': 1047 case '\'': 1048 if (res_size++ >= out_size) 1049 return 0; 1050 *outp++ = '\\'; 1051 /* fall through */ 1052 1053 default: 1054 *outp++ = *inp++; 1055 break; 1056 } 1057 } 1058 1059 /* NUL terminate if space allows */ 1060 if (res_size < out_size) 1061 *outp = '\0'; 1062 1063 return res_size; 1064 } 1065