18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant/hostapd / common helper functions, etc. 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hex2num(char c) 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (c >= '0' && c <= '9') 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return c - '0'; 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (c >= 'a' && c <= 'f') 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return c - 'a' + 10; 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (c >= 'A' && c <= 'F') 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return c - 'A' + 10; 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hex2byte(const char *hex) 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int a, b; 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a = hex2num(*hex++); 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (a < 0) 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt b = hex2num(*hex++); 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (b < 0) 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return (a << 4) | b; 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hwaddr_aton - Convert ASCII string to MAC address (colon-delimited format) 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @txt: MAC address as a string (e.g., "00:11:22:33:44:55") 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes) 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure (e.g., string not a MAC address) 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hwaddr_aton(const char *txt, u8 *addr) 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < 6; i++) { 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int a, b; 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a = hex2num(*txt++); 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (a < 0) 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt b = hex2num(*txt++); 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (b < 0) 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *addr++ = (a << 4) | b; 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (i < 5 && *txt++ != ':') 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hwaddr_compact_aton - Convert ASCII string to MAC address (no colon delimitors format) 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @txt: MAC address as a string (e.g., "001122334455") 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes) 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure (e.g., string not a MAC address) 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hwaddr_compact_aton(const char *txt, u8 *addr) 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < 6; i++) { 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int a, b; 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a = hex2num(*txt++); 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (a < 0) 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt b = hex2num(*txt++); 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (b < 0) 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *addr++ = (a << 4) | b; 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hwaddr_aton2 - Convert ASCII string to MAC address (in any known format) 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @txt: MAC address as a string (e.g., 00:11:22:33:44:55 or 0011.2233.4455) 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes) 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Characters used (> 0) on success, -1 on failure 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hwaddr_aton2(const char *txt, u8 *addr) 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *pos = txt; 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < 6; i++) { 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int a, b; 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (*pos == ':' || *pos == '.' || *pos == '-') 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a = hex2num(*pos++); 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (a < 0) 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt b = hex2num(*pos++); 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (b < 0) 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *addr++ = (a << 4) | b; 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - txt; 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hexstr2bin - Convert ASCII hex string into binary data 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @hex: ASCII hex string (e.g., "01ab") 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Buffer for the binary data 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Length of the text to convert in bytes (of buf); hex will be double 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * this size 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure (invalid hex string) 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hexstr2bin(const char *hex, u8 *buf, size_t len) 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int a; 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *ipos = hex; 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *opos = buf; 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < len; i++) { 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a = hex2byte(ipos); 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (a < 0) 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *opos++ = a; 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ipos += 2; 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * inc_byte_array - Increment arbitrary length byte array by one 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @counter: Pointer to byte array 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Length of the counter in bytes 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function increments the last byte of the counter by one and continues 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * rolling over to more significant bytes if the byte was incremented from 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 0xff to 0x00. 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid inc_byte_array(u8 *counter, size_t len) 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int pos = len - 1; 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos >= 0) { 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt counter[pos]++; 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (counter[pos] != 0) 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos--; 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_get_ntp_timestamp(u8 *buf) 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct os_time now; 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 sec, usec; 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt be32 tmp; 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 64-bit NTP timestamp (time from 1900-01-01 00:00:00) */ 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&now); 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sec = now.sec + 2208988800U; /* Epoch to 1900 */ 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Estimate 2^32/10^6 = 4295 - 1/32 - 1/512 */ 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt usec = now.usec; 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt usec = 4295 * usec - (usec >> 5) - (usec >> 9); 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = host_to_be32(sec); 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(buf, (u8 *) &tmp, 4); 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = host_to_be32(usec); 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(buf + 4, (u8 *) &tmp, 4); 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic inline int _wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len, int uppercase) 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *pos = buf, *end = buf + buf_size; 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf_size == 0) 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < len; i++) { 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, uppercase ? "%02X" : "%02x", 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data[i]); 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) { 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end[-1] = '\0'; 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end[-1] = '\0'; 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_snprintf_hex - Print data as a hex string into a buffer 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Memory area to use as the output buffer 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf_size: Maximum buffer size in bytes (should be at least 2 * len + 1) 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: Data to be printed 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Length of data in bytes 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Number of bytes written 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len) 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return _wpa_snprintf_hex(buf, buf_size, data, len, 0); 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_snprintf_hex_uppercase - Print data as a upper case hex string into buf 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Memory area to use as the output buffer 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf_size: Maximum buffer size in bytes (should be at least 2 * len + 1) 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: Data to be printed 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Length of data in bytes 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Number of bytes written 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_snprintf_hex_uppercase(char *buf, size_t buf_size, const u8 *data, 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len) 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return _wpa_snprintf_hex(buf, buf_size, data, len, 1); 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_ANSI_C_EXTRA 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef _WIN32_WCE 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid perror(const char *s) 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: GetLastError: %d", 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s, (int) GetLastError()); 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */ 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint optind = 1; 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint optopt; 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtchar *optarg; 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint getopt(int argc, char *const argv[], const char *optstring) 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt static int optchr = 1; 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *cp; 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (optchr == 1) { 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (optind >= argc) { 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* all arguments processed */ 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EOF; 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (argv[optind][0] != '-' || argv[optind][1] == '\0') { 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* no option characters */ 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EOF; 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strcmp(argv[optind], "--") == 0) { 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* no more options */ 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt optind++; 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EOF; 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt optopt = argv[optind][optchr]; 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cp = os_strchr(optstring, optopt); 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cp == NULL || optopt == ':') { 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (argv[optind][++optchr] == '\0') { 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt optchr = 1; 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt optind++; 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return '?'; 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cp[1] == ':') { 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Argument required */ 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt optchr = 1; 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (argv[optind][optchr + 1]) { 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* No space between option and argument */ 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt optarg = &argv[optind++][optchr + 1]; 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (++optind >= argc) { 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* option requires an argument */ 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return '?'; 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Argument in the next argv */ 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt optarg = argv[optind++]; 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* No argument */ 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (argv[optind][++optchr] == '\0') { 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt optchr = 1; 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt optind++; 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt optarg = NULL; 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return *cp; 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_ANSI_C_EXTRA */ 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_NATIVE_WINDOWS 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_unicode2ascii_inplace - Convert unicode string into ASCII 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @str: Pointer to string to convert 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function converts a unicode string to ASCII using the same 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * buffer for output. If UNICODE is not set, the buffer is not 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * modified. 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_unicode2ascii_inplace(TCHAR *str) 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef UNICODE 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *dst = (char *) str; 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (*str) 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *dst++ = (char) *str++; 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *dst = '\0'; 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* UNICODE */ 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtTCHAR * wpa_strdup_tchar(const char *str) 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef UNICODE 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TCHAR *buf; 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = os_malloc((strlen(str) + 1) * sizeof(TCHAR)); 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wsprintf(buf, L"%S", str); 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* UNICODE */ 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return os_strdup(str); 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* UNICODE */ 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid printf_encode(char *txt, size_t maxlen, const u8 *data, size_t len) 34861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 34961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt char *end = txt + maxlen; 35061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t i; 35161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 35261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (i = 0; i < len; i++) { 353b5d893b5dec601a58c3ce0fc9e5d6da3816ce97aDmitry Shmidt if (txt + 4 >= end) 35461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 35561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 35661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt switch (data[i]) { 35761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case '\"': 35861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *txt++ = '\\'; 35961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *txt++ = '\"'; 36061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 36161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case '\\': 36261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *txt++ = '\\'; 36361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *txt++ = '\\'; 36461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 365661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt case '\033': 36661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *txt++ = '\\'; 36761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *txt++ = 'e'; 36861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 36961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case '\n': 37061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *txt++ = '\\'; 37161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *txt++ = 'n'; 37261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 37361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case '\r': 37461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *txt++ = '\\'; 37561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *txt++ = 'r'; 37661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 37761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case '\t': 37861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *txt++ = '\\'; 37961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *txt++ = 't'; 38061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 38161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt default: 38261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (data[i] >= 32 && data[i] <= 127) { 38361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *txt++ = data[i]; 38461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else { 38561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt txt += os_snprintf(txt, end - txt, "\\x%02x", 38661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt data[i]); 38761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 38861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 38961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 39061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 39161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 39261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *txt = '\0'; 39361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 39461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 39561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 39661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtsize_t printf_decode(u8 *buf, size_t maxlen, const char *str) 39761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 39861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const char *pos = str; 39961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t len = 0; 40061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt int val; 40161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 40261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt while (*pos) { 4035605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (len + 1 >= maxlen) 40461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 40561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt switch (*pos) { 40661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case '\\': 40761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos++; 40861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt switch (*pos) { 40961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case '\\': 41061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt buf[len++] = '\\'; 41161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos++; 41261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 41361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case '"': 41461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt buf[len++] = '"'; 41561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos++; 41661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 41761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case 'n': 41861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt buf[len++] = '\n'; 41961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos++; 42061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 42161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case 'r': 42261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt buf[len++] = '\r'; 42361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos++; 42461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 42561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case 't': 42661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt buf[len++] = '\t'; 42761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos++; 42861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 42961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case 'e': 430661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt buf[len++] = '\033'; 43161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos++; 43261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 43361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case 'x': 43461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos++; 43561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt val = hex2byte(pos); 43661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (val < 0) { 43761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt val = hex2num(*pos); 43861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (val < 0) 43961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 44061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt buf[len++] = val; 44161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos++; 44261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else { 44361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt buf[len++] = val; 44461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos += 2; 44561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 44661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 44761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case '0': 44861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case '1': 44961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case '2': 45061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case '3': 45161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case '4': 45261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case '5': 45361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case '6': 45461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case '7': 45561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt val = *pos++ - '0'; 45661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (*pos >= '0' && *pos <= '7') 45761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt val = val * 8 + (*pos++ - '0'); 45861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (*pos >= '0' && *pos <= '7') 45961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt val = val * 8 + (*pos++ - '0'); 46061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt buf[len++] = val; 46161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 46261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt default: 46361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 46461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 46561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 46661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt default: 46761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt buf[len++] = *pos++; 46861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 46961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 47061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 4715605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (maxlen > len) 4725605286c30e1701491bd3af974ae423727750eddDmitry Shmidt buf[len] = '\0'; 47361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 47461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return len; 47561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 47661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 47761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_ssid_txt - Convert SSID to a printable string 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ssid: SSID (32-octet string) 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ssid_len: Length of ssid in octets 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to a printable string 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function can be used to convert SSIDs into printable form. In most 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * cases, SSIDs do not use unprintable characters, but IEEE 802.11 standard 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * does not limit the used character set, so anything could be used in an SSID. 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function uses a static buffer, so only one call can be used at the 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * time, i.e., this is not re-entrant and the returned buffer must be used 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * before calling this again. 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len) 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 49461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt static char ssid_txt[32 * 4 + 1]; 49561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 49661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (ssid == NULL) { 49761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ssid_txt[0] = '\0'; 49861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return ssid_txt; 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 50061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 50161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt printf_encode(ssid_txt, sizeof(ssid_txt), ssid, ssid_len); 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ssid_txt; 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid * __hide_aliasing_typecast(void *foo) 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return foo; 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 51061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 51161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 51261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtchar * wpa_config_parse_string(const char *value, size_t *len) 51361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 51461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (*value == '"') { 51561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const char *pos; 51661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt char *str; 51761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt value++; 51861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos = os_strrchr(value, '"'); 51961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (pos == NULL || pos[1] != '\0') 52061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 52161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *len = pos - value; 5224b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt str = dup_binstr(value, *len); 52361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (str == NULL) 52461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 52561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return str; 52661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else if (*value == 'P' && value[1] == '"') { 52761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const char *pos; 52861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt char *tstr, *str; 52961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t tlen; 53061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt value += 2; 53161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos = os_strrchr(value, '"'); 53261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (pos == NULL || pos[1] != '\0') 53361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 53461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt tlen = pos - value; 5354b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt tstr = dup_binstr(value, tlen); 53661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (tstr == NULL) 53761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 53861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 53961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt str = os_malloc(tlen + 1); 54061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (str == NULL) { 54161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(tstr); 54261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 54361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 54461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 54561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *len = printf_decode((u8 *) str, tlen + 1, tstr); 54661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(tstr); 54761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 54861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return str; 54961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else { 55061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 *str; 55161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t tlen, hlen = os_strlen(value); 55261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hlen & 1) 55361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 55461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt tlen = hlen / 2; 55561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt str = os_malloc(tlen + 1); 55661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (str == NULL) 55761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 55861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hexstr2bin(value, str, tlen)) { 55961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(str); 56061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 56161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 56261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt str[tlen] = '\0'; 56361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *len = tlen; 56461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return (char *) str; 56561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 56661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 56761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 56861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 56961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint is_hex(const u8 *data, size_t len) 57061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 57161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t i; 57261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 57361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (i = 0; i < len; i++) { 57461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (data[i] < 32 || data[i] >= 127) 57561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 1; 57661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 57761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 57861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 57961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 58061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 58168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtint find_first_bit(u32 value) 58268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt{ 58368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt int pos = 0; 58468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 58568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt while (value) { 58668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt if (value & 0x1) 58768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return pos; 58868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt value >>= 1; 58968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt pos++; 59068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 59168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 59268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt return -1; 59368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt} 59468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 59568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 59661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtsize_t merge_byte_arrays(u8 *res, size_t res_len, 59761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const u8 *src1, size_t src1_len, 59861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const u8 *src2, size_t src2_len) 59961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 60061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t len = 0; 60161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 60261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memset(res, 0, res_len); 60361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 60461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (src1) { 60561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (src1_len >= res_len) { 60661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memcpy(res, src1, res_len); 60761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return res_len; 60861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 60961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 61061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memcpy(res, src1, src1_len); 61161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt len += src1_len; 61261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 61361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 61461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (src2) { 61561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (len + src2_len >= res_len) { 61661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memcpy(res + len, src2, res_len - len); 61761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return res_len; 61861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 61961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 62061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memcpy(res + len, src2, src2_len); 62161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt len += src2_len; 62261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 62361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 62461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return len; 62561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 6264b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt 6274b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt 6284b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidtchar * dup_binstr(const void *src, size_t len) 6294b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt{ 6304b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt char *res; 6314b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt 6324b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (src == NULL) 6334b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt return NULL; 6344b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt res = os_malloc(len + 1); 6354b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (res == NULL) 6364b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt return NULL; 6374b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt os_memcpy(res, src, len); 6384b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt res[len] = '\0'; 6394b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt 6404b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt return res; 6414b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt} 6424ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 6434ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 6444ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidtint freq_range_list_parse(struct wpa_freq_range_list *res, const char *value) 6454ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt{ 6464ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt struct wpa_freq_range *freq = NULL, *n; 6474ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt unsigned int count = 0; 6484ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt const char *pos, *pos2, *pos3; 6494ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 6504ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt /* 6514ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt * Comma separated list of frequency ranges. 6524ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt * For example: 2412-2432,2462,5000-6000 6534ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt */ 6544ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt pos = value; 6554ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt while (pos && pos[0]) { 6564ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt n = os_realloc_array(freq, count + 1, 6574ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt sizeof(struct wpa_freq_range)); 6584ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (n == NULL) { 6594ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt os_free(freq); 6604ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt return -1; 6614ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt } 6624ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt freq = n; 6634ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt freq[count].min = atoi(pos); 6644ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt pos2 = os_strchr(pos, '-'); 6654ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt pos3 = os_strchr(pos, ','); 6664ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (pos2 && (!pos3 || pos2 < pos3)) { 6674ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt pos2++; 6684ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt freq[count].max = atoi(pos2); 6694ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt } else 6704ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt freq[count].max = freq[count].min; 6714ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt pos = pos3; 6724ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (pos) 6734ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt pos++; 6744ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt count++; 6754ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt } 6764ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 6774ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt os_free(res->range); 6784ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt res->range = freq; 6794ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt res->num = count; 6804ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 6814ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt return 0; 6824ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt} 6834ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 6844ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 6854ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidtint freq_range_list_includes(const struct wpa_freq_range_list *list, 6864ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt unsigned int freq) 6874ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt{ 6884ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt unsigned int i; 6894ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 6904ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (list == NULL) 6914ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt return 0; 6924ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 6934ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt for (i = 0; i < list->num; i++) { 6944ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (freq >= list->range[i].min && freq <= list->range[i].max) 6954ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt return 1; 6964ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt } 6974ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 6984ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt return 0; 6994ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt} 7004ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 7014ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 7024ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidtchar * freq_range_list_str(const struct wpa_freq_range_list *list) 7034ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt{ 7044ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt char *buf, *pos, *end; 7054ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt size_t maxlen; 7064ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt unsigned int i; 7074ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt int res; 7084ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 7094ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (list->num == 0) 7104ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt return NULL; 7114ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 7124ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt maxlen = list->num * 30; 7134ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt buf = os_malloc(maxlen); 7144ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (buf == NULL) 7154ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt return NULL; 7164ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt pos = buf; 7174ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt end = buf + maxlen; 7184ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 7194ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt for (i = 0; i < list->num; i++) { 7204ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt struct wpa_freq_range *range = &list->range[i]; 7214ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 7224ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (range->min == range->max) 7234ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt res = os_snprintf(pos, end - pos, "%s%u", 7244ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt i == 0 ? "" : ",", range->min); 7254ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt else 7264ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt res = os_snprintf(pos, end - pos, "%s%u-%u", 7274ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt i == 0 ? "" : ",", 7284ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt range->min, range->max); 7294ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (res < 0 || res > end - pos) { 7304ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt os_free(buf); 7314ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt return NULL; 7324ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt } 7334ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt pos += res; 7344ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt } 7354ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 7364ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt return buf; 7374ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt} 738fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 739fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 740fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtint int_array_len(const int *a) 741fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{ 742fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt int i; 743fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt for (i = 0; a && a[i]; i++) 744fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt ; 745fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return i; 746fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 747fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 748fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 749fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtvoid int_array_concat(int **res, const int *a) 750fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{ 751fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt int reslen, alen, i; 752fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt int *n; 753fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 754fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt reslen = int_array_len(*res); 755fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt alen = int_array_len(a); 756fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 757fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt n = os_realloc_array(*res, reslen + alen + 1, sizeof(int)); 758fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (n == NULL) { 759fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_free(*res); 760fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt *res = NULL; 761fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return; 762fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 763fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt for (i = 0; i <= alen; i++) 764fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt n[reslen + i] = a[i]; 765fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt *res = n; 766fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 767fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 768fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 769fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic int freq_cmp(const void *a, const void *b) 770fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{ 771fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt int _a = *(int *) a; 772fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt int _b = *(int *) b; 773fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 774fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (_a == 0) 775fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return 1; 776fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (_b == 0) 777fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return -1; 778fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return _a - _b; 779fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 780fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 781fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 782fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtvoid int_array_sort_unique(int *a) 783fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{ 784fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt int alen; 785fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt int i, j; 786fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 787fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (a == NULL) 788fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return; 789fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 790fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt alen = int_array_len(a); 791fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt qsort(a, alen, sizeof(int), freq_cmp); 792fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 793fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt i = 0; 794fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt j = 1; 795fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt while (a[i] && a[j]) { 796fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (a[i] == a[j]) { 797fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt j++; 798fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt continue; 799fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 800fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt a[++i] = a[j++]; 801fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 802fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (a[i]) 803fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt i++; 804fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt a[i] = 0; 805fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 806fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 807fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 808fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtvoid int_array_add_unique(int **res, int a) 809fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{ 810fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt int reslen; 811fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt int *n; 812fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 813fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt for (reslen = 0; *res && (*res)[reslen]; reslen++) { 814fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if ((*res)[reslen] == a) 815fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return; /* already in the list */ 816fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 817fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 818fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt n = os_realloc_array(*res, reslen + 2, sizeof(int)); 819fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (n == NULL) { 820fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_free(*res); 821fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt *res = NULL; 822fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return; 823fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 824fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 825fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt n[reslen] = a; 826fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt n[reslen + 1] = 0; 827fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 828fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt *res = n; 829fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 830c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt 831c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt 832c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidtvoid str_clear_free(char *str) 833c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt{ 834c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt if (str) { 835c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt size_t len = os_strlen(str); 836c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt os_memset(str, 0, len); 837c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt os_free(str); 838c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt } 839c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt} 840c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt 841c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt 842c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidtvoid bin_clear_free(void *bin, size_t len) 843c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt{ 844c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt if (bin) { 845c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt os_memset(bin, 0, len); 846c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt os_free(bin); 847c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt } 848c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt} 849661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt 850661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt 851661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidtint random_mac_addr(u8 *addr) 852661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt{ 853661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (os_get_random(addr, ETH_ALEN) < 0) 854661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt return -1; 855661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt addr[0] &= 0xfe; /* unicast */ 856661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt addr[0] |= 0x02; /* locally administered */ 857661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt return 0; 858661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt} 859661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt 860661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt 861661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidtint random_mac_addr_keep_oui(u8 *addr) 862661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt{ 863661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (os_get_random(addr + 3, 3) < 0) 864661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt return -1; 865661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt addr[0] &= 0xfe; /* unicast */ 866661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt addr[0] |= 0x02; /* locally administered */ 867661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt return 0; 868661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt} 869