Re-enable hardware UDP/TCP checksum calculation with pseudo header on
[dragonfly/port-amd64.git] / contrib / wpa_supplicant-0.4.9 / common.c
blob4b756d8f9292d1f9a8d87bbca43f7a70b211b437
1 /*
2 * wpa_supplicant/hostapd / common helper functions, etc.
3 * Copyright (c) 2002-2005, Jouni Malinen <jkmaline@cc.hut.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
10 * license.
12 * See README and COPYING for more details.
15 #include <stdlib.h>
16 #include <stdio.h>
17 #include <string.h>
18 #include <unistd.h>
19 #include <errno.h>
20 #include <stdarg.h>
21 #include <ctype.h>
22 #include <time.h>
23 #include <sys/time.h>
24 #ifdef CONFIG_NATIVE_WINDOWS
25 #include <winsock2.h>
26 #include <wincrypt.h>
27 #endif /* CONFIG_NATIVE_WINDOWS */
29 #include "common.h"
32 int wpa_debug_level = MSG_INFO;
33 int wpa_debug_show_keys = 0;
34 int wpa_debug_timestamp = 0;
37 int hostapd_get_rand(u8 *buf, size_t len)
39 #ifdef CONFIG_NATIVE_WINDOWS
40 HCRYPTPROV prov;
41 BOOL ret;
43 if (!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL,
44 CRYPT_VERIFYCONTEXT))
45 return -1;
47 ret = CryptGenRandom(prov, len, buf);
48 CryptReleaseContext(prov, 0);
50 return ret ? 0 : -1;
51 #else /* CONFIG_NATIVE_WINDOWS */
52 FILE *f;
53 size_t rc;
55 f = fopen("/dev/urandom", "r");
56 if (f == NULL) {
57 printf("Could not open /dev/urandom.\n");
58 return -1;
61 rc = fread(buf, 1, len, f);
62 fclose(f);
64 return rc != len ? -1 : 0;
65 #endif /* CONFIG_NATIVE_WINDOWS */
69 void hostapd_hexdump(const char *title, const u8 *buf, size_t len)
71 size_t i;
72 printf("%s - hexdump(len=%lu):", title, (unsigned long) len);
73 for (i = 0; i < len; i++)
74 printf(" %02x", buf[i]);
75 printf("\n");
79 static int hex2num(char c)
81 if (c >= '0' && c <= '9')
82 return c - '0';
83 if (c >= 'a' && c <= 'f')
84 return c - 'a' + 10;
85 if (c >= 'A' && c <= 'F')
86 return c - 'A' + 10;
87 return -1;
91 static int hex2byte(const char *hex)
93 int a, b;
94 a = hex2num(*hex++);
95 if (a < 0)
96 return -1;
97 b = hex2num(*hex++);
98 if (b < 0)
99 return -1;
100 return (a << 4) | b;
105 * hwaddr_aton - Convert ASCII string to MAC address
106 * @txt: MAC address as a string (e.g., "00:11:22:33:44:55")
107 * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
108 * Returns: 0 on success, -1 on failure (e.g., string not a MAC address)
110 int hwaddr_aton(const char *txt, u8 *addr)
112 int i;
114 for (i = 0; i < 6; i++) {
115 int a, b;
117 a = hex2num(*txt++);
118 if (a < 0)
119 return -1;
120 b = hex2num(*txt++);
121 if (b < 0)
122 return -1;
123 *addr++ = (a << 4) | b;
124 if (i < 5 && *txt++ != ':')
125 return -1;
128 return 0;
133 * hexstr2bin - Convert ASCII hex string into binary data
134 * @hex: ASCII hex string (e.g., "01ab")
135 * @buf: Buffer for the binary data
136 * @len: Length of the text to convert in bytes (of buf); hex will be double
137 * this size
138 * Returns: 0 on success, -1 on failure (invalid hex string)
140 int hexstr2bin(const char *hex, u8 *buf, size_t len)
142 int i, a;
143 const char *ipos = hex;
144 u8 *opos = buf;
146 for (i = 0; i < len; i++) {
147 a = hex2byte(ipos);
148 if (a < 0)
149 return -1;
150 *opos++ = a;
151 ipos += 2;
153 return 0;
157 char * rel2abs_path(const char *rel_path)
159 char *buf = NULL, *cwd, *ret;
160 size_t len = 128, cwd_len, rel_len, ret_len;
162 if (rel_path[0] == '/')
163 return strdup(rel_path);
165 for (;;) {
166 buf = malloc(len);
167 if (buf == NULL)
168 return NULL;
169 cwd = getcwd(buf, len);
170 if (cwd == NULL) {
171 free(buf);
172 if (errno != ERANGE) {
173 return NULL;
175 len *= 2;
176 } else {
177 break;
181 cwd_len = strlen(cwd);
182 rel_len = strlen(rel_path);
183 ret_len = cwd_len + 1 + rel_len + 1;
184 ret = malloc(ret_len);
185 if (ret) {
186 memcpy(ret, cwd, cwd_len);
187 ret[cwd_len] = '/';
188 memcpy(ret + cwd_len + 1, rel_path, rel_len);
189 ret[ret_len - 1] = '\0';
191 free(buf);
192 return ret;
197 * inc_byte_array - Increment arbitrary length byte array by one
198 * @counter: Pointer to byte array
199 * @len: Length of the counter in bytes
201 * This function increments the last byte of the counter by one and continues
202 * rolling over to more significant bytes if the byte was incremented from
203 * 0xff to 0x00.
205 void inc_byte_array(u8 *counter, size_t len)
207 int pos = len - 1;
208 while (pos >= 0) {
209 counter[pos]++;
210 if (counter[pos] != 0)
211 break;
212 pos--;
217 void print_char(char c)
219 if (c >= 32 && c < 127)
220 printf("%c", c);
221 else
222 printf("<%02x>", c);
226 void fprint_char(FILE *f, char c)
228 if (c >= 32 && c < 127)
229 fprintf(f, "%c", c);
230 else
231 fprintf(f, "<%02x>", c);
235 #ifndef CONFIG_NO_STDOUT_DEBUG
237 void wpa_debug_print_timestamp(void)
239 struct timeval tv;
240 char buf[16];
242 if (!wpa_debug_timestamp)
243 return;
245 gettimeofday(&tv, NULL);
246 if (strftime(buf, sizeof(buf), "%b %d %H:%M:%S",
247 localtime((const time_t *) &tv.tv_sec)) <= 0) {
248 snprintf(buf, sizeof(buf), "%u", (int) tv.tv_sec);
250 printf("%s.%06u: ", buf, (unsigned int) tv.tv_usec);
255 * wpa_printf - conditional printf
256 * @level: priority level (MSG_*) of the message
257 * @fmt: printf format string, followed by optional arguments
259 * This function is used to print conditional debugging and error messages. The
260 * output may be directed to stdout, stderr, and/or syslog based on
261 * configuration.
263 * Note: New line '\n' is added to the end of the text when printing to stdout.
265 void wpa_printf(int level, char *fmt, ...)
267 va_list ap;
269 va_start(ap, fmt);
270 if (level >= wpa_debug_level) {
271 wpa_debug_print_timestamp();
272 vprintf(fmt, ap);
273 printf("\n");
275 va_end(ap);
279 static void _wpa_hexdump(int level, const char *title, const u8 *buf,
280 size_t len, int show)
282 size_t i;
283 if (level < wpa_debug_level)
284 return;
285 wpa_debug_print_timestamp();
286 printf("%s - hexdump(len=%lu):", title, (unsigned long) len);
287 if (buf == NULL) {
288 printf(" [NULL]");
289 } else if (show) {
290 for (i = 0; i < len; i++)
291 printf(" %02x", buf[i]);
292 } else {
293 printf(" [REMOVED]");
295 printf("\n");
298 void wpa_hexdump(int level, const char *title, const u8 *buf, size_t len)
300 _wpa_hexdump(level, title, buf, len, 1);
304 void wpa_hexdump_key(int level, const char *title, const u8 *buf, size_t len)
306 _wpa_hexdump(level, title, buf, len, wpa_debug_show_keys);
310 static void _wpa_hexdump_ascii(int level, const char *title, const u8 *buf,
311 size_t len, int show)
313 int i, llen;
314 const u8 *pos = buf;
315 const int line_len = 16;
317 if (level < wpa_debug_level)
318 return;
319 wpa_debug_print_timestamp();
320 if (!show) {
321 printf("%s - hexdump_ascii(len=%lu): [REMOVED]\n",
322 title, (unsigned long) len);
323 return;
325 if (buf == NULL) {
326 printf("%s - hexdump_ascii(len=%lu): [NULL]\n",
327 title, (unsigned long) len);
328 return;
330 printf("%s - hexdump_ascii(len=%lu):\n", title, (unsigned long) len);
331 while (len) {
332 llen = len > line_len ? line_len : len;
333 printf(" ");
334 for (i = 0; i < llen; i++)
335 printf(" %02x", pos[i]);
336 for (i = llen; i < line_len; i++)
337 printf(" ");
338 printf(" ");
339 for (i = 0; i < llen; i++) {
340 if (isprint(pos[i]))
341 printf("%c", pos[i]);
342 else
343 printf("_");
345 for (i = llen; i < line_len; i++)
346 printf(" ");
347 printf("\n");
348 pos += llen;
349 len -= llen;
354 void wpa_hexdump_ascii(int level, const char *title, const u8 *buf, size_t len)
356 _wpa_hexdump_ascii(level, title, buf, len, 1);
360 void wpa_hexdump_ascii_key(int level, const char *title, const u8 *buf,
361 size_t len)
363 _wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys);
366 #endif /* CONFIG_NO_STDOUT_DEBUG */
369 #ifdef CONFIG_NATIVE_WINDOWS
371 #define EPOCHFILETIME (116444736000000000ULL)
373 int gettimeofday(struct timeval *tv, struct timezone *tz)
375 FILETIME ft;
376 LARGE_INTEGER li;
377 ULONGLONG t;
379 GetSystemTimeAsFileTime(&ft);
380 li.LowPart = ft.dwLowDateTime;
381 li.HighPart = ft.dwHighDateTime;
382 t = (li.QuadPart - EPOCHFILETIME) / 10;
383 tv->tv_sec = (long) (t / 1000000);
384 tv->tv_usec = (long) (t % 1000000);
386 return 0;
388 #endif /* CONFIG_NATIVE_WINDOWS */