2 * wpa_supplicant/hostapd / common helper functions, etc.
3 * Copyright (c) 2002-2006, Jouni Malinen <j@w1.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
12 * See README and COPYING for more details.
20 #ifdef CONFIG_DEBUG_FILE
21 static FILE *out_file = NULL;
22 #endif /* CONFIG_DEBUG_FILE */
23 int wpa_debug_level = MSG_INFO;
24 int wpa_debug_show_keys = 0;
25 int wpa_debug_timestamp = 0;
28 static int hex2num(char c)
30 if (c >= '0' && c <= '9')
32 if (c >= 'a' && c <= 'f')
34 if (c >= 'A' && c <= 'F')
40 static int hex2byte(const char *hex)
54 * hwaddr_aton - Convert ASCII string to MAC address
55 * @txt: MAC address as a string (e.g., "00:11:22:33:44:55")
56 * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
57 * Returns: 0 on success, -1 on failure (e.g., string not a MAC address)
59 int hwaddr_aton(const char *txt, u8 *addr)
63 for (i = 0; i < 6; i++) {
72 *addr++ = (a << 4) | b;
73 if (i < 5 && *txt++ != ':')
82 * hexstr2bin - Convert ASCII hex string into binary data
83 * @hex: ASCII hex string (e.g., "01ab")
84 * @buf: Buffer for the binary data
85 * @len: Length of the text to convert in bytes (of buf); hex will be double
87 * Returns: 0 on success, -1 on failure (invalid hex string)
89 int hexstr2bin(const char *hex, u8 *buf, size_t len)
93 const char *ipos = hex;
96 for (i = 0; i < len; i++) {
108 * inc_byte_array - Increment arbitrary length byte array by one
109 * @counter: Pointer to byte array
110 * @len: Length of the counter in bytes
112 * This function increments the last byte of the counter by one and continues
113 * rolling over to more significant bytes if the byte was incremented from
116 void inc_byte_array(u8 *counter, size_t len)
121 if (counter[pos] != 0)
128 void wpa_get_ntp_timestamp(u8 *buf)
133 /* 64-bit NTP timestamp (time from 1900-01-01 00:00:00) */
135 sec = host_to_be32(now.sec + 2208988800U); /* Epoch to 1900 */
136 /* Estimate 2^32/10^6 = 4295 - 1/32 - 1/512 */
138 usec = host_to_be32(4295 * usec - (usec >> 5) - (usec >> 9));
139 os_memcpy(buf, (u8 *) &sec, 4);
140 os_memcpy(buf + 4, (u8 *) &usec, 4);
145 #ifndef CONFIG_NO_STDOUT_DEBUG
147 void wpa_debug_print_timestamp(void)
151 if (!wpa_debug_timestamp)
155 #ifdef CONFIG_DEBUG_FILE
157 fprintf(out_file, "%ld.%06u: ", (long) tv.sec,
158 (unsigned int) tv.usec);
160 #endif /* CONFIG_DEBUG_FILE */
161 printf("%ld.%06u: ", (long) tv.sec, (unsigned int) tv.usec);
166 * wpa_printf - conditional printf
167 * @level: priority level (MSG_*) of the message
168 * @fmt: printf format string, followed by optional arguments
170 * This function is used to print conditional debugging and error messages. The
171 * output may be directed to stdout, stderr, and/or syslog based on
174 * Note: New line '\n' is added to the end of the text when printing to stdout.
176 void wpa_printf(int level, char *fmt, ...)
181 if (level >= wpa_debug_level) {
182 wpa_debug_print_timestamp();
183 #ifdef CONFIG_DEBUG_FILE
185 vfprintf(out_file, fmt, ap);
186 fprintf(out_file, "\n");
188 #endif /* CONFIG_DEBUG_FILE */
191 #ifdef CONFIG_DEBUG_FILE
193 #endif /* CONFIG_DEBUG_FILE */
199 static void _wpa_hexdump(int level, const char *title, const u8 *buf,
200 size_t len, int show)
203 if (level < wpa_debug_level)
205 wpa_debug_print_timestamp();
206 #ifdef CONFIG_DEBUG_FILE
208 fprintf(out_file, "%s - hexdump(len=%lu):",
209 title, (unsigned long) len);
211 fprintf(out_file, " [NULL]");
213 for (i = 0; i < len; i++)
214 fprintf(out_file, " %02x", buf[i]);
216 fprintf(out_file, " [REMOVED]");
218 fprintf(out_file, "\n");
220 #endif /* CONFIG_DEBUG_FILE */
221 printf("%s - hexdump(len=%lu):", title, (unsigned long) len);
225 for (i = 0; i < len; i++)
226 printf(" %02x", buf[i]);
228 printf(" [REMOVED]");
231 #ifdef CONFIG_DEBUG_FILE
233 #endif /* CONFIG_DEBUG_FILE */
236 void wpa_hexdump(int level, const char *title, const u8 *buf, size_t len)
238 _wpa_hexdump(level, title, buf, len, 1);
242 void wpa_hexdump_key(int level, const char *title, const u8 *buf, size_t len)
244 _wpa_hexdump(level, title, buf, len, wpa_debug_show_keys);
248 static void _wpa_hexdump_ascii(int level, const char *title, const u8 *buf,
249 size_t len, int show)
253 const size_t line_len = 16;
255 if (level < wpa_debug_level)
257 wpa_debug_print_timestamp();
258 #ifdef CONFIG_DEBUG_FILE
262 "%s - hexdump_ascii(len=%lu): [REMOVED]\n",
263 title, (unsigned long) len);
268 "%s - hexdump_ascii(len=%lu): [NULL]\n",
269 title, (unsigned long) len);
272 fprintf(out_file, "%s - hexdump_ascii(len=%lu):\n",
273 title, (unsigned long) len);
275 llen = len > line_len ? line_len : len;
276 fprintf(out_file, " ");
277 for (i = 0; i < llen; i++)
278 fprintf(out_file, " %02x", pos[i]);
279 for (i = llen; i < line_len; i++)
280 fprintf(out_file, " ");
281 fprintf(out_file, " ");
282 for (i = 0; i < llen; i++) {
284 fprintf(out_file, "%c", pos[i]);
286 fprintf(out_file, "_");
288 for (i = llen; i < line_len; i++)
289 fprintf(out_file, " ");
290 fprintf(out_file, "\n");
295 #endif /* CONFIG_DEBUG_FILE */
297 printf("%s - hexdump_ascii(len=%lu): [REMOVED]\n",
298 title, (unsigned long) len);
302 printf("%s - hexdump_ascii(len=%lu): [NULL]\n",
303 title, (unsigned long) len);
306 printf("%s - hexdump_ascii(len=%lu):\n", title, (unsigned long) len);
308 llen = len > line_len ? line_len : len;
310 for (i = 0; i < llen; i++)
311 printf(" %02x", pos[i]);
312 for (i = llen; i < line_len; i++)
315 for (i = 0; i < llen; i++) {
317 printf("%c", pos[i]);
321 for (i = llen; i < line_len; i++)
327 #ifdef CONFIG_DEBUG_FILE
329 #endif /* CONFIG_DEBUG_FILE */
333 void wpa_hexdump_ascii(int level, const char *title, const u8 *buf, size_t len)
335 _wpa_hexdump_ascii(level, title, buf, len, 1);
339 void wpa_hexdump_ascii_key(int level, const char *title, const u8 *buf,
342 _wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys);
346 int wpa_debug_open_file(const char *path)
348 #ifdef CONFIG_DEBUG_FILE
351 out_file = fopen(path, "a");
352 if (out_file == NULL) {
353 wpa_printf(MSG_ERROR, "wpa_debug_open_file: Failed to open "
354 "output file, using standard output");
358 setvbuf(out_file, NULL, _IOLBF, 0);
360 #endif /* CONFIG_DEBUG_FILE */
365 void wpa_debug_close_file(void)
367 #ifdef CONFIG_DEBUG_FILE
372 #endif /* CONFIG_DEBUG_FILE */
375 #endif /* CONFIG_NO_STDOUT_DEBUG */
378 #ifndef CONFIG_NO_WPA_MSG
379 static wpa_msg_cb_func wpa_msg_cb = NULL;
381 void wpa_msg_register_cb(wpa_msg_cb_func func)
387 void wpa_msg(void *ctx, int level, char *fmt, ...)
391 const int buflen = 2048;
394 buf = os_malloc(buflen);
396 wpa_printf(MSG_ERROR, "wpa_msg: Failed to allocate message "
401 len = vsnprintf(buf, buflen, fmt, ap);
403 wpa_printf(level, "%s", buf);
405 wpa_msg_cb(ctx, level, buf, len);
408 #endif /* CONFIG_NO_WPA_MSG */
411 static inline int _wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data,
412 size_t len, int uppercase)
415 char *pos = buf, *end = buf + buf_size;
419 for (i = 0; i < len; i++) {
420 ret = os_snprintf(pos, end - pos, uppercase ? "%02X" : "%02x",
422 if (ret < 0 || ret >= end - pos) {
433 * wpa_snprintf_hex - Print data as a hex string into a buffer
434 * @buf: Memory area to use as the output buffer
435 * @buf_size: Maximum buffer size in bytes (should be at least 2 * len + 1)
436 * @data: Data to be printed
437 * @len: Length of data in bytes
438 * Returns: Number of bytes written
440 int wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len)
442 return _wpa_snprintf_hex(buf, buf_size, data, len, 0);
447 * wpa_snprintf_hex_uppercase - Print data as a upper case hex string into buf
448 * @buf: Memory area to use as the output buffer
449 * @buf_size: Maximum buffer size in bytes (should be at least 2 * len + 1)
450 * @data: Data to be printed
451 * @len: Length of data in bytes
452 * Returns: Number of bytes written
454 int wpa_snprintf_hex_uppercase(char *buf, size_t buf_size, const u8 *data,
457 return _wpa_snprintf_hex(buf, buf_size, data, len, 1);
461 #ifdef CONFIG_ANSI_C_EXTRA
464 void perror(const char *s)
466 wpa_printf(MSG_ERROR, "%s: GetLastError: %d",
467 s, (int) GetLastError());
469 #endif /* _WIN32_WCE */
476 int getopt(int argc, char *const argv[], const char *optstring)
478 static int optchr = 1;
482 if (optind >= argc) {
483 /* all arguments processed */
487 if (argv[optind][0] != '-' || argv[optind][1] == '\0') {
488 /* no option characters */
493 if (os_strcmp(argv[optind], "--") == 0) {
494 /* no more options */
499 optopt = argv[optind][optchr];
500 cp = os_strchr(optstring, optopt);
501 if (cp == NULL || optopt == ':') {
502 if (argv[optind][++optchr] == '\0') {
510 /* Argument required */
512 if (argv[optind][optchr + 1]) {
513 /* No space between option and argument */
514 optarg = &argv[optind++][optchr + 1];
515 } else if (++optind >= argc) {
516 /* option requires an argument */
519 /* Argument in the next argv */
520 optarg = argv[optind++];
524 if (argv[optind][++optchr] == '\0') {
532 #endif /* CONFIG_ANSI_C_EXTRA */
535 #ifdef CONFIG_NATIVE_WINDOWS
537 * wpa_unicode2ascii_inplace - Convert unicode string into ASCII
538 * @str: Pointer to string to convert
540 * This function converts a unicode string to ASCII using the same
541 * buffer for output. If UNICODE is not set, the buffer is not
544 void wpa_unicode2ascii_inplace(TCHAR *str)
547 char *dst = (char *) str;
549 *dst++ = (char) *str++;
555 TCHAR * wpa_strdup_tchar(const char *str)
559 buf = os_malloc((strlen(str) + 1) * sizeof(TCHAR));
562 wsprintf(buf, L"%S", str);
565 return os_strdup(str);
568 #endif /* CONFIG_NATIVE_WINDOWS */
572 * wpa_ssid_txt - Convert SSID to a printable string
573 * @ssid: SSID (32-octet string)
574 * @ssid_len: Length of ssid in octets
575 * Returns: Pointer to a printable string
577 * This function can be used to convert SSIDs into printable form. In most
578 * cases, SSIDs do not use unprintable characters, but IEEE 802.11 standard
579 * does not limit the used character set, so anything could be used in an SSID.
581 * This function uses a static buffer, so only one call can be used at the
582 * time, i.e., this is not re-entrant and the returned buffer must be used
583 * before calling this again.
585 const char * wpa_ssid_txt(u8 *ssid, size_t ssid_len)
587 static char ssid_txt[33];
592 os_memcpy(ssid_txt, ssid, ssid_len);
593 ssid_txt[ssid_len] = '\0';
594 for (pos = ssid_txt; *pos != '\0'; pos++) {
595 if ((u8) *pos < 32 || (u8) *pos >= 127)