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 */
8957c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt	if (*r == '\0' || isspace((unsigned char) *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
700849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidtint has_ctrl_char(const u8 *data, size_t len)
701849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt{
702849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt	size_t i;
703849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt
704849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt	for (i = 0; i < len; i++) {
705849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt		if (data[i] < 32 || data[i] == 127)
706849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt			return 1;
707849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt	}
708849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt	return 0;
709849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt}
710849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt
711849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt
712849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidtint has_newline(const char *str)
713849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt{
714849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt	while (*str) {
715849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt		if (*str == '\n' || *str == '\r')
716849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt			return 1;
717849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt		str++;
718849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt	}
719849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt	return 0;
720849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt}
721849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt
722849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt
72361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtsize_t merge_byte_arrays(u8 *res, size_t res_len,
72461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			 const u8 *src1, size_t src1_len,
72561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			 const u8 *src2, size_t src2_len)
72661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{
72761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	size_t len = 0;
72861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
72961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	os_memset(res, 0, res_len);
73061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
73161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (src1) {
73261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (src1_len >= res_len) {
73361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			os_memcpy(res, src1, res_len);
73461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			return res_len;
73561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		}
73661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
73761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		os_memcpy(res, src1, src1_len);
73861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		len += src1_len;
73961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
74061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
74161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (src2) {
74261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (len + src2_len >= res_len) {
74361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			os_memcpy(res + len, src2, res_len - len);
74461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			return res_len;
74561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		}
74661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
74761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		os_memcpy(res + len, src2, src2_len);
74861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		len += src2_len;
74961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
75061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
75161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	return len;
75261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt}
7534b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt
7544b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt
7554b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidtchar * dup_binstr(const void *src, size_t len)
7564b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt{
7574b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt	char *res;
7584b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt
7594b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt	if (src == NULL)
7604b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt		return NULL;
7614b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt	res = os_malloc(len + 1);
7624b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt	if (res == NULL)
7634b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt		return NULL;
7644b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt	os_memcpy(res, src, len);
7654b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt	res[len] = '\0';
7664b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt
7674b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt	return res;
7684b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt}
7694ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt
7704ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt
7714ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidtint freq_range_list_parse(struct wpa_freq_range_list *res, const char *value)
7724ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt{
7734ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt	struct wpa_freq_range *freq = NULL, *n;
7744ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt	unsigned int count = 0;
7754ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt	const char *pos, *pos2, *pos3;
7764ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt
7774ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt	/*
7784ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt	 * Comma separated list of frequency ranges.
7794ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt	 * For example: 2412-2432,2462,5000-6000
7804ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt	 */
7814ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt	pos = value;
7824ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt	while (pos && pos[0]) {
7834ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt		n = os_realloc_array(freq, count + 1,
7844ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt				     sizeof(struct wpa_freq_range));
7854ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt		if (n == NULL) {
7864ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt			os_free(freq);
7874ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt			return -1;
7884ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt		}
7894ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt		freq = n;
7904ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt		freq[count].min = atoi(pos);
7914ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt		pos2 = os_strchr(pos, '-');
7924ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt		pos3 = os_strchr(pos, ',');
7934ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt		if (pos2 && (!pos3 || pos2 < pos3)) {
7944ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt			pos2++;
7954ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt			freq[count].max = atoi(pos2);
7964ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt		} else
7974ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt			freq[count].max = freq[count].min;
7984ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt		pos = pos3;
7994ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt		if (pos)
8004ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt			pos++;
8014ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt		count++;
8024ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt	}
8034ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt
8044ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt	os_free(res->range);
8054ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt	res->range = freq;
8064ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt	res->num = count;
8074ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt
8084ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt	return 0;
8094ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt}
8104ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt
8114ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt
8124ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidtint freq_range_list_includes(const struct wpa_freq_range_list *list,
8134ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt			     unsigned int freq)
8144ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt{
8154ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt	unsigned int i;
8164ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt
8174ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt	if (list == NULL)
8184ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt		return 0;
8194ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt
8204ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt	for (i = 0; i < list->num; i++) {
8214ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt		if (freq >= list->range[i].min && freq <= list->range[i].max)
8224ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt			return 1;
8234ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt	}
8244ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt
8254ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt	return 0;
8264ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt}
8274ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt
8284ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt
8294ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidtchar * freq_range_list_str(const struct wpa_freq_range_list *list)
8304ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt{
8314ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt	char *buf, *pos, *end;
8324ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt	size_t maxlen;
8334ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt	unsigned int i;
8344ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt	int res;
8354ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt
8364ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt	if (list->num == 0)
8374ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt		return NULL;
8384ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt
8394ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt	maxlen = list->num * 30;
8404ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt	buf = os_malloc(maxlen);
8414ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt	if (buf == NULL)
8424ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt		return NULL;
8434ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt	pos = buf;
8444ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt	end = buf + maxlen;
8454ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt
8464ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt	for (i = 0; i < list->num; i++) {
8474ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt		struct wpa_freq_range *range = &list->range[i];
8484ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt
8494ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt		if (range->min == range->max)
8504ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt			res = os_snprintf(pos, end - pos, "%s%u",
8514ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt					  i == 0 ? "" : ",", range->min);
8524ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt		else
8534ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt			res = os_snprintf(pos, end - pos, "%s%u-%u",
8544ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt					  i == 0 ? "" : ",",
8554ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt					  range->min, range->max);
8566c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		if (os_snprintf_error(end - pos, res)) {
8574ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt			os_free(buf);
8584ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt			return NULL;
8594ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt		}
8604ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt		pos += res;
8614ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt	}
8624ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt
8634ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt	return buf;
8644ce9c87407c036fc83eb5a6044ddf976c86f53fcDmitry Shmidt}
865fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
866fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
867fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtint int_array_len(const int *a)
868fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{
869fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	int i;
870fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	for (i = 0; a && a[i]; i++)
871fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		;
872fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	return i;
873fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt}
874fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
875fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
876fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtvoid int_array_concat(int **res, const int *a)
877fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{
878fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	int reslen, alen, i;
879fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	int *n;
880fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
881fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	reslen = int_array_len(*res);
882fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	alen = int_array_len(a);
883fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
884fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	n = os_realloc_array(*res, reslen + alen + 1, sizeof(int));
885fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (n == NULL) {
886fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		os_free(*res);
887fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		*res = NULL;
888fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return;
889fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
890fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	for (i = 0; i <= alen; i++)
891fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		n[reslen + i] = a[i];
892fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	*res = n;
893fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt}
894fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
895fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
896fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic int freq_cmp(const void *a, const void *b)
897fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{
898fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	int _a = *(int *) a;
899fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	int _b = *(int *) b;
900fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
901fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (_a == 0)
902fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return 1;
903fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (_b == 0)
904fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return -1;
905fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	return _a - _b;
906fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt}
907fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
908fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
909fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtvoid int_array_sort_unique(int *a)
910fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{
911fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	int alen;
912fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	int i, j;
913fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
914fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (a == NULL)
915fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return;
916fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
917fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	alen = int_array_len(a);
918fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	qsort(a, alen, sizeof(int), freq_cmp);
919fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
920fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	i = 0;
921fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	j = 1;
922fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	while (a[i] && a[j]) {
923fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		if (a[i] == a[j]) {
924fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			j++;
925fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			continue;
926fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		}
927fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		a[++i] = a[j++];
928fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
929fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (a[i])
930fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		i++;
931fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	a[i] = 0;
932fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt}
933fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
934fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
935fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtvoid int_array_add_unique(int **res, int a)
936fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{
937fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	int reslen;
938fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	int *n;
939fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
940fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	for (reslen = 0; *res && (*res)[reslen]; reslen++) {
941fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		if ((*res)[reslen] == a)
942fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt			return; /* already in the list */
943fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
944fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
945fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	n = os_realloc_array(*res, reslen + 2, sizeof(int));
946fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (n == NULL) {
947fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		os_free(*res);
948fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		*res = NULL;
949fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return;
950fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	}
951fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
952fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	n[reslen] = a;
953fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	n[reslen + 1] = 0;
954fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
955fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	*res = n;
956fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt}
957c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt
958c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt
959c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidtvoid str_clear_free(char *str)
960c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt{
961c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt	if (str) {
962c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt		size_t len = os_strlen(str);
963c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt		os_memset(str, 0, len);
964c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt		os_free(str);
965c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt	}
966c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt}
967c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt
968c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt
969c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidtvoid bin_clear_free(void *bin, size_t len)
970c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt{
971c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt	if (bin) {
972c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt		os_memset(bin, 0, len);
973c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt		os_free(bin);
974c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt	}
975c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt}
976661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt
977661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt
978661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidtint random_mac_addr(u8 *addr)
979661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt{
980661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt	if (os_get_random(addr, ETH_ALEN) < 0)
981661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt		return -1;
982661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt	addr[0] &= 0xfe; /* unicast */
983661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt	addr[0] |= 0x02; /* locally administered */
984661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt	return 0;
985661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt}
986661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt
987661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt
988661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidtint random_mac_addr_keep_oui(u8 *addr)
989661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt{
990661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt	if (os_get_random(addr + 3, 3) < 0)
991661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt		return -1;
992661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt	addr[0] &= 0xfe; /* unicast */
993661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt	addr[0] |= 0x02; /* locally administered */
994661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt	return 0;
995661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt}
9966c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
9976c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
9986c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt/**
999d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * cstr_token - Get next token from const char string
1000d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * @str: a constant string to tokenize
1001d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * @delim: a string of delimiters
1002d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * @last: a pointer to a character following the returned token
1003d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt *      It has to be set to NULL for the first call and passed for any
10049839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt *      further call.
1005d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * Returns: a pointer to token position in str or NULL
1006d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt *
1007d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * This function is similar to str_token, but it can be used with both
1008d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * char and const char strings. Differences:
1009d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * - The str buffer remains unmodified
1010d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * - The returned token is not a NULL terminated string, but a token
1011d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt *   position in str buffer. If a return value is not NULL a size
1012d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt *   of the returned token could be calculated as (last - token).
1013d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt */
1014d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtconst char * cstr_token(const char *str, const char *delim, const char **last)
1015d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{
1016d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	const char *end, *token = str;
1017d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
1018d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	if (!str || !delim || !last)
1019d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt		return NULL;
1020d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
1021d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	if (*last)
1022d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt		token = *last;
1023d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
1024d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	while (*token && os_strchr(delim, *token))
1025d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt		token++;
1026d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
1027d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	if (!*token)
1028d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt		return NULL;
1029d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
1030d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	end = token + 1;
1031d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
1032d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	while (*end && !os_strchr(delim, *end))
1033d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt		end++;
1034d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
1035d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	*last = end;
1036d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	return token;
1037d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt}
1038d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
1039d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt
1040d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt/**
10416c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * str_token - Get next token from a string
10426c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * @buf: String to tokenize. Note that the string might be modified.
10436c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * @delim: String of delimiters
10446c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * @context: Pointer to save our context. Should be initialized with
10456c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt *	NULL on the first call, and passed for any further call.
10466c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * Returns: The next token, NULL if there are no more valid tokens.
10476c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt */
10486c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtchar * str_token(char *str, const char *delim, char **context)
10496c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{
1050d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	char *token = (char *) cstr_token(str, delim, (const char **) context);
10516c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
1052d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	if (token && **context)
1053d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt		*(*context)++ = '\0';
10546c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
1055d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt	return token;
10566c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt}
1057216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
1058216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
1059216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtsize_t utf8_unescape(const char *inp, size_t in_size,
1060216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		     char *outp, size_t out_size)
1061216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{
1062216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	size_t res_size = 0;
1063216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
1064216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if (!inp || !outp)
1065216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		return 0;
1066216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
1067216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if (!in_size)
1068216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		in_size = os_strlen(inp);
1069216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
1070216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	/* Advance past leading single quote */
1071216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if (*inp == '\'' && in_size) {
1072216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		inp++;
1073216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		in_size--;
1074216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	}
1075216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
1076216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	while (in_size--) {
1077216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		if (res_size >= out_size)
1078216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			return 0;
1079216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
1080216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		switch (*inp) {
1081216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		case '\'':
1082216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			/* Terminate on bare single quote */
1083216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			*outp = '\0';
1084216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			return res_size;
1085216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
1086216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		case '\\':
1087216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			if (!in_size--)
1088216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				return 0;
1089216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			inp++;
1090216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			/* fall through */
1091216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
1092216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		default:
1093216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			*outp++ = *inp++;
1094216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			res_size++;
1095216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		}
1096216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	}
1097216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
1098216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	/* NUL terminate if space allows */
1099216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if (res_size < out_size)
1100216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		*outp = '\0';
1101216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
1102216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	return res_size;
1103216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt}
1104216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
1105216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
1106216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtsize_t utf8_escape(const char *inp, size_t in_size,
1107216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		   char *outp, size_t out_size)
1108216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{
1109216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	size_t res_size = 0;
1110216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
1111216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if (!inp || !outp)
1112216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		return 0;
1113216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
1114216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	/* inp may or may not be NUL terminated, but must be if 0 size
1115216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	 * is specified */
1116216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if (!in_size)
1117216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		in_size = os_strlen(inp);
1118216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
1119216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	while (in_size--) {
1120216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		if (res_size++ >= out_size)
1121216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			return 0;
1122216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
1123216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		switch (*inp) {
1124216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		case '\\':
1125216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		case '\'':
1126216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			if (res_size++ >= out_size)
1127216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt				return 0;
1128216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			*outp++ = '\\';
1129216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			/* fall through */
1130216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
1131216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		default:
1132216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			*outp++ = *inp++;
1133216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt			break;
1134216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		}
1135216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	}
1136216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
1137216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	/* NUL terminate if space allows */
1138216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	if (res_size < out_size)
1139216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt		*outp = '\0';
1140216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt
1141216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt	return res_size;
1142216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt}
11439d9e60286e05ae45025b672636490bd12586138dDmitry Shmidt
11449d9e60286e05ae45025b672636490bd12586138dDmitry Shmidt
11459d9e60286e05ae45025b672636490bd12586138dDmitry Shmidtint is_ctrl_char(char c)
11469d9e60286e05ae45025b672636490bd12586138dDmitry Shmidt{
11479d9e60286e05ae45025b672636490bd12586138dDmitry Shmidt	return c > 0 && c < 32;
11489d9e60286e05ae45025b672636490bd12586138dDmitry Shmidt}
1149849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt
1150849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt
1151849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt/**
1152849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt * ssid_parse - Parse a string that contains SSID in hex or text format
1153849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt * @buf: Input NULL terminated string that contains the SSID
1154849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt * @ssid: Output SSID
1155849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt * Returns: 0 on success, -1 otherwise
1156849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt *
1157849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt * The SSID has to be enclosed in double quotes for the text format or space
1158849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt * or NULL terminated string of hex digits for the hex format. buf can include
1159849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt * additional arguments after the SSID.
1160849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt */
1161849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidtint ssid_parse(const char *buf, struct wpa_ssid_value *ssid)
1162849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt{
1163849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt	char *tmp, *res, *end;
1164849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt	size_t len;
1165849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt
1166849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt	ssid->ssid_len = 0;
1167849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt
1168849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt	tmp = os_strdup(buf);
1169849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt	if (!tmp)
1170849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt		return -1;
1171849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt
1172849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt	if (*tmp != '"') {
1173849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt		end = os_strchr(tmp, ' ');
1174849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt		if (end)
1175849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt			*end = '\0';
1176849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt	} else {
1177849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt		end = os_strchr(tmp + 1, '"');
1178849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt		if (!end) {
1179849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt			os_free(tmp);
1180849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt			return -1;
1181849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt		}
1182849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt
1183849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt		end[1] = '\0';
1184849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt	}
1185849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt
1186849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt	res = wpa_config_parse_string(tmp, &len);
1187849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt	if (res && len <= SSID_MAX_LEN) {
1188849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt		ssid->ssid_len = len;
1189849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt		os_memcpy(ssid->ssid, res, len);
1190849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt	}
1191849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt
1192849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt	os_free(tmp);
1193849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt	os_free(res);
1194849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt
1195849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt	return ssid->ssid_len ? 0 : -1;
1196849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt}
11977f2c753f60025528366b5f19b8b490a47bf5080bDmitry Shmidt
11987f2c753f60025528366b5f19b8b490a47bf5080bDmitry Shmidt
11997f2c753f60025528366b5f19b8b490a47bf5080bDmitry Shmidtint str_starts(const char *str, const char *start)
12007f2c753f60025528366b5f19b8b490a47bf5080bDmitry Shmidt{
12017f2c753f60025528366b5f19b8b490a47bf5080bDmitry Shmidt	return os_strncmp(str, start, os_strlen(start)) == 0;
12027f2c753f60025528366b5f19b8b490a47bf5080bDmitry Shmidt}
1203293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt
1204293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt
1205293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt/**
1206293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt * rssi_to_rcpi - Convert RSSI to RCPI
1207293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt * @rssi: RSSI to convert
1208293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt * Returns: RCPI corresponding to the given RSSI value, or 255 if not available.
1209293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt *
1210293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt * It's possible to estimate RCPI based on RSSI in dBm. This calculation will
1211293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt * not reflect the correct value for high rates, but it's good enough for Action
1212293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt * frames which are transmitted with up to 24 Mbps rates.
1213293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt */
1214293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidtu8 rssi_to_rcpi(int rssi)
1215293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt{
1216293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt	if (!rssi)
1217293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt		return 255; /* not available */
1218293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt	if (rssi < -110)
1219293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt		return 0;
1220293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt	if (rssi > 0)
1221293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt		return 220;
1222293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt	return (rssi + 110) * 2;
1223293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt}
1224