xref: /freebsd/contrib/wpa/src/utils/os_unix.c (revision e28a4053b110e06768631ac8401ed4a3c05e68a5)
139beb93cSSam Leffler /*
2*e28a4053SRui Paulo  * OS specific functions for UNIX/POSIX systems
3*e28a4053SRui Paulo  * Copyright (c) 2005-2009, Jouni Malinen <j@w1.fi>
439beb93cSSam Leffler  *
539beb93cSSam Leffler  * This program is free software; you can redistribute it and/or modify
639beb93cSSam Leffler  * it under the terms of the GNU General Public License version 2 as
739beb93cSSam Leffler  * published by the Free Software Foundation.
839beb93cSSam Leffler  *
939beb93cSSam Leffler  * Alternatively, this software may be distributed under the terms of BSD
1039beb93cSSam Leffler  * license.
1139beb93cSSam Leffler  *
1239beb93cSSam Leffler  * See README and COPYING for more details.
1339beb93cSSam Leffler  */
1439beb93cSSam Leffler 
1539beb93cSSam Leffler #include "includes.h"
1639beb93cSSam Leffler 
1739beb93cSSam Leffler #include "os.h"
1839beb93cSSam Leffler 
19*e28a4053SRui Paulo #ifdef WPA_TRACE
20*e28a4053SRui Paulo 
21*e28a4053SRui Paulo #include "common.h"
22*e28a4053SRui Paulo #include "list.h"
23*e28a4053SRui Paulo #include "wpa_debug.h"
24*e28a4053SRui Paulo #include "trace.h"
25*e28a4053SRui Paulo 
26*e28a4053SRui Paulo static struct dl_list alloc_list;
27*e28a4053SRui Paulo 
28*e28a4053SRui Paulo #define ALLOC_MAGIC 0xa84ef1b2
29*e28a4053SRui Paulo #define FREED_MAGIC 0x67fd487a
30*e28a4053SRui Paulo 
31*e28a4053SRui Paulo struct os_alloc_trace {
32*e28a4053SRui Paulo 	unsigned int magic;
33*e28a4053SRui Paulo 	struct dl_list list;
34*e28a4053SRui Paulo 	size_t len;
35*e28a4053SRui Paulo 	WPA_TRACE_INFO
36*e28a4053SRui Paulo };
37*e28a4053SRui Paulo 
38*e28a4053SRui Paulo #endif /* WPA_TRACE */
39*e28a4053SRui Paulo 
40*e28a4053SRui Paulo 
4139beb93cSSam Leffler void os_sleep(os_time_t sec, os_time_t usec)
4239beb93cSSam Leffler {
4339beb93cSSam Leffler 	if (sec)
4439beb93cSSam Leffler 		sleep(sec);
4539beb93cSSam Leffler 	if (usec)
4639beb93cSSam Leffler 		usleep(usec);
4739beb93cSSam Leffler }
4839beb93cSSam Leffler 
4939beb93cSSam Leffler 
5039beb93cSSam Leffler int os_get_time(struct os_time *t)
5139beb93cSSam Leffler {
5239beb93cSSam Leffler 	int res;
5339beb93cSSam Leffler 	struct timeval tv;
5439beb93cSSam Leffler 	res = gettimeofday(&tv, NULL);
5539beb93cSSam Leffler 	t->sec = tv.tv_sec;
5639beb93cSSam Leffler 	t->usec = tv.tv_usec;
5739beb93cSSam Leffler 	return res;
5839beb93cSSam Leffler }
5939beb93cSSam Leffler 
6039beb93cSSam Leffler 
6139beb93cSSam Leffler int os_mktime(int year, int month, int day, int hour, int min, int sec,
6239beb93cSSam Leffler 	      os_time_t *t)
6339beb93cSSam Leffler {
6439beb93cSSam Leffler 	struct tm tm, *tm1;
6539beb93cSSam Leffler 	time_t t_local, t1, t2;
6639beb93cSSam Leffler 	os_time_t tz_offset;
6739beb93cSSam Leffler 
6839beb93cSSam Leffler 	if (year < 1970 || month < 1 || month > 12 || day < 1 || day > 31 ||
6939beb93cSSam Leffler 	    hour < 0 || hour > 23 || min < 0 || min > 59 || sec < 0 ||
7039beb93cSSam Leffler 	    sec > 60)
7139beb93cSSam Leffler 		return -1;
7239beb93cSSam Leffler 
7339beb93cSSam Leffler 	memset(&tm, 0, sizeof(tm));
7439beb93cSSam Leffler 	tm.tm_year = year - 1900;
7539beb93cSSam Leffler 	tm.tm_mon = month - 1;
7639beb93cSSam Leffler 	tm.tm_mday = day;
7739beb93cSSam Leffler 	tm.tm_hour = hour;
7839beb93cSSam Leffler 	tm.tm_min = min;
7939beb93cSSam Leffler 	tm.tm_sec = sec;
8039beb93cSSam Leffler 
8139beb93cSSam Leffler 	t_local = mktime(&tm);
8239beb93cSSam Leffler 
8339beb93cSSam Leffler 	/* figure out offset to UTC */
8439beb93cSSam Leffler 	tm1 = localtime(&t_local);
8539beb93cSSam Leffler 	if (tm1) {
8639beb93cSSam Leffler 		t1 = mktime(tm1);
8739beb93cSSam Leffler 		tm1 = gmtime(&t_local);
8839beb93cSSam Leffler 		if (tm1) {
8939beb93cSSam Leffler 			t2 = mktime(tm1);
9039beb93cSSam Leffler 			tz_offset = t2 - t1;
9139beb93cSSam Leffler 		} else
9239beb93cSSam Leffler 			tz_offset = 0;
9339beb93cSSam Leffler 	} else
9439beb93cSSam Leffler 		tz_offset = 0;
9539beb93cSSam Leffler 
9639beb93cSSam Leffler 	*t = (os_time_t) t_local - tz_offset;
9739beb93cSSam Leffler 	return 0;
9839beb93cSSam Leffler }
9939beb93cSSam Leffler 
10039beb93cSSam Leffler 
10139beb93cSSam Leffler #ifdef __APPLE__
10239beb93cSSam Leffler #include <fcntl.h>
10339beb93cSSam Leffler static int os_daemon(int nochdir, int noclose)
10439beb93cSSam Leffler {
10539beb93cSSam Leffler 	int devnull;
10639beb93cSSam Leffler 
10739beb93cSSam Leffler 	if (chdir("/") < 0)
10839beb93cSSam Leffler 		return -1;
10939beb93cSSam Leffler 
11039beb93cSSam Leffler 	devnull = open("/dev/null", O_RDWR);
11139beb93cSSam Leffler 	if (devnull < 0)
11239beb93cSSam Leffler 		return -1;
11339beb93cSSam Leffler 
11439beb93cSSam Leffler 	if (dup2(devnull, STDIN_FILENO) < 0) {
11539beb93cSSam Leffler 		close(devnull);
11639beb93cSSam Leffler 		return -1;
11739beb93cSSam Leffler 	}
11839beb93cSSam Leffler 
11939beb93cSSam Leffler 	if (dup2(devnull, STDOUT_FILENO) < 0) {
12039beb93cSSam Leffler 		close(devnull);
12139beb93cSSam Leffler 		return -1;
12239beb93cSSam Leffler 	}
12339beb93cSSam Leffler 
12439beb93cSSam Leffler 	if (dup2(devnull, STDERR_FILENO) < 0) {
12539beb93cSSam Leffler 		close(devnull);
12639beb93cSSam Leffler 		return -1;
12739beb93cSSam Leffler 	}
12839beb93cSSam Leffler 
12939beb93cSSam Leffler 	return 0;
13039beb93cSSam Leffler }
13139beb93cSSam Leffler #else /* __APPLE__ */
13239beb93cSSam Leffler #define os_daemon daemon
13339beb93cSSam Leffler #endif /* __APPLE__ */
13439beb93cSSam Leffler 
13539beb93cSSam Leffler 
13639beb93cSSam Leffler int os_daemonize(const char *pid_file)
13739beb93cSSam Leffler {
13839beb93cSSam Leffler #ifdef __uClinux__
13939beb93cSSam Leffler 	return -1;
14039beb93cSSam Leffler #else /* __uClinux__ */
14139beb93cSSam Leffler 	if (os_daemon(0, 0)) {
14239beb93cSSam Leffler 		perror("daemon");
14339beb93cSSam Leffler 		return -1;
14439beb93cSSam Leffler 	}
14539beb93cSSam Leffler 
14639beb93cSSam Leffler 	if (pid_file) {
14739beb93cSSam Leffler 		FILE *f = fopen(pid_file, "w");
14839beb93cSSam Leffler 		if (f) {
14939beb93cSSam Leffler 			fprintf(f, "%u\n", getpid());
15039beb93cSSam Leffler 			fclose(f);
15139beb93cSSam Leffler 		}
15239beb93cSSam Leffler 	}
15339beb93cSSam Leffler 
15439beb93cSSam Leffler 	return -0;
15539beb93cSSam Leffler #endif /* __uClinux__ */
15639beb93cSSam Leffler }
15739beb93cSSam Leffler 
15839beb93cSSam Leffler 
15939beb93cSSam Leffler void os_daemonize_terminate(const char *pid_file)
16039beb93cSSam Leffler {
16139beb93cSSam Leffler 	if (pid_file)
16239beb93cSSam Leffler 		unlink(pid_file);
16339beb93cSSam Leffler }
16439beb93cSSam Leffler 
16539beb93cSSam Leffler 
16639beb93cSSam Leffler int os_get_random(unsigned char *buf, size_t len)
16739beb93cSSam Leffler {
16839beb93cSSam Leffler 	FILE *f;
16939beb93cSSam Leffler 	size_t rc;
17039beb93cSSam Leffler 
17139beb93cSSam Leffler 	f = fopen("/dev/urandom", "rb");
17239beb93cSSam Leffler 	if (f == NULL) {
17339beb93cSSam Leffler 		printf("Could not open /dev/urandom.\n");
17439beb93cSSam Leffler 		return -1;
17539beb93cSSam Leffler 	}
17639beb93cSSam Leffler 
17739beb93cSSam Leffler 	rc = fread(buf, 1, len, f);
17839beb93cSSam Leffler 	fclose(f);
17939beb93cSSam Leffler 
18039beb93cSSam Leffler 	return rc != len ? -1 : 0;
18139beb93cSSam Leffler }
18239beb93cSSam Leffler 
18339beb93cSSam Leffler 
18439beb93cSSam Leffler unsigned long os_random(void)
18539beb93cSSam Leffler {
18639beb93cSSam Leffler 	return random();
18739beb93cSSam Leffler }
18839beb93cSSam Leffler 
18939beb93cSSam Leffler 
19039beb93cSSam Leffler char * os_rel2abs_path(const char *rel_path)
19139beb93cSSam Leffler {
19239beb93cSSam Leffler 	char *buf = NULL, *cwd, *ret;
19339beb93cSSam Leffler 	size_t len = 128, cwd_len, rel_len, ret_len;
19439beb93cSSam Leffler 	int last_errno;
19539beb93cSSam Leffler 
19639beb93cSSam Leffler 	if (rel_path[0] == '/')
197*e28a4053SRui Paulo 		return os_strdup(rel_path);
19839beb93cSSam Leffler 
19939beb93cSSam Leffler 	for (;;) {
200*e28a4053SRui Paulo 		buf = os_malloc(len);
20139beb93cSSam Leffler 		if (buf == NULL)
20239beb93cSSam Leffler 			return NULL;
20339beb93cSSam Leffler 		cwd = getcwd(buf, len);
20439beb93cSSam Leffler 		if (cwd == NULL) {
20539beb93cSSam Leffler 			last_errno = errno;
206*e28a4053SRui Paulo 			os_free(buf);
20739beb93cSSam Leffler 			if (last_errno != ERANGE)
20839beb93cSSam Leffler 				return NULL;
20939beb93cSSam Leffler 			len *= 2;
21039beb93cSSam Leffler 			if (len > 2000)
21139beb93cSSam Leffler 				return NULL;
21239beb93cSSam Leffler 		} else {
21339beb93cSSam Leffler 			buf[len - 1] = '\0';
21439beb93cSSam Leffler 			break;
21539beb93cSSam Leffler 		}
21639beb93cSSam Leffler 	}
21739beb93cSSam Leffler 
218*e28a4053SRui Paulo 	cwd_len = os_strlen(cwd);
219*e28a4053SRui Paulo 	rel_len = os_strlen(rel_path);
22039beb93cSSam Leffler 	ret_len = cwd_len + 1 + rel_len + 1;
221*e28a4053SRui Paulo 	ret = os_malloc(ret_len);
22239beb93cSSam Leffler 	if (ret) {
223*e28a4053SRui Paulo 		os_memcpy(ret, cwd, cwd_len);
22439beb93cSSam Leffler 		ret[cwd_len] = '/';
225*e28a4053SRui Paulo 		os_memcpy(ret + cwd_len + 1, rel_path, rel_len);
22639beb93cSSam Leffler 		ret[ret_len - 1] = '\0';
22739beb93cSSam Leffler 	}
228*e28a4053SRui Paulo 	os_free(buf);
22939beb93cSSam Leffler 	return ret;
23039beb93cSSam Leffler }
23139beb93cSSam Leffler 
23239beb93cSSam Leffler 
23339beb93cSSam Leffler int os_program_init(void)
23439beb93cSSam Leffler {
235*e28a4053SRui Paulo #ifdef WPA_TRACE
236*e28a4053SRui Paulo 	dl_list_init(&alloc_list);
237*e28a4053SRui Paulo #endif /* WPA_TRACE */
23839beb93cSSam Leffler 	return 0;
23939beb93cSSam Leffler }
24039beb93cSSam Leffler 
24139beb93cSSam Leffler 
24239beb93cSSam Leffler void os_program_deinit(void)
24339beb93cSSam Leffler {
244*e28a4053SRui Paulo #ifdef WPA_TRACE
245*e28a4053SRui Paulo 	struct os_alloc_trace *a;
246*e28a4053SRui Paulo 	unsigned long total = 0;
247*e28a4053SRui Paulo 	dl_list_for_each(a, &alloc_list, struct os_alloc_trace, list) {
248*e28a4053SRui Paulo 		total += a->len;
249*e28a4053SRui Paulo 		if (a->magic != ALLOC_MAGIC) {
250*e28a4053SRui Paulo 			wpa_printf(MSG_INFO, "MEMLEAK[%p]: invalid magic 0x%x "
251*e28a4053SRui Paulo 				   "len %lu",
252*e28a4053SRui Paulo 				   a, a->magic, (unsigned long) a->len);
253*e28a4053SRui Paulo 			continue;
254*e28a4053SRui Paulo 		}
255*e28a4053SRui Paulo 		wpa_printf(MSG_INFO, "MEMLEAK[%p]: len %lu",
256*e28a4053SRui Paulo 			   a, (unsigned long) a->len);
257*e28a4053SRui Paulo 		wpa_trace_dump("memleak", a);
258*e28a4053SRui Paulo 	}
259*e28a4053SRui Paulo 	if (total)
260*e28a4053SRui Paulo 		wpa_printf(MSG_INFO, "MEMLEAK: total %lu bytes",
261*e28a4053SRui Paulo 			   (unsigned long) total);
262*e28a4053SRui Paulo #endif /* WPA_TRACE */
26339beb93cSSam Leffler }
26439beb93cSSam Leffler 
26539beb93cSSam Leffler 
26639beb93cSSam Leffler int os_setenv(const char *name, const char *value, int overwrite)
26739beb93cSSam Leffler {
26839beb93cSSam Leffler 	return setenv(name, value, overwrite);
26939beb93cSSam Leffler }
27039beb93cSSam Leffler 
27139beb93cSSam Leffler 
27239beb93cSSam Leffler int os_unsetenv(const char *name)
27339beb93cSSam Leffler {
2743157ba21SRui Paulo #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__) || \
2753157ba21SRui Paulo     defined(__OpenBSD__)
27639beb93cSSam Leffler 	unsetenv(name);
27739beb93cSSam Leffler 	return 0;
27839beb93cSSam Leffler #else
27939beb93cSSam Leffler 	return unsetenv(name);
28039beb93cSSam Leffler #endif
28139beb93cSSam Leffler }
28239beb93cSSam Leffler 
28339beb93cSSam Leffler 
28439beb93cSSam Leffler char * os_readfile(const char *name, size_t *len)
28539beb93cSSam Leffler {
28639beb93cSSam Leffler 	FILE *f;
28739beb93cSSam Leffler 	char *buf;
28839beb93cSSam Leffler 
28939beb93cSSam Leffler 	f = fopen(name, "rb");
29039beb93cSSam Leffler 	if (f == NULL)
29139beb93cSSam Leffler 		return NULL;
29239beb93cSSam Leffler 
29339beb93cSSam Leffler 	fseek(f, 0, SEEK_END);
29439beb93cSSam Leffler 	*len = ftell(f);
29539beb93cSSam Leffler 	fseek(f, 0, SEEK_SET);
29639beb93cSSam Leffler 
297*e28a4053SRui Paulo 	buf = os_malloc(*len);
29839beb93cSSam Leffler 	if (buf == NULL) {
29939beb93cSSam Leffler 		fclose(f);
30039beb93cSSam Leffler 		return NULL;
30139beb93cSSam Leffler 	}
30239beb93cSSam Leffler 
30339beb93cSSam Leffler 	if (fread(buf, 1, *len, f) != *len) {
30439beb93cSSam Leffler 		fclose(f);
305*e28a4053SRui Paulo 		os_free(buf);
30639beb93cSSam Leffler 		return NULL;
30739beb93cSSam Leffler 	}
30839beb93cSSam Leffler 
30939beb93cSSam Leffler 	fclose(f);
31039beb93cSSam Leffler 
31139beb93cSSam Leffler 	return buf;
31239beb93cSSam Leffler }
31339beb93cSSam Leffler 
31439beb93cSSam Leffler 
315*e28a4053SRui Paulo #ifndef WPA_TRACE
31639beb93cSSam Leffler void * os_zalloc(size_t size)
31739beb93cSSam Leffler {
31839beb93cSSam Leffler 	return calloc(1, size);
31939beb93cSSam Leffler }
320*e28a4053SRui Paulo #endif /* WPA_TRACE */
32139beb93cSSam Leffler 
32239beb93cSSam Leffler 
32339beb93cSSam Leffler size_t os_strlcpy(char *dest, const char *src, size_t siz)
32439beb93cSSam Leffler {
32539beb93cSSam Leffler 	const char *s = src;
32639beb93cSSam Leffler 	size_t left = siz;
32739beb93cSSam Leffler 
32839beb93cSSam Leffler 	if (left) {
32939beb93cSSam Leffler 		/* Copy string up to the maximum size of the dest buffer */
33039beb93cSSam Leffler 		while (--left != 0) {
33139beb93cSSam Leffler 			if ((*dest++ = *s++) == '\0')
33239beb93cSSam Leffler 				break;
33339beb93cSSam Leffler 		}
33439beb93cSSam Leffler 	}
33539beb93cSSam Leffler 
33639beb93cSSam Leffler 	if (left == 0) {
33739beb93cSSam Leffler 		/* Not enough room for the string; force NUL-termination */
33839beb93cSSam Leffler 		if (siz != 0)
33939beb93cSSam Leffler 			*dest = '\0';
34039beb93cSSam Leffler 		while (*s++)
34139beb93cSSam Leffler 			; /* determine total src string length */
34239beb93cSSam Leffler 	}
34339beb93cSSam Leffler 
34439beb93cSSam Leffler 	return s - src - 1;
34539beb93cSSam Leffler }
346*e28a4053SRui Paulo 
347*e28a4053SRui Paulo 
348*e28a4053SRui Paulo #ifdef WPA_TRACE
349*e28a4053SRui Paulo 
350*e28a4053SRui Paulo void * os_malloc(size_t size)
351*e28a4053SRui Paulo {
352*e28a4053SRui Paulo 	struct os_alloc_trace *a;
353*e28a4053SRui Paulo 	a = malloc(sizeof(*a) + size);
354*e28a4053SRui Paulo 	if (a == NULL)
355*e28a4053SRui Paulo 		return NULL;
356*e28a4053SRui Paulo 	a->magic = ALLOC_MAGIC;
357*e28a4053SRui Paulo 	dl_list_add(&alloc_list, &a->list);
358*e28a4053SRui Paulo 	a->len = size;
359*e28a4053SRui Paulo 	wpa_trace_record(a);
360*e28a4053SRui Paulo 	return a + 1;
361*e28a4053SRui Paulo }
362*e28a4053SRui Paulo 
363*e28a4053SRui Paulo 
364*e28a4053SRui Paulo void * os_realloc(void *ptr, size_t size)
365*e28a4053SRui Paulo {
366*e28a4053SRui Paulo 	struct os_alloc_trace *a;
367*e28a4053SRui Paulo 	size_t copy_len;
368*e28a4053SRui Paulo 	void *n;
369*e28a4053SRui Paulo 
370*e28a4053SRui Paulo 	if (ptr == NULL)
371*e28a4053SRui Paulo 		return os_malloc(size);
372*e28a4053SRui Paulo 
373*e28a4053SRui Paulo 	a = (struct os_alloc_trace *) ptr - 1;
374*e28a4053SRui Paulo 	if (a->magic != ALLOC_MAGIC) {
375*e28a4053SRui Paulo 		wpa_printf(MSG_INFO, "REALLOC[%p]: invalid magic 0x%x%s",
376*e28a4053SRui Paulo 			   a, a->magic,
377*e28a4053SRui Paulo 			   a->magic == FREED_MAGIC ? " (already freed)" : "");
378*e28a4053SRui Paulo 		wpa_trace_show("Invalid os_realloc() call");
379*e28a4053SRui Paulo 		abort();
380*e28a4053SRui Paulo 	}
381*e28a4053SRui Paulo 	n = os_malloc(size);
382*e28a4053SRui Paulo 	if (n == NULL)
383*e28a4053SRui Paulo 		return NULL;
384*e28a4053SRui Paulo 	copy_len = a->len;
385*e28a4053SRui Paulo 	if (copy_len > size)
386*e28a4053SRui Paulo 		copy_len = size;
387*e28a4053SRui Paulo 	os_memcpy(n, a + 1, copy_len);
388*e28a4053SRui Paulo 	os_free(ptr);
389*e28a4053SRui Paulo 	return n;
390*e28a4053SRui Paulo }
391*e28a4053SRui Paulo 
392*e28a4053SRui Paulo 
393*e28a4053SRui Paulo void os_free(void *ptr)
394*e28a4053SRui Paulo {
395*e28a4053SRui Paulo 	struct os_alloc_trace *a;
396*e28a4053SRui Paulo 
397*e28a4053SRui Paulo 	if (ptr == NULL)
398*e28a4053SRui Paulo 		return;
399*e28a4053SRui Paulo 	a = (struct os_alloc_trace *) ptr - 1;
400*e28a4053SRui Paulo 	if (a->magic != ALLOC_MAGIC) {
401*e28a4053SRui Paulo 		wpa_printf(MSG_INFO, "FREE[%p]: invalid magic 0x%x%s",
402*e28a4053SRui Paulo 			   a, a->magic,
403*e28a4053SRui Paulo 			   a->magic == FREED_MAGIC ? " (already freed)" : "");
404*e28a4053SRui Paulo 		wpa_trace_show("Invalid os_free() call");
405*e28a4053SRui Paulo 		abort();
406*e28a4053SRui Paulo 	}
407*e28a4053SRui Paulo 	dl_list_del(&a->list);
408*e28a4053SRui Paulo 	a->magic = FREED_MAGIC;
409*e28a4053SRui Paulo 
410*e28a4053SRui Paulo 	wpa_trace_check_ref(ptr);
411*e28a4053SRui Paulo 	free(a);
412*e28a4053SRui Paulo }
413*e28a4053SRui Paulo 
414*e28a4053SRui Paulo 
415*e28a4053SRui Paulo void * os_zalloc(size_t size)
416*e28a4053SRui Paulo {
417*e28a4053SRui Paulo 	void *ptr = os_malloc(size);
418*e28a4053SRui Paulo 	if (ptr)
419*e28a4053SRui Paulo 		os_memset(ptr, 0, size);
420*e28a4053SRui Paulo 	return ptr;
421*e28a4053SRui Paulo }
422*e28a4053SRui Paulo 
423*e28a4053SRui Paulo 
424*e28a4053SRui Paulo char * os_strdup(const char *s)
425*e28a4053SRui Paulo {
426*e28a4053SRui Paulo 	size_t len;
427*e28a4053SRui Paulo 	char *d;
428*e28a4053SRui Paulo 	len = os_strlen(s);
429*e28a4053SRui Paulo 	d = os_malloc(len + 1);
430*e28a4053SRui Paulo 	if (d == NULL)
431*e28a4053SRui Paulo 		return NULL;
432*e28a4053SRui Paulo 	os_memcpy(d, s, len);
433*e28a4053SRui Paulo 	d[len] = '\0';
434*e28a4053SRui Paulo 	return d;
435*e28a4053SRui Paulo }
436*e28a4053SRui Paulo 
437*e28a4053SRui Paulo #endif /* WPA_TRACE */
438