• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * wpa_supplicant/hostapd / common helper functions, etc.
3  * Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8 
9 #include "includes.h"
10 
11 #include "common.h"
12 
13 
hex2num(char c)14 static int hex2num(char c)
15 {
16 	if (c >= '0' && c <= '9')
17 		return c - '0';
18 	if (c >= 'a' && c <= 'f')
19 		return c - 'a' + 10;
20 	if (c >= 'A' && c <= 'F')
21 		return c - 'A' + 10;
22 	return -1;
23 }
24 
25 
hex2byte(const char * hex)26 int hex2byte(const char *hex)
27 {
28 	int a, b;
29 	a = hex2num(*hex++);
30 	if (a < 0)
31 		return -1;
32 	b = hex2num(*hex++);
33 	if (b < 0)
34 		return -1;
35 	return (a << 4) | b;
36 }
37 
38 
39 /**
40  * hwaddr_aton - Convert ASCII string to MAC address (colon-delimited format)
41  * @txt: MAC address as a string (e.g., "00:11:22:33:44:55")
42  * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
43  * Returns: 0 on success, -1 on failure (e.g., string not a MAC address)
44  */
hwaddr_aton(const char * txt,u8 * addr)45 int hwaddr_aton(const char *txt, u8 *addr)
46 {
47 	int i;
48 
49 	for (i = 0; i < 6; i++) {
50 		int a, b;
51 
52 		a = hex2num(*txt++);
53 		if (a < 0)
54 			return -1;
55 		b = hex2num(*txt++);
56 		if (b < 0)
57 			return -1;
58 		*addr++ = (a << 4) | b;
59 		if (i < 5 && *txt++ != ':')
60 			return -1;
61 	}
62 
63 	return 0;
64 }
65 
66 /**
67  * hwaddr_compact_aton - Convert ASCII string to MAC address (no colon delimitors format)
68  * @txt: MAC address as a string (e.g., "001122334455")
69  * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
70  * Returns: 0 on success, -1 on failure (e.g., string not a MAC address)
71  */
hwaddr_compact_aton(const char * txt,u8 * addr)72 int hwaddr_compact_aton(const char *txt, u8 *addr)
73 {
74 	int i;
75 
76 	for (i = 0; i < 6; i++) {
77 		int a, b;
78 
79 		a = hex2num(*txt++);
80 		if (a < 0)
81 			return -1;
82 		b = hex2num(*txt++);
83 		if (b < 0)
84 			return -1;
85 		*addr++ = (a << 4) | b;
86 	}
87 
88 	return 0;
89 }
90 
91 /**
92  * hwaddr_aton2 - Convert ASCII string to MAC address (in any known format)
93  * @txt: MAC address as a string (e.g., 00:11:22:33:44:55 or 0011.2233.4455)
94  * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
95  * Returns: Characters used (> 0) on success, -1 on failure
96  */
hwaddr_aton2(const char * txt,u8 * addr)97 int hwaddr_aton2(const char *txt, u8 *addr)
98 {
99 	int i;
100 	const char *pos = txt;
101 
102 	for (i = 0; i < 6; i++) {
103 		int a, b;
104 
105 		while (*pos == ':' || *pos == '.' || *pos == '-')
106 			pos++;
107 
108 		a = hex2num(*pos++);
109 		if (a < 0)
110 			return -1;
111 		b = hex2num(*pos++);
112 		if (b < 0)
113 			return -1;
114 		*addr++ = (a << 4) | b;
115 	}
116 
117 	return pos - txt;
118 }
119 
120 
121 /**
122  * hexstr2bin - Convert ASCII hex string into binary data
123  * @hex: ASCII hex string (e.g., "01ab")
124  * @buf: Buffer for the binary data
125  * @len: Length of the text to convert in bytes (of buf); hex will be double
126  * this size
127  * Returns: 0 on success, -1 on failure (invalid hex string)
128  */
hexstr2bin(const char * hex,u8 * buf,size_t len)129 int hexstr2bin(const char *hex, u8 *buf, size_t len)
130 {
131 	size_t i;
132 	int a;
133 	const char *ipos = hex;
134 	u8 *opos = buf;
135 
136 	for (i = 0; i < len; i++) {
137 		a = hex2byte(ipos);
138 		if (a < 0)
139 			return -1;
140 		*opos++ = a;
141 		ipos += 2;
142 	}
143 	return 0;
144 }
145 
146 
147 /**
148  * inc_byte_array - Increment arbitrary length byte array by one
149  * @counter: Pointer to byte array
150  * @len: Length of the counter in bytes
151  *
152  * This function increments the last byte of the counter by one and continues
153  * rolling over to more significant bytes if the byte was incremented from
154  * 0xff to 0x00.
155  */
inc_byte_array(u8 * counter,size_t len)156 void inc_byte_array(u8 *counter, size_t len)
157 {
158 	int pos = len - 1;
159 	while (pos >= 0) {
160 		counter[pos]++;
161 		if (counter[pos] != 0)
162 			break;
163 		pos--;
164 	}
165 }
166 
167 
wpa_get_ntp_timestamp(u8 * buf)168 void wpa_get_ntp_timestamp(u8 *buf)
169 {
170 	struct os_time now;
171 	u32 sec, usec;
172 	be32 tmp;
173 
174 	/* 64-bit NTP timestamp (time from 1900-01-01 00:00:00) */
175 	os_get_time(&now);
176 	sec = now.sec + 2208988800U; /* Epoch to 1900 */
177 	/* Estimate 2^32/10^6 = 4295 - 1/32 - 1/512 */
178 	usec = now.usec;
179 	usec = 4295 * usec - (usec >> 5) - (usec >> 9);
180 	tmp = host_to_be32(sec);
181 	os_memcpy(buf, (u8 *) &tmp, 4);
182 	tmp = host_to_be32(usec);
183 	os_memcpy(buf + 4, (u8 *) &tmp, 4);
184 }
185 
186 
_wpa_snprintf_hex(char * buf,size_t buf_size,const u8 * data,size_t len,int uppercase)187 static inline int _wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data,
188 				    size_t len, int uppercase)
189 {
190 	size_t i;
191 	char *pos = buf, *end = buf + buf_size;
192 	int ret;
193 	if (buf_size == 0)
194 		return 0;
195 	for (i = 0; i < len; i++) {
196 		ret = os_snprintf(pos, end - pos, uppercase ? "%02X" : "%02x",
197 				  data[i]);
198 		if (ret < 0 || ret >= end - pos) {
199 			end[-1] = '\0';
200 			return pos - buf;
201 		}
202 		pos += ret;
203 	}
204 	end[-1] = '\0';
205 	return pos - buf;
206 }
207 
208 /**
209  * wpa_snprintf_hex - Print data as a hex string into a buffer
210  * @buf: Memory area to use as the output buffer
211  * @buf_size: Maximum buffer size in bytes (should be at least 2 * len + 1)
212  * @data: Data to be printed
213  * @len: Length of data in bytes
214  * Returns: Number of bytes written
215  */
wpa_snprintf_hex(char * buf,size_t buf_size,const u8 * data,size_t len)216 int wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len)
217 {
218 	return _wpa_snprintf_hex(buf, buf_size, data, len, 0);
219 }
220 
221 
222 /**
223  * wpa_snprintf_hex_uppercase - Print data as a upper case hex string into buf
224  * @buf: Memory area to use as the output buffer
225  * @buf_size: Maximum buffer size in bytes (should be at least 2 * len + 1)
226  * @data: Data to be printed
227  * @len: Length of data in bytes
228  * Returns: Number of bytes written
229  */
wpa_snprintf_hex_uppercase(char * buf,size_t buf_size,const u8 * data,size_t len)230 int wpa_snprintf_hex_uppercase(char *buf, size_t buf_size, const u8 *data,
231 			       size_t len)
232 {
233 	return _wpa_snprintf_hex(buf, buf_size, data, len, 1);
234 }
235 
236 
237 #ifdef CONFIG_ANSI_C_EXTRA
238 
239 #ifdef _WIN32_WCE
perror(const char * s)240 void perror(const char *s)
241 {
242 	wpa_printf(MSG_ERROR, "%s: GetLastError: %d",
243 		   s, (int) GetLastError());
244 }
245 #endif /* _WIN32_WCE */
246 
247 
248 int optind = 1;
249 int optopt;
250 char *optarg;
251 
getopt(int argc,char * const argv[],const char * optstring)252 int getopt(int argc, char *const argv[], const char *optstring)
253 {
254 	static int optchr = 1;
255 	char *cp;
256 
257 	if (optchr == 1) {
258 		if (optind >= argc) {
259 			/* all arguments processed */
260 			return EOF;
261 		}
262 
263 		if (argv[optind][0] != '-' || argv[optind][1] == '\0') {
264 			/* no option characters */
265 			return EOF;
266 		}
267 	}
268 
269 	if (os_strcmp(argv[optind], "--") == 0) {
270 		/* no more options */
271 		optind++;
272 		return EOF;
273 	}
274 
275 	optopt = argv[optind][optchr];
276 	cp = os_strchr(optstring, optopt);
277 	if (cp == NULL || optopt == ':') {
278 		if (argv[optind][++optchr] == '\0') {
279 			optchr = 1;
280 			optind++;
281 		}
282 		return '?';
283 	}
284 
285 	if (cp[1] == ':') {
286 		/* Argument required */
287 		optchr = 1;
288 		if (argv[optind][optchr + 1]) {
289 			/* No space between option and argument */
290 			optarg = &argv[optind++][optchr + 1];
291 		} else if (++optind >= argc) {
292 			/* option requires an argument */
293 			return '?';
294 		} else {
295 			/* Argument in the next argv */
296 			optarg = argv[optind++];
297 		}
298 	} else {
299 		/* No argument */
300 		if (argv[optind][++optchr] == '\0') {
301 			optchr = 1;
302 			optind++;
303 		}
304 		optarg = NULL;
305 	}
306 	return *cp;
307 }
308 #endif /* CONFIG_ANSI_C_EXTRA */
309 
310 
311 #ifdef CONFIG_NATIVE_WINDOWS
312 /**
313  * wpa_unicode2ascii_inplace - Convert unicode string into ASCII
314  * @str: Pointer to string to convert
315  *
316  * This function converts a unicode string to ASCII using the same
317  * buffer for output. If UNICODE is not set, the buffer is not
318  * modified.
319  */
wpa_unicode2ascii_inplace(TCHAR * str)320 void wpa_unicode2ascii_inplace(TCHAR *str)
321 {
322 #ifdef UNICODE
323 	char *dst = (char *) str;
324 	while (*str)
325 		*dst++ = (char) *str++;
326 	*dst = '\0';
327 #endif /* UNICODE */
328 }
329 
330 
wpa_strdup_tchar(const char * str)331 TCHAR * wpa_strdup_tchar(const char *str)
332 {
333 #ifdef UNICODE
334 	TCHAR *buf;
335 	buf = os_malloc((strlen(str) + 1) * sizeof(TCHAR));
336 	if (buf == NULL)
337 		return NULL;
338 	wsprintf(buf, L"%S", str);
339 	return buf;
340 #else /* UNICODE */
341 	return os_strdup(str);
342 #endif /* UNICODE */
343 }
344 #endif /* CONFIG_NATIVE_WINDOWS */
345 
346 
printf_encode(char * txt,size_t maxlen,const u8 * data,size_t len)347 void printf_encode(char *txt, size_t maxlen, const u8 *data, size_t len)
348 {
349 	char *end = txt + maxlen;
350 	size_t i;
351 
352 	for (i = 0; i < len; i++) {
353 		if (txt + 4 >= end)
354 			break;
355 
356 		switch (data[i]) {
357 		case '\"':
358 			*txt++ = '\\';
359 			*txt++ = '\"';
360 			break;
361 		case '\\':
362 			*txt++ = '\\';
363 			*txt++ = '\\';
364 			break;
365 		case '\033':
366 			*txt++ = '\\';
367 			*txt++ = 'e';
368 			break;
369 		case '\n':
370 			*txt++ = '\\';
371 			*txt++ = 'n';
372 			break;
373 		case '\r':
374 			*txt++ = '\\';
375 			*txt++ = 'r';
376 			break;
377 		case '\t':
378 			*txt++ = '\\';
379 			*txt++ = 't';
380 			break;
381 		default:
382 			if (data[i] >= 32 && data[i] <= 127) {
383 				*txt++ = data[i];
384 			} else {
385 				txt += os_snprintf(txt, end - txt, "\\x%02x",
386 						   data[i]);
387 			}
388 			break;
389 		}
390 	}
391 
392 	*txt = '\0';
393 }
394 
395 
printf_decode(u8 * buf,size_t maxlen,const char * str)396 size_t printf_decode(u8 *buf, size_t maxlen, const char *str)
397 {
398 	const char *pos = str;
399 	size_t len = 0;
400 	int val;
401 
402 	while (*pos) {
403 		if (len + 1 >= maxlen)
404 			break;
405 		switch (*pos) {
406 		case '\\':
407 			pos++;
408 			switch (*pos) {
409 			case '\\':
410 				buf[len++] = '\\';
411 				pos++;
412 				break;
413 			case '"':
414 				buf[len++] = '"';
415 				pos++;
416 				break;
417 			case 'n':
418 				buf[len++] = '\n';
419 				pos++;
420 				break;
421 			case 'r':
422 				buf[len++] = '\r';
423 				pos++;
424 				break;
425 			case 't':
426 				buf[len++] = '\t';
427 				pos++;
428 				break;
429 			case 'e':
430 				buf[len++] = '\033';
431 				pos++;
432 				break;
433 			case 'x':
434 				pos++;
435 				val = hex2byte(pos);
436 				if (val < 0) {
437 					val = hex2num(*pos);
438 					if (val < 0)
439 						break;
440 					buf[len++] = val;
441 					pos++;
442 				} else {
443 					buf[len++] = val;
444 					pos += 2;
445 				}
446 				break;
447 			case '0':
448 			case '1':
449 			case '2':
450 			case '3':
451 			case '4':
452 			case '5':
453 			case '6':
454 			case '7':
455 				val = *pos++ - '0';
456 				if (*pos >= '0' && *pos <= '7')
457 					val = val * 8 + (*pos++ - '0');
458 				if (*pos >= '0' && *pos <= '7')
459 					val = val * 8 + (*pos++ - '0');
460 				buf[len++] = val;
461 				break;
462 			default:
463 				break;
464 			}
465 			break;
466 		default:
467 			buf[len++] = *pos++;
468 			break;
469 		}
470 	}
471 	if (maxlen > len)
472 		buf[len] = '\0';
473 
474 	return len;
475 }
476 
477 
478 /**
479  * wpa_ssid_txt - Convert SSID to a printable string
480  * @ssid: SSID (32-octet string)
481  * @ssid_len: Length of ssid in octets
482  * Returns: Pointer to a printable string
483  *
484  * This function can be used to convert SSIDs into printable form. In most
485  * cases, SSIDs do not use unprintable characters, but IEEE 802.11 standard
486  * does not limit the used character set, so anything could be used in an SSID.
487  *
488  * This function uses a static buffer, so only one call can be used at the
489  * time, i.e., this is not re-entrant and the returned buffer must be used
490  * before calling this again.
491  */
wpa_ssid_txt(const u8 * ssid,size_t ssid_len)492 const char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len)
493 {
494 	static char ssid_txt[32 * 4 + 1];
495 
496 	if (ssid == NULL) {
497 		ssid_txt[0] = '\0';
498 		return ssid_txt;
499 	}
500 
501 	printf_encode(ssid_txt, sizeof(ssid_txt), ssid, ssid_len);
502 	return ssid_txt;
503 }
504 
505 
__hide_aliasing_typecast(void * foo)506 void * __hide_aliasing_typecast(void *foo)
507 {
508 	return foo;
509 }
510 
511 
wpa_config_parse_string(const char * value,size_t * len)512 char * wpa_config_parse_string(const char *value, size_t *len)
513 {
514 	if (*value == '"') {
515 		const char *pos;
516 		char *str;
517 		value++;
518 		pos = os_strrchr(value, '"');
519 		if (pos == NULL || pos[1] != '\0')
520 			return NULL;
521 		*len = pos - value;
522 		str = dup_binstr(value, *len);
523 		if (str == NULL)
524 			return NULL;
525 		return str;
526 	} else if (*value == 'P' && value[1] == '"') {
527 		const char *pos;
528 		char *tstr, *str;
529 		size_t tlen;
530 		value += 2;
531 		pos = os_strrchr(value, '"');
532 		if (pos == NULL || pos[1] != '\0')
533 			return NULL;
534 		tlen = pos - value;
535 		tstr = dup_binstr(value, tlen);
536 		if (tstr == NULL)
537 			return NULL;
538 
539 		str = os_malloc(tlen + 1);
540 		if (str == NULL) {
541 			os_free(tstr);
542 			return NULL;
543 		}
544 
545 		*len = printf_decode((u8 *) str, tlen + 1, tstr);
546 		os_free(tstr);
547 
548 		return str;
549 	} else {
550 		u8 *str;
551 		size_t tlen, hlen = os_strlen(value);
552 		if (hlen & 1)
553 			return NULL;
554 		tlen = hlen / 2;
555 		str = os_malloc(tlen + 1);
556 		if (str == NULL)
557 			return NULL;
558 		if (hexstr2bin(value, str, tlen)) {
559 			os_free(str);
560 			return NULL;
561 		}
562 		str[tlen] = '\0';
563 		*len = tlen;
564 		return (char *) str;
565 	}
566 }
567 
568 
is_hex(const u8 * data,size_t len)569 int is_hex(const u8 *data, size_t len)
570 {
571 	size_t i;
572 
573 	for (i = 0; i < len; i++) {
574 		if (data[i] < 32 || data[i] >= 127)
575 			return 1;
576 	}
577 	return 0;
578 }
579 
580 
find_first_bit(u32 value)581 int find_first_bit(u32 value)
582 {
583 	int pos = 0;
584 
585 	while (value) {
586 		if (value & 0x1)
587 			return pos;
588 		value >>= 1;
589 		pos++;
590 	}
591 
592 	return -1;
593 }
594 
595 
merge_byte_arrays(u8 * res,size_t res_len,const u8 * src1,size_t src1_len,const u8 * src2,size_t src2_len)596 size_t merge_byte_arrays(u8 *res, size_t res_len,
597 			 const u8 *src1, size_t src1_len,
598 			 const u8 *src2, size_t src2_len)
599 {
600 	size_t len = 0;
601 
602 	os_memset(res, 0, res_len);
603 
604 	if (src1) {
605 		if (src1_len >= res_len) {
606 			os_memcpy(res, src1, res_len);
607 			return res_len;
608 		}
609 
610 		os_memcpy(res, src1, src1_len);
611 		len += src1_len;
612 	}
613 
614 	if (src2) {
615 		if (len + src2_len >= res_len) {
616 			os_memcpy(res + len, src2, res_len - len);
617 			return res_len;
618 		}
619 
620 		os_memcpy(res + len, src2, src2_len);
621 		len += src2_len;
622 	}
623 
624 	return len;
625 }
626 
627 
dup_binstr(const void * src,size_t len)628 char * dup_binstr(const void *src, size_t len)
629 {
630 	char *res;
631 
632 	if (src == NULL)
633 		return NULL;
634 	res = os_malloc(len + 1);
635 	if (res == NULL)
636 		return NULL;
637 	os_memcpy(res, src, len);
638 	res[len] = '\0';
639 
640 	return res;
641 }
642 
643 
freq_range_list_parse(struct wpa_freq_range_list * res,const char * value)644 int freq_range_list_parse(struct wpa_freq_range_list *res, const char *value)
645 {
646 	struct wpa_freq_range *freq = NULL, *n;
647 	unsigned int count = 0;
648 	const char *pos, *pos2, *pos3;
649 
650 	/*
651 	 * Comma separated list of frequency ranges.
652 	 * For example: 2412-2432,2462,5000-6000
653 	 */
654 	pos = value;
655 	while (pos && pos[0]) {
656 		n = os_realloc_array(freq, count + 1,
657 				     sizeof(struct wpa_freq_range));
658 		if (n == NULL) {
659 			os_free(freq);
660 			return -1;
661 		}
662 		freq = n;
663 		freq[count].min = atoi(pos);
664 		pos2 = os_strchr(pos, '-');
665 		pos3 = os_strchr(pos, ',');
666 		if (pos2 && (!pos3 || pos2 < pos3)) {
667 			pos2++;
668 			freq[count].max = atoi(pos2);
669 		} else
670 			freq[count].max = freq[count].min;
671 		pos = pos3;
672 		if (pos)
673 			pos++;
674 		count++;
675 	}
676 
677 	os_free(res->range);
678 	res->range = freq;
679 	res->num = count;
680 
681 	return 0;
682 }
683 
684 
freq_range_list_includes(const struct wpa_freq_range_list * list,unsigned int freq)685 int freq_range_list_includes(const struct wpa_freq_range_list *list,
686 			     unsigned int freq)
687 {
688 	unsigned int i;
689 
690 	if (list == NULL)
691 		return 0;
692 
693 	for (i = 0; i < list->num; i++) {
694 		if (freq >= list->range[i].min && freq <= list->range[i].max)
695 			return 1;
696 	}
697 
698 	return 0;
699 }
700 
701 
freq_range_list_str(const struct wpa_freq_range_list * list)702 char * freq_range_list_str(const struct wpa_freq_range_list *list)
703 {
704 	char *buf, *pos, *end;
705 	size_t maxlen;
706 	unsigned int i;
707 	int res;
708 
709 	if (list->num == 0)
710 		return NULL;
711 
712 	maxlen = list->num * 30;
713 	buf = os_malloc(maxlen);
714 	if (buf == NULL)
715 		return NULL;
716 	pos = buf;
717 	end = buf + maxlen;
718 
719 	for (i = 0; i < list->num; i++) {
720 		struct wpa_freq_range *range = &list->range[i];
721 
722 		if (range->min == range->max)
723 			res = os_snprintf(pos, end - pos, "%s%u",
724 					  i == 0 ? "" : ",", range->min);
725 		else
726 			res = os_snprintf(pos, end - pos, "%s%u-%u",
727 					  i == 0 ? "" : ",",
728 					  range->min, range->max);
729 		if (res < 0 || res > end - pos) {
730 			os_free(buf);
731 			return NULL;
732 		}
733 		pos += res;
734 	}
735 
736 	return buf;
737 }
738 
739 
int_array_len(const int * a)740 int int_array_len(const int *a)
741 {
742 	int i;
743 	for (i = 0; a && a[i]; i++)
744 		;
745 	return i;
746 }
747 
748 
int_array_concat(int ** res,const int * a)749 void int_array_concat(int **res, const int *a)
750 {
751 	int reslen, alen, i;
752 	int *n;
753 
754 	reslen = int_array_len(*res);
755 	alen = int_array_len(a);
756 
757 	n = os_realloc_array(*res, reslen + alen + 1, sizeof(int));
758 	if (n == NULL) {
759 		os_free(*res);
760 		*res = NULL;
761 		return;
762 	}
763 	for (i = 0; i <= alen; i++)
764 		n[reslen + i] = a[i];
765 	*res = n;
766 }
767 
768 
freq_cmp(const void * a,const void * b)769 static int freq_cmp(const void *a, const void *b)
770 {
771 	int _a = *(int *) a;
772 	int _b = *(int *) b;
773 
774 	if (_a == 0)
775 		return 1;
776 	if (_b == 0)
777 		return -1;
778 	return _a - _b;
779 }
780 
781 
int_array_sort_unique(int * a)782 void int_array_sort_unique(int *a)
783 {
784 	int alen;
785 	int i, j;
786 
787 	if (a == NULL)
788 		return;
789 
790 	alen = int_array_len(a);
791 	qsort(a, alen, sizeof(int), freq_cmp);
792 
793 	i = 0;
794 	j = 1;
795 	while (a[i] && a[j]) {
796 		if (a[i] == a[j]) {
797 			j++;
798 			continue;
799 		}
800 		a[++i] = a[j++];
801 	}
802 	if (a[i])
803 		i++;
804 	a[i] = 0;
805 }
806 
807 
int_array_add_unique(int ** res,int a)808 void int_array_add_unique(int **res, int a)
809 {
810 	int reslen;
811 	int *n;
812 
813 	for (reslen = 0; *res && (*res)[reslen]; reslen++) {
814 		if ((*res)[reslen] == a)
815 			return; /* already in the list */
816 	}
817 
818 	n = os_realloc_array(*res, reslen + 2, sizeof(int));
819 	if (n == NULL) {
820 		os_free(*res);
821 		*res = NULL;
822 		return;
823 	}
824 
825 	n[reslen] = a;
826 	n[reslen + 1] = 0;
827 
828 	*res = n;
829 }
830 
831 
str_clear_free(char * str)832 void str_clear_free(char *str)
833 {
834 	if (str) {
835 		size_t len = os_strlen(str);
836 		os_memset(str, 0, len);
837 		os_free(str);
838 	}
839 }
840 
841 
bin_clear_free(void * bin,size_t len)842 void bin_clear_free(void *bin, size_t len)
843 {
844 	if (bin) {
845 		os_memset(bin, 0, len);
846 		os_free(bin);
847 	}
848 }
849 
850 
random_mac_addr(u8 * addr)851 int random_mac_addr(u8 *addr)
852 {
853 	if (os_get_random(addr, ETH_ALEN) < 0)
854 		return -1;
855 	addr[0] &= 0xfe; /* unicast */
856 	addr[0] |= 0x02; /* locally administered */
857 	return 0;
858 }
859 
860 
random_mac_addr_keep_oui(u8 * addr)861 int random_mac_addr_keep_oui(u8 *addr)
862 {
863 	if (os_get_random(addr + 3, 3) < 0)
864 		return -1;
865 	addr[0] &= 0xfe; /* unicast */
866 	addr[0] |= 0x02; /* locally administered */
867 	return 0;
868 }
869