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