common.c revision 8d520ff1dc2da35cdca849e982051b86468016d8
18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant/hostapd / common helper functions, etc.
38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi>
48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
58d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This program is free software; you can redistribute it and/or modify
68d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * it under the terms of the GNU General Public License version 2 as
78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * published by the Free Software Foundation.
88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Alternatively, this software may be distributed under the terms of BSD
108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * license.
118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * See README and COPYING for more details.
138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h"
168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h"
188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hex2num(char c)
218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (c >= '0' && c <= '9')
238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return c - '0';
248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (c >= 'a' && c <= 'f')
258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return c - 'a' + 10;
268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (c >= 'A' && c <= 'F')
278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return c - 'A' + 10;
288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return -1;
298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hex2byte(const char *hex)
338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int a, b;
358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	a = hex2num(*hex++);
368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (a < 0)
378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	b = hex2num(*hex++);
398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (b < 0)
408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return (a << 4) | b;
428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hwaddr_aton - Convert ASCII string to MAC address (colon-delimited format)
478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @txt: MAC address as a string (e.g., "00:11:22:33:44:55")
488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure (e.g., string not a MAC address)
508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hwaddr_aton(const char *txt, u8 *addr)
528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i;
548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < 6; i++) {
568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		int a, b;
578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		a = hex2num(*txt++);
598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (a < 0)
608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		b = hex2num(*txt++);
628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (b < 0)
638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		*addr++ = (a << 4) | b;
658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (i < 5 && *txt++ != ':')
668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hwaddr_compact_aton - Convert ASCII string to MAC address (no colon delimitors format)
748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @txt: MAC address as a string (e.g., "001122334455")
758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure (e.g., string not a MAC address)
778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hwaddr_compact_aton(const char *txt, u8 *addr)
798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i;
818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < 6; i++) {
838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		int a, b;
848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		a = hex2num(*txt++);
868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (a < 0)
878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		b = hex2num(*txt++);
898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (b < 0)
908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		*addr++ = (a << 4) | b;
928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hwaddr_aton2 - Convert ASCII string to MAC address (in any known format)
998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @txt: MAC address as a string (e.g., 00:11:22:33:44:55 or 0011.2233.4455)
1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Characters used (> 0) on success, -1 on failure
1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hwaddr_aton2(const char *txt, u8 *addr)
1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i;
1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const char *pos = txt;
1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < 6; i++) {
1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		int a, b;
1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		while (*pos == ':' || *pos == '.' || *pos == '-')
1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pos++;
1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		a = hex2num(*pos++);
1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (a < 0)
1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		b = hex2num(*pos++);
1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (b < 0)
1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		*addr++ = (a << 4) | b;
1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return pos - txt;
1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hexstr2bin - Convert ASCII hex string into binary data
1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @hex: ASCII hex string (e.g., "01ab")
1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Buffer for the binary data
1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Length of the text to convert in bytes (of buf); hex will be double
1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * this size
1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure (invalid hex string)
1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hexstr2bin(const char *hex, u8 *buf, size_t len)
1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t i;
1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int a;
1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const char *ipos = hex;
1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 *opos = buf;
1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < len; i++) {
1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		a = hex2byte(ipos);
1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (a < 0)
1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		*opos++ = a;
1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ipos += 2;
1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * inc_byte_array - Increment arbitrary length byte array by one
1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @counter: Pointer to byte array
1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Length of the counter in bytes
1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function increments the last byte of the counter by one and continues
1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * rolling over to more significant bytes if the byte was incremented from
1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 0xff to 0x00.
1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid inc_byte_array(u8 *counter, size_t len)
1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int pos = len - 1;
1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (pos >= 0) {
1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		counter[pos]++;
1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (counter[pos] != 0)
1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos--;
1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_get_ntp_timestamp(u8 *buf)
1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct os_time now;
1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u32 sec, usec;
1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	be32 tmp;
1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* 64-bit NTP timestamp (time from 1900-01-01 00:00:00) */
1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_get_time(&now);
1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	sec = now.sec + 2208988800U; /* Epoch to 1900 */
1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Estimate 2^32/10^6 = 4295 - 1/32 - 1/512 */
1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	usec = now.usec;
1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	usec = 4295 * usec - (usec >> 5) - (usec >> 9);
1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	tmp = host_to_be32(sec);
1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(buf, (u8 *) &tmp, 4);
1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	tmp = host_to_be32(usec);
1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(buf + 4, (u8 *) &tmp, 4);
1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic inline int _wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data,
1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    size_t len, int uppercase)
1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t i;
1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos = buf, *end = buf + buf_size;
1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ret;
1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (buf_size == 0)
2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < len; i++) {
2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret = os_snprintf(pos, end - pos, uppercase ? "%02X" : "%02x",
2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  data[i]);
2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret < 0 || ret >= end - pos) {
2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			end[-1] = '\0';
2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return pos - buf;
2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos += ret;
2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	end[-1] = '\0';
2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return pos - buf;
2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_snprintf_hex - Print data as a hex string into a buffer
2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Memory area to use as the output buffer
2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf_size: Maximum buffer size in bytes (should be at least 2 * len + 1)
2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: Data to be printed
2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Length of data in bytes
2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Number of bytes written
2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len)
2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return _wpa_snprintf_hex(buf, buf_size, data, len, 0);
2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_snprintf_hex_uppercase - Print data as a upper case hex string into buf
2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Memory area to use as the output buffer
2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf_size: Maximum buffer size in bytes (should be at least 2 * len + 1)
2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: Data to be printed
2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Length of data in bytes
2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Number of bytes written
2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_snprintf_hex_uppercase(char *buf, size_t buf_size, const u8 *data,
2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			       size_t len)
2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return _wpa_snprintf_hex(buf, buf_size, data, len, 1);
2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_ANSI_C_EXTRA
2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef _WIN32_WCE
2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid perror(const char *s)
2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_ERROR, "%s: GetLastError: %d",
2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   s, (int) GetLastError());
2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */
2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint optind = 1;
2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint optopt;
2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtchar *optarg;
2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint getopt(int argc, char *const argv[], const char *optstring)
2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	static int optchr = 1;
2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *cp;
2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (optchr == 1) {
2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (optind >= argc) {
2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/* all arguments processed */
2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return EOF;
2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (argv[optind][0] != '-' || argv[optind][1] == '\0') {
2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/* no option characters */
2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return EOF;
2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strcmp(argv[optind], "--") == 0) {
2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* no more options */
2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		optind++;
2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return EOF;
2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	optopt = argv[optind][optchr];
2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	cp = os_strchr(optstring, optopt);
2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (cp == NULL || optopt == ':') {
2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (argv[optind][++optchr] == '\0') {
2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			optchr = 1;
2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			optind++;
2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return '?';
2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (cp[1] == ':') {
2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Argument required */
2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		optchr = 1;
2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (argv[optind][optchr + 1]) {
2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/* No space between option and argument */
2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			optarg = &argv[optind++][optchr + 1];
2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (++optind >= argc) {
2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/* option requires an argument */
2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return '?';
3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else {
3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/* Argument in the next argv */
3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			optarg = argv[optind++];
3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* No argument */
3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (argv[optind][++optchr] == '\0') {
3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			optchr = 1;
3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			optind++;
3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		optarg = NULL;
3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return *cp;
3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_ANSI_C_EXTRA */
3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_NATIVE_WINDOWS
3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_unicode2ascii_inplace - Convert unicode string into ASCII
3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @str: Pointer to string to convert
3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function converts a unicode string to ASCII using the same
3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * buffer for output. If UNICODE is not set, the buffer is not
3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * modified.
3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_unicode2ascii_inplace(TCHAR *str)
3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef UNICODE
3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *dst = (char *) str;
3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (*str)
3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		*dst++ = (char) *str++;
3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	*dst = '\0';
3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* UNICODE */
3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtTCHAR * wpa_strdup_tchar(const char *str)
3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef UNICODE
3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	TCHAR *buf;
3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	buf = os_malloc((strlen(str) + 1) * sizeof(TCHAR));
3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (buf == NULL)
3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wsprintf(buf, L"%S", str);
3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return buf;
3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* UNICODE */
3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return os_strdup(str);
3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* UNICODE */
3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */
3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_ssid_txt - Convert SSID to a printable string
3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ssid: SSID (32-octet string)
3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ssid_len: Length of ssid in octets
3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to a printable string
3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function can be used to convert SSIDs into printable form. In most
3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * cases, SSIDs do not use unprintable characters, but IEEE 802.11 standard
3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * does not limit the used character set, so anything could be used in an SSID.
3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function uses a static buffer, so only one call can be used at the
3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * time, i.e., this is not re-entrant and the returned buffer must be used
3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * before calling this again.
3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len)
3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	static char ssid_txt[33];
3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos;
3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid_len > 32)
3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ssid_len = 32;
3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(ssid_txt, ssid, ssid_len);
3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ssid_txt[ssid_len] = '\0';
3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (pos = ssid_txt; *pos != '\0'; pos++) {
3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if ((u8) *pos < 32 || (u8) *pos >= 127)
3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			*pos = '_';
3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return ssid_txt;
3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid * __hide_aliasing_typecast(void *foo)
3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return foo;
3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
388