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.
19 #ifdef CONFIG_DEBUG_SYSLOG
21 #endif /* CONFIG_DEBUG_SYSLOG */
24 #ifdef CONFIG_DEBUG_FILE
25 static FILE *out_file = NULL;
26 #endif /* CONFIG_DEBUG_FILE */
27 int wpa_debug_level = MSG_INFO;
28 int wpa_debug_show_keys = 0;
29 int wpa_debug_timestamp = 0;
30 int wpa_debug_syslog = 0;
33 static int hex2num(char c)
35 if (c >= '0' && c <= '9')
37 if (c >= 'a' && c <= 'f')
39 if (c >= 'A' && c <= 'F')
45 static int hex2byte(const char *hex)
59 * hwaddr_aton - Convert ASCII string to MAC address
60 * @txt: MAC address as a string (e.g., "00:11:22:33:44:55")
61 * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
62 * Returns: 0 on success, -1 on failure (e.g., string not a MAC address)
64 int hwaddr_aton(const char *txt, u8 *addr)
68 for (i = 0; i < 6; i++) {
77 *addr++ = (a << 4) | b;
78 if (i < 5 && *txt++ != ':')
87 * hexstr2bin - Convert ASCII hex string into binary data
88 * @hex: ASCII hex string (e.g., "01ab")
89 * @buf: Buffer for the binary data
90 * @len: Length of the text to convert in bytes (of buf); hex will be double
92 * Returns: 0 on success, -1 on failure (invalid hex string)
94 int hexstr2bin(const char *hex, u8 *buf, size_t len)
98 const char *ipos = hex;
101 for (i = 0; i < len; i++) {
113 * inc_byte_array - Increment arbitrary length byte array by one
114 * @counter: Pointer to byte array
115 * @len: Length of the counter in bytes
117 * This function increments the last byte of the counter by one and continues
118 * rolling over to more significant bytes if the byte was incremented from
121 void inc_byte_array(u8 *counter, size_t len)
126 if (counter[pos] != 0)
133 void wpa_get_ntp_timestamp(u8 *buf)
138 /* 64-bit NTP timestamp (time from 1900-01-01 00:00:00) */
140 sec = host_to_be32(now.sec + 2208988800U); /* Epoch to 1900 */
141 /* Estimate 2^32/10^6 = 4295 - 1/32 - 1/512 */
143 usec = host_to_be32(4295 * usec - (usec >> 5) - (usec >> 9));
144 os_memcpy(buf, (u8 *) &sec, 4);
145 os_memcpy(buf + 4, (u8 *) &usec, 4);
150 #ifndef CONFIG_NO_STDOUT_DEBUG
152 void wpa_debug_print_timestamp(void)
156 if (!wpa_debug_timestamp)
160 #ifdef CONFIG_DEBUG_FILE
162 fprintf(out_file, "%ld.%06u: ", (long) tv.sec,
163 (unsigned int) tv.usec);
165 #endif /* CONFIG_DEBUG_FILE */
166 printf("%ld.%06u: ", (long) tv.sec, (unsigned int) tv.usec);
169 void wpa_debug_open_syslog(void)
171 #ifdef CONFIG_DEBUG_SYSLOG
172 openlog("wpa_supplicant", LOG_PID | LOG_NDELAY, LOG_DAEMON);
177 void wpa_debug_close_syslog(void)
179 #ifdef CONFIG_DEBUG_SYSLOG
180 if (wpa_debug_syslog)
185 #ifdef CONFIG_DEBUG_SYSLOG
186 static int syslog_priority(int level)
201 #endif /* CONFIG_DEBUG_SYSLOG */
205 * wpa_printf - conditional printf
206 * @level: priority level (MSG_*) of the message
207 * @fmt: printf format string, followed by optional arguments
209 * This function is used to print conditional debugging and error messages. The
210 * output may be directed to stdout, stderr, and/or syslog based on
213 * Note: New line '\n' is added to the end of the text when printing to stdout.
215 void wpa_printf(int level, char *fmt, ...)
220 if (level >= wpa_debug_level) {
221 #ifdef CONFIG_DEBUG_SYSLOG
222 if (wpa_debug_syslog) {
223 vsyslog(syslog_priority(level), fmt, ap);
225 #endif /* CONFIG_DEBUG_SYSLOG */
226 wpa_debug_print_timestamp();
227 #ifdef CONFIG_DEBUG_FILE
229 vfprintf(out_file, fmt, ap);
230 fprintf(out_file, "\n");
232 #endif /* CONFIG_DEBUG_FILE */
235 #ifdef CONFIG_DEBUG_FILE
237 #endif /* CONFIG_DEBUG_FILE */
238 #ifdef CONFIG_DEBUG_SYSLOG
240 #endif /* CONFIG_DEBUG_SYSLOG */
246 static void _wpa_hexdump(int level, const char *title, const u8 *buf,
247 size_t len, int show)
250 if (level < wpa_debug_level)
252 wpa_debug_print_timestamp();
253 #ifdef CONFIG_DEBUG_FILE
255 fprintf(out_file, "%s - hexdump(len=%lu):",
256 title, (unsigned long) len);
258 fprintf(out_file, " [NULL]");
260 for (i = 0; i < len; i++)
261 fprintf(out_file, " %02x", buf[i]);
263 fprintf(out_file, " [REMOVED]");
265 fprintf(out_file, "\n");
267 #endif /* CONFIG_DEBUG_FILE */
268 printf("%s - hexdump(len=%lu):", title, (unsigned long) len);
272 for (i = 0; i < len; i++)
273 printf(" %02x", buf[i]);
275 printf(" [REMOVED]");
278 #ifdef CONFIG_DEBUG_FILE
280 #endif /* CONFIG_DEBUG_FILE */
283 void wpa_hexdump(int level, const char *title, const u8 *buf, size_t len)
285 _wpa_hexdump(level, title, buf, len, 1);
289 void wpa_hexdump_key(int level, const char *title, const u8 *buf, size_t len)
291 _wpa_hexdump(level, title, buf, len, wpa_debug_show_keys);
295 static void _wpa_hexdump_ascii(int level, const char *title, const u8 *buf,
296 size_t len, int show)
300 const size_t line_len = 16;
302 if (level < wpa_debug_level)
304 wpa_debug_print_timestamp();
305 #ifdef CONFIG_DEBUG_FILE
309 "%s - hexdump_ascii(len=%lu): [REMOVED]\n",
310 title, (unsigned long) len);
315 "%s - hexdump_ascii(len=%lu): [NULL]\n",
316 title, (unsigned long) len);
319 fprintf(out_file, "%s - hexdump_ascii(len=%lu):\n",
320 title, (unsigned long) len);
322 llen = len > line_len ? line_len : len;
323 fprintf(out_file, " ");
324 for (i = 0; i < llen; i++)
325 fprintf(out_file, " %02x", pos[i]);
326 for (i = llen; i < line_len; i++)
327 fprintf(out_file, " ");
328 fprintf(out_file, " ");
329 for (i = 0; i < llen; i++) {
331 fprintf(out_file, "%c", pos[i]);
333 fprintf(out_file, "_");
335 for (i = llen; i < line_len; i++)
336 fprintf(out_file, " ");
337 fprintf(out_file, "\n");
342 #endif /* CONFIG_DEBUG_FILE */
344 printf("%s - hexdump_ascii(len=%lu): [REMOVED]\n",
345 title, (unsigned long) len);
349 printf("%s - hexdump_ascii(len=%lu): [NULL]\n",
350 title, (unsigned long) len);
353 printf("%s - hexdump_ascii(len=%lu):\n", title, (unsigned long) len);
355 llen = len > line_len ? line_len : len;
357 for (i = 0; i < llen; i++)
358 printf(" %02x", pos[i]);
359 for (i = llen; i < line_len; i++)
362 for (i = 0; i < llen; i++) {
364 printf("%c", pos[i]);
368 for (i = llen; i < line_len; i++)
374 #ifdef CONFIG_DEBUG_FILE
376 #endif /* CONFIG_DEBUG_FILE */
380 void wpa_hexdump_ascii(int level, const char *title, const u8 *buf, size_t len)
382 _wpa_hexdump_ascii(level, title, buf, len, 1);
386 void wpa_hexdump_ascii_key(int level, const char *title, const u8 *buf,
389 _wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys);
393 int wpa_debug_open_file(const char *path)
395 #ifdef CONFIG_DEBUG_FILE
398 out_file = fopen(path, "a");
399 if (out_file == NULL) {
400 wpa_printf(MSG_ERROR, "wpa_debug_open_file: Failed to open "
401 "output file, using standard output");
405 setvbuf(out_file, NULL, _IOLBF, 0);
407 #endif /* CONFIG_DEBUG_FILE */
412 void wpa_debug_close_file(void)
414 #ifdef CONFIG_DEBUG_FILE
419 #endif /* CONFIG_DEBUG_FILE */
422 #endif /* CONFIG_NO_STDOUT_DEBUG */
425 #ifndef CONFIG_NO_WPA_MSG
426 static wpa_msg_cb_func wpa_msg_cb = NULL;
428 void wpa_msg_register_cb(wpa_msg_cb_func func)
434 void wpa_msg(void *ctx, int level, char *fmt, ...)
438 const int buflen = 2048;
441 buf = os_malloc(buflen);
443 wpa_printf(MSG_ERROR, "wpa_msg: Failed to allocate message "
448 len = vsnprintf(buf, buflen, fmt, ap);
450 wpa_printf(level, "%s", buf);
452 wpa_msg_cb(ctx, level, buf, len);
455 #endif /* CONFIG_NO_WPA_MSG */
458 static inline int _wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data,
459 size_t len, int uppercase)
462 char *pos = buf, *end = buf + buf_size;
466 for (i = 0; i < len; i++) {
467 ret = os_snprintf(pos, end - pos, uppercase ? "%02X" : "%02x",
469 if (ret < 0 || ret >= end - pos) {
480 * wpa_snprintf_hex - Print data as a hex string into a buffer
481 * @buf: Memory area to use as the output buffer
482 * @buf_size: Maximum buffer size in bytes (should be at least 2 * len + 1)
483 * @data: Data to be printed
484 * @len: Length of data in bytes
485 * Returns: Number of bytes written
487 int wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len)
489 return _wpa_snprintf_hex(buf, buf_size, data, len, 0);
494 * wpa_snprintf_hex_uppercase - Print data as a upper case hex string into buf
495 * @buf: Memory area to use as the output buffer
496 * @buf_size: Maximum buffer size in bytes (should be at least 2 * len + 1)
497 * @data: Data to be printed
498 * @len: Length of data in bytes
499 * Returns: Number of bytes written
501 int wpa_snprintf_hex_uppercase(char *buf, size_t buf_size, const u8 *data,
504 return _wpa_snprintf_hex(buf, buf_size, data, len, 1);
508 #ifdef CONFIG_ANSI_C_EXTRA
511 void perror(const char *s)
513 wpa_printf(MSG_ERROR, "%s: GetLastError: %d",
514 s, (int) GetLastError());
516 #endif /* _WIN32_WCE */
523 int getopt(int argc, char *const argv[], const char *optstring)
525 static int optchr = 1;
529 if (optind >= argc) {
530 /* all arguments processed */
534 if (argv[optind][0] != '-' || argv[optind][1] == '\0') {
535 /* no option characters */
540 if (os_strcmp(argv[optind], "--") == 0) {
541 /* no more options */
546 optopt = argv[optind][optchr];
547 cp = os_strchr(optstring, optopt);
548 if (cp == NULL || optopt == ':') {
549 if (argv[optind][++optchr] == '\0') {
557 /* Argument required */
559 if (argv[optind][optchr + 1]) {
560 /* No space between option and argument */
561 optarg = &argv[optind++][optchr + 1];
562 } else if (++optind >= argc) {
563 /* option requires an argument */
566 /* Argument in the next argv */
567 optarg = argv[optind++];
571 if (argv[optind][++optchr] == '\0') {
579 #endif /* CONFIG_ANSI_C_EXTRA */
582 #ifdef CONFIG_NATIVE_WINDOWS
584 * wpa_unicode2ascii_inplace - Convert unicode string into ASCII
585 * @str: Pointer to string to convert
587 * This function converts a unicode string to ASCII using the same
588 * buffer for output. If UNICODE is not set, the buffer is not
591 void wpa_unicode2ascii_inplace(TCHAR *str)
594 char *dst = (char *) str;
596 *dst++ = (char) *str++;
602 TCHAR * wpa_strdup_tchar(const char *str)
606 buf = os_malloc((strlen(str) + 1) * sizeof(TCHAR));
609 wsprintf(buf, L"%S", str);
612 return os_strdup(str);
615 #endif /* CONFIG_NATIVE_WINDOWS */
619 * wpa_ssid_txt - Convert SSID to a printable string
620 * @ssid: SSID (32-octet string)
621 * @ssid_len: Length of ssid in octets
622 * Returns: Pointer to a printable string
624 * This function can be used to convert SSIDs into printable form. In most
625 * cases, SSIDs do not use unprintable characters, but IEEE 802.11 standard
626 * does not limit the used character set, so anything could be used in an SSID.
628 * This function uses a static buffer, so only one call can be used at the
629 * time, i.e., this is not re-entrant and the returned buffer must be used
630 * before calling this again.
632 const char * wpa_ssid_txt(u8 *ssid, size_t ssid_len)
634 static char ssid_txt[33];
639 os_memcpy(ssid_txt, ssid, ssid_len);
640 ssid_txt[ssid_len] = '\0';
641 for (pos = ssid_txt; *pos != '\0'; pos++) {
642 if ((u8) *pos < 32 || (u8) *pos >= 127)