]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/wpa_supplicant/common.c
This commit was generated by cvs2svn to compensate for changes in r151937,
[FreeBSD/FreeBSD.git] / contrib / wpa_supplicant / common.c
1 /*
2  * Host AP (software wireless LAN access point) user space daemon for
3  * Host AP kernel driver / common helper functions, etc.
4  * Copyright (c) 2002-2005, Jouni Malinen <jkmaline@cc.hut.fi>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * Alternatively, this software may be distributed under the terms of BSD
11  * license.
12  *
13  * See README and COPYING for more details.
14  */
15
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include <string.h>
19 #include <unistd.h>
20 #include <errno.h>
21 #include <stdarg.h>
22 #include <ctype.h>
23 #include <time.h>
24 #include <sys/time.h>
25
26 #include "common.h"
27
28
29 int wpa_debug_level = MSG_INFO;
30 int wpa_debug_show_keys = 0;
31 int wpa_debug_timestamp = 0;
32
33
34 int hostapd_get_rand(u8 *buf, size_t len)
35 {
36 #ifdef CONFIG_NATIVE_WINDOWS
37         int i;
38         /* FIX: use more secure pseudo random number generator */
39         for (i = 0; i < len; i++) {
40                 buf[i] = rand();
41         }
42         return 0;
43 #else /* CONFIG_NATIVE_WINDOWS */
44         FILE *f;
45         size_t rc;
46
47         f = fopen("/dev/urandom", "r");
48         if (f == NULL) {
49                 printf("Could not open /dev/urandom.\n");
50                 return -1;
51         }
52
53         rc = fread(buf, 1, len, f);
54         fclose(f);
55
56         return rc != len ? -1 : 0;
57 #endif /* CONFIG_NATIVE_WINDOWS */
58 }
59
60
61 void hostapd_hexdump(const char *title, const u8 *buf, size_t len)
62 {
63         size_t i;
64         printf("%s - hexdump(len=%lu):", title, (unsigned long) len);
65         for (i = 0; i < len; i++)
66                 printf(" %02x", buf[i]);
67         printf("\n");
68 }
69
70
71 static int hex2num(char c)
72 {
73         if (c >= '0' && c <= '9')
74                 return c - '0';
75         if (c >= 'a' && c <= 'f')
76                 return c - 'a' + 10;
77         if (c >= 'A' && c <= 'F')
78                 return c - 'A' + 10;
79         return -1;
80 }
81
82
83 static int hex2byte(const char *hex)
84 {
85         int a, b;
86         a = hex2num(*hex++);
87         if (a < 0)
88                 return -1;
89         b = hex2num(*hex++);
90         if (b < 0)
91                 return -1;
92         return (a << 4) | b;
93 }
94
95
96 int hwaddr_aton(const char *txt, u8 *addr)
97 {
98         int i;
99
100         for (i = 0; i < 6; i++) {
101                 int a, b;
102
103                 a = hex2num(*txt++);
104                 if (a < 0)
105                         return -1;
106                 b = hex2num(*txt++);
107                 if (b < 0)
108                         return -1;
109                 *addr++ = (a << 4) | b;
110                 if (i < 5 && *txt++ != ':')
111                         return -1;
112         }
113
114         return 0;
115 }
116
117
118 int hexstr2bin(const char *hex, u8 *buf, size_t len)
119 {
120         int i, a;
121         const char *ipos = hex;
122         u8 *opos = buf;
123
124         for (i = 0; i < len; i++) {
125                 a = hex2byte(ipos);
126                 if (a < 0)
127                         return -1;
128                 *opos++ = a;
129                 ipos += 2;
130         }
131         return 0;
132 }
133
134
135 char * rel2abs_path(const char *rel_path)
136 {
137         char *buf = NULL, *cwd, *ret;
138         size_t len = 128, cwd_len, rel_len, ret_len;
139
140         if (rel_path[0] == '/')
141                 return strdup(rel_path);
142
143         for (;;) {
144                 buf = malloc(len);
145                 if (buf == NULL)
146                         return NULL;
147                 cwd = getcwd(buf, len);
148                 if (cwd == NULL) {
149                         free(buf);
150                         if (errno != ERANGE) {
151                                 return NULL;
152                         }
153                         len *= 2;
154                 } else {
155                         break;
156                 }
157         }
158
159         cwd_len = strlen(cwd);
160         rel_len = strlen(rel_path);
161         ret_len = cwd_len + 1 + rel_len + 1;
162         ret = malloc(ret_len);
163         if (ret) {
164                 memcpy(ret, cwd, cwd_len);
165                 ret[cwd_len] = '/';
166                 memcpy(ret + cwd_len + 1, rel_path, rel_len);
167                 ret[ret_len - 1] = '\0';
168         }
169         free(buf);
170         return ret;
171 }
172
173
174 void inc_byte_array(u8 *counter, size_t len)
175 {
176         int pos = len - 1;
177         while (pos >= 0) {
178                 counter[pos]++;
179                 if (counter[pos] != 0)
180                         break;
181                 pos--;
182         }
183 }
184
185
186 void print_char(char c)
187 {
188         if (c >= 32 && c < 127)
189                 printf("%c", c);
190         else
191                 printf("<%02x>", c);
192 }
193
194
195 void fprint_char(FILE *f, char c)
196 {
197         if (c >= 32 && c < 127)
198                 fprintf(f, "%c", c);
199         else
200                 fprintf(f, "<%02x>", c);
201 }
202
203
204 static void wpa_debug_print_timestamp(void)
205 {
206         struct timeval tv;
207         char buf[16];
208
209         if (!wpa_debug_timestamp)
210                 return;
211
212         gettimeofday(&tv, NULL);
213         if (strftime(buf, sizeof(buf), "%b %d %H:%M:%S",
214                      localtime((const time_t *) &tv.tv_sec)) <= 0) {
215                 snprintf(buf, sizeof(buf), "%u", (int) tv.tv_sec);
216         }
217         printf("%s.%06u: ", buf, (unsigned int) tv.tv_usec);
218 }
219
220
221 void wpa_printf(int level, char *fmt, ...)
222 {
223         va_list ap;
224
225         va_start(ap, fmt);
226         if (level >= wpa_debug_level) {
227                 wpa_debug_print_timestamp();
228                 vprintf(fmt, ap);
229                 printf("\n");
230         }
231         va_end(ap);
232 }
233
234
235 static void _wpa_hexdump(int level, const char *title, const u8 *buf,
236                          size_t len, int show)
237 {
238         size_t i;
239         if (level < wpa_debug_level)
240                 return;
241         wpa_debug_print_timestamp();
242         printf("%s - hexdump(len=%lu):", title, (unsigned long) len);
243         if (show) {
244                 for (i = 0; i < len; i++)
245                         printf(" %02x", buf[i]);
246         } else {
247                 printf(" [REMOVED]");
248         }
249         printf("\n");
250 }
251
252 void wpa_hexdump(int level, const char *title, const u8 *buf, size_t len)
253 {
254         _wpa_hexdump(level, title, buf, len, 1);
255 }
256
257
258 void wpa_hexdump_key(int level, const char *title, const u8 *buf, size_t len)
259 {
260         _wpa_hexdump(level, title, buf, len, wpa_debug_show_keys);
261 }
262
263
264 static void _wpa_hexdump_ascii(int level, const char *title, const u8 *buf,
265                                size_t len, int show)
266 {
267         int i, llen;
268         const u8 *pos = buf;
269         const int line_len = 16;
270
271         if (level < wpa_debug_level)
272                 return;
273         wpa_debug_print_timestamp();
274         if (!show) {
275                 printf("%s - hexdump_ascii(len=%lu): [REMOVED]\n",
276                        title, (unsigned long) len);
277                 return;
278         }
279         printf("%s - hexdump_ascii(len=%lu):\n", title, (unsigned long) len);
280         while (len) {
281                 llen = len > line_len ? line_len : len;
282                 printf("    ");
283                 for (i = 0; i < llen; i++)
284                         printf(" %02x", pos[i]);
285                 for (i = llen; i < line_len; i++)
286                         printf("   ");
287                 printf("   ");
288                 for (i = 0; i < llen; i++) {
289                         if (isprint(pos[i]))
290                                 printf("%c", pos[i]);
291                         else
292                                 printf("_");
293                 }
294                 for (i = llen; i < line_len; i++)
295                         printf(" ");
296                 printf("\n");
297                 pos += llen;
298                 len -= llen;
299         }
300 }
301
302
303 void wpa_hexdump_ascii(int level, const char *title, const u8 *buf, size_t len)
304 {
305         _wpa_hexdump_ascii(level, title, buf, len, 1);
306 }
307
308
309 void wpa_hexdump_ascii_key(int level, const char *title, const u8 *buf,
310                            size_t len)
311 {
312         _wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys);
313 }
314
315
316 #ifdef CONFIG_NATIVE_WINDOWS
317
318 #define EPOCHFILETIME (116444736000000000ULL)
319
320 int gettimeofday(struct timeval *tv, struct timezone *tz)
321 {
322         FILETIME ft;
323         LARGE_INTEGER li;
324         ULONGLONG t;
325
326         GetSystemTimeAsFileTime(&ft);
327         li.LowPart = ft.dwLowDateTime;
328         li.HighPart = ft.dwHighDateTime;
329         t = (li.QuadPart - EPOCHFILETIME) / 10;
330         tv->tv_sec = (long) (t / 1000000);
331         tv->tv_usec = (long) (t % 1000000);
332
333         return 0;
334 }
335 #endif /* CONFIG_NATIVE_WINDOWS */