common.c revision d80a401aed31d06f261efd19223cf55d1a2a8228
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 119d9e60286e05ae45025b672636490bd12586138dDmitry Shmidt#include "common/ieee802_11_defs.h" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hex2num(char c) 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (c >= '0' && c <= '9') 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return c - '0'; 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (c >= 'a' && c <= 'f') 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return c - 'a' + 10; 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (c >= 'A' && c <= 'F') 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return c - 'A' + 10; 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hex2byte(const char *hex) 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int a, b; 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a = hex2num(*hex++); 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (a < 0) 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt b = hex2num(*hex++); 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (b < 0) 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return (a << 4) | b; 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidtstatic const char * hwaddr_parse(const char *txt, u8 *addr) 41ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt{ 42ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt size_t i; 43ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 44ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt for (i = 0; i < ETH_ALEN; i++) { 45ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt int a; 46ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 47ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt a = hex2byte(txt); 48ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (a < 0) 49ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return NULL; 50ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt txt += 2; 51ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt addr[i] = a; 52ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (i < ETH_ALEN - 1 && *txt++ != ':') 53ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return NULL; 54ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 55ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return txt; 56ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt} 57ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 58ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hwaddr_aton - Convert ASCII string to MAC address (colon-delimited format) 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @txt: MAC address as a string (e.g., "00:11:22:33:44:55") 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes) 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure (e.g., string not a MAC address) 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hwaddr_aton(const char *txt, u8 *addr) 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 67ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return hwaddr_parse(txt, addr) ? 0 : -1; 68ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt} 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 71ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt/** 72ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt * hwaddr_masked_aton - Convert ASCII string with optional mask to MAC address (colon-delimited format) 73ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt * @txt: MAC address with optional mask as a string (e.g., "00:11:22:33:44:55/ff:ff:ff:ff:00:00") 74ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes) 75ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt * @mask: Buffer for the MAC address mask (ETH_ALEN = 6 bytes) 76ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt * @maskable: Flag to indicate whether a mask is allowed 77ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt * Returns: 0 on success, -1 on failure (e.g., string not a MAC address) 78ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt */ 79ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidtint hwaddr_masked_aton(const char *txt, u8 *addr, u8 *mask, u8 maskable) 80ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt{ 81ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt const char *r; 82ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 83ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt /* parse address part */ 84ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt r = hwaddr_parse(txt, addr); 85ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (!r) 86ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return -1; 87ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 88ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt /* check for optional mask */ 89ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (*r == '\0' || isspace(*r)) { 90ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt /* no mask specified, assume default */ 91ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt os_memset(mask, 0xff, ETH_ALEN); 92ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } else if (maskable && *r == '/') { 93ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt /* mask specified and allowed */ 94ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt r = hwaddr_parse(r + 1, mask); 95ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt /* parser error? */ 96ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (!r) 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 98ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } else { 99ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt /* mask specified but not allowed or trailing garbage */ 100ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return -1; 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 106ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hwaddr_compact_aton - Convert ASCII string to MAC address (no colon delimitors format) 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @txt: MAC address as a string (e.g., "001122334455") 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes) 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure (e.g., string not a MAC address) 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hwaddr_compact_aton(const char *txt, u8 *addr) 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < 6; i++) { 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int a, b; 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a = hex2num(*txt++); 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (a < 0) 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt b = hex2num(*txt++); 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (b < 0) 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *addr++ = (a << 4) | b; 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hwaddr_aton2 - Convert ASCII string to MAC address (in any known format) 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @txt: MAC address as a string (e.g., 00:11:22:33:44:55 or 0011.2233.4455) 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes) 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Characters used (> 0) on success, -1 on failure 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hwaddr_aton2(const char *txt, u8 *addr) 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *pos = txt; 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < 6; i++) { 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int a, b; 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (*pos == ':' || *pos == '.' || *pos == '-') 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a = hex2num(*pos++); 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (a < 0) 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt b = hex2num(*pos++); 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (b < 0) 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *addr++ = (a << 4) | b; 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - txt; 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hexstr2bin - Convert ASCII hex string into binary data 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @hex: ASCII hex string (e.g., "01ab") 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Buffer for the binary data 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Length of the text to convert in bytes (of buf); hex will be double 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * this size 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure (invalid hex string) 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hexstr2bin(const char *hex, u8 *buf, size_t len) 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int a; 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *ipos = hex; 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *opos = buf; 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < len; i++) { 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a = hex2byte(ipos); 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (a < 0) 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *opos++ = a; 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ipos += 2; 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 188ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidtint hwaddr_mask_txt(char *buf, size_t len, const u8 *addr, const u8 *mask) 189ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt{ 190ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt size_t i; 191ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt int print_mask = 0; 192ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt int res; 193ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 194ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt for (i = 0; i < ETH_ALEN; i++) { 195ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (mask[i] != 0xff) { 196ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt print_mask = 1; 197ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt break; 198ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 199ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 200ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 201ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (print_mask) 202ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt res = os_snprintf(buf, len, MACSTR "/" MACSTR, 203ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt MAC2STR(addr), MAC2STR(mask)); 204ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt else 205ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt res = os_snprintf(buf, len, MACSTR, MAC2STR(addr)); 206ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (os_snprintf_error(len, res)) 207ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return -1; 208ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return res; 209ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt} 210ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 211ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * inc_byte_array - Increment arbitrary length byte array by one 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @counter: Pointer to byte array 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Length of the counter in bytes 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function increments the last byte of the counter by one and continues 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * rolling over to more significant bytes if the byte was incremented from 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 0xff to 0x00. 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid inc_byte_array(u8 *counter, size_t len) 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int pos = len - 1; 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos >= 0) { 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt counter[pos]++; 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (counter[pos] != 0) 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos--; 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_get_ntp_timestamp(u8 *buf) 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct os_time now; 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 sec, usec; 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt be32 tmp; 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 64-bit NTP timestamp (time from 1900-01-01 00:00:00) */ 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&now); 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sec = now.sec + 2208988800U; /* Epoch to 1900 */ 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Estimate 2^32/10^6 = 4295 - 1/32 - 1/512 */ 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt usec = now.usec; 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt usec = 4295 * usec - (usec >> 5) - (usec >> 9); 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = host_to_be32(sec); 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(buf, (u8 *) &tmp, 4); 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = host_to_be32(usec); 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(buf + 4, (u8 *) &tmp, 4); 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2516c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt/** 2526c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * wpa_scnprintf - Simpler-to-use snprintf function 2536c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * @buf: Output buffer 2546c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * @size: Buffer size 2556c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * @fmt: format 2566c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * 2576c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * Simpler snprintf version that doesn't require further error checks - the 2586c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * return value only indicates how many bytes were actually written, excluding 2596c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * the NULL byte (i.e., 0 on error, size-1 if buffer is not big enough). 2606c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt */ 2616c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtint wpa_scnprintf(char *buf, size_t size, const char *fmt, ...) 2626c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 2636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt va_list ap; 2646c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt int ret; 2656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 2666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!size) 2676c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return 0; 2686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 2696c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt va_start(ap, fmt); 2706c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ret = vsnprintf(buf, size, fmt, ap); 2716c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt va_end(ap); 2726c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 2736c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (ret < 0) 2746c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return 0; 2756c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if ((size_t) ret >= size) 2766c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return size - 1; 2776c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 2786c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return ret; 2796c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 281af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt 282af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidtint wpa_snprintf_hex_sep(char *buf, size_t buf_size, const u8 *data, size_t len, 283af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt char sep) 284af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt{ 285af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt size_t i; 286af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt char *pos = buf, *end = buf + buf_size; 287af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt int ret; 288af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt 289af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt if (buf_size == 0) 290af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt return 0; 291af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt 292af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt for (i = 0; i < len; i++) { 293af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt ret = os_snprintf(pos, end - pos, "%02x%c", 294af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt data[i], sep); 295af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt if (os_snprintf_error(end - pos, ret)) { 296af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt end[-1] = '\0'; 297af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt return pos - buf; 298af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt } 299af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt pos += ret; 300af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt } 301af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt pos[-1] = '\0'; 302af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt return pos - buf; 303af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt} 304af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt 305af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic inline int _wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len, int uppercase) 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *pos = buf, *end = buf + buf_size; 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf_size == 0) 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < len; i++) { 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, uppercase ? "%02X" : "%02x", 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data[i]); 3176c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(end - pos, ret)) { 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end[-1] = '\0'; 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end[-1] = '\0'; 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_snprintf_hex - Print data as a hex string into a buffer 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Memory area to use as the output buffer 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf_size: Maximum buffer size in bytes (should be at least 2 * len + 1) 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: Data to be printed 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Length of data in bytes 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Number of bytes written 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len) 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return _wpa_snprintf_hex(buf, buf_size, data, len, 0); 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_snprintf_hex_uppercase - Print data as a upper case hex string into buf 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Memory area to use as the output buffer 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf_size: Maximum buffer size in bytes (should be at least 2 * len + 1) 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: Data to be printed 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Length of data in bytes 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Number of bytes written 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_snprintf_hex_uppercase(char *buf, size_t buf_size, const u8 *data, 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len) 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return _wpa_snprintf_hex(buf, buf_size, data, len, 1); 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_ANSI_C_EXTRA 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef _WIN32_WCE 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid perror(const char *s) 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: GetLastError: %d", 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s, (int) GetLastError()); 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */ 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint optind = 1; 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint optopt; 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtchar *optarg; 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint getopt(int argc, char *const argv[], const char *optstring) 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt static int optchr = 1; 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *cp; 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (optchr == 1) { 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (optind >= argc) { 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* all arguments processed */ 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EOF; 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (argv[optind][0] != '-' || argv[optind][1] == '\0') { 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* no option characters */ 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EOF; 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strcmp(argv[optind], "--") == 0) { 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* no more options */ 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt optind++; 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return EOF; 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt optopt = argv[optind][optchr]; 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cp = os_strchr(optstring, optopt); 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cp == NULL || optopt == ':') { 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (argv[optind][++optchr] == '\0') { 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt optchr = 1; 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt optind++; 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return '?'; 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cp[1] == ':') { 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Argument required */ 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt optchr = 1; 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (argv[optind][optchr + 1]) { 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* No space between option and argument */ 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt optarg = &argv[optind++][optchr + 1]; 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (++optind >= argc) { 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* option requires an argument */ 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return '?'; 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Argument in the next argv */ 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt optarg = argv[optind++]; 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* No argument */ 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (argv[optind][++optchr] == '\0') { 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt optchr = 1; 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt optind++; 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt optarg = NULL; 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return *cp; 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_ANSI_C_EXTRA */ 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_NATIVE_WINDOWS 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_unicode2ascii_inplace - Convert unicode string into ASCII 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @str: Pointer to string to convert 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function converts a unicode string to ASCII using the same 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * buffer for output. If UNICODE is not set, the buffer is not 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * modified. 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_unicode2ascii_inplace(TCHAR *str) 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef UNICODE 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *dst = (char *) str; 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (*str) 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *dst++ = (char) *str++; 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *dst = '\0'; 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* UNICODE */ 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtTCHAR * wpa_strdup_tchar(const char *str) 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef UNICODE 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TCHAR *buf; 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = os_malloc((strlen(str) + 1) * sizeof(TCHAR)); 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wsprintf(buf, L"%S", str); 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* UNICODE */ 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return os_strdup(str); 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* UNICODE */ 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid printf_encode(char *txt, size_t maxlen, const u8 *data, size_t len) 46761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 46861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt char *end = txt + maxlen; 46961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t i; 47061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 47161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (i = 0; i < len; i++) { 472b5d893b5dec601a58c3ce0fc9e5d6da3816ce97aDmitry Shmidt if (txt + 4 >= end) 47361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 47461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 47561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt switch (data[i]) { 47661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case '\"': 47761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *txt++ = '\\'; 47861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *txt++ = '\"'; 47961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 48061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case '\\': 48161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *txt++ = '\\'; 48261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *txt++ = '\\'; 48361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 484661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt case '\033': 48561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *txt++ = '\\'; 48661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *txt++ = 'e'; 48761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 48861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case '\n': 48961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *txt++ = '\\'; 49061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *txt++ = 'n'; 49161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 49261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case '\r': 49361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *txt++ = '\\'; 49461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *txt++ = 'r'; 49561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 49661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case '\t': 49761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *txt++ = '\\'; 49861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *txt++ = 't'; 49961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 50061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt default: 501d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (data[i] >= 32 && data[i] <= 126) { 50261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *txt++ = data[i]; 50361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else { 50461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt txt += os_snprintf(txt, end - txt, "\\x%02x", 50561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt data[i]); 50661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 50761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 50861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 50961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 51061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 51161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *txt = '\0'; 51261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 51361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 51461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 51561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtsize_t printf_decode(u8 *buf, size_t maxlen, const char *str) 51661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 51761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const char *pos = str; 51861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t len = 0; 51961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt int val; 52061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 52161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt while (*pos) { 5225605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (len + 1 >= maxlen) 52361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 52461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt switch (*pos) { 52561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case '\\': 52661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos++; 52761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt switch (*pos) { 52861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case '\\': 52961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt buf[len++] = '\\'; 53061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos++; 53161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 53261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case '"': 53361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt buf[len++] = '"'; 53461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos++; 53561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 53661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case 'n': 53761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt buf[len++] = '\n'; 53861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos++; 53961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 54061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case 'r': 54161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt buf[len++] = '\r'; 54261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos++; 54361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 54461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case 't': 54561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt buf[len++] = '\t'; 54661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos++; 54761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 54861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case 'e': 549661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt buf[len++] = '\033'; 55061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos++; 55161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 55261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case 'x': 55361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos++; 55461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt val = hex2byte(pos); 55561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (val < 0) { 55661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt val = hex2num(*pos); 55761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (val < 0) 55861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 55961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt buf[len++] = val; 56061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos++; 56161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else { 56261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt buf[len++] = val; 56361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos += 2; 56461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 56561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 56661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case '0': 56761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case '1': 56861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case '2': 56961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case '3': 57061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case '4': 57161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case '5': 57261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case '6': 57361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case '7': 57461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt val = *pos++ - '0'; 57561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (*pos >= '0' && *pos <= '7') 57661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt val = val * 8 + (*pos++ - '0'); 57761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (*pos >= '0' && *pos <= '7') 57861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt val = val * 8 + (*pos++ - '0'); 57961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt buf[len++] = val; 58061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 58161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt default: 58261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 58361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 58461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 58561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt default: 58661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt buf[len++] = *pos++; 58761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 58861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 58961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 5905605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (maxlen > len) 5915605286c30e1701491bd3af974ae423727750eddDmitry Shmidt buf[len] = '\0'; 59261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 59361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return len; 59461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 59561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 59661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_ssid_txt - Convert SSID to a printable string 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ssid: SSID (32-octet string) 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ssid_len: Length of ssid in octets 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to a printable string 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function can be used to convert SSIDs into printable form. In most 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * cases, SSIDs do not use unprintable characters, but IEEE 802.11 standard 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * does not limit the used character set, so anything could be used in an SSID. 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function uses a static buffer, so only one call can be used at the 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * time, i.e., this is not re-entrant and the returned buffer must be used 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * before calling this again. 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len) 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6139d9e60286e05ae45025b672636490bd12586138dDmitry Shmidt static char ssid_txt[SSID_MAX_LEN * 4 + 1]; 61461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 61561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (ssid == NULL) { 61661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ssid_txt[0] = '\0'; 61761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return ssid_txt; 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 61961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 62061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt printf_encode(ssid_txt, sizeof(ssid_txt), ssid, ssid_len); 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ssid_txt; 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid * __hide_aliasing_typecast(void *foo) 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return foo; 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 62961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 63061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 63161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtchar * wpa_config_parse_string(const char *value, size_t *len) 63261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 63361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (*value == '"') { 63461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const char *pos; 63561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt char *str; 63661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt value++; 63761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos = os_strrchr(value, '"'); 63861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (pos == NULL || pos[1] != '\0') 63961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 64061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *len = pos - value; 6414b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt str = dup_binstr(value, *len); 64261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (str == NULL) 64361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 64461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return str; 64561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else if (*value == 'P' && value[1] == '"') { 64661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const char *pos; 64761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt char *tstr, *str; 64861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t tlen; 64961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt value += 2; 65061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos = os_strrchr(value, '"'); 65161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (pos == NULL || pos[1] != '\0') 65261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 65361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt tlen = pos - value; 6544b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt tstr = dup_binstr(value, tlen); 65561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (tstr == NULL) 65661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 65761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 65861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt str = os_malloc(tlen + 1); 65961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (str == NULL) { 66061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(tstr); 66161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 66261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 66361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 66461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *len = printf_decode((u8 *) str, tlen + 1, tstr); 66561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(tstr); 66661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 66761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return str; 66861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else { 66961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 *str; 67061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t tlen, hlen = os_strlen(value); 67161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hlen & 1) 67261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 67361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt tlen = hlen / 2; 67461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt str = os_malloc(tlen + 1); 67561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (str == NULL) 67661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 67761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hexstr2bin(value, str, tlen)) { 67861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(str); 67961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 68061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 68161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt str[tlen] = '\0'; 68261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *len = tlen; 68361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return (char *) str; 68461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 68561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 68661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 68761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 68861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint is_hex(const u8 *data, size_t len) 68961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 69061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t i; 69161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 69261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (i = 0; i < len; i++) { 69361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (data[i] < 32 || data[i] >= 127) 69461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 1; 69561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 69661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 69761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 69861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 69961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 70061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtsize_t merge_byte_arrays(u8 *res, size_t res_len, 70161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const u8 *src1, size_t src1_len, 70261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const u8 *src2, size_t src2_len) 70361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 70461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t len = 0; 70561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 70661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memset(res, 0, res_len); 70761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 70861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (src1) { 70961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (src1_len >= res_len) { 71061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memcpy(res, src1, res_len); 71161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return res_len; 71261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 71361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 71461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memcpy(res, src1, src1_len); 71561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt len += src1_len; 71661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 71761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 71861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (src2) { 71961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (len + src2_len >= res_len) { 72061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memcpy(res + len, src2, res_len - len); 72161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return res_len; 72261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 72361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 72461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memcpy(res + len, src2, src2_len); 72561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt len += src2_len; 72661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 72761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 72861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return len; 72961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 7304b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt 7314b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt 7324b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidtchar * dup_binstr(const void *src, size_t len) 7334b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt{ 7344b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt char *res; 7354b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt 7364b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (src == NULL) 7374b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt return NULL; 7384b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt res = os_malloc(len + 1); 7394b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (res == NULL) 7404b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt return NULL; 7414b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt os_memcpy(res, src, len); 7424b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt res[len] = '\0'; 7434b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt 7444b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt return res; 7454b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt} 7464ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 7474ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 7484ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidtint freq_range_list_parse(struct wpa_freq_range_list *res, const char *value) 7494ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt{ 7504ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt struct wpa_freq_range *freq = NULL, *n; 7514ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt unsigned int count = 0; 7524ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt const char *pos, *pos2, *pos3; 7534ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 7544ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt /* 7554ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt * Comma separated list of frequency ranges. 7564ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt * For example: 2412-2432,2462,5000-6000 7574ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt */ 7584ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt pos = value; 7594ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt while (pos && pos[0]) { 7604ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt n = os_realloc_array(freq, count + 1, 7614ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt sizeof(struct wpa_freq_range)); 7624ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (n == NULL) { 7634ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt os_free(freq); 7644ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt return -1; 7654ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt } 7664ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt freq = n; 7674ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt freq[count].min = atoi(pos); 7684ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt pos2 = os_strchr(pos, '-'); 7694ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt pos3 = os_strchr(pos, ','); 7704ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (pos2 && (!pos3 || pos2 < pos3)) { 7714ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt pos2++; 7724ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt freq[count].max = atoi(pos2); 7734ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt } else 7744ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt freq[count].max = freq[count].min; 7754ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt pos = pos3; 7764ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (pos) 7774ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt pos++; 7784ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt count++; 7794ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt } 7804ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 7814ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt os_free(res->range); 7824ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt res->range = freq; 7834ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt res->num = count; 7844ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 7854ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt return 0; 7864ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt} 7874ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 7884ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 7894ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidtint freq_range_list_includes(const struct wpa_freq_range_list *list, 7904ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt unsigned int freq) 7914ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt{ 7924ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt unsigned int i; 7934ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 7944ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (list == NULL) 7954ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt return 0; 7964ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 7974ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt for (i = 0; i < list->num; i++) { 7984ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (freq >= list->range[i].min && freq <= list->range[i].max) 7994ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt return 1; 8004ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt } 8014ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 8024ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt return 0; 8034ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt} 8044ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 8054ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 8064ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidtchar * freq_range_list_str(const struct wpa_freq_range_list *list) 8074ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt{ 8084ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt char *buf, *pos, *end; 8094ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt size_t maxlen; 8104ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt unsigned int i; 8114ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt int res; 8124ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 8134ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (list->num == 0) 8144ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt return NULL; 8154ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 8164ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt maxlen = list->num * 30; 8174ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt buf = os_malloc(maxlen); 8184ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (buf == NULL) 8194ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt return NULL; 8204ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt pos = buf; 8214ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt end = buf + maxlen; 8224ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 8234ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt for (i = 0; i < list->num; i++) { 8244ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt struct wpa_freq_range *range = &list->range[i]; 8254ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 8264ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt if (range->min == range->max) 8274ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt res = os_snprintf(pos, end - pos, "%s%u", 8284ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt i == 0 ? "" : ",", range->min); 8294ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt else 8304ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt res = os_snprintf(pos, end - pos, "%s%u-%u", 8314ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt i == 0 ? "" : ",", 8324ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt range->min, range->max); 8336c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(end - pos, res)) { 8344ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt os_free(buf); 8354ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt return NULL; 8364ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt } 8374ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt pos += res; 8384ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt } 8394ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt 8404ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt return buf; 8414ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt} 842fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 843fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 844fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtint int_array_len(const int *a) 845fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{ 846fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt int i; 847fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt for (i = 0; a && a[i]; i++) 848fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt ; 849fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return i; 850fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 851fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 852fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 853fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtvoid int_array_concat(int **res, const int *a) 854fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{ 855fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt int reslen, alen, i; 856fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt int *n; 857fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 858fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt reslen = int_array_len(*res); 859fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt alen = int_array_len(a); 860fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 861fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt n = os_realloc_array(*res, reslen + alen + 1, sizeof(int)); 862fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (n == NULL) { 863fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_free(*res); 864fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt *res = NULL; 865fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return; 866fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 867fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt for (i = 0; i <= alen; i++) 868fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt n[reslen + i] = a[i]; 869fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt *res = n; 870fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 871fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 872fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 873fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic int freq_cmp(const void *a, const void *b) 874fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{ 875fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt int _a = *(int *) a; 876fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt int _b = *(int *) b; 877fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 878fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (_a == 0) 879fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return 1; 880fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (_b == 0) 881fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return -1; 882fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return _a - _b; 883fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 884fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 885fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 886fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtvoid int_array_sort_unique(int *a) 887fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{ 888fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt int alen; 889fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt int i, j; 890fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 891fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (a == NULL) 892fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return; 893fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 894fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt alen = int_array_len(a); 895fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt qsort(a, alen, sizeof(int), freq_cmp); 896fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 897fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt i = 0; 898fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt j = 1; 899fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt while (a[i] && a[j]) { 900fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (a[i] == a[j]) { 901fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt j++; 902fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt continue; 903fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 904fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt a[++i] = a[j++]; 905fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 906fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (a[i]) 907fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt i++; 908fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt a[i] = 0; 909fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 910fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 911fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 912fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtvoid int_array_add_unique(int **res, int a) 913fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{ 914fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt int reslen; 915fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt int *n; 916fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 917fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt for (reslen = 0; *res && (*res)[reslen]; reslen++) { 918fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if ((*res)[reslen] == a) 919fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return; /* already in the list */ 920fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 921fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 922fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt n = os_realloc_array(*res, reslen + 2, sizeof(int)); 923fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (n == NULL) { 924fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_free(*res); 925fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt *res = NULL; 926fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return; 927fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 928fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 929fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt n[reslen] = a; 930fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt n[reslen + 1] = 0; 931fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 932fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt *res = n; 933fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt} 934c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt 935c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt 936c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidtvoid str_clear_free(char *str) 937c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt{ 938c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt if (str) { 939c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt size_t len = os_strlen(str); 940c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt os_memset(str, 0, len); 941c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt os_free(str); 942c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt } 943c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt} 944c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt 945c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt 946c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidtvoid bin_clear_free(void *bin, size_t len) 947c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt{ 948c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt if (bin) { 949c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt os_memset(bin, 0, len); 950c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt os_free(bin); 951c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt } 952c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt} 953661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt 954661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt 955661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidtint random_mac_addr(u8 *addr) 956661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt{ 957661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (os_get_random(addr, ETH_ALEN) < 0) 958661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt return -1; 959661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt addr[0] &= 0xfe; /* unicast */ 960661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt addr[0] |= 0x02; /* locally administered */ 961661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt return 0; 962661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt} 963661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt 964661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt 965661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidtint random_mac_addr_keep_oui(u8 *addr) 966661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt{ 967661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (os_get_random(addr + 3, 3) < 0) 968661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt return -1; 969661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt addr[0] &= 0xfe; /* unicast */ 970661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt addr[0] |= 0x02; /* locally administered */ 971661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt return 0; 972661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt} 9736c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 9746c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 9756c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt/** 976d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * cstr_token - Get next token from const char string 977d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * @str: a constant string to tokenize 978d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * @delim: a string of delimiters 979d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * @last: a pointer to a character following the returned token 980d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * It has to be set to NULL for the first call and passed for any 981d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * futher call. 982d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * Returns: a pointer to token position in str or NULL 983d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * 984d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * This function is similar to str_token, but it can be used with both 985d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * char and const char strings. Differences: 986d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * - The str buffer remains unmodified 987d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * - The returned token is not a NULL terminated string, but a token 988d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * position in str buffer. If a return value is not NULL a size 989d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * of the returned token could be calculated as (last - token). 990d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt */ 991d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtconst char * cstr_token(const char *str, const char *delim, const char **last) 992d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 993d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const char *end, *token = str; 994d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 995d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!str || !delim || !last) 996d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return NULL; 997d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 998d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (*last) 999d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt token = *last; 1000d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1001d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt while (*token && os_strchr(delim, *token)) 1002d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt token++; 1003d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1004d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!*token) 1005d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return NULL; 1006d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1007d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt end = token + 1; 1008d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1009d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt while (*end && !os_strchr(delim, *end)) 1010d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt end++; 1011d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1012d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt *last = end; 1013d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return token; 1014d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 1015d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1016d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1017d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt/** 10186c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * str_token - Get next token from a string 10196c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * @buf: String to tokenize. Note that the string might be modified. 10206c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * @delim: String of delimiters 10216c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * @context: Pointer to save our context. Should be initialized with 10226c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * NULL on the first call, and passed for any further call. 10236c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * Returns: The next token, NULL if there are no more valid tokens. 10246c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt */ 10256c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtchar * str_token(char *str, const char *delim, char **context) 10266c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 1027d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt char *token = (char *) cstr_token(str, delim, (const char **) context); 10286c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1029d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (token && **context) 1030d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt *(*context)++ = '\0'; 10316c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1032d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return token; 10336c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 1034216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 1035216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 1036216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtsize_t utf8_unescape(const char *inp, size_t in_size, 1037216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt char *outp, size_t out_size) 1038216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{ 1039216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt size_t res_size = 0; 1040216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 1041216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!inp || !outp) 1042216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return 0; 1043216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 1044216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!in_size) 1045216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt in_size = os_strlen(inp); 1046216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 1047216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* Advance past leading single quote */ 1048216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (*inp == '\'' && in_size) { 1049216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt inp++; 1050216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt in_size--; 1051216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 1052216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 1053216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt while (in_size--) { 1054216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (res_size >= out_size) 1055216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return 0; 1056216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 1057216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt switch (*inp) { 1058216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt case '\'': 1059216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* Terminate on bare single quote */ 1060216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt *outp = '\0'; 1061216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return res_size; 1062216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 1063216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt case '\\': 1064216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!in_size--) 1065216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return 0; 1066216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt inp++; 1067216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* fall through */ 1068216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 1069216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt default: 1070216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt *outp++ = *inp++; 1071216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt res_size++; 1072216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 1073216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 1074216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 1075216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* NUL terminate if space allows */ 1076216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (res_size < out_size) 1077216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt *outp = '\0'; 1078216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 1079216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return res_size; 1080216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt} 1081216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 1082216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 1083216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtsize_t utf8_escape(const char *inp, size_t in_size, 1084216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt char *outp, size_t out_size) 1085216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{ 1086216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt size_t res_size = 0; 1087216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 1088216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!inp || !outp) 1089216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return 0; 1090216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 1091216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* inp may or may not be NUL terminated, but must be if 0 size 1092216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt * is specified */ 1093216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!in_size) 1094216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt in_size = os_strlen(inp); 1095216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 1096216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt while (in_size--) { 1097216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (res_size++ >= out_size) 1098216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return 0; 1099216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 1100216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt switch (*inp) { 1101216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt case '\\': 1102216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt case '\'': 1103216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (res_size++ >= out_size) 1104216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return 0; 1105216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt *outp++ = '\\'; 1106216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* fall through */ 1107216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 1108216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt default: 1109216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt *outp++ = *inp++; 1110216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt break; 1111216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 1112216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 1113216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 1114216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* NUL terminate if space allows */ 1115216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (res_size < out_size) 1116216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt *outp = '\0'; 1117216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 1118216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return res_size; 1119216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt} 11209d9e60286e05ae45025b672636490bd12586138dDmitry Shmidt 11219d9e60286e05ae45025b672636490bd12586138dDmitry Shmidt 11229d9e60286e05ae45025b672636490bd12586138dDmitry Shmidtint is_ctrl_char(char c) 11239d9e60286e05ae45025b672636490bd12586138dDmitry Shmidt{ 11249d9e60286e05ae45025b672636490bd12586138dDmitry Shmidt return c > 0 && c < 32; 11259d9e60286e05ae45025b672636490bd12586138dDmitry Shmidt} 1126